From 42528f291db16bf2e7d5f831ebe2ad87fd0b1f42 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 15 Nov 2024 22:09:06 -0800 Subject: [PATCH 01/12] Only apps should have lockfiles --- .gitignore | 5 +++++ .npmrc | 1 + 2 files changed, 6 insertions(+) create mode 100644 .npmrc diff --git a/.gitignore b/.gitignore index 3c3629e..d029b6e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ node_modules + +# Only apps should have lockfiles +npm-shrinkwrap.json +package-lock.json +yarn.lock diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..43c97e7 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false From ae02fd6624c41ac4ac18077be797111d1955bc76 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 15 Nov 2024 22:15:20 -0800 Subject: [PATCH 02/12] [Tests] standard -> eslint, make test dir, etc --- .eslintrc | 20 ++++++- index.js | 158 ++++++++++++++++++++++++++------------------------ package.json | 12 ++-- test.js | 111 ----------------------------------- test/index.js | 130 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 238 insertions(+), 193 deletions(-) delete mode 100644 test.js create mode 100644 test/index.js diff --git a/.eslintrc b/.eslintrc index a755cdb..fb62a75 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,3 +1,21 @@ { - "extends": ["standard"] + "root": true, + + "extends": "@ljharb", + + "rules": { + "func-style": "off", + }, + + "overrides": [ + { + "files": [ + "./index.js", + "./test/index.js", + ], + "rules": { + "no-underscore-dangle": "warn", + }, + }, + ], } diff --git a/index.js b/index.js index 6728005..39c8bcc 100644 --- a/index.js +++ b/index.js @@ -1,99 +1,103 @@ -var Buffer = require('safe-buffer').Buffer -var Transform = require('stream').Transform -var StringDecoder = require('string_decoder').StringDecoder -var inherits = require('inherits') - -function CipherBase (hashMode) { - Transform.call(this) - this.hashMode = typeof hashMode === 'string' - if (this.hashMode) { - this[hashMode] = this._finalOrDigest - } else { - this.final = this._finalOrDigest - } - if (this._final) { - this.__final = this._final - this._final = null - } - this._decoder = null - this._encoding = null +'use strict'; + +var Buffer = require('safe-buffer').Buffer; +var Transform = require('stream').Transform; +var StringDecoder = require('string_decoder').StringDecoder; +var inherits = require('inherits'); + +function CipherBase(hashMode) { + Transform.call(this); + this.hashMode = typeof hashMode === 'string'; + if (this.hashMode) { + this[hashMode] = this._finalOrDigest; + } else { + this['final'] = this._finalOrDigest; + } + if (this._final) { + this.__final = this._final; + this._final = null; + } + this._decoder = null; + this._encoding = null; } -inherits(CipherBase, Transform) +inherits(CipherBase, Transform); CipherBase.prototype.update = function (data, inputEnc, outputEnc) { - if (typeof data === 'string') { - data = Buffer.from(data, inputEnc) - } + var bufferData = typeof data === 'string' ? Buffer.from(data, inputEnc) : data; - var outData = this._update(data) - if (this.hashMode) return this + var outData = this._update(bufferData); + if (this.hashMode) { + return this; + } - if (outputEnc) { - outData = this._toString(outData, outputEnc) - } + if (outputEnc) { + outData = this._toString(outData, outputEnc); + } - return outData -} + return outData; +}; -CipherBase.prototype.setAutoPadding = function () {} +CipherBase.prototype.setAutoPadding = function () {}; CipherBase.prototype.getAuthTag = function () { - throw new Error('trying to get auth tag in unsupported state') -} + throw new Error('trying to get auth tag in unsupported state'); +}; CipherBase.prototype.setAuthTag = function () { - throw new Error('trying to set auth tag in unsupported state') -} + throw new Error('trying to set auth tag in unsupported state'); +}; CipherBase.prototype.setAAD = function () { - throw new Error('trying to set aad in unsupported state') -} + throw new Error('trying to set aad in unsupported state'); +}; CipherBase.prototype._transform = function (data, _, next) { - var err - try { - if (this.hashMode) { - this._update(data) - } else { - this.push(this._update(data)) - } - } catch (e) { - err = e - } finally { - next(err) - } -} + var err; + try { + if (this.hashMode) { + this._update(data); + } else { + this.push(this._update(data)); + } + } catch (e) { + err = e; + } finally { + next(err); + } +}; CipherBase.prototype._flush = function (done) { - var err - try { - this.push(this.__final()) - } catch (e) { - err = e - } - - done(err) -} + var err; + try { + this.push(this.__final()); + } catch (e) { + err = e; + } + + done(err); +}; CipherBase.prototype._finalOrDigest = function (outputEnc) { - var outData = this.__final() || Buffer.alloc(0) - if (outputEnc) { - outData = this._toString(outData, outputEnc, true) - } - return outData -} + var outData = this.__final() || Buffer.alloc(0); + if (outputEnc) { + outData = this._toString(outData, outputEnc, true); + } + return outData; +}; CipherBase.prototype._toString = function (value, enc, fin) { - if (!this._decoder) { - this._decoder = new StringDecoder(enc) - this._encoding = enc - } + if (!this._decoder) { + this._decoder = new StringDecoder(enc); + this._encoding = enc; + } - if (this._encoding !== enc) throw new Error('can\'t switch encodings') + if (this._encoding !== enc) { + throw new Error('can’t switch encodings'); + } - var out = this._decoder.write(value) - if (fin) { - out += this._decoder.end() - } + var out = this._decoder.write(value); + if (fin) { + out += this._decoder.end(); + } - return out -} + return out; +}; -module.exports = CipherBase +module.exports = CipherBase; diff --git a/package.json b/package.json index f372599..20b292a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,11 @@ "description": "abstract base class for crypto-streams", "main": "index.js", "scripts": { - "test": "node test.js | tspec" + "lint": "eslint --ext=js,.mjs .", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "tape 'test/**/*.js'", + "posttest": "npx npm@'>=10.2' audit --production" }, "repository": { "type": "git", @@ -25,8 +29,8 @@ "safe-buffer": "^5.0.1" }, "devDependencies": { - "standard": "^10.0.2", - "tap-spec": "^4.1.0", - "tape": "^4.2.0" + "@ljharb/eslint-config": "^21.1.1", + "eslint": "=8.8.0", + "tape": "^5.9.0" } } diff --git a/test.js b/test.js deleted file mode 100644 index 29d3492..0000000 --- a/test.js +++ /dev/null @@ -1,111 +0,0 @@ -var Buffer = require('safe-buffer').Buffer -var CipherBase = require('./') - -var test = require('tape') -var inherits = require('inherits') - -test('basic version', function (t) { - function Cipher () { - CipherBase.call(this) - } - inherits(Cipher, CipherBase) - Cipher.prototype._update = function (input) { - t.ok(Buffer.isBuffer(input)) - return input - } - Cipher.prototype._final = function () { - // noop - } - var cipher = new Cipher() - var utf8 = 'abc123abcd' - var update = cipher.update(utf8, 'utf8', 'base64') + cipher.final('base64') - var string = (Buffer.from(update, 'base64')).toString() - t.equals(utf8, string) - t.end() -}) -test('hash mode', function (t) { - function Cipher () { - CipherBase.call(this, 'finalName') - this._cache = [] - } - inherits(Cipher, CipherBase) - Cipher.prototype._update = function (input) { - t.ok(Buffer.isBuffer(input)) - this._cache.push(input) - } - Cipher.prototype._final = function () { - return Buffer.concat(this._cache) - } - var cipher = new Cipher() - var utf8 = 'abc123abcd' - var update = cipher.update(utf8, 'utf8').finalName('base64') - var string = (Buffer.from(update, 'base64')).toString() - - t.equals(utf8, string) - t.end() -}) -test('hash mode as stream', function (t) { - function Cipher () { - CipherBase.call(this, 'finalName') - this._cache = [] - } - inherits(Cipher, CipherBase) - Cipher.prototype._update = function (input) { - t.ok(Buffer.isBuffer(input)) - this._cache.push(input) - } - Cipher.prototype._final = function () { - return Buffer.concat(this._cache) - } - var cipher = new Cipher() - cipher.on('error', function (e) { - t.notOk(e) - }) - var utf8 = 'abc123abcd' - cipher.end(utf8, 'utf8') - var update = cipher.read().toString('base64') - var string = (Buffer.from(update, 'base64')).toString() - - t.equals(utf8, string) - t.end() -}) - -test('encodings', function (t) { - inherits(Cipher, CipherBase) - function Cipher () { - CipherBase.call(this) - } - Cipher.prototype._update = function (input) { - return input - } - Cipher.prototype._final = function () { - // noop - } - t.test('mix and match encoding', function (t) { - t.plan(2) - - var cipher = new Cipher() - cipher.update('foo', 'utf8', 'utf8') - t.throws(function () { - cipher.update('foo', 'utf8', 'base64') - }) - cipher = new Cipher() - cipher.update('foo', 'utf8', 'base64') - t.doesNotThrow(function () { - cipher.update('foo', 'utf8') - cipher.final('base64') - }) - }) - t.test('handle long uft8 plaintexts', function (t) { - t.plan(1) - var txt = 'ふっかつ あきる すぶり はやい つける まゆげ たんさん みんぞく ねほりはほり せまい たいまつばな ひはん' - - var cipher = new Cipher() - var decipher = new Cipher() - var enc = decipher.update(cipher.update(txt, 'utf8', 'base64'), 'base64', 'utf8') - enc += decipher.update(cipher.final('base64'), 'base64', 'utf8') - enc += decipher.final('utf8') - - t.equals(txt, enc) - }) -}) diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..b612701 --- /dev/null +++ b/test/index.js @@ -0,0 +1,130 @@ +'use strict'; + +var Buffer = require('safe-buffer').Buffer; +var CipherBase = require('../'); + +var test = require('tape'); +var inherits = require('inherits'); + +test('basic version', function (t) { + function Cipher() { + CipherBase.call(this); + } + + inherits(Cipher, CipherBase); + + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + return input; + }; + + Cipher.prototype._final = function () { + // noop + }; + + var cipher = new Cipher(); + var utf8 = 'abc123abcd'; + var update = cipher.update(utf8, 'utf8', 'base64') + cipher['final']('base64'); + var string = Buffer.from(update, 'base64').toString(); + + t.equals(utf8, string); + + t.end(); +}); + +test('hash mode', function (t) { + function Cipher() { + CipherBase.call(this, 'finalName'); + this._cache = []; + } + inherits(Cipher, CipherBase); + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + this._cache.push(input); + }; + Cipher.prototype._final = function () { + return Buffer.concat(this._cache); + }; + var cipher = new Cipher(); + var utf8 = 'abc123abcd'; + var update = cipher.update(utf8, 'utf8').finalName('base64'); + var string = Buffer.from(update, 'base64').toString(); + + t.equals(utf8, string); + + t.end(); +}); + +test('hash mode as stream', function (t) { + function Cipher() { + CipherBase.call(this, 'finalName'); + this._cache = []; + } + inherits(Cipher, CipherBase); + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + this._cache.push(input); + }; + Cipher.prototype._final = function () { + return Buffer.concat(this._cache); + }; + var cipher = new Cipher(); + cipher.on('error', function (e) { + t.notOk(e); + }); + var utf8 = 'abc123abcd'; + cipher.end(utf8, 'utf8'); + var update = cipher.read().toString('base64'); + var string = Buffer.from(update, 'base64').toString(); + + t.equals(utf8, string); + + t.end(); +}); + +test('encodings', function (t) { + function Cipher() { + CipherBase.call(this); + } + inherits(Cipher, CipherBase); + + Cipher.prototype._update = function (input) { + return input; + }; + + Cipher.prototype._final = function () { + // noop + }; + + t.test('mix and match encoding', function (st) { + st.plan(2); + + var cipher = new Cipher(); + cipher.update('foo', 'utf8', 'utf8'); + + st['throws'](function () { + cipher.update('foo', 'utf8', 'base64'); + }); + + cipher = new Cipher(); + cipher.update('foo', 'utf8', 'base64'); + + st.doesNotThrow(function () { + cipher.update('foo', 'utf8'); + cipher['final']('base64'); + }); + }); + + t.test('handle long uft8 plaintexts', function (st) { + st.plan(1); + var txt = 'ふっかつ あきる すぶり はやい つける まゆげ たんさん みんぞく ねほりはほり せまい たいまつばな ひはん'; + + var cipher = new Cipher(); + var decipher = new Cipher(); + var enc = decipher.update(cipher.update(txt, 'utf8', 'base64'), 'base64', 'utf8'); + enc += decipher.update(cipher['final']('base64'), 'base64', 'utf8'); + enc += decipher['final']('utf8'); + + st.equals(txt, enc); + }); +}); From 0e7a2d9a33a391e82fa9cf512d6e25cc91ab8613 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 15 Nov 2024 22:15:35 -0800 Subject: [PATCH 03/12] [Deps] update `inherits`, `safe-buffer` --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 20b292a..e61c7df 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ }, "homepage": "https://github.com/crypto-browserify/cipher-base#readme", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" }, "devDependencies": { "@ljharb/eslint-config": "^21.1.1", From f2dc13e47bbcf3c873db9a9e0f83e5f29d0783fe Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 15 Nov 2024 22:15:48 -0800 Subject: [PATCH 04/12] [meta] add missing `engines.node` --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index e61c7df..74f9048 100644 --- a/package.json +++ b/package.json @@ -32,5 +32,8 @@ "@ljharb/eslint-config": "^21.1.1", "eslint": "=8.8.0", "tape": "^5.9.0" + }, + "engines": { + "node": ">= 0.4" } } From 66387d71461287ad9067bb1bcbfdc47403a33ee7 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 15 Nov 2024 22:08:30 -0800 Subject: [PATCH 05/12] [Tests] migrate from travis to GHA --- .github/FUNDING.yml | 12 ++++++++++++ .github/workflows/node-aught.yml | 11 +++++++++++ .github/workflows/node-pretest.yml | 7 +++++++ .github/workflows/node-tens.yml | 11 +++++++++++ .github/workflows/node-twenties.yml | 14 ++++++++++++++ .github/workflows/rebase.yml | 22 ++++++++++++++++++++++ .github/workflows/require-allow-edits.yml | 12 ++++++++++++ .travis.yml | 6 ------ package.json | 2 +- 9 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/node-aught.yml create mode 100644 .github/workflows/node-pretest.yml create mode 100644 .github/workflows/node-tens.yml create mode 100644 .github/workflows/node-twenties.yml create mode 100644 .github/workflows/rebase.yml create mode 100644 .github/workflows/require-allow-edits.yml delete mode 100644 .travis.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..fbfd907 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/cipher-base +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/node-aught.yml b/.github/workflows/node-aught.yml new file mode 100644 index 0000000..1af040e --- /dev/null +++ b/.github/workflows/node-aught.yml @@ -0,0 +1,11 @@ +name: 'Tests: node.js < 10' + +on: [pull_request, push] + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '0.10 - 9' + type: minors + command: npm run tests-only diff --git a/.github/workflows/node-pretest.yml b/.github/workflows/node-pretest.yml new file mode 100644 index 0000000..765edf7 --- /dev/null +++ b/.github/workflows/node-pretest.yml @@ -0,0 +1,7 @@ +name: 'Tests: pretest/posttest' + +on: [pull_request, push] + +jobs: + tests: + uses: ljharb/actions/.github/workflows/pretest.yml@main diff --git a/.github/workflows/node-tens.yml b/.github/workflows/node-tens.yml new file mode 100644 index 0000000..1f55be0 --- /dev/null +++ b/.github/workflows/node-tens.yml @@ -0,0 +1,11 @@ +name: 'Tests: node.js >= 10' + +on: [pull_request, push] + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '>= 10' + type: minors + command: npm run tests-only diff --git a/.github/workflows/node-twenties.yml b/.github/workflows/node-twenties.yml new file mode 100644 index 0000000..209e157 --- /dev/null +++ b/.github/workflows/node-twenties.yml @@ -0,0 +1,14 @@ +name: 'Tests: node.js >= 20' + +on: [pull_request, push] + +permissions: + contents: read + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '>= 20' + type: minors + command: npm run tests-only diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml new file mode 100644 index 0000000..8b2a811 --- /dev/null +++ b/.github/workflows/rebase.yml @@ -0,0 +1,22 @@ +name: Automatic Rebase + +on: [pull_request_target] + +permissions: + contents: read + +jobs: + _: + permissions: + contents: write # for ljharb/rebase to push code to rebase + pull-requests: read # for ljharb/rebase to get info about PR + + name: "Automatic Rebase" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: ljharb/rebase@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/require-allow-edits.yml b/.github/workflows/require-allow-edits.yml new file mode 100644 index 0000000..7b842f8 --- /dev/null +++ b/.github/workflows/require-allow-edits.yml @@ -0,0 +1,12 @@ +name: Require “Allow Edits” + +on: [pull_request_target] + +jobs: + _: + name: "Require “Allow Edits”" + + runs-on: ubuntu-latest + + steps: + - uses: ljharb/require-allow-edits@main diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index eb83acd..0000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: node_js -node_js: - - "0.11" - - "0.10" - - "0.12" - - "iojs" diff --git a/package.json b/package.json index 74f9048..e36a53c 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,6 @@ "tape": "^5.9.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.10" } } From 8fd136432ca298a664f5637629cf2b42a6c7f294 Mon Sep 17 00:00:00 2001 From: Nikita Skovoroda Date: Sat, 16 Nov 2024 09:19:57 +0400 Subject: [PATCH 06/12] [Fix] return valid values on multi-byte-wide TypedArray input --- .eslintrc | 5 +++++ index.js | 41 ++++++++++++++++++++++++++++++++++++++++- test/index.js | 25 +++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index fb62a75..ff010df 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,6 +7,11 @@ "func-style": "off", }, + "globals": { + "Uint8Array": false, + "Uint16Array": false, + }, + "overrides": [ { "files": [ diff --git a/index.js b/index.js index 39c8bcc..741d913 100644 --- a/index.js +++ b/index.js @@ -22,8 +22,47 @@ function CipherBase(hashMode) { } inherits(CipherBase, Transform); +var useUint8Array = typeof Uint8Array !== 'undefined'; +var useArrayBuffer = typeof ArrayBuffer !== 'undefined' + && typeof Uint8Array !== 'undefined' + && ArrayBuffer.isView + && (Buffer.prototype instanceof Uint8Array || Buffer.TYPED_ARRAY_SUPPORT); + CipherBase.prototype.update = function (data, inputEnc, outputEnc) { - var bufferData = typeof data === 'string' ? Buffer.from(data, inputEnc) : data; + var bufferData; + if (data instanceof Buffer) { + // No need to do anything + bufferData = data; + } else if (typeof data === 'string') { + // Convert strings to Buffer + bufferData = Buffer.from(data, inputEnc); + } else if (useArrayBuffer && ArrayBuffer.isView(data)) { + /* + * Wrap any TypedArray instances and DataViews + * Makes sense only on engines with full TypedArray support -- let Buffer detect that + */ + bufferData = Buffer.from(data.buffer, data.byteOffset, data.byteLength); + } else if (useUint8Array && data instanceof Uint8Array) { + /* + * Uint8Array in engines where Buffer.from might not work with ArrayBuffer, just copy over + * Doesn't make sense with other TypedArray instances + */ + bufferData = Buffer.from(data); + } else if ( + Buffer.isBuffer(data) + && data.constructor + && data.constructor.isBuffer + && data.constructor.isBuffer(data) + ) { + /* + * Old Buffer polyfill on an engine that doesn't have TypedArray support + * Also, this is from a different Buffer polyfill implementation then we have, as instanceof check failed + * Convert to our current Buffer implementation + */ + bufferData = Buffer.from(data); + } else { + throw new Error('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView.'); + } var outData = this._update(bufferData); if (this.hashMode) { diff --git a/test/index.js b/test/index.js index b612701..ea2c651 100644 --- a/test/index.js +++ b/test/index.js @@ -128,3 +128,28 @@ test('encodings', function (t) { st.equals(txt, enc); }); }); + +test('handle UInt16Array', function (t) { + function Cipher() { + CipherBase.call(this, 'finalName'); + this._cache = []; + } + inherits(Cipher, CipherBase); + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + this._cache.push(input); + }; + Cipher.prototype._final = function () { + return Buffer.concat(this._cache); + }; + + if (ArrayBuffer.isView && (Buffer.prototype instanceof Uint8Array || Buffer.TYPED_ARRAY_SUPPORT)) { + var cipher = new Cipher(); + var final = cipher.update(new Uint16Array([1234, 512])).finalName('hex'); + t.equals(final, 'd2040002'); + } else { + t.skip('ArrayBuffer.isView and/or TypedArray not fully supported'); + } + + t.end(); +}); From 5c02918ac58c875ed36913c2dc3e1043f4d1c99c Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 17 Nov 2024 09:03:38 -0800 Subject: [PATCH 07/12] [meta] fix package.json indentation --- package.json | 74 ++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index e36a53c..a42fbc5 100644 --- a/package.json +++ b/package.json @@ -1,39 +1,39 @@ { - "name": "cipher-base", - "version": "1.0.4", - "description": "abstract base class for crypto-streams", - "main": "index.js", - "scripts": { - "lint": "eslint --ext=js,.mjs .", - "pretest": "npm run lint", - "test": "npm run tests-only", - "tests-only": "tape 'test/**/*.js'", - "posttest": "npx npm@'>=10.2' audit --production" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/crypto-browserify/cipher-base.git" - }, - "keywords": [ - "cipher", - "stream" - ], - "author": "Calvin Metcalf ", - "license": "MIT", - "bugs": { - "url": "https://github.com/crypto-browserify/cipher-base/issues" - }, - "homepage": "https://github.com/crypto-browserify/cipher-base#readme", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" - }, - "devDependencies": { - "@ljharb/eslint-config": "^21.1.1", - "eslint": "=8.8.0", - "tape": "^5.9.0" - }, - "engines": { - "node": ">= 0.10" - } + "name": "cipher-base", + "version": "1.0.4", + "description": "abstract base class for crypto-streams", + "main": "index.js", + "scripts": { + "lint": "eslint --ext=js,.mjs .", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "tape 'test/**/*.js'", + "posttest": "npx npm@'>=10.2' audit --production" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/crypto-browserify/cipher-base.git" + }, + "keywords": [ + "cipher", + "stream" + ], + "author": "Calvin Metcalf ", + "license": "MIT", + "bugs": { + "url": "https://github.com/crypto-browserify/cipher-base/issues" + }, + "homepage": "https://github.com/crypto-browserify/cipher-base#readme", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.1.1", + "eslint": "=8.8.0", + "tape": "^5.9.0" + }, + "engines": { + "node": ">= 0.10" + } } From 7a137d749ce7ea7ea56b9c096844b1b8ab723f61 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 17 Nov 2024 09:04:32 -0800 Subject: [PATCH 08/12] [meta] add `npmignore` and `safe-publish-latest` --- .gitignore | 2 ++ package.json | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/.gitignore b/.gitignore index d029b6e..34aaa91 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ node_modules npm-shrinkwrap.json package-lock.json yarn.lock + +.npmignore diff --git a/package.json b/package.json index a42fbc5..4da326d 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,9 @@ "description": "abstract base class for crypto-streams", "main": "index.js", "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", "lint": "eslint --ext=js,.mjs .", "pretest": "npm run lint", "test": "npm run tests-only", @@ -31,8 +34,16 @@ "devDependencies": { "@ljharb/eslint-config": "^21.1.1", "eslint": "=8.8.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "safe-publish-latest": "^2.0.0", "tape": "^5.9.0" }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, "engines": { "node": ">= 0.10" } From 88dc806806d3dc41444dbf639c87c00f82c949b3 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 17 Nov 2024 09:06:06 -0800 Subject: [PATCH 09/12] [meta] add `auto-changelog` --- .npmrc | 2 ++ CHANGELOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 14 +++++++++++++- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md diff --git a/.npmrc b/.npmrc index 43c97e7..eacea13 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,3 @@ package-lock=false +allow-same-version=true +message=v%s diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..018e75c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.4](https://github.com/browserify/cipher-base/compare/v1.0.3...v1.0.4) - 2017-07-06 + +### Merged + +- Safe Buffer & License [`#8`](https://github.com/browserify/cipher-base/pull/8) +- fix break in node 8 [`#9`](https://github.com/browserify/cipher-base/pull/9) + +### Commits + +- use safe-buffer [`193bbeb`](https://github.com/browserify/cipher-base/commit/193bbeb0d60ff206b072d4e18b32fcf150eb0fad) +- add MIT LICENSE [`a9fb6e3`](https://github.com/browserify/cipher-base/commit/a9fb6e316c25b25d2bd04fa5b6eb748318bdcb04) +- index: add missing Buffer.alloc [`2397a9e`](https://github.com/browserify/cipher-base/commit/2397a9e0db33b2f3d6abbd89f01db1c066804a91) +- rename README to README, add .gitignore [`9345e1d`](https://github.com/browserify/cipher-base/commit/9345e1d21fd10555bc4f39ccae5512ca0202c5f6) + +## [v1.0.3](https://github.com/browserify/cipher-base/compare/v1.0.2...v1.0.3) - 2016-09-13 + +### Merged + +- closure-compiler fix - final is a reserved word [`#4`](https://github.com/browserify/cipher-base/pull/4) + +## [v1.0.2](https://github.com/browserify/cipher-base/compare/v1.0.1...v1.0.2) - 2015-10-23 + +### Merged + +- fix up typo in README [`#1`](https://github.com/browserify/cipher-base/pull/1) + +### Commits + +- Update api-methods. [`c4a7156`](https://github.com/browserify/cipher-base/commit/c4a7156c7beedb524ce5005374d2fd1327fa3ca4) +- travis [`a5873f7`](https://github.com/browserify/cipher-base/commit/a5873f7dbfe542d7ec28bcb3e306096d1d2b951c) +- Add api-methods [`208b338`](https://github.com/browserify/cipher-base/commit/208b33841d3e8a6f5322e54bdf442e1ee0d77590) +- Update error messages [`dc19a24`](https://github.com/browserify/cipher-base/commit/dc19a24119786518c1c835d948e36ddae3bf3adb) + +## v1.0.1 - 2015-09-26 + +### Commits + +- first [`8fbd9e7`](https://github.com/browserify/cipher-base/commit/8fbd9e7654d384b578e63d12e0311ae16dc07741) +- fix error in 0.10 [`61491fe`](https://github.com/browserify/cipher-base/commit/61491fe31fcc9bee0901f93b26cee6eaaca07575) diff --git a/package.json b/package.json index 4da326d..8fb7c1d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "pretest": "npm run lint", "test": "npm run tests-only", "tests-only": "tape 'test/**/*.js'", - "posttest": "npx npm@'>=10.2' audit --production" + "posttest": "npx npm@'>=10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" }, "repository": { "type": "git", @@ -33,6 +35,8 @@ }, "devDependencies": { "@ljharb/eslint-config": "^21.1.1", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", "eslint": "=8.8.0", "in-publish": "^2.0.1", "npmignore": "^0.3.1", @@ -44,6 +48,14 @@ ".github/workflows" ] }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, "engines": { "node": ">= 0.10" } From f03cebfdad1cba1d56614c58affa303b0fa2a43e Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 17 Nov 2024 10:06:22 -0800 Subject: [PATCH 10/12] v1.0.5 --- CHANGELOG.md | 14 ++++++++++++++ package.json | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 018e75c..53f1cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.0.5](https://github.com/browserify/cipher-base/compare/v1.0.4...v1.0.5) - 2024-11-17 + +### Commits + +- [Tests] standard -> eslint, make test dir, etc [`ae02fd6`](https://github.com/browserify/cipher-base/commit/ae02fd6624c41ac4ac18077be797111d1955bc76) +- [Tests] migrate from travis to GHA [`66387d7`](https://github.com/browserify/cipher-base/commit/66387d71461287ad9067bb1bcbfdc47403a33ee7) +- [meta] fix package.json indentation [`5c02918`](https://github.com/browserify/cipher-base/commit/5c02918ac58c875ed36913c2dc3e1043f4d1c99c) +- [Fix] return valid values on multi-byte-wide TypedArray input [`8fd1364`](https://github.com/browserify/cipher-base/commit/8fd136432ca298a664f5637629cf2b42a6c7f294) +- [meta] add `auto-changelog` [`88dc806`](https://github.com/browserify/cipher-base/commit/88dc806806d3dc41444dbf639c87c00f82c949b3) +- [meta] add `npmignore` and `safe-publish-latest` [`7a137d7`](https://github.com/browserify/cipher-base/commit/7a137d749ce7ea7ea56b9c096844b1b8ab723f61) +- Only apps should have lockfiles [`42528f2`](https://github.com/browserify/cipher-base/commit/42528f291db16bf2e7d5f831ebe2ad87fd0b1f42) +- [Deps] update `inherits`, `safe-buffer` [`0e7a2d9`](https://github.com/browserify/cipher-base/commit/0e7a2d9a33a391e82fa9cf512d6e25cc91ab8613) +- [meta] add missing `engines.node` [`f2dc13e`](https://github.com/browserify/cipher-base/commit/f2dc13e47bbcf3c873db9a9e0f83e5f29d0783fe) + ## [v1.0.4](https://github.com/browserify/cipher-base/compare/v1.0.3...v1.0.4) - 2017-07-06 ### Merged diff --git a/package.json b/package.json index 8fb7c1d..0128c7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cipher-base", - "version": "1.0.4", + "version": "1.0.5", "description": "abstract base class for crypto-streams", "main": "index.js", "scripts": { From b7ddd2ac24e65cc47befc1e0eb5026422f8ab037 Mon Sep 17 00:00:00 2001 From: Nikita Skovoroda Date: Wed, 20 Nov 2024 19:43:28 +0400 Subject: [PATCH 11/12] [Fix] io.js 3.0 - Node.js 5.3 typed array support --- index.js | 83 +++++++++++++++++++++++++++++++++------------------ test/index.js | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 29 deletions(-) diff --git a/index.js b/index.js index 741d913..804c108 100644 --- a/index.js +++ b/index.js @@ -28,42 +28,67 @@ var useArrayBuffer = typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView && (Buffer.prototype instanceof Uint8Array || Buffer.TYPED_ARRAY_SUPPORT); -CipherBase.prototype.update = function (data, inputEnc, outputEnc) { - var bufferData; +function toBuffer(data, encoding) { + /* + * No need to do anything for exact instance + * This is only valid when safe-buffer.Buffer === buffer.Buffer, i.e. when Buffer.from/Buffer.alloc existed + */ if (data instanceof Buffer) { - // No need to do anything - bufferData = data; - } else if (typeof data === 'string') { - // Convert strings to Buffer - bufferData = Buffer.from(data, inputEnc); - } else if (useArrayBuffer && ArrayBuffer.isView(data)) { - /* - * Wrap any TypedArray instances and DataViews - * Makes sense only on engines with full TypedArray support -- let Buffer detect that - */ - bufferData = Buffer.from(data.buffer, data.byteOffset, data.byteLength); - } else if (useUint8Array && data instanceof Uint8Array) { + return data; + } + + // Convert strings to Buffer + if (typeof data === 'string') { + return Buffer.from(data, encoding); + } + + /* + * Wrap any TypedArray instances and DataViews + * Makes sense only on engines with full TypedArray support -- let Buffer detect that + */ + if (useArrayBuffer && ArrayBuffer.isView(data)) { + // Bug in Node.js <6.3.1, which treats this as out-of-bounds + if (data.byteLength === 0) { + return Buffer.alloc(0); + } + + var res = Buffer.from(data.buffer, data.byteOffset, data.byteLength); /* - * Uint8Array in engines where Buffer.from might not work with ArrayBuffer, just copy over - * Doesn't make sense with other TypedArray instances + * Recheck result size, as offset/length doesn't work on Node.js <5.10 + * We just go to Uint8Array case if this fails */ - bufferData = Buffer.from(data); - } else if ( + if (res.byteLength === data.byteLength) { + return res; + } + } + + /* + * Uint8Array in engines where Buffer.from might not work with ArrayBuffer, just copy over + * Doesn't make sense with other TypedArray instances + */ + if (useUint8Array && data instanceof Uint8Array) { + return Buffer.from(data); + } + + /* + * Old Buffer polyfill on an engine that doesn't have TypedArray support + * Also, this is from a different Buffer polyfill implementation then we have, as instanceof check failed + * Convert to our current Buffer implementation + */ + if ( Buffer.isBuffer(data) - && data.constructor - && data.constructor.isBuffer - && data.constructor.isBuffer(data) + && data.constructor + && typeof data.constructor.isBuffer === 'function' + && data.constructor.isBuffer(data) ) { - /* - * Old Buffer polyfill on an engine that doesn't have TypedArray support - * Also, this is from a different Buffer polyfill implementation then we have, as instanceof check failed - * Convert to our current Buffer implementation - */ - bufferData = Buffer.from(data); - } else { - throw new Error('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView.'); + return Buffer.from(data); } + throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView.'); +} + +CipherBase.prototype.update = function (data, inputEnc, outputEnc) { + var bufferData = toBuffer(data, inputEnc); // asserts correct input type var outData = this._update(bufferData); if (this.hashMode) { return this; diff --git a/test/index.js b/test/index.js index ea2c651..8a3ceeb 100644 --- a/test/index.js +++ b/test/index.js @@ -129,6 +129,72 @@ test('encodings', function (t) { }); }); +test('handle SafeBuffer instances', function (t) { + function Cipher() { + CipherBase.call(this, 'finalName'); + this._cache = []; + } + inherits(Cipher, CipherBase); + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + this._cache.push(input); + }; + Cipher.prototype._final = function () { + return Buffer.concat(this._cache); + }; + + var cipher = new Cipher(); + var final = cipher.update(Buffer.from('a0c1', 'hex')).finalName('hex'); + t.equals(final, 'a0c1'); + + t.end(); +}); + +test('handle Uint8Array view', function (t) { + function Cipher() { + CipherBase.call(this, 'finalName'); + this._cache = []; + } + inherits(Cipher, CipherBase); + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + this._cache.push(input); + }; + Cipher.prototype._final = function () { + return Buffer.concat(this._cache); + }; + + var buf = new Uint8Array([0, 1, 2, 3, 4, 5]); + var uarr = new Uint8Array(buf.buffer, 2, 3); + + var cipher = new Cipher(); + var final = cipher.update(uarr).finalName('hex'); + t.equals(final, '020304'); + + t.end(); +}); + +test('handle empty Uint8Array instances', function (t) { + function Cipher() { + CipherBase.call(this, 'finalName'); + this._cache = []; + } + inherits(Cipher, CipherBase); + Cipher.prototype._update = function (input) { + t.ok(Buffer.isBuffer(input)); + this._cache.push(input); + }; + Cipher.prototype._final = function () { + return Buffer.concat(this._cache); + }; + + var cipher = new Cipher(); + var final = cipher.update(new Uint8Array(0)).finalName('hex'); + t.equals(final, ''); + + t.end(); +}); + test('handle UInt16Array', function (t) { function Cipher() { CipherBase.call(this, 'finalName'); From f5249f94611506ef35a8be4d48a3fc5ecf1fac63 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 26 Nov 2024 12:07:59 -0800 Subject: [PATCH 12/12] v1.0.6 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53f1cfa..a99ec0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.0.6](https://github.com/browserify/cipher-base/compare/v1.0.5...v1.0.6) - 2024-11-26 + +### Commits + +- [Fix] io.js 3.0 - Node.js 5.3 typed array support [`b7ddd2a`](https://github.com/browserify/cipher-base/commit/b7ddd2ac24e65cc47befc1e0eb5026422f8ab037) + ## [v1.0.5](https://github.com/browserify/cipher-base/compare/v1.0.4...v1.0.5) - 2024-11-17 ### Commits diff --git a/package.json b/package.json index 0128c7f..daef6d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cipher-base", - "version": "1.0.5", + "version": "1.0.6", "description": "abstract base class for crypto-streams", "main": "index.js", "scripts": {