diff options
author | Antoine du Hamel <duhamelantoine1995@gmail.com> | 2022-11-01 02:47:51 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-01 02:47:51 +0300 |
commit | d6ee27445b58651f40bc2be54b63986dace2e997 (patch) | |
tree | b70d88a7f34bfcbb56225cf2e0e16e60a39b2e9f | |
parent | 17ae2ab7509c8379e842e606a011f688fcbcf7f2 (diff) |
buffer: fix validation of options in `Blob` constructor
PR-URL: https://github.com/nodejs/node/pull/45156
Refs: https://webidl.spec.whatwg.org/#es-dictionary
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
-rw-r--r-- | lib/internal/blob.js | 8 | ||||
-rw-r--r-- | lib/internal/validators.js | 20 | ||||
-rw-r--r-- | test/parallel/test-blob.js | 29 |
3 files changed, 53 insertions, 4 deletions
diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 69feb22c330..82a708a88db 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -61,8 +61,8 @@ const { } = require('internal/errors'); const { - validateObject, isUint32, + validateDictionary, } = require('internal/validators'); const kHandle = Symbol('kHandle'); @@ -138,17 +138,17 @@ class Blob { * }} [options] * @constructs {Blob} */ - constructor(sources = [], options = kEmptyObject) { + constructor(sources = [], options) { if (sources === null || typeof sources[SymbolIterator] !== 'function' || typeof sources === 'string') { throw new ERR_INVALID_ARG_TYPE('sources', 'a sequence', sources); } - validateObject(options, 'options'); + validateDictionary(options, 'options'); let { type = '', endings = 'transparent', - } = options; + } = options ?? kEmptyObject; endings = `${endings}`; if (endings !== 'transparent' && endings !== 'native') diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 695e198d2cb..753b135d3d0 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -258,6 +258,25 @@ const validateObject = hideStackFrames( }); /** + * @callback validateDictionary - We are using the Web IDL Standard definition + * of "dictionary" here, which means any value + * whose Type is either Undefined, Null, or + * Object (which includes functions). + * @param {*} value + * @param {string} name + * @see https://webidl.spec.whatwg.org/#es-dictionary + * @see https://tc39.es/ecma262/#table-typeof-operator-results + */ + +/** @type {validateDictionary} */ +const validateDictionary = hideStackFrames( + (value, name) => { + if (value != null && typeof value !== 'object' && typeof value !== 'function') { + throw new ERR_INVALID_ARG_TYPE(name, 'a dictionary', value); + } + }); + +/** * @callback validateArray * @param {*} value * @param {string} name @@ -511,6 +530,7 @@ module.exports = { validateBooleanArray, validateBoolean, validateBuffer, + validateDictionary, validateEncoding, validateFunction, validateInt32, diff --git a/test/parallel/test-blob.js b/test/parallel/test-blob.js index 7bec9dbf69e..588fc0bfff0 100644 --- a/test/parallel/test-blob.js +++ b/test/parallel/test-blob.js @@ -287,3 +287,32 @@ assert.throws(() => new Blob({}), { assert.strictEqual(blob.size, 28); assert.strictEqual(blob.type, ''); })().then(common.mustCall()); + +{ + // Testing the defaults + [undefined, null, Object.create(null), { type: undefined }, { + get type() {}, // eslint-disable-line getter-return + }].forEach((options) => { + assert.strictEqual( + new Blob([], options).type, + new Blob([]).type, + ); + }); + + Reflect.defineProperty(Object.prototype, 'type', { + __proto__: null, + configurable: true, + get: common.mustCall(() => 3, 7), + }); + + [{}, [], () => {}, Number, new Number(), new String(), new Boolean()].forEach( + (options) => { + assert.strictEqual(new Blob([], options).type, '3'); + }, + ); + [0, '', true, Symbol(), 0n].forEach((options) => { + assert.throws(() => new Blob([], options), { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + delete Object.prototype.type; +} |