GeezerVison is showing github.com — buffer: fix validation of options in `Blob` constructor · nodejs/node@345b847
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/blob.js +4-4Lines changed: 4 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -61,8 +61,8 @@ const { | 61 | 61 | } = require('internal/errors'); | 62 | 62 |
| 63 | 63 | const { | 64 | | - validateObject, | 65 | 64 | isUint32, | | 65 | + validateDictionary, | 66 | 66 | } = require('internal/validators'); | 67 | 67 |
| 68 | 68 | const kHandle = Symbol('kHandle'); | @@ -138,17 +138,17 @@ class Blob { | 138 | 138 | * }} [options] | 139 | 139 | * @constructs {Blob} | 140 | 140 | */ | 141 | | - constructor(sources = [], options = kEmptyObject) { | | 141 | + constructor(sources = [], options) { | 142 | 142 | if (sources === null || | 143 | 143 | typeof sources[SymbolIterator] !== 'function' || | 144 | 144 | typeof sources === 'string') { | 145 | 145 | throw new ERR_INVALID_ARG_TYPE('sources', 'a sequence', sources); | 146 | 146 | } | 147 | | - validateObject(options, 'options'); | | 147 | + validateDictionary(options, 'options'); | 148 | 148 | let { | 149 | 149 | type = '', | 150 | 150 | endings = 'transparent', | 151 | | - } = options; | | 151 | + } = options ?? kEmptyObject; | 152 | 152 |
| 153 | 153 | endings = `${endings}`; | 154 | 154 | if (endings !== 'transparent' && endings !== 'native') | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/validators.js +20Lines changed: 20 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -257,6 +257,25 @@ const validateObject = hideStackFrames( | 257 | 257 | } | 258 | 258 | }); | 259 | 259 |
| | 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 | + | 260 | 279 | /** | 261 | 280 | * @callback validateArray | 262 | 281 | * @param {*} value | @@ -505,6 +524,7 @@ module.exports = { | 505 | 524 | validateBooleanArray, | 506 | 525 | validateBoolean, | 507 | 526 | validateBuffer, | | 527 | + validateDictionary, | 508 | 528 | validateEncoding, | 509 | 529 | validateFunction, | 510 | 530 | validateInt32, | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-blob.js +29Lines changed: 29 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -287,3 +287,32 @@ assert.throws(() => new Blob({}), { | 287 | 287 | assert.strictEqual(blob.size, 28); | 288 | 288 | assert.strictEqual(blob.type, ''); | 289 | 289 | })().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 | +} |
|