mirror of
https://github.com/zhigang1992/adm-zip.git
synced 2026-01-12 17:12:25 +08:00
Read ZIP64 extended information
The extra block of a file header can contain a ZIP64 that overrides some of the fields from the file header with longer values if the fields had been set to 0xffffffff (or 0xffff for the disk number). See sections 4.5.2, 4.5.3, 4.4.8, 4.4.9, 4.4.13 and 4.4.16 of the specification for reference. Closes cthackers/adm-zip#81 as fixed.
This commit is contained in:
@@ -80,5 +80,36 @@ module.exports = {
|
||||
/* Load type */
|
||||
FILE : 0,
|
||||
BUFFER : 1,
|
||||
NONE : 2
|
||||
NONE : 2,
|
||||
|
||||
/* 4.5 Extensible data fields */
|
||||
EF_ID : 0,
|
||||
EF_SIZE : 2,
|
||||
|
||||
/* Header IDs */
|
||||
ID_ZIP64 : 0x0001,
|
||||
ID_AVINFO : 0x0007,
|
||||
ID_PFS : 0x0008,
|
||||
ID_OS2 : 0x0009,
|
||||
ID_NTFS : 0x000a,
|
||||
ID_OPENVMS : 0x000c,
|
||||
ID_UNIX : 0x000d,
|
||||
ID_FORK : 0x000e,
|
||||
ID_PATCH : 0x000f,
|
||||
ID_X509_PKCS7 : 0x0014,
|
||||
ID_X509_CERTID_F : 0x0015,
|
||||
ID_X509_CERTID_C : 0x0016,
|
||||
ID_STRONGENC : 0x0017,
|
||||
ID_RECORD_MGT : 0x0018,
|
||||
ID_X509_PKCS7_RL : 0x0019,
|
||||
ID_IBM1 : 0x0065,
|
||||
ID_IBM2 : 0x0066,
|
||||
ID_POSZIP : 0x4690,
|
||||
|
||||
EF_ZIP64_OR_32 : 0xffffffff,
|
||||
EF_ZIP64_OR_16 : 0xffff,
|
||||
EF_ZIP64_SUNCOMP : 0,
|
||||
EF_ZIP64_SCOMP : 8,
|
||||
EF_ZIP64_RHO : 16,
|
||||
EF_ZIP64_DSN : 24
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ var fs = require("fs"),
|
||||
pth = require('path');
|
||||
|
||||
fs.existsSync = fs.existsSync || pth.existsSync;
|
||||
|
||||
|
||||
module.exports = (function() {
|
||||
|
||||
var crcTable = [],
|
||||
@@ -81,7 +81,7 @@ module.exports = (function() {
|
||||
case Constants.DEFLATED:
|
||||
return 'DEFLATED (' + method + ')';
|
||||
default:
|
||||
return 'UNSUPPORTED (' + method + ')'
|
||||
return 'UNSUPPORTED (' + method + ')';
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
52
zipEntry.js
52
zipEntry.js
@@ -136,6 +136,57 @@ module.exports = function (/*Buffer*/input) {
|
||||
}
|
||||
}
|
||||
|
||||
function readUInt64LE(buffer, offset) {
|
||||
return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
|
||||
}
|
||||
|
||||
function parseExtra(data) {
|
||||
var offset = 0;
|
||||
var signature, size, part;
|
||||
while(offset<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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(_entryHeader.size === Constants.EF_ZIP64_OR_32) {
|
||||
_entryHeader.size = size;
|
||||
}
|
||||
}
|
||||
if(data.length >= Constants.EF_ZIP64_RHO) {
|
||||
compressedSize = readUInt64LE(data, Constants.EF_ZIP64_SCOMP);
|
||||
if(_entryHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
|
||||
_entryHeader.compressedSize = compressedSize;
|
||||
}
|
||||
}
|
||||
if(data.length >= Constants.EF_ZIP64_DSN) {
|
||||
offset = readUInt64LE(data, Constants.EF_ZIP64_RHO);
|
||||
if(_entryHeader.offset === Constants.EF_ZIP64_OR_32) {
|
||||
_entryHeader.offset = offset;
|
||||
}
|
||||
}
|
||||
if(data.length >= Constants.EF_ZIP64_DSN+4) {
|
||||
diskNumStart = data.readUInt32LE(Constants.EF_ZIP64_DSN);
|
||||
if(_entryHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
|
||||
_entryHeader.diskNumStart = diskNumStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
get entryName () { return _entryName.toString(); },
|
||||
get rawEntryName() { return _entryName; },
|
||||
@@ -150,6 +201,7 @@ module.exports = function (/*Buffer*/input) {
|
||||
set extra (val) {
|
||||
_extra = val;
|
||||
_entryHeader.extraLength = val.length;
|
||||
parseExtra(val);
|
||||
},
|
||||
|
||||
get comment () { return _comment.toString(); },
|
||||
|
||||
Reference in New Issue
Block a user