| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 | 
							- var Utils = require("./util"),
 
-     Headers = require("./headers"),
 
-     Constants = Utils.Constants,
 
-     Methods = require("./methods");
 
- module.exports = function (/** object */ options, /*Buffer*/ input) {
 
-     var _centralHeader = new Headers.EntryHeader(),
 
-         _entryName = Buffer.alloc(0),
 
-         _comment = Buffer.alloc(0),
 
-         _isDirectory = false,
 
-         uncompressedData = null,
 
-         _extra = Buffer.alloc(0),
 
-         _extralocal = Buffer.alloc(0),
 
-         _efs = true;
 
-     // assign options
 
-     const opts = options;
 
-     const decoder = typeof opts.decoder === "object" ? opts.decoder : Utils.decoder;
 
-     _efs = decoder.hasOwnProperty("efs") ? decoder.efs : false;
 
-     function getCompressedDataFromZip() {
 
-         //if (!input || !Buffer.isBuffer(input)) {
 
-         if (!input || !(input instanceof Uint8Array)) {
 
-             return Buffer.alloc(0);
 
-         }
 
-         _extralocal = _centralHeader.loadLocalHeaderFromBinary(input);
 
-         return input.slice(_centralHeader.realDataOffset, _centralHeader.realDataOffset + _centralHeader.compressedSize);
 
-     }
 
-     function crc32OK(data) {
 
-         // if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the local header is written
 
-         if (!_centralHeader.flags_desc) {
 
-             if (Utils.crc32(data) !== _centralHeader.localHeader.crc) {
 
-                 return false;
 
-             }
 
-         } else {
 
-             const descriptor = {};
 
-             const dataEndOffset = _centralHeader.realDataOffset + _centralHeader.compressedSize;
 
-             // no descriptor after compressed data, instead new local header
 
-             if (input.readUInt32LE(dataEndOffset) == Constants.LOCSIG || input.readUInt32LE(dataEndOffset) == Constants.CENSIG) {
 
-                 throw Utils.Errors.DESCRIPTOR_NOT_EXIST();
 
-             }
 
-             // get decriptor data
 
-             if (input.readUInt32LE(dataEndOffset) == Constants.EXTSIG) {
 
-                 // descriptor with signature
 
-                 descriptor.crc = input.readUInt32LE(dataEndOffset + Constants.EXTCRC);
 
-                 descriptor.compressedSize = input.readUInt32LE(dataEndOffset + Constants.EXTSIZ);
 
-                 descriptor.size = input.readUInt32LE(dataEndOffset + Constants.EXTLEN);
 
-             } else if (input.readUInt16LE(dataEndOffset + 12) === 0x4b50) {
 
-                 // descriptor without signature (we check is new header starting where we expect)
 
-                 descriptor.crc = input.readUInt32LE(dataEndOffset + Constants.EXTCRC - 4);
 
-                 descriptor.compressedSize = input.readUInt32LE(dataEndOffset + Constants.EXTSIZ - 4);
 
-                 descriptor.size = input.readUInt32LE(dataEndOffset + Constants.EXTLEN - 4);
 
-             } else {
 
-                 throw Utils.Errors.DESCRIPTOR_UNKNOWN();
 
-             }
 
-             // check data integrity
 
-             if (descriptor.compressedSize !== _centralHeader.compressedSize || descriptor.size !== _centralHeader.size || descriptor.crc !== _centralHeader.crc) {
 
-                 throw Utils.Errors.DESCRIPTOR_FAULTY();
 
-             }
 
-             if (Utils.crc32(data) !== descriptor.crc) {
 
-                 return false;
 
-             }
 
-             // @TODO: zip64 bit descriptor fields
 
-             // if bit 3 is set and any value in local header "zip64 Extended information" extra field are set 0 (place holder)
 
-             // then 64-bit descriptor format is used instead of 32-bit
 
-             // central header - "zip64 Extended information" extra field should store real values and not place holders
 
-         }
 
-         return true;
 
-     }
 
-     function decompress(/*Boolean*/ async, /*Function*/ callback, /*String, Buffer*/ pass) {
 
-         if (typeof callback === "undefined" && typeof async === "string") {
 
-             pass = async;
 
-             async = void 0;
 
-         }
 
-         if (_isDirectory) {
 
-             if (async && callback) {
 
-                 callback(Buffer.alloc(0), Utils.Errors.DIRECTORY_CONTENT_ERROR()); //si added error.
 
-             }
 
-             return Buffer.alloc(0);
 
-         }
 
-         var compressedData = getCompressedDataFromZip();
 
-         if (compressedData.length === 0) {
 
-             // File is empty, nothing to decompress.
 
-             if (async && callback) callback(compressedData);
 
-             return compressedData;
 
-         }
 
-         if (_centralHeader.encrypted) {
 
-             if ("string" !== typeof pass && !Buffer.isBuffer(pass)) {
 
-                 throw Utils.Errors.INVALID_PASS_PARAM();
 
-             }
 
-             compressedData = Methods.ZipCrypto.decrypt(compressedData, _centralHeader, pass);
 
-         }
 
-         var data = Buffer.alloc(_centralHeader.size);
 
-         switch (_centralHeader.method) {
 
-             case Utils.Constants.STORED:
 
-                 compressedData.copy(data);
 
-                 if (!crc32OK(data)) {
 
-                     if (async && callback) callback(data, Utils.Errors.BAD_CRC()); //si added error
 
-                     throw Utils.Errors.BAD_CRC();
 
-                 } else {
 
-                     //si added otherwise did not seem to return data.
 
-                     if (async && callback) callback(data);
 
-                     return data;
 
-                 }
 
-             case Utils.Constants.DEFLATED:
 
-                 var inflater = new Methods.Inflater(compressedData, _centralHeader.size);
 
-                 if (!async) {
 
-                     const result = inflater.inflate(data);
 
-                     result.copy(data, 0);
 
-                     if (!crc32OK(data)) {
 
-                         throw Utils.Errors.BAD_CRC(`"${decoder.decode(_entryName)}"`);
 
-                     }
 
-                     return data;
 
-                 } else {
 
-                     inflater.inflateAsync(function (result) {
 
-                         result.copy(result, 0);
 
-                         if (callback) {
 
-                             if (!crc32OK(result)) {
 
-                                 callback(result, Utils.Errors.BAD_CRC()); //si added error
 
-                             } else {
 
-                                 callback(result);
 
-                             }
 
-                         }
 
-                     });
 
-                 }
 
-                 break;
 
-             default:
 
-                 if (async && callback) callback(Buffer.alloc(0), Utils.Errors.UNKNOWN_METHOD());
 
-                 throw Utils.Errors.UNKNOWN_METHOD();
 
-         }
 
-     }
 
-     function compress(/*Boolean*/ async, /*Function*/ callback) {
 
-         if ((!uncompressedData || !uncompressedData.length) && Buffer.isBuffer(input)) {
 
-             // no data set or the data wasn't changed to require recompression
 
-             if (async && callback) callback(getCompressedDataFromZip());
 
-             return getCompressedDataFromZip();
 
-         }
 
-         if (uncompressedData.length && !_isDirectory) {
 
-             var compressedData;
 
-             // Local file header
 
-             switch (_centralHeader.method) {
 
-                 case Utils.Constants.STORED:
 
-                     _centralHeader.compressedSize = _centralHeader.size;
 
-                     compressedData = Buffer.alloc(uncompressedData.length);
 
-                     uncompressedData.copy(compressedData);
 
-                     if (async && callback) callback(compressedData);
 
-                     return compressedData;
 
-                 default:
 
-                 case Utils.Constants.DEFLATED:
 
-                     var deflater = new Methods.Deflater(uncompressedData);
 
-                     if (!async) {
 
-                         var deflated = deflater.deflate();
 
-                         _centralHeader.compressedSize = deflated.length;
 
-                         return deflated;
 
-                     } else {
 
-                         deflater.deflateAsync(function (data) {
 
-                             compressedData = Buffer.alloc(data.length);
 
-                             _centralHeader.compressedSize = data.length;
 
-                             data.copy(compressedData);
 
-                             callback && callback(compressedData);
 
-                         });
 
-                     }
 
-                     deflater = null;
 
-                     break;
 
-             }
 
-         } else if (async && callback) {
 
-             callback(Buffer.alloc(0));
 
-         } else {
 
-             return Buffer.alloc(0);
 
-         }
 
-     }
 
-     function readUInt64LE(buffer, offset) {
 
-         return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
 
-     }
 
-     function parseExtra(data) {
 
-         try {
 
-             var offset = 0;
 
-             var signature, size, part;
 
-             while (offset + 4 < data.length) {
 
-                 signature = data.readUInt16LE(offset);
 
-                 offset += 2;
 
-                 size = data.readUInt16LE(offset);
 
-                 offset += 2;
 
-                 part = data.slice(offset, offset + size);
 
-                 offset += size;
 
-                 if (Constants.ID_ZIP64 === signature) {
 
-                     parseZip64ExtendedInformation(part);
 
-                 }
 
-             }
 
-         } catch (error) {
 
-             throw Utils.Errors.EXTRA_FIELD_PARSE_ERROR();
 
-         }
 
-     }
 
-     //Override header field values with values from the ZIP64 extra field
 
-     function parseZip64ExtendedInformation(data) {
 
-         var size, compressedSize, offset, diskNumStart;
 
-         if (data.length >= Constants.EF_ZIP64_SCOMP) {
 
-             size = readUInt64LE(data, Constants.EF_ZIP64_SUNCOMP);
 
-             if (_centralHeader.size === Constants.EF_ZIP64_OR_32) {
 
-                 _centralHeader.size = size;
 
-             }
 
-         }
 
-         if (data.length >= Constants.EF_ZIP64_RHO) {
 
-             compressedSize = readUInt64LE(data, Constants.EF_ZIP64_SCOMP);
 
-             if (_centralHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
 
-                 _centralHeader.compressedSize = compressedSize;
 
-             }
 
-         }
 
-         if (data.length >= Constants.EF_ZIP64_DSN) {
 
-             offset = readUInt64LE(data, Constants.EF_ZIP64_RHO);
 
-             if (_centralHeader.offset === Constants.EF_ZIP64_OR_32) {
 
-                 _centralHeader.offset = offset;
 
-             }
 
-         }
 
-         if (data.length >= Constants.EF_ZIP64_DSN + 4) {
 
-             diskNumStart = data.readUInt32LE(Constants.EF_ZIP64_DSN);
 
-             if (_centralHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
 
-                 _centralHeader.diskNumStart = diskNumStart;
 
-             }
 
-         }
 
-     }
 
-     return {
 
-         get entryName() {
 
-             return decoder.decode(_entryName);
 
-         },
 
-         get rawEntryName() {
 
-             return _entryName;
 
-         },
 
-         set entryName(val) {
 
-             _entryName = Utils.toBuffer(val, decoder.encode);
 
-             var lastChar = _entryName[_entryName.length - 1];
 
-             _isDirectory = lastChar === 47 || lastChar === 92;
 
-             _centralHeader.fileNameLength = _entryName.length;
 
-         },
 
-         get efs() {
 
-             if (typeof _efs === "function") {
 
-                 return _efs(this.entryName);
 
-             } else {
 
-                 return _efs;
 
-             }
 
-         },
 
-         get extra() {
 
-             return _extra;
 
-         },
 
-         set extra(val) {
 
-             _extra = val;
 
-             _centralHeader.extraLength = val.length;
 
-             parseExtra(val);
 
-         },
 
-         get comment() {
 
-             return decoder.decode(_comment);
 
-         },
 
-         set comment(val) {
 
-             _comment = Utils.toBuffer(val, decoder.encode);
 
-             _centralHeader.commentLength = _comment.length;
 
-             if (_comment.length > 0xffff) throw Utils.Errors.COMMENT_TOO_LONG();
 
-         },
 
-         get name() {
 
-             var n = decoder.decode(_entryName);
 
-             return _isDirectory
 
-                 ? n
 
-                       .substr(n.length - 1)
 
-                       .split("/")
 
-                       .pop()
 
-                 : n.split("/").pop();
 
-         },
 
-         get isDirectory() {
 
-             return _isDirectory;
 
-         },
 
-         getCompressedData: function () {
 
-             return compress(false, null);
 
-         },
 
-         getCompressedDataAsync: function (/*Function*/ callback) {
 
-             compress(true, callback);
 
-         },
 
-         setData: function (value) {
 
-             uncompressedData = Utils.toBuffer(value, Utils.decoder.encode);
 
-             if (!_isDirectory && uncompressedData.length) {
 
-                 _centralHeader.size = uncompressedData.length;
 
-                 _centralHeader.method = Utils.Constants.DEFLATED;
 
-                 _centralHeader.crc = Utils.crc32(value);
 
-                 _centralHeader.changed = true;
 
-             } else {
 
-                 // folders and blank files should be stored
 
-                 _centralHeader.method = Utils.Constants.STORED;
 
-             }
 
-         },
 
-         getData: function (pass) {
 
-             if (_centralHeader.changed) {
 
-                 return uncompressedData;
 
-             } else {
 
-                 return decompress(false, null, pass);
 
-             }
 
-         },
 
-         getDataAsync: function (/*Function*/ callback, pass) {
 
-             if (_centralHeader.changed) {
 
-                 callback(uncompressedData);
 
-             } else {
 
-                 decompress(true, callback, pass);
 
-             }
 
-         },
 
-         set attr(attr) {
 
-             _centralHeader.attr = attr;
 
-         },
 
-         get attr() {
 
-             return _centralHeader.attr;
 
-         },
 
-         set header(/*Buffer*/ data) {
 
-             _centralHeader.loadFromBinary(data);
 
-         },
 
-         get header() {
 
-             return _centralHeader;
 
-         },
 
-         packCentralHeader: function () {
 
-             _centralHeader.flags_efs = this.efs;
 
-             _centralHeader.extraLength = _extra.length;
 
-             // 1. create header (buffer)
 
-             var header = _centralHeader.centralHeaderToBinary();
 
-             var addpos = Utils.Constants.CENHDR;
 
-             // 2. add file name
 
-             _entryName.copy(header, addpos);
 
-             addpos += _entryName.length;
 
-             // 3. add extra data
 
-             _extra.copy(header, addpos);
 
-             addpos += _centralHeader.extraLength;
 
-             // 4. add file comment
 
-             _comment.copy(header, addpos);
 
-             return header;
 
-         },
 
-         packLocalHeader: function () {
 
-             let addpos = 0;
 
-             _centralHeader.flags_efs = this.efs;
 
-             _centralHeader.extraLocalLength = _extralocal.length;
 
-             // 1. construct local header Buffer
 
-             const localHeaderBuf = _centralHeader.localHeaderToBinary();
 
-             // 2. localHeader - crate header buffer
 
-             const localHeader = Buffer.alloc(localHeaderBuf.length + _entryName.length + _centralHeader.extraLocalLength);
 
-             // 2.1 add localheader
 
-             localHeaderBuf.copy(localHeader, addpos);
 
-             addpos += localHeaderBuf.length;
 
-             // 2.2 add file name
 
-             _entryName.copy(localHeader, addpos);
 
-             addpos += _entryName.length;
 
-             // 2.3 add extra field
 
-             _extralocal.copy(localHeader, addpos);
 
-             addpos += _extralocal.length;
 
-             return localHeader;
 
-         },
 
-         toJSON: function () {
 
-             const bytes = function (nr) {
 
-                 return "<" + ((nr && nr.length + " bytes buffer") || "null") + ">";
 
-             };
 
-             return {
 
-                 entryName: this.entryName,
 
-                 name: this.name,
 
-                 comment: this.comment,
 
-                 isDirectory: this.isDirectory,
 
-                 header: _centralHeader.toJSON(),
 
-                 compressedData: bytes(input),
 
-                 data: bytes(uncompressedData)
 
-             };
 
-         },
 
-         toString: function () {
 
-             return JSON.stringify(this.toJSON(), null, "\t");
 
-         }
 
-     };
 
- };
 
 
  |