diff --git a/server/core/FileDecompressor.js b/server/core/FileDecompressor.js index 382d4105..ab2e58b2 100644 --- a/server/core/FileDecompressor.js +++ b/server/core/FileDecompressor.js @@ -119,14 +119,19 @@ class FileDecompressor { try { return await zip.unpack(filename, outputDir, { limitFileSize: this.limitFileSize, - limitFileCount: 1000 - }); + limitFileCount: 1000, + decodeEntryNameCallback: (nameRaw) => { + return utils.bufferRemoveZeroes(nameRaw); + } + } +); } catch (e) { fs.emptyDir(outputDir); return await zip.unpack(filename, outputDir, { limitFileSize: this.limitFileSize, limitFileCount: 1000, decodeEntryNameCallback: (nameRaw) => { + nameRaw = utils.bufferRemoveZeroes(nameRaw); const enc = textUtils.getEncodingLite(nameRaw); if (enc.indexOf('ISO-8859') < 0) { return iconv.decode(nameRaw, enc); diff --git a/server/core/Zip/node_stream_zip.js b/server/core/Zip/node_stream_zip.js index d60cc996..81a40fc2 100644 --- a/server/core/Zip/node_stream_zip.js +++ b/server/core/Zip/node_stream_zip.js @@ -766,7 +766,7 @@ ZipEntry.prototype.readDataHeader = function(data) { }; ZipEntry.prototype.read = function(data, offset) { - this.nameRaw = data.slice(offset, offset += this.fnameLen); + this.nameRaw = Buffer.from(data.slice(offset, offset += this.fnameLen)); this.name = this.nameRaw.toString(); var lastChar = data[offset - 1]; this.isDirectory = (lastChar == 47) || (lastChar == 92); diff --git a/server/core/utils.js b/server/core/utils.js index 53f7a2b3..f5190ded 100644 --- a/server/core/utils.js +++ b/server/core/utils.js @@ -14,6 +14,14 @@ function fromBase36(data) { return bs36.decode(data); } +function bufferRemoveZeroes(buf) { + const i = buf.indexOf(0); + if (i >= 0) { + return buf.slice(0, i); + } + return buf; +} + function getFileHash(filename, hashName, enc) { return new Promise((resolve, reject) => { const hash = crypto.createHash(hashName); @@ -86,6 +94,7 @@ function spawnProcess(cmd, opts) { module.exports = { toBase36, fromBase36, + bufferRemoveZeroes, getFileHash, sleep, randomHexString,