Uname: Linux business55.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
Software: LiteSpeed
PHP version: 8.1.31 [ PHP INFO ] PHP os: Linux
Server Ip: 162.213.251.212
Your Ip: 3.143.239.189
User: allssztx (535) | Group: allssztx (533)
Safe Mode: OFF
Disable Function:
NONE

name : zipEntry.js
"use strict";

var StringReader = require("./stringReader.js");
var utils = require("./utils.js");
var CompressedObject = require("./compressedObject.js");
var pizzipProto = require("./object.js");
var support = require("./support.js");
var MADE_BY_DOS = 0x00;
var MADE_BY_UNIX = 0x03;

// class ZipEntry {{{
/**
 * An entry in the zip file.
 * @constructor
 * @param {Object} options Options of the current file.
 * @param {Object} loadOptions Options for loading the stream.
 */
function ZipEntry(options, loadOptions) {
  this.options = options;
  this.loadOptions = loadOptions;
}
ZipEntry.prototype = {
  /**
   * say if the file is encrypted.
   * @return {boolean} true if the file is encrypted, false otherwise.
   */
  isEncrypted: function isEncrypted() {
    // bit 1 is set
    return (this.bitFlag & 0x0001) === 0x0001;
  },
  /**
   * say if the file has utf-8 filename/comment.
   * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
   */
  useUTF8: function useUTF8() {
    // bit 11 is set
    return (this.bitFlag & 0x0800) === 0x0800;
  },
  /**
   * Prepare the function used to generate the compressed content from this ZipFile.
   * @param {DataReader} reader the reader to use.
   * @param {number} from the offset from where we should read the data.
   * @param {number} length the length of the data to read.
   * @return {Function} the callback to get the compressed content (the type depends of the DataReader class).
   */
  prepareCompressedContent: function prepareCompressedContent(reader, from, length) {
    return function () {
      var previousIndex = reader.index;
      reader.setIndex(from);
      var compressedFileData = reader.readData(length);
      reader.setIndex(previousIndex);
      return compressedFileData;
    };
  },
  /**
   * Prepare the function used to generate the uncompressed content from this ZipFile.
   * @param {DataReader} reader the reader to use.
   * @param {number} from the offset from where we should read the data.
   * @param {number} length the length of the data to read.
   * @param {PizZip.compression} compression the compression used on this file.
   * @param {number} uncompressedSize the uncompressed size to expect.
   * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class).
   */
  prepareContent: function prepareContent(reader, from, length, compression, uncompressedSize) {
    return function () {
      var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent());
      var uncompressedFileData = compression.uncompress(compressedFileData);
      if (uncompressedFileData.length !== uncompressedSize) {
        throw new Error("Bug : uncompressed data size mismatch");
      }
      return uncompressedFileData;
    };
  },
  /**
   * Read the local part of a zip file and add the info in this object.
   * @param {DataReader} reader the reader to use.
   */
  readLocalPart: function readLocalPart(reader) {
    // we already know everything from the central dir !
    // If the central dir data are false, we are doomed.
    // On the bright side, the local part is scary  : zip64, data descriptors, both, etc.
    // The less data we get here, the more reliable this should be.
    // Let's skip the whole header and dash to the data !
    reader.skip(22);
    // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
    // Strangely, the filename here is OK.
    // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
    // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
    // Search "unzip mismatching "local" filename continuing with "central" filename version" on
    // the internet.
    //
    // I think I see the logic here : the central directory is used to display
    // content and the local directory is used to extract the files. Mixing / and \
    // may be used to display \ to windows users and use / when extracting the files.
    // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
    this.fileNameLength = reader.readInt(2);
    var localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
    this.fileName = reader.readData(this.fileNameLength);
    reader.skip(localExtraFieldsLength);
    if (this.compressedSize === -1 || this.uncompressedSize === -1) {
      throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)");
    }
    var compression = utils.findCompression(this.compressionMethod);
    if (compression === null) {
      // no compression found
      throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")");
    }
    this.decompressed = new CompressedObject();
    this.decompressed.compressedSize = this.compressedSize;
    this.decompressed.uncompressedSize = this.uncompressedSize;
    this.decompressed.crc32 = this.crc32;
    this.decompressed.compressionMethod = this.compressionMethod;
    this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression);
    this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize);

    // we need to compute the crc32...
    if (this.loadOptions.checkCRC32) {
      this.decompressed = utils.transformTo("string", this.decompressed.getContent());
      if (pizzipProto.crc32(this.decompressed) !== this.crc32) {
        throw new Error("Corrupted zip : CRC32 mismatch");
      }
    }
  },
  /**
   * Read the central part of a zip file and add the info in this object.
   * @param {DataReader} reader the reader to use.
   */
  readCentralPart: function readCentralPart(reader) {
    this.versionMadeBy = reader.readInt(2);
    this.versionNeeded = reader.readInt(2);
    this.bitFlag = reader.readInt(2);
    this.compressionMethod = reader.readString(2);
    this.date = reader.readDate();
    this.crc32 = reader.readInt(4);
    this.compressedSize = reader.readInt(4);
    this.uncompressedSize = reader.readInt(4);
    this.fileNameLength = reader.readInt(2);
    this.extraFieldsLength = reader.readInt(2);
    this.fileCommentLength = reader.readInt(2);
    this.diskNumberStart = reader.readInt(2);
    this.internalFileAttributes = reader.readInt(2);
    this.externalFileAttributes = reader.readInt(4);
    this.localHeaderOffset = reader.readInt(4);
    if (this.isEncrypted()) {
      throw new Error("Encrypted zip are not supported");
    }
    this.fileName = reader.readData(this.fileNameLength);
    this.readExtraFields(reader);
    this.parseZIP64ExtraField(reader);
    this.fileComment = reader.readData(this.fileCommentLength);
  },
  /**
   * Parse the external file attributes and get the unix/dos permissions.
   */
  processAttributes: function processAttributes() {
    this.unixPermissions = null;
    this.dosPermissions = null;
    var madeBy = this.versionMadeBy >> 8;

    // Check if we have the DOS directory flag set.
    // We look for it in the DOS and UNIX permissions
    // but some unknown platform could set it as a compatibility flag.
    this.dir = !!(this.externalFileAttributes & 0x0010);
    if (madeBy === MADE_BY_DOS) {
      // first 6 bits (0 to 5)
      this.dosPermissions = this.externalFileAttributes & 0x3f;
    }
    if (madeBy === MADE_BY_UNIX) {
      this.unixPermissions = this.externalFileAttributes >> 16 & 0xffff;
      // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8);
    }

    // fail safe : if the name ends with a / it probably means a folder
    if (!this.dir && this.fileNameStr.slice(-1) === "/") {
      this.dir = true;
    }
  },
  /**
   * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
   */
  parseZIP64ExtraField: function parseZIP64ExtraField() {
    if (!this.extraFields[0x0001]) {
      return;
    }

    // should be something, preparing the extra reader
    var extraReader = new StringReader(this.extraFields[0x0001].value);

    // I really hope that these 64bits integer can fit in 32 bits integer, because js
    // won't let us have more.
    if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {
      this.uncompressedSize = extraReader.readInt(8);
    }
    if (this.compressedSize === utils.MAX_VALUE_32BITS) {
      this.compressedSize = extraReader.readInt(8);
    }
    if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {
      this.localHeaderOffset = extraReader.readInt(8);
    }
    if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {
      this.diskNumberStart = extraReader.readInt(4);
    }
  },
  /**
   * Read the central part of a zip file and add the info in this object.
   * @param {DataReader} reader the reader to use.
   */
  readExtraFields: function readExtraFields(reader) {
    var start = reader.index;
    var extraFieldId, extraFieldLength, extraFieldValue;
    this.extraFields = this.extraFields || {};
    while (reader.index < start + this.extraFieldsLength) {
      extraFieldId = reader.readInt(2);
      extraFieldLength = reader.readInt(2);
      extraFieldValue = reader.readString(extraFieldLength);
      this.extraFields[extraFieldId] = {
        id: extraFieldId,
        length: extraFieldLength,
        value: extraFieldValue
      };
    }
  },
  /**
   * Apply an UTF8 transformation if needed.
   */
  handleUTF8: function handleUTF8() {
    var decodeParamType = support.uint8array ? "uint8array" : "array";
    if (this.useUTF8()) {
      this.fileNameStr = pizzipProto.utf8decode(this.fileName);
      this.fileCommentStr = pizzipProto.utf8decode(this.fileComment);
    } else {
      var upath = this.findExtraFieldUnicodePath();
      if (upath !== null) {
        this.fileNameStr = upath;
      } else {
        var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName);
        this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray);
      }
      var ucomment = this.findExtraFieldUnicodeComment();
      if (ucomment !== null) {
        this.fileCommentStr = ucomment;
      } else {
        var commentByteArray = utils.transformTo(decodeParamType, this.fileComment);
        this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray);
      }
    }
  },
  /**
   * Find the unicode path declared in the extra field, if any.
   * @return {String} the unicode path, null otherwise.
   */
  findExtraFieldUnicodePath: function findExtraFieldUnicodePath() {
    var upathField = this.extraFields[0x7075];
    if (upathField) {
      var extraReader = new StringReader(upathField.value);

      // wrong version
      if (extraReader.readInt(1) !== 1) {
        return null;
      }

      // the crc of the filename changed, this field is out of date.
      if (pizzipProto.crc32(this.fileName) !== extraReader.readInt(4)) {
        return null;
      }
      return pizzipProto.utf8decode(extraReader.readString(upathField.length - 5));
    }
    return null;
  },
  /**
   * Find the unicode comment declared in the extra field, if any.
   * @return {String} the unicode comment, null otherwise.
   */
  findExtraFieldUnicodeComment: function findExtraFieldUnicodeComment() {
    var ucommentField = this.extraFields[0x6375];
    if (ucommentField) {
      var extraReader = new StringReader(ucommentField.value);

      // wrong version
      if (extraReader.readInt(1) !== 1) {
        return null;
      }

      // the crc of the comment changed, this field is out of date.
      if (pizzipProto.crc32(this.fileComment) !== extraReader.readInt(4)) {
        return null;
      }
      return pizzipProto.utf8decode(extraReader.readString(ucommentField.length - 5));
    }
    return null;
  }
};
module.exports = ZipEntry;
© 2025 GrazzMean-Shell