From 5af315c406d10ae2a3d0a642e30517619a8fc08f Mon Sep 17 00:00:00 2001 From: kinolaev Date: Wed, 8 Jul 2020 17:18:15 +0300 Subject: [PATCH] Fix parsing zip64 extra field https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT, 4.5.3 --- lib/parseExtraField.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/parseExtraField.js b/lib/parseExtraField.js index 8956a77..4de43d2 100644 --- a/lib/parseExtraField.js +++ b/lib/parseExtraField.js @@ -6,19 +6,25 @@ module.exports = function(extraField, vars) { while(!extra && extraField && extraField.length) { var candidateExtra = binary.parse(extraField) .word16lu('signature') - .word16lu('partsize') - .word64lu('uncompressedSize') - .word64lu('compressedSize') - .word64lu('offset') - .word64lu('disknum') - .vars; - - if(candidateExtra.signature === 0x0001) { - extra = candidateExtra; + .word16lu('partsize'); + + if(candidateExtra.vars.signature === 0x0001) { + // the fields MUST only appear if the corresponding + // Local or Central directory record field is set to 0xFFFF or 0xFFFFFFFF + if (vars.uncompressedSize === 0xffffffff) + candidateExtra.word64lu('uncompressedSize'); + if (vars.compressedSize === 0xffffffff) + candidateExtra.word64lu('compressedSize'); + if (vars.offsetToLocalFileHeader === 0xffffffff) + candidateExtra.word64lu('offset'); + if (vars.diskNumber === 0xffff) + candidateExtra.word32lu('disknum'); + + extra = candidateExtra.vars; } else { // Advance the buffer to the next part. // The total size of this part is the 4 byte header + partsize. - extraField = extraField.slice(candidateExtra.partsize + 4); + extraField = extraField.slice(candidateExtra.vars.partsize + 4); } }