From 4d841576189771238743104607063c62b70dca25 Mon Sep 17 00:00:00 2001 From: 5saviahv <5saviahv@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:05:07 +0300 Subject: [PATCH] inital "decoder" functionality --- adm-zip.js | 13 +++++++++---- headers/entryHeader.js | 11 +++++++++++ util/decoder.js | 5 +++++ util/index.js | 1 + util/utils.js | 4 ++-- zipEntry.js | 30 +++++++++++++++++++++++------- zipFile.js | 12 ++++++------ 7 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 util/decoder.js diff --git a/adm-zip.js b/adm-zip.js index 317a7ec..eb9c6ee 100644 --- a/adm-zip.js +++ b/adm-zip.js @@ -46,6 +46,11 @@ module.exports = function (/**String*/ input, /** object */ options) { // instanciate utils filesystem const filetools = new Utils(opts); + opts.decoder = Utils.decoder; + if (typeof opts.decoder !== "object" || typeof opts.decoder.encode !== "function" || typeof opts.decoder.decode !== "function") { + opts.decoder = Utils.decoder; + } + // if input is file name we retrieve its content if (input && "string" === typeof input) { // load zip file @@ -553,7 +558,7 @@ module.exports = function (/**String*/ input, /** object */ options) { // prepare new entry if (!update) { - entry = new ZipEntry(); + entry = new ZipEntry(opts); entry.entryName = entryName; } entry.comment = comment || ""; @@ -731,7 +736,7 @@ module.exports = function (/**String*/ input, /** object */ options) { throw new Error(Utils.Errors.NO_ZIP); } _zip.entries.forEach(function (entry) { - var entryName = sanitize(targetPath, canonical(entry.entryName.toString())); + var entryName = sanitize(targetPath, canonical(entry.entryName)); if (entry.isDirectory) { filetools.makeDir(entryName); return; @@ -784,7 +789,7 @@ module.exports = function (/**String*/ input, /** object */ options) { targetPath = pth.resolve(targetPath); // convert entryName to - const getPath = (entry) => sanitize(targetPath, pth.normalize(canonical(entry.entryName.toString()))); + const getPath = (entry) => sanitize(targetPath, pth.normalize(canonical(entry.entryName))); const getError = (msg, file) => new Error(msg + ': "' + file + '"'); // separate directories from files @@ -819,7 +824,7 @@ module.exports = function (/**String*/ input, /** object */ options) { if (err) { next(err); } else { - const entryName = pth.normalize(canonical(entry.entryName.toString())); + const entryName = pth.normalize(canonical(entry.entryName)); const filePath = sanitize(targetPath, entryName); entry.getDataAsync(function (content, err_1) { if (err_1) { diff --git a/headers/entryHeader.js b/headers/entryHeader.js index c153059..1d02a16 100644 --- a/headers/entryHeader.js +++ b/headers/entryHeader.js @@ -63,6 +63,17 @@ module.exports = function () { _flags = val; }, + get flags_efs() { + return (_flags & Constants.FLG_EFS) > 0; + }, + set flags_efs(val) { + if (val) { + _flags |= Constants.FLG_EFS; + } else { + _flags &= ~Constants.FLG_EFS; + } + }, + get method() { return _method; }, diff --git a/util/decoder.js b/util/decoder.js new file mode 100644 index 0000000..d8b98f0 --- /dev/null +++ b/util/decoder.js @@ -0,0 +1,5 @@ +module.exports = { + efs: true, + encode: (data) => Buffer.from(data, "utf8"), + decode: (data) => data.toString("utf8") +}; diff --git a/util/index.js b/util/index.js index 6790df4..10119cf 100644 --- a/util/index.js +++ b/util/index.js @@ -2,3 +2,4 @@ module.exports = require("./utils"); module.exports.Constants = require("./constants"); module.exports.Errors = require("./errors"); module.exports.FileAttr = require("./fattr"); +module.exports.decoder = require("./decoder"); diff --git a/util/utils.js b/util/utils.js index 784ae0a..72d2e0b 100644 --- a/util/utils.js +++ b/util/utils.js @@ -267,14 +267,14 @@ Utils.sanitize = function (/*string*/ prefix, /*string*/ name) { }; // converts buffer, Uint8Array, string types to buffer -Utils.toBuffer = function toBuffer(/*buffer, Uint8Array, string*/ input) { +Utils.toBuffer = function toBuffer(/*buffer, Uint8Array, string*/ input, /* function */ encoder) { if (Buffer.isBuffer(input)) { return input; } else if (input instanceof Uint8Array) { return Buffer.from(input); } else { // expect string all other values are invalid and return empty buffer - return typeof input === "string" ? Buffer.from(input, "utf8") : Buffer.alloc(0); + return typeof input === "string" ? encoder(input) : Buffer.alloc(0); } }; diff --git a/zipEntry.js b/zipEntry.js index 486e092..6eacc4c 100644 --- a/zipEntry.js +++ b/zipEntry.js @@ -3,13 +3,20 @@ var Utils = require("./util"), Constants = Utils.Constants, Methods = require("./methods"); -module.exports = function (/*Buffer*/ input) { +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); + _extra = 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)) { @@ -198,18 +205,26 @@ module.exports = function (/*Buffer*/ input) { return { get entryName() { - return _entryName.toString(); + return decoder.decode(_entryName); }, get rawEntryName() { return _entryName; }, set entryName(val) { - _entryName = Utils.toBuffer(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; }, @@ -220,10 +235,10 @@ module.exports = function (/*Buffer*/ input) { }, get comment() { - return _comment.toString(); + return decoder.decode(_comment); }, set comment(val) { - _comment = Utils.toBuffer(val); + _comment = Utils.toBuffer(val, decoder.encode); _centralHeader.commentLength = _comment.length; }, @@ -249,7 +264,7 @@ module.exports = function (/*Buffer*/ input) { }, setData: function (value) { - uncompressedData = Utils.toBuffer(value); + uncompressedData = Utils.toBuffer(value, Utils.decoder.encode); if (!_isDirectory && uncompressedData.length) { _centralHeader.size = uncompressedData.length; _centralHeader.method = Utils.Constants.DEFLATED; @@ -293,6 +308,7 @@ module.exports = function (/*Buffer*/ input) { }, packCentralHeader: function () { + _centralHeader.flag_efs = this.efs; // 1. create header (buffer) var header = _centralHeader.centralHeaderToBinary(); var addpos = Utils.Constants.CENHDR; diff --git a/zipFile.js b/zipFile.js index 4a7d453..afd0787 100644 --- a/zipFile.js +++ b/zipFile.js @@ -11,9 +11,9 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) { var password = null; // assign options - const opts = Object.assign(Object.create(null), options); + const opts = options; - const { noSort } = opts; + const { noSort, decoder } = opts; if (inBuffer) { // is a memory buffer @@ -29,7 +29,7 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) { for (let i = 0; i < totalEntries; i++) { let tmp = index; - const entry = new ZipEntry(inBuffer); + const entry = new ZipEntry(opts, inBuffer); entry.header = inBuffer.slice(tmp, (tmp += Utils.Constants.CENHDR)); entry.entryName = inBuffer.slice(tmp, (tmp += entry.header.fileNameLength)); @@ -50,7 +50,7 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) { var index = mainHeader.offset; // offset of first CEN header for (var i = 0; i < entryList.length; i++) { var tmp = index, - entry = new ZipEntry(inBuffer); + entry = new ZipEntry(opts, inBuffer); entry.header = inBuffer.slice(tmp, (tmp += Utils.Constants.CENHDR)); entry.entryName = inBuffer.slice(tmp, (tmp += entry.header.fileNameLength)); @@ -134,10 +134,10 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) { * @return {String} */ get comment() { - return _comment.toString(); + return decoder.decode(_comment); }, set comment(val) { - _comment = Utils.toBuffer(val); + _comment = Utils.toBuffer(val, decoder.encode); mainHeader.commentLength = _comment.length; },