diff --git a/adm-zip.js b/adm-zip.js index 4c23c24..a55d794 100644 --- a/adm-zip.js +++ b/adm-zip.js @@ -27,6 +27,18 @@ module.exports = function (/*String*/input) { _zip = new ZipFile(null, Utils.Constants.NONE); } + function sanitize(prefix, name) { + prefix = pth.resolve(pth.normalize(prefix)); + var parts = name.split('/'); + for (var i = 0, l = parts.length; i < l; i++) { + var path = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep))); + if (path.indexOf(prefix) === 0) { + return path; + } + } + return pth.normalize(pth.join(prefix, pth.basename(name))); + } + function getEntry(/*Object*/entry) { if (entry && _zip) { var item; @@ -344,9 +356,9 @@ module.exports = function (/*String*/input) { throw Utils.Errors.NO_ENTRY; } - var entryName = pth.normalize(item.entryName); + var entryName = item.entryName; - var target = pth.resolve(targetPath, maintainEntryPath ? entryName : pth.basename(entryName)); + var target = sanitize(targetPath, pth.resolve(targetPath, maintainEntryPath ? entryName : pth.basename(entryName))); if (item.isDirectory) { target = pth.resolve(target, ".."); @@ -357,7 +369,7 @@ module.exports = function (/*String*/input) { if (!content) { throw Utils.Errors.CANT_EXTRACT_FILE; } - var childName = child.entryName; + var childName = sanitize(targetPath, child.entryName); Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? childName : childName.substr(entryName.length)), content, overwrite); }); @@ -413,19 +425,17 @@ module.exports = function (/*String*/input) { throw Utils.Errors.NO_ZIP; } _zip.entries.forEach(function (entry) { - var entryName = pth.normalize(entry.entryName.toString()); - + var entryName = sanitize(targetPath, entry.entryName.toString()); if (entry.isDirectory) { - Utils.makeDir(pth.resolve(targetPath, entryName)); + Utils.makeDir(entryName); return; } var content = entry.getData(); if (!content) { throw Utils.Errors.CANT_EXTRACT_FILE; } - var fname = pth.resolve(targetPath, entryName); - Utils.writeFileTo(fname, content, overwrite); - fs.utimesSync(fname, entry.header.time, entry.header.time) + Utils.writeFileTo(entryName, content, overwrite); + fs.utimesSync(entryName, entry.header.time, entry.header.time) }) }, @@ -455,7 +465,7 @@ module.exports = function (/*String*/input) { var entryName = pth.normalize(entry.entryName.toString()); if (entry.isDirectory) { - Utils.makeDir(pth.resolve(targetPath, entryName)); + Utils.makeDir(sanitize(targetPath, entryName)); if (--i === 0) callback(undefined); return; @@ -468,7 +478,7 @@ module.exports = function (/*String*/input) { return; } - Utils.writeFileToAsync(pth.resolve(targetPath, entryName), content, overwrite, function (succ) { + Utils.writeFileToAsync(sanitize(targetPath, entryName), content, overwrite, function (succ) { fs.utimesSync(pth.resolve(targetPath, entryName), entry.header.time, entry.header.time); if (i <= 0) return; if (!succ) { diff --git a/methods/inflater.js b/methods/inflater.js index df7cdec..d566031 100644 --- a/methods/inflater.js +++ b/methods/inflater.js @@ -28,7 +28,7 @@ function JSInflater(/*Buffer*/input) { function HuffTable(clen, cnum, cval, blist, elist, lookupm) { this.status = 0; - this.root = null; + this.r = null; this.maxbit = 0; var el, f, tail, @@ -38,7 +38,7 @@ function JSInflater(/*Buffer*/input) { values = [], tentry = {extra: 0, bitcnt: 0, lbase: 0, next: null}; - tail = this.root = null; + tail = this.r = null; for (var i = 0; i < 0x11; i++) { countTbl[i] = 0; sTbl[i] = 0; @@ -115,7 +115,7 @@ function JSInflater(/*Buffer*/input) { cnode = []; while (cnode.length < tblCnt) cnode.push({extra: 0, bitcnt: 0, lbase: 0, next: null}); if (tail == null) { - tail = this.root = {next: null, list: null}; + tail = this.r = {next: null, list: null}; } else { tail = tail.next = {next: null, list: null} } @@ -278,7 +278,7 @@ function JSInflater(/*Buffer*/input) { if (htbl.status !== 0) return -1; - fixedTableList = htbl.root; + fixedTableList = htbl.r; fixedLookup = htbl.maxbit; for (symbol = 0; symbol < 30; symbol++) lengths[symbol] = 5; @@ -289,7 +289,7 @@ function JSInflater(/*Buffer*/input) { fixedTableList = null; return -1; } - fixedTableDist = htbl.root; + fixedTableDist = htbl.r; fixed_bd = htbl.maxbit; } @@ -320,7 +320,7 @@ function JSInflater(/*Buffer*/input) { if (hufTable.status !== 0) return -1; // incomplete code set - tblList = hufTable.root; + tblList = hufTable.r; bitList = hufTable.maxbit; var lencnt = llencnt + dcodescnt, i = 0, @@ -354,13 +354,13 @@ function JSInflater(/*Buffer*/input) { if (hufTable.status !== 0) return -1; - tblList = hufTable.root; + tblList = hufTable.r; bitList = hufTable.maxbit; for (i = 0; i < dcodescnt; i++) ll[i] = ll[i + llencnt]; bitdist = 6; hufTable = new HuffTable(ll, dcodescnt, 0, DISTS, DEXT, bitdist); - tblDist = hufTable.root; + tblDist = hufTable.r; bitdist = hufTable.maxbit; if ((bitdist === 0 && llencnt > 257) || hufTable.status !== 0) return -1; diff --git a/test/assets/attributes_test/New folder/hidden.txt b/test/assets/attributes_test/New folder/hidden.txt deleted file mode 100644 index e14c371..0000000 --- a/test/assets/attributes_test/New folder/hidden.txt +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/test/assets/attributes_test/New folder/hidden_readonly.txt b/test/assets/attributes_test/New folder/hidden_readonly.txt deleted file mode 100644 index e14c371..0000000 --- a/test/assets/attributes_test/New folder/hidden_readonly.txt +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/test/assets/attributes_test/New folder/readonly.txt b/test/assets/attributes_test/New folder/readonly.txt deleted file mode 100644 index e14c371..0000000 --- a/test/assets/attributes_test/New folder/readonly.txt +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/test/assets/attributes_test/New folder/somefile.txt b/test/assets/attributes_test/New folder/somefile.txt deleted file mode 100644 index e14c371..0000000 --- a/test/assets/attributes_test/New folder/somefile.txt +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/test/assets/attributes_test/asd/New Text Document.txt b/test/assets/attributes_test/asd/New Text Document.txt deleted file mode 100644 index e69de29..0000000 diff --git a/test/assets/attributes_test/blank file.txt b/test/assets/attributes_test/blank file.txt deleted file mode 100644 index e69de29..0000000 diff --git a/test/assets/ultra.zip b/test/assets/ultra.zip index 86a8ec7..726d7ab 100644 Binary files a/test/assets/ultra.zip and b/test/assets/ultra.zip differ diff --git a/test/index.js b/test/index.js index dbd0a81..4077280 100644 --- a/test/index.js +++ b/test/index.js @@ -1,25 +1,8 @@ var Attr = require("../util").FileAttr, Zip = require("../adm-zip"), + pth = require("path"); fs = require("fs"); -var zip = Zip("./test/assets/ultra.zip"); -var zipEntries = zip.getEntries(); - -zipEntries.forEach(function(zipEntry) -{ - if (zipEntry.entryName === "attributes_test/blank file.txt") - { - zip.updateFile(zipEntry.entryName, "inner content"); - console.log(zip.readAsText(zipEntry.entryName)); - } -}); - -zipEntries.forEach(function(zipEntry) -{ - if (zipEntry.entryName === "attributes_test/blank file.txt") - { - console.log(zip.readAsText(zipEntry.entryName)); - } -}); -zip.writeZip("files3.zip"); \ No newline at end of file +var zip = new Zip('./test/assets/ultra.zip'); +zip.extractAllTo('./test/xxx'); \ No newline at end of file diff --git a/util/utils.js b/util/utils.js index 832322f..2ea4c23 100644 --- a/util/utils.js +++ b/util/utils.js @@ -9,7 +9,7 @@ module.exports = (function() { Constants = require('./constants'), Errors = require('./errors'), - PATH_SEPARATOR = pth.normalize("/"); + PATH_SEPARATOR = pth.sep; function mkdirSync(/*String*/path) { @@ -28,14 +28,14 @@ module.exports = (function() { }); } - function findSync(/*String*/root, /*RegExp*/pattern, /*Boolean*/recoursive) { + function findSync(/*String*/dir, /*RegExp*/pattern, /*Boolean*/recoursive) { if (typeof pattern === 'boolean') { recoursive = pattern; pattern = undefined; } var files = []; - fs.readdirSync(root).forEach(function(file) { - var path = pth.join(root, file); + fs.readdirSync(dir).forEach(function(file) { + var path = pth.join(dir, file); if (fs.statSync(path).isDirectory() && recoursive) files = files.concat(findSync(path, pattern, recoursive)); @@ -92,7 +92,7 @@ module.exports = (function() { writeFileTo : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr) { if (fs.existsSync(path)) { if (!overwrite) - return false; // cannot overwite + return false; // cannot overwrite var stat = fs.statSync(path); if (stat.isDirectory()) {