Skip to content

Commit 345b847

Browse files
aduh95danielleadams
authored andcommitted
buffer: fix validation of options in Blob constructor
PR-URL: #45156 Refs: https://webidl.spec.whatwg.org/#es-dictionary Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent bf028a6 commit 345b847

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

lib/internal/blob.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ const {
6161
} = require('internal/errors');
6262

6363
const {
64-
validateObject,
6564
isUint32,
65+
validateDictionary,
6666
} = require('internal/validators');
6767

6868
const kHandle = Symbol('kHandle');
@@ -138,17 +138,17 @@ class Blob {
138138
* }} [options]
139139
* @constructs {Blob}
140140
*/
141-
constructor(sources = [], options = kEmptyObject) {
141+
constructor(sources = [], options) {
142142
if (sources === null ||
143143
typeof sources[SymbolIterator] !== 'function' ||
144144
typeof sources === 'string') {
145145
throw new ERR_INVALID_ARG_TYPE('sources', 'a sequence', sources);
146146
}
147-
validateObject(options, 'options');
147+
validateDictionary(options, 'options');
148148
let {
149149
type = '',
150150
endings = 'transparent',
151-
} = options;
151+
} = options ?? kEmptyObject;
152152

153153
endings = `${endings}`;
154154
if (endings !== 'transparent' && endings !== 'native')

lib/internal/validators.js

+20
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,25 @@ const validateObject = hideStackFrames(
257257
}
258258
});
259259

260+
/**
261+
* @callback validateDictionary - We are using the Web IDL Standard definition
262+
* of "dictionary" here, which means any value
263+
* whose Type is either Undefined, Null, or
264+
* Object (which includes functions).
265+
* @param {*} value
266+
* @param {string} name
267+
* @see https://webidl.spec.whatwg.org/#es-dictionary
268+
* @see https://tc39.es/ecma262/#table-typeof-operator-results
269+
*/
270+
271+
/** @type {validateDictionary} */
272+
const validateDictionary = hideStackFrames(
273+
(value, name) => {
274+
if (value != null && typeof value !== 'object' && typeof value !== 'function') {
275+
throw new ERR_INVALID_ARG_TYPE(name, 'a dictionary', value);
276+
}
277+
});
278+
260279
/**
261280
* @callback validateArray
262281
* @param {*} value
@@ -505,6 +524,7 @@ module.exports = {
505524
validateBooleanArray,
506525
validateBoolean,
507526
validateBuffer,
527+
validateDictionary,
508528
validateEncoding,
509529
validateFunction,
510530
validateInt32,

test/parallel/test-blob.js

+29
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,32 @@ assert.throws(() => new Blob({}), {
287287
assert.strictEqual(blob.size, 28);
288288
assert.strictEqual(blob.type, '');
289289
})().then(common.mustCall());
290+
291+
{
292+
// Testing the defaults
293+
[undefined, null, Object.create(null), { type: undefined }, {
294+
get type() {}, // eslint-disable-line getter-return
295+
}].forEach((options) => {
296+
assert.strictEqual(
297+
new Blob([], options).type,
298+
new Blob([]).type,
299+
);
300+
});
301+
302+
Reflect.defineProperty(Object.prototype, 'type', {
303+
__proto__: null,
304+
configurable: true,
305+
get: common.mustCall(() => 3, 7),
306+
});
307+
308+
[{}, [], () => {}, Number, new Number(), new String(), new Boolean()].forEach(
309+
(options) => {
310+
assert.strictEqual(new Blob([], options).type, '3');
311+
},
312+
);
313+
[0, '', true, Symbol(), 0n].forEach((options) => {
314+
assert.throws(() => new Blob([], options), { code: 'ERR_INVALID_ARG_TYPE' });
315+
});
316+
317+
delete Object.prototype.type;
318+
}

0 commit comments

Comments
 (0)