diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..7c3f0271 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,43 @@ +"use strict"; + +module.exports = { + "env": { + "browser": true, + "commonjs": true, + "es2021": true, + "node": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": "latest" + }, + "ignorePatterns": ["vendor/*.js", "dist/*.js", "test/jquery-1.8.3.min.js"], + "rules": { + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ], + "curly": "error", + "eqeqeq": "error", + "no-new": "error", + "no-caller": "error", + "guard-for-in": "error", + "no-extend-native": "error", + "strict": [ + "error", + "global" + ], + } +}; diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 00000000..ba6d24c5 --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,58 @@ +name: pull-request + +on: + pull_request: + branches: [ main ] + push: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-node@v2 + with: + node-version: 'lts/*' + cache: 'npm' + + - name: Cache Node modules + uses: actions/cache@v3 + id: npm-cache + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install dependencies + run: | + npm install + sudo npx playwright install-deps + + - name: Lint + run: npm run lint + - name: Test + run: npm test + + - name: Benchmark + run: npm run benchmark | tee benchmark.txt + + - name: Download previous benchmark data + uses: actions/cache@v3 + with: + path: ./cache + key: ${{ runner.os }}-benchmark + + - name: Store benchmark result + uses: benchmark-action/github-action-benchmark@v1 + with: + tool: 'benchmarkjs' + output-file-path: benchmark.txt + external-data-json-path: ./cache/benchmark-data.json + github-token: ${{ secrets.GITHUB_TOKEN }} + alert-threshold: '150%' + comment-on-alert: true + fail-on-alert: true + alert-comment-cc-users: '@Stuk' diff --git a/.gitignore b/.gitignore index 972cdc6f..84ef79a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ +_site +.c9revisions +.DS_Store +.jekyll-metadata *~ node_modules sauce_connect.log -.c9revisions \ No newline at end of file diff --git a/.jshintignore b/.jshintignore deleted file mode 100644 index 3c3629e6..00000000 --- a/.jshintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index e7bffa0e..00000000 --- a/.jshintrc +++ /dev/null @@ -1,21 +0,0 @@ -{ - "curly": true, - "eqeqeq": true, - "nonew": true, - "noarg": true, - "forin": true, - "futurehostile": true, - "freeze": true, - "undef": true, - "strict": true, - "sub": true, - "esversion": 3, - - "globals": { - "TextEncoder": false, - "TextDecoder": false, - "self": true - }, - "browser": true, - "node": true -} diff --git a/CHANGES.md b/CHANGES.md index abb085ac..96aaf299 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,69 @@ layout: default section: main --- +### v3.10.1 2022-08-02 + +- Add sponsorship files. + + If you appreciate the time spent maintaining JSZip then I would really appreciate [your sponsorship](https://github.com/sponsors/Stuk). +- Consolidate metadata types and expose OnUpdateCallback [#851](https://github.com/Stuk/jszip/pull/851) and [#852](https://github.com/Stuk/jszip/pull/852) +- use `const` instead `var` in example from README.markdown [#828](https://github.com/Stuk/jszip/pull/828) +- Switch manual download link to HTTPS [#839](https://github.com/Stuk/jszip/pull/839) + +Internals: + +- Replace jshint with eslint [#842](https://github.com/Stuk/jszip/pull/842) +- Add performance tests [#834](https://github.com/Stuk/jszip/pull/834) + +### v3.10.0 2022-05-20 + +- Change setimmediate dependency to more efficient one. Fixes https://github.com/Stuk/jszip/issues/617 (see [#829](https://github.com/Stuk/jszip/pull/829)) +- Update types of `currentFile` metadata to include `null` (see [#826](https://github.com/Stuk/jszip/pull/826)) + +### v3.9.1 2022-04-06 + +- Fix recursive definition of `InputFileFormat` introduced in 3.9.0. + +### v3.9.0 2022-04-04 + +- Update types JSZip#loadAsync to accept a promise for data, and remove arguments from `new JSZip()` (see [#752](https://github.com/Stuk/jszip/pull/752)) +- Update types for `compressionOptions` to JSZipFileOptions and JSZipGeneratorOptions (see [#722](https://github.com/Stuk/jszip/pull/722)) +- Add types for `generateInternalStream` (see [#774](https://github.com/Stuk/jszip/pull/774)) + +### v3.8.0 2022-03-30 + +- Santize filenames when files are loaded with `loadAsync`, to avoid ["zip slip" attacks](https://snyk.io/research/zip-slip-vulnerability). The original filename is available on each zip entry as `unsafeOriginalName`. See the [documentation](https://stuk.github.io/jszip/documentation/api_jszip/load_async.html). Many thanks to McCaulay Hudson for reporting. + +### v3.7.1 2021-08-05 + +- Fix build of `dist` files. + + Note: this version ensures the changes from 3.7.0 are actually included in the `dist` files. Thanks to Evan W for reporting. + +### v3.7.0 2021-07-23 + +- Fix: Use a null prototype object for this.files (see [#766](https://github.com/Stuk/jszip/pull/766)) + + This change might break existing code if it uses prototype methods on the `.files` property of a zip object, for example `zip.files.toString()`. This approach is taken to prevent files in the zip overriding object methods that would exist on a normal object. + +### v3.6.0 2021-02-09 + +- Fix: redirect main to dist on browsers (see [#742](https://github.com/Stuk/jszip/pull/742)) +- Fix duplicate require DataLengthProbe, utils (see [#734](https://github.com/Stuk/jszip/pull/734)) +- Fix small error in read_zip.md (see [#703](https://github.com/Stuk/jszip/pull/703)) + +### v3.5.0 2020-05-31 + +- Fix 'End of data reached' error when file extra field is invalid (see [#544](https://github.com/Stuk/jszip/pull/544)). +- Typescript definitions: Add null to return types of functions that may return null (see [#669](https://github.com/Stuk/jszip/pull/669)). +- Typescript definitions: Correct nodeStream's type (see [#682](https://github.com/Stuk/jszip/pull/682)) +- Typescript definitions: Add string output type (see [#666](https://github.com/Stuk/jszip/pull/666)) + +### v3.4.0 2020-04-19 + +- Add Typescript type definitions (see [#601](https://github.com/Stuk/jszip/pull/601)). + +### v3.3.0 2020-04-1 + +- Change browser module resolution to support Angular packager (see [#614](https://github.com/Stuk/jszip/pull/614)). + ### v3.2.2 2019-07-04 - No public changes, but a number of testing dependencies have been updated. - Tested browsers are now: Internet Explorer 11, Chrome (most recent) and Firefox (most recent). Other browsers (specifically Safari) are still supported however testing them on Saucelabs is broken and so they were removed from the test matrix. @@ -139,4 +202,3 @@ This release changes a lot of methods, please see [the upgrade guide](http://stu # v1.0.0, 2013-02-14 - First release after a long period without version. - diff --git a/Gruntfile.js b/Gruntfile.js index 45e7c4c5..9f1b1b88 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,126 +1,46 @@ -/*jshint node: true */ "use strict"; module.exports = function(grunt) { - // https://wiki.saucelabs.com/display/DOCS/Platform+Configurator - // A lot of the browsers seem to time out with Saucelab's unit testing - // framework. Here are the browsers that work and get enough coverage for our - // needs. - var browsers = [ - {browserName: "chrome"}, - {browserName: "firefox", platform: "Linux"}, - {browserName: "internet explorer"} - ]; - - var tags = []; - if (process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST != "false") { - tags.push("pr" + process.env.TRAVIS_PULL_REQUEST); - } else if (process.env.TRAVIS_BRANCH) { - tags.push(process.env.TRAVIS_BRANCH); - } - - var version = require("./package.json").version; - - grunt.initConfig({ - connect: { - server: { - options: { - base: "", - port: 8080 - } - } - }, - 'saucelabs-qunit': { - all: { - options: { - urls: ["http://127.0.0.1:8080/test/index.html?hidepassed"], - build: process.env.TRAVIS_JOB_ID, - throttled: 4, - "max-duration": 1200, // seconds, IE6 is slow - browsers: browsers, - testname: "qunit tests", - tags: tags, - // Tests have statusCheckAttempts * pollInterval seconds to complete - pollInterval: 2000, - statusCheckAttempts: 240, - "max-duration": 1200, - browsers: browsers, - maxRetries: 2 - } - } - }, - jshint: { - // see https://github.com/gruntjs/grunt-contrib-jshint/issues/198 - // we can't override the options using the jshintrc path - options: grunt.file.readJSON('.jshintrc'), - production: ['./lib/**/*.js'], - test: ['./test/helpers/**/*.js', './test/asserts/**/*.js'], - documentation: { - options: { - // we include js files with jekyll, jshint can't see all - // variables and we can't declare all of them - undef: false, - // 'implied' still give false positives in our case - strict: false + var version = require("./package.json").version; + + grunt.initConfig({ + browserify: { + all: { + files: { + "dist/jszip.js": ["lib/index.js"] + }, + options: { + browserifyOptions: { + standalone: "JSZip", + transform: ["package-json-versionify"], + insertGlobalVars: { + process: undefined, + Buffer: undefined, + __filename: undefined, + __dirname: undefined + }, + builtins: false + }, + banner: grunt.file.read("lib/license_header.js").replace(/__VERSION__/, version) + } + } }, - files: { - src: ['./documentation/**/*.js'] - } - } - }, - browserify: { - all: { - files: { - 'dist/jszip.js': ['lib/index.js'] - }, - options: { - browserifyOptions: { - standalone: 'JSZip', - transform: ['package-json-versionify'], - insertGlobalVars: { - process: undefined, - Buffer: undefined, - __filename: undefined, - __dirname: undefined + uglify: { + options: { + mangle: true, + preserveComments: false, + banner: grunt.file.read("lib/license_header.js").replace(/__VERSION__/, version) }, - builtins: false - }, - banner: grunt.file.read('lib/license_header.js').replace(/__VERSION__/, version) + all: { + src: "dist/jszip.js", + dest: "dist/jszip.min.js" + } } - } - }, - uglify: { - options: { - mangle: true, - preserveComments: false, - banner: grunt.file.read('lib/license_header.js').replace(/__VERSION__/, version) - }, - all: { - src: 'dist/jszip.js', - dest: 'dist/jszip.min.js' - } - } - }); - - grunt.loadNpmTasks("grunt-contrib-connect"); - grunt.loadNpmTasks("grunt-saucelabs"); - grunt.loadNpmTasks('grunt-browserify'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - - // A task to cause Grunt to sit and wait, keeping the test server running - grunt.registerTask("wait", function() { - this.async(); - }); + }); - grunt.registerTask("test-local", ["build", "connect", "wait"]); - grunt.registerTask("test-remote", ["build", "connect", "saucelabs-qunit"]); + grunt.loadNpmTasks("grunt-browserify"); + grunt.loadNpmTasks("grunt-contrib-uglify"); - if (process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY) { - grunt.registerTask("test", ["jshint", "test-remote"]); - } else { - grunt.registerTask("test", ["jshint", "test-local"]); - } - grunt.registerTask("build", ["browserify", "uglify"]); - grunt.registerTask("default", ["jshint", "build"]); + grunt.registerTask("build", ["browserify", "uglify"]); + grunt.registerTask("default", ["build"]); }; diff --git a/LICENSE.markdown b/LICENSE.markdown index 43a98191..f8250b37 100644 --- a/LICENSE.markdown +++ b/LICENSE.markdown @@ -1,4 +1,4 @@ -JSZip is dual licensed. You may use it under the MIT license *or* the GPLv3 +JSZip is dual licensed. At your choice you may use it under the MIT license *or* the GPLv3 license. The MIT License diff --git a/README.markdown b/README.markdown index 4fd56286..2f2ea2ed 100644 --- a/README.markdown +++ b/README.markdown @@ -1,19 +1,17 @@ -JSZip [![Build Status](https://api.travis-ci.org/Stuk/jszip.svg?branch=master)](http://travis-ci.org/Stuk/jszip) [![Code Climate](https://codeclimate.com/github/Stuk/jszip/badges/gpa.svg)](https://codeclimate.com/github/Stuk/jszip) +JSZip ===== -[![Selenium Test Status](https://saucelabs.com/browser-matrix/jszip.svg)](https://saucelabs.com/u/jszip) - A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API. See https://stuk.github.io/jszip for all the documentation. ```javascript -var zip = new JSZip(); +const zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); -var img = zip.folder("images"); +const img = zip.folder("images"); img.file("smile.gif", imgData, {base64: true}); zip.generateAsync({type:"blob"}).then(function(content) { diff --git a/dist/jszip.js b/dist/jszip.js index e53c056b..60fbb41a 100644 --- a/dist/jszip.js +++ b/dist/jszip.js @@ -1,19 +1,19 @@ /*! -JSZip v3.2.1 - A JavaScript class for generating and reading zip files +JSZip v3.10.1 - A JavaScript class for generating and reading zip files (c) 2009-2016 Stuart Knightley -Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. JSZip uses the library pako released under the MIT license : -https://github.com/nodeca/pako/blob/master/LICENSE +https://github.com/nodeca/pako/blob/main/LICENSE */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.JSZip = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) ? path.substring(0, lastSlash) : ""; }; @@ -1469,7 +1475,7 @@ var forceTrailingSlash = function(path) { * @return {Object} the new folder. */ var folderAdd = function(name, createFolders) { - createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders; + createFolders = (typeof createFolders !== "undefined") ? createFolders : defaults.createFolders; name = forceTrailingSlash(name); @@ -1511,10 +1517,9 @@ var out = { */ forEach: function(cb) { var filename, relativePath, file; + // ignore warning about unwanted properties because this.files is a null prototype object + /* eslint-disable-next-line guard-for-in */ for (filename in this.files) { - if (!this.files.hasOwnProperty(filename)) { - continue; - } file = this.files[filename]; relativePath = filename.slice(this.root.length, filename.length); if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root @@ -1633,13 +1638,9 @@ var out = { }, /** - * Generate the complete zip file - * @param {Object} options the options to generate the zip file : - * - compression, "STORE" by default. - * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. - * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + * @deprecated This method has been removed in JSZip 3.0, please check the upgrade guide. */ - generate: function(options) { + generate: function() { throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); }, @@ -1651,53 +1652,53 @@ var out = { * @return {StreamHelper} the streamed zip file. */ generateInternalStream: function(options) { - var worker, opts = {}; - try { - opts = utils.extend(options || {}, { - streamFiles: false, - compression: "STORE", - compressionOptions : null, - type: "", - platform: "DOS", - comment: null, - mimeType: 'application/zip', - encodeFileName: utf8.utf8encode - }); - - opts.type = opts.type.toLowerCase(); - opts.compression = opts.compression.toUpperCase(); - - // "binarystring" is prefered but the internals use "string". - if(opts.type === "binarystring") { - opts.type = "string"; - } + var worker, opts = {}; + try { + opts = utils.extend(options || {}, { + streamFiles: false, + compression: "STORE", + compressionOptions : null, + type: "", + platform: "DOS", + comment: null, + mimeType: "application/zip", + encodeFileName: utf8.utf8encode + }); - if (!opts.type) { - throw new Error("No output type specified."); - } + opts.type = opts.type.toLowerCase(); + opts.compression = opts.compression.toUpperCase(); - utils.checkSupport(opts.type); + // "binarystring" is preferred but the internals use "string". + if(opts.type === "binarystring") { + opts.type = "string"; + } - // accept nodejs `process.platform` - if( - opts.platform === 'darwin' || - opts.platform === 'freebsd' || - opts.platform === 'linux' || - opts.platform === 'sunos' - ) { - opts.platform = "UNIX"; - } - if (opts.platform === 'win32') { - opts.platform = "DOS"; - } + if (!opts.type) { + throw new Error("No output type specified."); + } - var comment = opts.comment || this.comment || ""; - worker = generate.generateWorker(this, opts, comment); - } catch (e) { - worker = new GenericWorker("error"); - worker.error(e); - } - return new StreamHelper(worker, opts.type || "string", opts.mimeType); + utils.checkSupport(opts.type); + + // accept nodejs `process.platform` + if( + opts.platform === "darwin" || + opts.platform === "freebsd" || + opts.platform === "linux" || + opts.platform === "sunos" + ) { + opts.platform = "UNIX"; + } + if (opts.platform === "win32") { + opts.platform = "DOS"; + } + + var comment = opts.comment || this.comment || ""; + worker = generate.generateWorker(this, opts, comment); + } catch (e) { + worker = new GenericWorker("error"); + worker.error(e); + } + return new StreamHelper(worker, opts.type || "string", opts.mimeType); }, /** * Generate the complete zip file asynchronously. @@ -1721,6 +1722,7 @@ var out = { module.exports = out; },{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(require,module,exports){ +"use strict"; /* * This file is used by module bundlers (browserify/webpack/etc) when * including a stream implementation. We use "readable-stream" to get a @@ -1732,15 +1734,15 @@ module.exports = out; module.exports = require("stream"); },{"stream":undefined}],17:[function(require,module,exports){ -'use strict'; -var DataReader = require('./DataReader'); -var utils = require('../utils'); +"use strict"; +var DataReader = require("./DataReader"); +var utils = require("../utils"); function ArrayReader(data) { DataReader.call(this, data); - for(var i = 0; i < this.data.length; i++) { - data[i] = data[i] & 0xFF; - } + for(var i = 0; i < this.data.length; i++) { + data[i] = data[i] & 0xFF; + } } utils.inherits(ArrayReader, DataReader); /** @@ -1791,8 +1793,8 @@ ArrayReader.prototype.readData = function(size) { module.exports = ArrayReader; },{"../utils":32,"./DataReader":18}],18:[function(require,module,exports){ -'use strict'; -var utils = require('../utils'); +"use strict"; +var utils = require("../utils"); function DataReader(data) { this.data = data; // type : see implementation @@ -1841,7 +1843,7 @@ DataReader.prototype = { * @param {number} i the index to use. * @return {number} a byte. */ - byteAt: function(i) { + byteAt: function() { // see implementations }, /** @@ -1872,15 +1874,15 @@ DataReader.prototype = { * @param {number} size the number of bytes to read. * @return {Object} the raw data, implementation specific. */ - readData: function(size) { + readData: function() { // see implementations }, /** - * Find the last occurence of a zip signature (4 bytes). + * Find the last occurrence of a zip signature (4 bytes). * @param {string} sig the signature to find. - * @return {number} the index of the last occurence, -1 if not found. + * @return {number} the index of the last occurrence, -1 if not found. */ - lastIndexOfSignature: function(sig) { + lastIndexOfSignature: function() { // see implementations }, /** @@ -1888,7 +1890,7 @@ DataReader.prototype = { * @param {string} sig the expected signature * @return {boolean} true if the signature matches, false otherwise. */ - readAndCheckSignature: function(sig) { + readAndCheckSignature: function() { // see implementations }, /** @@ -1898,20 +1900,20 @@ DataReader.prototype = { readDate: function() { var dostime = this.readInt(4); return new Date(Date.UTC( - ((dostime >> 25) & 0x7f) + 1980, // year - ((dostime >> 21) & 0x0f) - 1, // month - (dostime >> 16) & 0x1f, // day - (dostime >> 11) & 0x1f, // hour - (dostime >> 5) & 0x3f, // minute - (dostime & 0x1f) << 1)); // second + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1)); // second } }; module.exports = DataReader; },{"../utils":32}],19:[function(require,module,exports){ -'use strict'; -var Uint8ArrayReader = require('./Uint8ArrayReader'); -var utils = require('../utils'); +"use strict"; +var Uint8ArrayReader = require("./Uint8ArrayReader"); +var utils = require("../utils"); function NodeBufferReader(data) { Uint8ArrayReader.call(this, data); @@ -1930,9 +1932,9 @@ NodeBufferReader.prototype.readData = function(size) { module.exports = NodeBufferReader; },{"../utils":32,"./Uint8ArrayReader":21}],20:[function(require,module,exports){ -'use strict'; -var DataReader = require('./DataReader'); -var utils = require('../utils'); +"use strict"; +var DataReader = require("./DataReader"); +var utils = require("../utils"); function StringReader(data) { DataReader.call(this, data); @@ -1970,9 +1972,9 @@ StringReader.prototype.readData = function(size) { module.exports = StringReader; },{"../utils":32,"./DataReader":18}],21:[function(require,module,exports){ -'use strict'; -var ArrayReader = require('./ArrayReader'); -var utils = require('../utils'); +"use strict"; +var ArrayReader = require("./ArrayReader"); +var utils = require("../utils"); function Uint8ArrayReader(data) { ArrayReader.call(this, data); @@ -1994,14 +1996,14 @@ Uint8ArrayReader.prototype.readData = function(size) { module.exports = Uint8ArrayReader; },{"../utils":32,"./ArrayReader":17}],22:[function(require,module,exports){ -'use strict'; +"use strict"; -var utils = require('../utils'); -var support = require('../support'); -var ArrayReader = require('./ArrayReader'); -var StringReader = require('./StringReader'); -var NodeBufferReader = require('./NodeBufferReader'); -var Uint8ArrayReader = require('./Uint8ArrayReader'); +var utils = require("../utils"); +var support = require("../support"); +var ArrayReader = require("./ArrayReader"); +var StringReader = require("./StringReader"); +var NodeBufferReader = require("./NodeBufferReader"); +var Uint8ArrayReader = require("./Uint8ArrayReader"); /** * Create a reader adapted to the data. @@ -2024,7 +2026,7 @@ module.exports = function (data) { }; },{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(require,module,exports){ -'use strict'; +"use strict"; exports.LOCAL_FILE_HEADER = "PK\x03\x04"; exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; @@ -2033,10 +2035,10 @@ exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; exports.DATA_DESCRIPTOR = "PK\x07\x08"; },{}],24:[function(require,module,exports){ -'use strict'; +"use strict"; -var GenericWorker = require('./GenericWorker'); -var utils = require('../utils'); +var GenericWorker = require("./GenericWorker"); +var utils = require("../utils"); /** * A worker which convert chunks to a specified type. @@ -2061,11 +2063,11 @@ ConvertWorker.prototype.processChunk = function (chunk) { module.exports = ConvertWorker; },{"../utils":32,"./GenericWorker":28}],25:[function(require,module,exports){ -'use strict'; +"use strict"; -var GenericWorker = require('./GenericWorker'); -var crc32 = require('../crc32'); -var utils = require('../utils'); +var GenericWorker = require("./GenericWorker"); +var crc32 = require("../crc32"); +var utils = require("../utils"); /** * A worker which calculate the crc32 of the data flowing through. @@ -2087,10 +2089,10 @@ Crc32Probe.prototype.processChunk = function (chunk) { module.exports = Crc32Probe; },{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(require,module,exports){ -'use strict'; +"use strict"; -var utils = require('../utils'); -var GenericWorker = require('./GenericWorker'); +var utils = require("../utils"); +var GenericWorker = require("./GenericWorker"); /** * A worker which calculate the total length of the data flowing through. @@ -2118,10 +2120,10 @@ module.exports = DataLengthProbe; },{"../utils":32,"./GenericWorker":28}],27:[function(require,module,exports){ -'use strict'; +"use strict"; -var utils = require('../utils'); -var GenericWorker = require('./GenericWorker'); +var utils = require("../utils"); +var GenericWorker = require("./GenericWorker"); // the size of the generated chunks // TODO expose this as a public variable @@ -2212,15 +2214,15 @@ DataWorker.prototype._tick = function() { return this.end(); } else { switch(this.type) { - case "string": - data = this.data.substring(this.index, nextIndex); + case "string": + data = this.data.substring(this.index, nextIndex); break; - case "uint8array": - data = this.data.subarray(this.index, nextIndex); + case "uint8array": + data = this.data.subarray(this.index, nextIndex); break; - case "array": - case "nodebuffer": - data = this.data.slice(this.index, nextIndex); + case "array": + case "nodebuffer": + data = this.data.slice(this.index, nextIndex); break; } this.index = nextIndex; @@ -2236,7 +2238,7 @@ DataWorker.prototype._tick = function() { module.exports = DataWorker; },{"../utils":32,"./GenericWorker":28}],28:[function(require,module,exports){ -'use strict'; +"use strict"; /** * A worker that does nothing but passing chunks to the next one. This is like @@ -2269,9 +2271,9 @@ function GenericWorker(name) { this.isLocked = false; // the event listeners this._listeners = { - 'data':[], - 'end':[], - 'error':[] + "data":[], + "end":[], + "error":[] }; // the previous worker, if any this.previous = null; @@ -2388,13 +2390,13 @@ GenericWorker.prototype = { this.mergeStreamInfo(); this.previous = previous; var self = this; - previous.on('data', function (chunk) { + previous.on("data", function (chunk) { self.processChunk(chunk); }); - previous.on('end', function () { + previous.on("end", function () { self.end(); }); - previous.on('error', function (e) { + previous.on("error", function (e) { self.error(e); }); return this; @@ -2463,7 +2465,7 @@ GenericWorker.prototype = { */ mergeStreamInfo : function () { for(var key in this.extraStreamInfo) { - if (!this.extraStreamInfo.hasOwnProperty(key)) { + if (!Object.prototype.hasOwnProperty.call(this.extraStreamInfo, key)) { continue; } this.streamInfo[key] = this.extraStreamInfo[key]; @@ -2501,20 +2503,22 @@ GenericWorker.prototype = { module.exports = GenericWorker; },{}],29:[function(require,module,exports){ -'use strict'; +"use strict"; -var utils = require('../utils'); -var ConvertWorker = require('./ConvertWorker'); -var GenericWorker = require('./GenericWorker'); -var base64 = require('../base64'); +var utils = require("../utils"); +var ConvertWorker = require("./ConvertWorker"); +var GenericWorker = require("./GenericWorker"); +var base64 = require("../base64"); var support = require("../support"); var external = require("../external"); var NodejsStreamOutputAdapter = null; if (support.nodestream) { try { - NodejsStreamOutputAdapter = require('../nodejs/NodejsStreamOutputAdapter'); - } catch(e) {} + NodejsStreamOutputAdapter = require("../nodejs/NodejsStreamOutputAdapter"); + } catch(e) { + // ignore + } } /** @@ -2528,12 +2532,12 @@ if (support.nodestream) { */ function transformZipOutput(type, content, mimeType) { switch(type) { - case "blob" : - return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType); - case "base64" : - return base64.encode(content); - default : - return utils.transformTo(type, content); + case "blob" : + return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType); + case "base64" : + return base64.encode(content); + default : + return utils.transformTo(type, content); } } @@ -2550,21 +2554,21 @@ function concat (type, dataArray) { totalLength += dataArray[i].length; } switch(type) { - case "string": - return dataArray.join(""); - case "array": - return Array.prototype.concat.apply([], dataArray); - case "uint8array": - res = new Uint8Array(totalLength); - for(i = 0; i < dataArray.length; i++) { - res.set(dataArray[i], index); - index += dataArray[i].length; - } - return res; - case "nodebuffer": - return Buffer.concat(dataArray); - default: - throw new Error("concat : unsupported type '" + type + "'"); + case "string": + return dataArray.join(""); + case "array": + return Array.prototype.concat.apply([], dataArray); + case "uint8array": + res = new Uint8Array(totalLength); + for(i = 0; i < dataArray.length; i++) { + res.set(dataArray[i], index); + index += dataArray[i].length; + } + return res; + case "nodebuffer": + return Buffer.concat(dataArray); + default: + throw new Error("concat : unsupported type '" + type + "'"); } } @@ -2584,26 +2588,26 @@ function accumulate(helper, updateCallback) { resultType = helper._outputType, mimeType = helper._mimeType; helper - .on('data', function (data, meta) { - dataArray.push(data); - if(updateCallback) { - updateCallback(meta); - } - }) - .on('error', function(err) { - dataArray = []; - reject(err); - }) - .on('end', function (){ - try { - var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType); - resolve(result); - } catch (e) { - reject(e); - } - dataArray = []; - }) - .resume(); + .on("data", function (data, meta) { + dataArray.push(data); + if(updateCallback) { + updateCallback(meta); + } + }) + .on("error", function(err) { + dataArray = []; + reject(err); + }) + .on("end", function (){ + try { + var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType); + resolve(result); + } catch (e) { + reject(e); + } + dataArray = []; + }) + .resume(); }); } @@ -2617,12 +2621,12 @@ function accumulate(helper, updateCallback) { function StreamHelper(worker, outputType, mimeType) { var internalType = outputType; switch(outputType) { - case "blob": - case "arraybuffer": - internalType = "uint8array"; + case "blob": + case "arraybuffer": + internalType = "uint8array"; break; - case "base64": - internalType = "string"; + case "base64": + internalType = "string"; break; } @@ -2715,7 +2719,7 @@ StreamHelper.prototype = { module.exports = StreamHelper; },{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(require,module,exports){ -'use strict'; +"use strict"; exports.base64 = true; exports.array = true; @@ -2740,7 +2744,7 @@ else { var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; var builder = new Builder(); builder.append(buffer); - exports.blob = builder.getBlob('application/zip').size === 0; + exports.blob = builder.getBlob("application/zip").size === 0; } catch (e) { exports.blob = false; @@ -2749,18 +2753,18 @@ else { } try { - exports.nodestream = !!require('readable-stream').Readable; + exports.nodestream = !!require("readable-stream").Readable; } catch(e) { exports.nodestream = false; } },{"readable-stream":16}],31:[function(require,module,exports){ -'use strict'; +"use strict"; -var utils = require('./utils'); -var support = require('./support'); -var nodejsUtils = require('./nodejsUtils'); -var GenericWorker = require('./stream/GenericWorker'); +var utils = require("./utils"); +var support = require("./support"); +var nodejsUtils = require("./nodejsUtils"); +var GenericWorker = require("./stream/GenericWorker"); /** * The following functions come from pako, from pako/lib/utils/strings @@ -2772,7 +2776,7 @@ var GenericWorker = require('./stream/GenericWorker'); // because max possible codepoint is 0x10ffff var _utf8len = new Array(256); for (var i=0; i<256; i++) { - _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); } _utf8len[254]=_utf8len[254]=1; // Invalid sequence start @@ -2863,7 +2867,7 @@ var utf8border = function(buf, max) { // convert array to string var buf2string = function (buf) { - var str, i, out, c, c_len; + var i, out, c, c_len; var len = buf.length; // Reserve max possible length (2 words per char) @@ -3032,13 +3036,13 @@ Utf8EncodeWorker.prototype.processChunk = function (chunk) { exports.Utf8EncodeWorker = Utf8EncodeWorker; },{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(require,module,exports){ -'use strict'; +"use strict"; -var support = require('./support'); -var base64 = require('./base64'); -var nodejsUtils = require('./nodejsUtils'); -var setImmediate = require('set-immediate-shim'); +var support = require("./support"); +var base64 = require("./base64"); +var nodejsUtils = require("./nodejsUtils"); var external = require("./external"); +require("setimmediate"); /** @@ -3051,9 +3055,9 @@ var external = require("./external"); function string2binary(str) { var result = null; if (support.uint8array) { - result = new Uint8Array(str.length); + result = new Uint8Array(str.length); } else { - result = new Array(str.length); + result = new Array(str.length); } return stringToArrayLike(str, result); } @@ -3122,7 +3126,7 @@ function stringToArrayLike(str, array) { /** * An helper for the function arrayLikeToString. - * This contains static informations and functions that + * This contains static information and functions that * can be optimized by the browser JIT compiler. */ var arrayToStringHelper = { @@ -3351,6 +3355,31 @@ exports.transformTo = function(outputType, input) { return result; }; +/** + * Resolve all relative path components, "." and "..", in a path. If these relative components + * traverse above the root then the resulting path will only contain the final path component. + * + * All empty components, e.g. "//", are removed. + * @param {string} path A path with / or \ separators + * @returns {string} The path with all relative path components resolved. + */ +exports.resolve = function(path) { + var parts = path.split("/"); + var result = []; + for (var index = 0; index < parts.length; index++) { + var part = parts[index]; + // Allow the first and last component to be empty for trailing slashes. + if (part === "." || (part === "" && index !== 0 && index !== parts.length - 1)) { + continue; + } else if (part === "..") { + result.pop(); + } else { + result.push(part); + } + } + return result.join("/"); +}; + /** * Return the type of the input. * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. @@ -3396,11 +3425,11 @@ exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is pa * @return {string} a pretty string. */ exports.pretty = function(str) { - var res = '', + var res = "", code, i; for (i = 0; i < (str || "").length; i++) { code = str.charCodeAt(i); - res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + res += "\\x" + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); } return res; }; @@ -3438,7 +3467,7 @@ exports.extend = function() { var result = {}, i, attr; for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers for (attr in arguments[i]) { - if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + if (Object.prototype.hasOwnProperty.call(arguments[i], attr) && typeof result[attr] === "undefined") { result[attr] = arguments[i][attr]; } } @@ -3459,9 +3488,9 @@ exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinarySt // if inputData is already a promise, this flatten it. var promise = external.Promise.resolve(inputData).then(function(data) { - - - var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1); + + + var isBlob = support.blob && (data instanceof Blob || ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(data)) !== -1); if (isBlob && typeof FileReader !== "undefined") { return new external.Promise(function (resolve, reject) { @@ -3509,14 +3538,13 @@ exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinarySt }); }; -},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"set-immediate-shim":54}],33:[function(require,module,exports){ -'use strict'; -var readerFor = require('./reader/readerFor'); -var utils = require('./utils'); -var sig = require('./signature'); -var ZipEntry = require('./zipEntry'); -var utf8 = require('./utf8'); -var support = require('./support'); +},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"setimmediate":54}],33:[function(require,module,exports){ +"use strict"; +var readerFor = require("./reader/readerFor"); +var utils = require("./utils"); +var sig = require("./signature"); +var ZipEntry = require("./zipEntry"); +var support = require("./support"); // class ZipEntries {{{ /** * All the entries in the zip file. @@ -3773,15 +3801,15 @@ ZipEntries.prototype = { // }}} end of ZipEntries module.exports = ZipEntries; -},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(require,module,exports){ -'use strict'; -var readerFor = require('./reader/readerFor'); -var utils = require('./utils'); -var CompressedObject = require('./compressedObject'); -var crc32fn = require('./crc32'); -var utf8 = require('./utf8'); -var compressions = require('./compressions'); -var support = require('./support'); +},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utils":32,"./zipEntry":34}],34:[function(require,module,exports){ +"use strict"; +var readerFor = require("./reader/readerFor"); +var utils = require("./utils"); +var CompressedObject = require("./compressedObject"); +var crc32fn = require("./crc32"); +var utf8 = require("./utf8"); +var compressions = require("./compressions"); +var support = require("./support"); var MADE_BY_DOS = 0x00; var MADE_BY_UNIX = 0x03; @@ -3793,7 +3821,7 @@ var MADE_BY_UNIX = 0x03; */ var findCompression = function(compressionMethod) { for (var method in compressions) { - if (!compressions.hasOwnProperty(method)) { + if (!Object.prototype.hasOwnProperty.call(compressions, method)) { continue; } if (compressions[method].magic === compressionMethod) { @@ -3862,7 +3890,7 @@ ZipEntry.prototype = { reader.skip(localExtraFieldsLength); if (this.compressedSize === -1 || this.uncompressedSize === -1) { - throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); + throw new Error("Bug or corrupted zip : didn't get enough information from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); } compression = findCompression(this.compressionMethod); @@ -3929,7 +3957,7 @@ ZipEntry.prototype = { } // fail safe : if the name ends with a / it probably means a folder - if (!this.dir && this.fileNameStr.slice(-1) === '/') { + if (!this.dir && this.fileNameStr.slice(-1) === "/") { this.dir = true; } }, @@ -3938,8 +3966,7 @@ ZipEntry.prototype = { * Parse the ZIP64 extra field and merge the info in the current ZipEntry. * @param {DataReader} reader the reader to use. */ - parseZIP64ExtraField: function(reader) { - + parseZIP64ExtraField: function() { if (!this.extraFields[0x0001]) { return; } @@ -3976,7 +4003,7 @@ ZipEntry.prototype = { this.extraFields = {}; } - while (reader.index < end) { + while (reader.index + 4 < end) { extraFieldId = reader.readInt(2); extraFieldLength = reader.readInt(2); extraFieldValue = reader.readData(extraFieldLength); @@ -3987,6 +4014,8 @@ ZipEntry.prototype = { value: extraFieldValue }; } + + reader.setIndex(end); }, /** * Apply an UTF8 transformation if needed. @@ -4068,13 +4097,13 @@ ZipEntry.prototype = { module.exports = ZipEntry; },{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(require,module,exports){ -'use strict'; +"use strict"; -var StreamHelper = require('./stream/StreamHelper'); -var DataWorker = require('./stream/DataWorker'); -var utf8 = require('./utf8'); -var CompressedObject = require('./compressedObject'); -var GenericWorker = require('./stream/GenericWorker'); +var StreamHelper = require("./stream/StreamHelper"); +var DataWorker = require("./stream/DataWorker"); +var utf8 = require("./utf8"); +var CompressedObject = require("./compressedObject"); +var GenericWorker = require("./stream/GenericWorker"); /** * A simple object representing a file in the zip file. @@ -11355,13 +11384,194 @@ function ZStream() { module.exports = ZStream; },{}],54:[function(require,module,exports){ -'use strict'; -module.exports = typeof setImmediate === 'function' ? setImmediate : - function setImmediate() { - var args = [].slice.apply(arguments); - args.splice(1, 0, 0); - setTimeout.apply(null, args); - }; +(function (global){ +(function (global, undefined) { + "use strict"; + + if (global.setImmediate) { + return; + } + + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var currentlyRunningATask = false; + var doc = global.document; + var registerImmediate; + + function setImmediate(callback) { + // Callback can either be a function or a string + if (typeof callback !== "function") { + callback = new Function("" + callback); + } + // Copy function arguments + var args = new Array(arguments.length - 1); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i + 1]; + } + // Store and register the task + var task = { callback: callback, args: args }; + tasksByHandle[nextHandle] = task; + registerImmediate(nextHandle); + return nextHandle++; + } + + function clearImmediate(handle) { + delete tasksByHandle[handle]; + } + + function run(task) { + var callback = task.callback; + var args = task.args; + switch (args.length) { + case 0: + callback(); + break; + case 1: + callback(args[0]); + break; + case 2: + callback(args[0], args[1]); + break; + case 3: + callback(args[0], args[1], args[2]); + break; + default: + callback.apply(undefined, args); + break; + } + } + + function runIfPresent(handle) { + // From the spec: "Wait until any invocations of this algorithm started before this one have completed." + // So if we're currently running a task, we'll need to delay this invocation. + if (currentlyRunningATask) { + // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a + // "too much recursion" error. + setTimeout(runIfPresent, 0, handle); + } else { + var task = tasksByHandle[handle]; + if (task) { + currentlyRunningATask = true; + try { + run(task); + } finally { + clearImmediate(handle); + currentlyRunningATask = false; + } + } + } + } + + function installNextTickImplementation() { + registerImmediate = function(handle) { + process.nextTick(function () { runIfPresent(handle); }); + }; + } + function canUsePostMessage() { + // The test against `importScripts` prevents this implementation from being installed inside a web worker, + // where `global.postMessage` means something completely different and can't be used for this purpose. + if (global.postMessage && !global.importScripts) { + var postMessageIsAsynchronous = true; + var oldOnMessage = global.onmessage; + global.onmessage = function() { + postMessageIsAsynchronous = false; + }; + global.postMessage("", "*"); + global.onmessage = oldOnMessage; + return postMessageIsAsynchronous; + } + } + + function installPostMessageImplementation() { + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages + + var messagePrefix = "setImmediate$" + Math.random() + "$"; + var onGlobalMessage = function(event) { + if (event.source === global && + typeof event.data === "string" && + event.data.indexOf(messagePrefix) === 0) { + runIfPresent(+event.data.slice(messagePrefix.length)); + } + }; + + if (global.addEventListener) { + global.addEventListener("message", onGlobalMessage, false); + } else { + global.attachEvent("onmessage", onGlobalMessage); + } + + registerImmediate = function(handle) { + global.postMessage(messagePrefix + handle, "*"); + }; + } + + function installMessageChannelImplementation() { + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + var handle = event.data; + runIfPresent(handle); + }; + + registerImmediate = function(handle) { + channel.port2.postMessage(handle); + }; + } + + function installReadyStateChangeImplementation() { + var html = doc.documentElement; + registerImmediate = function(handle) { + // Create a + + + + + + diff --git a/test/benchmark/node.js b/test/benchmark/node.js new file mode 100644 index 00000000..8b359596 --- /dev/null +++ b/test/benchmark/node.js @@ -0,0 +1,7 @@ +"use strict"; + +globalThis.Benchmark = require("benchmark"); +globalThis.JSZip = require("../../lib/index"); + +const benchmark = require("./benchmark"); +benchmark("nodebuffer"); diff --git a/test/helpers/browser-test-utils.js b/test/helpers/browser-test-utils.js index f1d5db3a..add57eb8 100644 --- a/test/helpers/browser-test-utils.js +++ b/test/helpers/browser-test-utils.js @@ -1,5 +1,4 @@ -/* global JSZip,JSZipUtils,JSZipTestUtils */ -'use strict'; +"use strict"; JSZipTestUtils.loadZipFile = function (name, callback) { JSZipUtils.getBinaryContent(name + "?_=" + ( new Date() ).getTime(), callback); }; diff --git a/test/helpers/node-test-utils.js b/test/helpers/node-test-utils.js index b415b7a7..9dc22eea 100644 --- a/test/helpers/node-test-utils.js +++ b/test/helpers/node-test-utils.js @@ -1,5 +1,4 @@ -/* global QUnit,JSZip,JSZipTestUtils */ -'use strict'; +"use strict"; var fs = require("fs"); var path = require("path"); @@ -9,12 +8,12 @@ global.JSZip = require("../../lib/index"); global.JSZipTestUtils.loadZipFile = function(name, callback) { fs.readFile(path.join("test", name), "binary", callback); }; -process.on('uncaughtException', function(err) { - console.log('uncaughtException: ' + err, err.stack); - process.exit(1); +process.on("uncaughtException", function(err) { + console.log("uncaughtException: " + err, err.stack); + process.exit(1); }); -process.on('unhandledRejection', function(err) { - console.log('unhandledRejection: ' + err, err.stack); - process.exit(1); +process.on("unhandledRejection", function(err) { + console.log("unhandledRejection: " + err, err.stack); + process.exit(1); }); diff --git a/test/helpers/test-utils.js b/test/helpers/test-utils.js index 77543948..ef7528d2 100644 --- a/test/helpers/test-utils.js +++ b/test/helpers/test-utils.js @@ -1,5 +1,4 @@ -/* global QUnit,JSZip,JSZipTestUtils */ -'use strict'; +"use strict"; (function (global) { // Expose assert object globally @@ -64,7 +63,7 @@ }).then(function (content) { assert.ok(JSZipTestUtils.similar(bytesStream, content, 0), "generate stability : stable"); done(); - })['catch'](JSZipTestUtils.assertNoError); + })["catch"](JSZipTestUtils.assertNoError); }; JSZipTestUtils.checkBasicStreamBehavior = function checkBasicStreamBehavior(assert, stream, testName) { @@ -74,26 +73,26 @@ } var triggeredStream = false; stream - .on("data", function (data, metadata) { + .on("data", function (data, metadata) { // triggering a lot of passing checks makes the result unreadable - if (!data) { - assert.ok(data, testName + "basic check stream, data event handler, data is defined"); - } - if(!metadata) { - assert.ok(metadata, testName + "basic check stream, data event handler, metadata is defined"); - } - triggeredStream = true; - }) - .on("error", function (e) { - assert.ok(e, testName + "basic check stream, error event handler, error is defined"); - triggeredStream = true; - done(); - }) - .on("end", function () { - triggeredStream = true; - done(); - }) - .resume() + if (!data) { + assert.ok(data, testName + "basic check stream, data event handler, data is defined"); + } + if(!metadata) { + assert.ok(metadata, testName + "basic check stream, data event handler, metadata is defined"); + } + triggeredStream = true; + }) + .on("error", function (e) { + assert.ok(e, testName + "basic check stream, error event handler, error is defined"); + triggeredStream = true; + done(); + }) + .on("end", function () { + triggeredStream = true; + done(); + }) + .resume() ; assert.ok(!triggeredStream, testName + "basic check stream, the stream callback is async"); }; @@ -189,7 +188,7 @@ var base64Dict = { "": "", - "\xE2\x82\xAC15\n": "4oKsMTUK", + "\xE2\x82\xAC15\n": "4oKsMTUK", "test\r\ntest\r\n": "dGVzdA0KdGVzdA0K", "all.zip.base64,stream=false": "UEsDBAoAAAAAAO+7TTrj5ZWwDAAAAAwAAAAJAAAASGVsbG8udHh0SGVsbG8gV29ybGQKUEsDBAoAAAAAAA9qUToAAAAAAAAAAAAAAAAHAAAAaW1hZ2VzL1BLAwQKAAAAAACZoEg6PD/riikAAAApAAAAEAAAAGltYWdlcy9zbWlsZS5naWZHSUY4N2EFAAUAgAIAAAAA/94ALAAAAAAFAAUAAAIIjA+RZ6sKUgEAO1BLAQIUAAoAAAAAAO+7TTrj5ZWwDAAAAAwAAAAJAAAAAAAAAAAAAAAAAAAAAABIZWxsby50eHRQSwECFAAKAAAAAAAPalE6AAAAAAAAAAAAAAAABwAAAAAAAAAAABAAAAAzAAAAaW1hZ2VzL1BLAQIUAAoAAAAAAJmgSDo8P+uKKQAAACkAAAAQAAAAAAAAAAAAAAAAAFgAAABpbWFnZXMvc21pbGUuZ2lmUEsFBgAAAAADAAMAqgAAAK8AAAAAAA==", "all.zip.base64,stream=true": "UEsDBAoACAAAAO+7TToAAAAAAAAAAAAAAAAJAAAASGVsbG8udHh0SGVsbG8gV29ybGQKUEsHCOPllbAMAAAADAAAAFBLAwQKAAAAAAAPalE6AAAAAAAAAAAAAAAABwAAAGltYWdlcy9QSwMECgAIAAAAmaBIOgAAAAAAAAAAAAAAABAAAABpbWFnZXMvc21pbGUuZ2lmR0lGODdhBQAFAIACAAAAAP/eACwAAAAABQAFAAACCIwPkWerClIBADtQSwcIPD/riikAAAApAAAAUEsBAhQACgAIAAAA77tNOuPllbAMAAAADAAAAAkAAAAAAAAAAAAAAAAAAAAAAEhlbGxvLnR4dFBLAQIUAAoAAAAAAA9qUToAAAAAAAAAAAAAAAAHAAAAAAAAAAAAEAAAAEMAAABpbWFnZXMvUEsBAhQACgAIAAAAmaBIOjw/64opAAAAKQAAABAAAAAAAAAAAAAAAAAAaAAAAGltYWdlcy9zbWlsZS5naWZQSwUGAAAAAAMAAwCqAAAAzwAAAAAA" diff --git a/test/index.html b/test/index.html index 652513d3..e53a54d8 100644 --- a/test/index.html +++ b/test/index.html @@ -3,8 +3,8 @@ JSZip Testing - - + +