Skip to content

Commit af69bca

Browse files
committed
fixup! lib: refactor internal webidl converters
1 parent a058d58 commit af69bca

6 files changed

Lines changed: 77 additions & 10 deletions

File tree

benchmark/misc/webidl-convert-to-int.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const common = require('../common.js');
55

66
const bench = common.createBenchmark(main, {
77
converter: [
8+
'byte',
89
'octet',
910
'unsigned short',
1011
'unsigned long',
@@ -23,6 +24,8 @@ const bench = common.createBenchmark(main, {
2324

2425
function getConverter(converter) {
2526
switch (converter) {
27+
case 'byte':
28+
return { bitLength: 8, signedness: 'signed' };
2629
case 'octet':
2730
return { bitLength: 8 };
2831
case 'unsigned short':

lib/internal/webidl.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@ function convertToInt(
386386
if (V >= upperBound) {
387387
return upperBound === 0 ? 0 : upperBound;
388388
}
389-
return evenRound(V);
390389
}
391390
x = V;
392391
} else {
@@ -623,15 +622,24 @@ function createEnumConverter(name, values) {
623622

624623
/**
625624
* Returns the context used when converting a dictionary member.
626-
* @param {string} dictionaryName Dictionary identifier.
627625
* @param {string} key Dictionary member identifier.
628626
* @param {ConversionOptions} options Conversion options.
629627
* @returns {string}
630628
*/
631-
function dictionaryMemberContext(dictionaryName, key, options) {
629+
function dictionaryMemberContext(key, options) {
632630
return options.context ? `${key} in ${options.context}` : key;
633631
}
634632

633+
/**
634+
* Returns the context used when converting a sequence element.
635+
* @param {number} index Sequence element index.
636+
* @param {ConversionOptions} options Conversion options.
637+
* @returns {string}
638+
*/
639+
function sequenceElementContext(index, options) {
640+
return `${options.context ?? 'Value'}[${index}]`;
641+
}
642+
635643
/**
636644
* Returns the message used for a missing required dictionary member.
637645
* @param {string} dictionaryName Dictionary identifier.
@@ -692,7 +700,7 @@ function createDictionaryConverter(
692700
{
693701
__proto__: null,
694702
...options,
695-
context: dictionaryMemberContext(dictionaryName, key, options),
703+
context: dictionaryMemberContext(key, options),
696704
},
697705
);
698706
// Validators are a Node.js extension after conversion. They let
@@ -770,7 +778,7 @@ function createSequenceConverter(converter) {
770778
const idlValue = converter(next.value, {
771779
__proto__: null,
772780
...options,
773-
context: `${options.context}[${idlSequence.length}]`,
781+
context: sequenceElementContext(idlSequence.length, options),
774782
});
775783
// Step 3.4: store the value and advance i.
776784
ArrayPrototypePush(idlSequence, idlValue);
@@ -823,6 +831,7 @@ function validateBufferSourceBacking(buffer, options) {
823831
// ArrayBuffer.prototype.resizable is an ArrayBuffer brand check and the
824832
// [AllowResizable] value we need. For SharedArrayBuffer-backed views it
825833
// throws, which lets this path avoid a separate IsSharedArrayBuffer check.
834+
// Keep this in sync with the inlined BufferSource view branch below.
826835
resizable = ArrayBufferPrototypeGetResizable(buffer);
827836
} catch {
828837
// ArrayBufferView conversion step 2: reject SharedArrayBuffer
@@ -921,6 +930,7 @@ converters.BufferSource = (V, options = kEmptyObject) => {
921930
// Keep this logic inline instead of calling validateBufferSourceBacking().
922931
// BufferSource conversion is hot, and this avoids a helper call while still
923932
// using a primordial getter for the backing-buffer internal-slot check.
933+
// Keep this in sync with validateBufferSourceBacking().
924934
let resizable;
925935
try {
926936
// ArrayBuffer.prototype.resizable is both the ArrayBuffer brand check

test/parallel/test-blob.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ assert.throws(() => new Blob({}), {
157157
assert.strictEqual(b.type, '');
158158
}
159159

160+
{
161+
const b = new Blob(['hello']);
162+
163+
assert.throws(() => b.slice(1n), {
164+
name: 'TypeError',
165+
code: 'ERR_INVALID_ARG_TYPE',
166+
message: 'start is a BigInt and cannot be converted to a number.',
167+
});
168+
169+
assert.throws(() => b.slice(0, Symbol()), {
170+
name: 'TypeError',
171+
code: 'ERR_INVALID_ARG_TYPE',
172+
message: 'end is a Symbol and cannot be converted to a number.',
173+
});
174+
}
175+
160176
{
161177
const b = new Blob([Buffer.from('hello'), Buffer.from('world')]);
162178
const mc = new MessageChannel();

test/parallel/test-internal-webidl.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,24 @@ assert.throws(() => webidl.requiredArguments(1, 2, opts), {
377377
const converter = converters['sequence<DOMString>'];
378378
assert.deepStrictEqual(converter([1, 2]), ['1', '2']);
379379

380+
assert.throws(() => converter([Symbol()]), {
381+
name: 'TypeError',
382+
code: 'ERR_INVALID_ARG_TYPE',
383+
message: 'Value[0] is a Symbol and cannot be converted to a string.',
384+
});
385+
380386
assert.throws(() => converter({ [Symbol.iterator]: 1 }, opts), {
381387
name: 'TypeError',
382388
code: 'ERR_INVALID_ARG_TYPE',
383389
message: 'Prefix: Context cannot be converted to sequence.',
384390
});
391+
392+
assert.throws(() => converter([Symbol()], opts), {
393+
name: 'TypeError',
394+
code: 'ERR_INVALID_ARG_TYPE',
395+
message: 'Prefix: Context[0] is a Symbol and cannot be converted ' +
396+
'to a string.',
397+
});
385398
}
386399

387400
{

test/parallel/test-performance-resourcetimingbuffersize.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ async function main() {
3737
globalThis,
3838
cacheMode,
3939
];
40+
41+
assert.throws(() => performance.setResourceTimingBufferSize(1n), {
42+
name: 'TypeError',
43+
code: 'ERR_INVALID_ARG_TYPE',
44+
message: 'maxSize is a BigInt and cannot be converted to a number.',
45+
});
46+
47+
assert.throws(() => performance.setResourceTimingBufferSize(Symbol()), {
48+
name: 'TypeError',
49+
code: 'ERR_INVALID_ARG_TYPE',
50+
message: 'maxSize is a Symbol and cannot be converted to a number.',
51+
});
52+
4053
// Invalid buffer size values are converted to 0.
4154
const invalidValues = [ null, undefined, true, false, -1, 0.5, Infinity, NaN, '', 'foo', {}, [], () => {} ];
4255
for (const value of invalidValues) {

test/parallel/test-webcrypto-webidl.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,27 @@ function assertJsonWebKey(actual, expected) {
228228
assert.deepStrictEqual(converters.BufferSource(resizable), resizable);
229229
assert.deepStrictEqual(converters.BufferSource(view), view);
230230
assert.deepStrictEqual(converters.BufferSource(dataView), dataView);
231+
const resizableError = {
232+
name: 'TypeError',
233+
code: 'ERR_INVALID_ARG_TYPE',
234+
message: `${prefix}: ${context} is backed by a resizable ` +
235+
'ArrayBuffer, which is not allowed.',
236+
};
231237
assert.throws(() => converters.BufferSource(resizable, {
232238
__proto__: null,
233239
...opts,
234240
allowResizable: false,
235-
}), {
236-
name: 'TypeError',
237-
code: 'ERR_INVALID_ARG_TYPE',
238-
message: `${prefix}: ${context} is backed by a resizable ArrayBuffer, which is not allowed.`
239-
});
241+
}), resizableError);
242+
assert.throws(() => converters.BufferSource(view, {
243+
__proto__: null,
244+
...opts,
245+
allowResizable: false,
246+
}), resizableError);
247+
assert.throws(() => converters.BufferSource(dataView, {
248+
__proto__: null,
249+
...opts,
250+
allowResizable: false,
251+
}), resizableError);
240252
}
241253
}
242254

0 commit comments

Comments
 (0)