Skip to content

Commit

Permalink
buffer: fix validation of options in Blob constructor
Browse files Browse the repository at this point in the history
PR-URL: #45156
Refs: https://webidl.spec.whatwg.org/#es-dictionary
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
  • Loading branch information
aduh95 authored and RafaelGSS committed Nov 10, 2022
1 parent 34bfef9 commit 3369120
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
8 changes: 4 additions & 4 deletions lib/internal/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ const {
} = require('internal/errors');

const {
validateObject,
isUint32,
validateDictionary,
} = require('internal/validators');

const kHandle = Symbol('kHandle');
Expand Down Expand Up @@ -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')
Expand Down
20 changes: 20 additions & 0 deletions lib/internal/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,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
Expand Down Expand Up @@ -511,6 +530,7 @@ module.exports = {
validateBooleanArray,
validateBoolean,
validateBuffer,
validateDictionary,
validateEncoding,
validateFunction,
validateInt32,
Expand Down
29 changes: 29 additions & 0 deletions test/parallel/test-blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 3369120

Please sign in to comment.