From beee53884dfe365021a51711da59f5bf05e6b52d Mon Sep 17 00:00:00 2001 From: ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Date: Sun, 24 Jan 2021 13:00:00 +0100 Subject: [PATCH] =?UTF-8?q?lib:=20fix=C2=A0WebIDL=C2=A0`object`=20and?= =?UTF-8?q?=C2=A0dictionary=20type=C2=A0conversion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/37047 Reviewed-By: Antoine du Hamel Reviewed-By: Joyee Cheung Reviewed-By: Rich Trott --- lib/internal/crypto/webcrypto.js | 4 +++- lib/internal/event_target.js | 9 ++++++--- lib/internal/validators.js | 12 +++++++++--- test/parallel/test-eventtarget.js | 1 - test/parallel/test-validators.js | 5 ++++- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index 2e14fcc90c35ed..eba0b08e836c38 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -161,7 +161,9 @@ async function deriveKey( } if (baseKey.algorithm.name !== algorithm.name) throw lazyDOMException('Key algorithm mismatch', 'InvalidAccessError'); - validateObject(derivedKeyAlgorithm, 'derivedKeyAlgorithm'); + validateObject(derivedKeyAlgorithm, 'derivedKeyAlgorithm', { + allowArray: true, allowFunction: true, + }); validateBoolean(extractable, 'extractable'); validateArray(keyUsages, 'keyUsages'); diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index f79d1eb23faf70..9dfbb8f9c4a5ce 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -87,8 +87,9 @@ class Event { constructor(type, options = null) { if (arguments.length === 0) throw new ERR_MISSING_ARGS('type'); - if (options !== null) - validateObject(options, 'options'); + validateObject(options, 'options', { + allowArray: true, allowFunction: true, nullable: true, + }); const { cancelable, bubbles, composed } = { ...options }; this[kCancelable] = !!cancelable; this[kBubbles] = !!bubbles; @@ -601,7 +602,9 @@ function shouldAddListener(listener) { function validateEventListenerOptions(options) { if (typeof options === 'boolean') return { capture: options }; - validateObject(options, 'options'); + validateObject(options, 'options', { + allowArray: true, allowFunction: true, + }); return { once: Boolean(options.once), capture: Boolean(options.capture), diff --git a/lib/internal/validators.js b/lib/internal/validators.js index bf7bf93aa268ad..75efbf5c8a5186 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -151,10 +151,16 @@ function validateBoolean(value, name) { } const validateObject = hideStackFrames( - (value, name, { nullable = false } = {}) => { + (value, name, { + nullable = false, + allowArray = false, + allowFunction = false, + } = {}) => { if ((!nullable && value === null) || - ArrayIsArray(value) || - typeof value !== 'object') { + (!allowArray && ArrayIsArray(value)) || + (typeof value !== 'object' && ( + !allowFunction || typeof value !== 'function' + ))) { throw new ERR_INVALID_ARG_TYPE(name, 'Object', value); } }); diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 1789d794f41ea3..63c166fc1be421 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -60,7 +60,6 @@ let asyncTest = Promise.resolve(); 'foo', 1, false, - function() {}, ].forEach((i) => ( throws(() => new Event('foo', i), { code: 'ERR_INVALID_ARG_TYPE', diff --git a/test/parallel/test-validators.js b/test/parallel/test-validators.js index cf4ba17f52e9d7..55c73b2d86d388 100644 --- a/test/parallel/test-validators.js +++ b/test/parallel/test-validators.js @@ -78,14 +78,17 @@ const invalidArgValueError = { validateObject({}, 'foo'); validateObject({ a: 42, b: 'foo' }, 'foo'); - [undefined, null, true, false, 0, 0.0, 42, '', 'string', []] + [undefined, null, true, false, 0, 0.0, 42, '', 'string', [], () => {}] .forEach((val) => { assert.throws(() => { validateObject(val, 'foo'); }, invalidArgTypeError); }); + // validateObject options tests: validateObject(null, 'foo', { nullable: true }); + validateObject([], 'foo', { allowArray: true }); + validateObject(() => {}, 'foo', { allowFunction: true }); } {