Skip to content

Commit bdacc08

Browse files
panvaaduh95
authored andcommitted
lib: validate sequence iterator objects
Reject primitive iterator factory results before accessing next, as required by GetIteratorFromMethod. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #65844 Reviewed-By: Jason Zhang <xzha4350@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day> Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
1 parent 5b6ac71 commit bdacc08

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

lib/internal/webidl.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,12 @@ function createSequenceConverter(converter) {
835835

836836
// Step 4 and create-sequence step 1: get the iterator record.
837837
const iterator = FunctionPrototypeCall(method, V);
838-
const nextMethod = iterator?.next;
838+
if (type(iterator) !== 'Object') {
839+
throw makeException(
840+
'cannot be converted to sequence.',
841+
options);
842+
}
843+
const nextMethod = iterator.next;
839844
if (typeof nextMethod !== 'function') {
840845
throw makeException(
841846
'cannot be converted to sequence.',

test/parallel/test-internal-webidl.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,39 @@ assert.throws(() => webidl.requiredArguments(1, 2, opts), {
510510
}), []);
511511
}
512512

513+
for (const [prototype, value] of [
514+
[Number.prototype, 1],
515+
[String.prototype, 'iterator'],
516+
[Boolean.prototype, true],
517+
[BigInt.prototype, 1n],
518+
[Symbol.prototype, Symbol()],
519+
]) {
520+
let nextReads = 0;
521+
Object.defineProperty(prototype, 'next', {
522+
configurable: true,
523+
get() {
524+
nextReads++;
525+
return () => ({ done: true });
526+
},
527+
});
528+
try {
529+
const iterable = { [Symbol.iterator]: () => value };
530+
assertInvalidArgType(() => converters['sequence<DOMString>'](iterable));
531+
assertInvalidArgType(() => structuredClone(null, { transfer: iterable }));
532+
assert.strictEqual(nextReads, 0);
533+
} finally {
534+
delete prototype.next;
535+
}
536+
}
537+
538+
{
539+
function iterator() {}
540+
iterator.next = () => ({ done: true });
541+
assert.deepStrictEqual(converters['sequence<DOMString>']({
542+
[Symbol.iterator]: () => iterator,
543+
}), []);
544+
}
545+
513546
{
514547
class Example {
515548
#brand;

0 commit comments

Comments
 (0)