Skip to content

Commit 740f901

Browse files
committed
fixup! lib: refactor internal webidl converters
Signed-off-by: Filip Skokan <[email protected]>
1 parent 57bf371 commit 740f901

5 files changed

Lines changed: 86 additions & 99 deletions

File tree

lib/internal/crypto/webidl.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function namedCurveValidator(V, dict) {
5151
'NotSupportedError');
5252
}
5353

54-
const converters = { ...webidl };
54+
const converters = { __proto__: null, ...webidl };
5555

5656
/**
5757
* @param {string | object} V - The hash algorithm identifier (string or object).

lib/internal/webidl.js

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,15 @@ const {
2121
NumberMAX_SAFE_INTEGER,
2222
NumberMIN_SAFE_INTEGER,
2323
ObjectAssign,
24-
ObjectGetOwnPropertyDescriptor,
2524
ObjectPrototypeIsPrototypeOf,
2625
SafeSet,
2726
String,
2827
SymbolIterator,
2928
TypeError,
3029
TypedArrayPrototypeGetBuffer,
3130
TypedArrayPrototypeGetSymbolToStringTag,
32-
globalThis,
3331
} = primordials;
3432

35-
const { SharedArrayBuffer } = globalThis;
36-
const SharedArrayBufferPrototypeGetGrowable = SharedArrayBuffer === undefined ?
37-
undefined :
38-
ObjectGetOwnPropertyDescriptor(SharedArrayBuffer.prototype, 'growable')?.get;
39-
4033
const { kEmptyObject } = require('internal/util');
4134
const {
4235
isArrayBuffer,
@@ -611,7 +604,7 @@ function createDictionaryConverter(
611604
}
612605

613606
// Step 2: create the IDL dictionary value.
614-
const idlDict = {};
607+
const idlDict = { __proto__: null };
615608

616609
// Steps 3-4: iterate the flattened dictionary/member list.
617610
for (let i = 0; i < sortedMembers.length; i++) {
@@ -674,14 +667,8 @@ function createSequenceConverter(converter) {
674667

675668
// Step 2: GetMethod(V, %Symbol.iterator%).
676669
const method = V[SymbolIterator];
677-
// Step 3: throw if the iterator method is undefined or null.
678-
if (method === undefined || method === null) {
679-
throw makeException(
680-
'cannot be converted to sequence.',
681-
options);
682-
}
683-
// GetMethod also throws if the method is not callable.
684-
if (typeof method !== 'function') {
670+
// Step 3: throw if the iterator method is undefined, null, or not callable.
671+
if (method == null || typeof method !== 'function') {
685672
throw makeException(
686673
'cannot be converted to sequence.',
687674
options);
@@ -811,9 +798,12 @@ function validateBufferSourceBacking(buffer, options) {
811798
function validateAllowGrowableSharedArrayBuffer(buffer, options) {
812799
// SharedArrayBuffer and ArrayBufferView conversion step 3:
813800
// IsFixedLengthArrayBuffer(buffer) must be true without [AllowResizable].
814-
if (!options.allowResizable &&
815-
SharedArrayBufferPrototypeGetGrowable !== undefined &&
816-
FunctionPrototypeCall(SharedArrayBufferPrototypeGetGrowable, buffer)) {
801+
// Do not use a primordial getter here. When this module is included in the
802+
// startup snapshot, an early-captured SharedArrayBuffer.prototype.growable
803+
// getter does not detect growable buffers created after deserialization.
804+
// Lazily capturing the getter would work, but it would observe the runtime
805+
// prototype at first comparison, so it would not be an actual primordial.
806+
if (!options.allowResizable && buffer.growable) {
817807
throw makeException(
818808
'is backed by a growable SharedArrayBuffer, which is not allowed.',
819809
options);

test/parallel/test-internal-webidl-buffer-source.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,12 @@ const TYPED_ARRAY_CTORS = [
1717
];
1818

1919
function createGrowableSharedArrayBufferView(Ctor) {
20-
try {
21-
const buffer = new SharedArrayBuffer(0, { maxByteLength: 1 });
22-
const view = new Ctor(buffer);
23-
return view.buffer.growable === true ? view : undefined;
24-
} catch {
25-
return undefined;
26-
}
20+
const buffer = new SharedArrayBuffer(0, { maxByteLength: 1 });
21+
const view = new Ctor(buffer);
22+
assert.strictEqual(view.buffer.growable, true);
23+
return view;
2724
}
2825

29-
const hasGrowableSharedArrayBufferViews =
30-
createGrowableSharedArrayBufferView(Uint8Array) !== undefined;
31-
3226
test('BufferSource accepts ArrayBuffer', () => {
3327
const ab = new ArrayBuffer(8);
3428
assert.strictEqual(converters.BufferSource(ab), ab);
@@ -172,13 +166,10 @@ test('BufferSource handles resizable-backed views with explicit options', () =>
172166
}
173167
});
174168

175-
test('BufferSource handles growable SAB-backed views with explicit options', {
176-
skip: !hasGrowableSharedArrayBufferViews,
177-
}, () => {
169+
test('BufferSource handles growable SAB-backed views with explicit options', () => {
178170
for (const Ctor of [DataView, ...TYPED_ARRAY_CTORS]) {
179171
{
180172
const view = createGrowableSharedArrayBufferView(Ctor);
181-
assert.notStrictEqual(view, undefined);
182173
assert.throws(
183174
() => converters.BufferSource(view, {
184175
allowShared: true,
@@ -190,7 +181,6 @@ test('BufferSource handles growable SAB-backed views with explicit options', {
190181

191182
{
192183
const view = createGrowableSharedArrayBufferView(Ctor);
193-
assert.notStrictEqual(view, undefined);
194184
assert.strictEqual(converters.BufferSource(view, {
195185
allowShared: true,
196186
allowResizable: true,

test/parallel/test-internal-webidl.js

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,12 @@ const opts = {
1313
context: 'Context',
1414
};
1515
function createGrowableSharedArrayBufferView() {
16-
try {
17-
const buffer = new SharedArrayBuffer(4, { maxByteLength: 8 });
18-
const view = new Uint8Array(buffer);
19-
return view.buffer.growable === true ? view : undefined;
20-
} catch {
21-
return undefined;
22-
}
16+
const buffer = new SharedArrayBuffer(4, { maxByteLength: 8 });
17+
const view = new Uint8Array(buffer);
18+
assert.strictEqual(view.buffer.growable, true);
19+
return view;
2320
}
2421

25-
const hasGrowableSharedArrayBufferView =
26-
createGrowableSharedArrayBufferView() !== undefined;
27-
2822
function assertInvalidArgType(fn) {
2923
assert.throws(fn, {
3024
name: 'TypeError',
@@ -369,7 +363,7 @@ assert.throws(() => webidl.requiredArguments(1, 2, opts), {
369363
]);
370364

371365
const idlDict = converter({ value: 1 });
372-
assert.deepStrictEqual(idlDict, { value: '1' });
366+
assert.deepStrictEqual(idlDict, { __proto__: null, value: '1' });
373367

374368
assert.throws(() => converter({}, opts), {
375369
name: 'TypeError',
@@ -441,39 +435,37 @@ assert.throws(() => webidl.requiredArguments(1, 2, opts), {
441435
assert.strictEqual(converters.BufferSource(view, allowShared), view);
442436
assert.strictEqual(converters.Uint8Array(view, allowShared), view);
443437

444-
if (hasGrowableSharedArrayBufferView) {
445-
const growableView = createGrowableSharedArrayBufferView();
446-
447-
assert.throws(() => converters.BufferSource(growableView, {
448-
__proto__: null,
449-
...opts,
450-
allowShared: true,
451-
allowResizable: false,
452-
}), {
453-
name: 'TypeError',
454-
code: 'ERR_INVALID_ARG_TYPE',
455-
message: 'Prefix: Context is backed by a growable ' +
456-
'SharedArrayBuffer, which is not allowed.',
457-
});
458-
assert.throws(() => converters.Uint8Array(growableView, {
459-
__proto__: null,
460-
...opts,
461-
allowShared: true,
462-
}), {
463-
name: 'TypeError',
464-
code: 'ERR_INVALID_ARG_TYPE',
465-
message: 'Prefix: Context is backed by a growable ' +
466-
'SharedArrayBuffer, which is not allowed.',
467-
});
468-
assert.strictEqual(converters.BufferSource(growableView, {
469-
__proto__: null,
470-
allowShared: true,
471-
allowResizable: true,
472-
}), growableView);
473-
assert.strictEqual(converters.Uint8Array(growableView, {
474-
__proto__: null,
475-
allowShared: true,
476-
allowResizable: true,
477-
}), growableView);
478-
}
438+
const growableView = createGrowableSharedArrayBufferView();
439+
440+
assert.throws(() => converters.BufferSource(growableView, {
441+
__proto__: null,
442+
...opts,
443+
allowShared: true,
444+
allowResizable: false,
445+
}), {
446+
name: 'TypeError',
447+
code: 'ERR_INVALID_ARG_TYPE',
448+
message: 'Prefix: Context is backed by a growable ' +
449+
'SharedArrayBuffer, which is not allowed.',
450+
});
451+
assert.throws(() => converters.Uint8Array(growableView, {
452+
__proto__: null,
453+
...opts,
454+
allowShared: true,
455+
}), {
456+
name: 'TypeError',
457+
code: 'ERR_INVALID_ARG_TYPE',
458+
message: 'Prefix: Context is backed by a growable ' +
459+
'SharedArrayBuffer, which is not allowed.',
460+
});
461+
assert.strictEqual(converters.BufferSource(growableView, {
462+
__proto__: null,
463+
allowShared: true,
464+
allowResizable: true,
465+
}), growableView);
466+
assert.strictEqual(converters.Uint8Array(growableView, {
467+
__proto__: null,
468+
allowShared: true,
469+
allowResizable: true,
470+
}), growableView);
479471
}

0 commit comments

Comments
 (0)