From 3f556899b79ada303fc5f8a6d2cc42139c71c773 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Sat, 14 Dec 2024 21:07:24 -0800 Subject: [PATCH 1/3] add tests for "iterator helpers close receiver on argument validation failure" --- ...nt-validation-failure-closes-underlying.js | 46 +++++++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 34 ++++++++++++++ ...nt-validation-failure-closes-underlying.js | 46 +++++++++++++++++++ 10 files changed, 364 insertions(+) create mode 100644 test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js create mode 100644 test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js diff --git a/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..9fa85f7c261 --- /dev/null +++ b/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js @@ -0,0 +1,46 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.drop +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.drop ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(RangeError, function() { + closable.drop(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(RangeError, function() { + closable.drop(NaN); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(RangeError, function() { + closable.drop(-1); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(Test262Error, function() { + closable.drop({ get valueOf() { throw new Test262Error(); }}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..3a4b198c851 --- /dev/null +++ b/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.every +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.every ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.every(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.every({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..d80f4f5be70 --- /dev/null +++ b/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.filter +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.filter ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.filter(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.filter({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..c2a0ec5473f --- /dev/null +++ b/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.find +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.find ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.find(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.find({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..38bece1e0cc --- /dev/null +++ b/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.flatMap +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.flatMap ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.flatMap(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.flatMap({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..49dcac48923 --- /dev/null +++ b/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.forEach +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.forEach ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.forEach(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.forEach({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..c0a3ee1f04b --- /dev/null +++ b/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.map +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.map ( mapper ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.map(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.map({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..61b35a32583 --- /dev/null +++ b/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.reduce +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.reduce ( reducer, [ initialValue ] ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.reduce(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.reduce({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..fef1d13672c --- /dev/null +++ b/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.some +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.some ( predicate ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(TypeError, function() { + closable.some(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(TypeError, function() { + closable.some({}); +}); +assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js new file mode 100644 index 00000000000..ba3c0e1f5c0 --- /dev/null +++ b/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js @@ -0,0 +1,46 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.take +description: > + Underlying iterator is closed when argument validation fails +info: | + %Iterator.prototype%.take ( limit ) + +features: [iterator-helpers] +flags: [] +---*/ + +let closed = false; +let closable = { + __proto__: Iterator.prototype, + get next() { + throw new Test262Error('next should not be read'); + }, + return() { + closed = true; + }, +}; + +assert.throws(RangeError, function() { + closable.take(); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(RangeError, function() { + closable.take(NaN); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(RangeError, function() { + closable.take(-1); +}); +assert.sameValue(closed, true); + +closed = false; +assert.throws(Test262Error, function() { + closable.take({ get valueOf() { throw new Test262Error(); }}); +}); +assert.sameValue(closed, true); From ff1f256ed04dedbb85e9ac33e2e88716ba33611d Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Wed, 8 Jan 2025 15:23:09 -0800 Subject: [PATCH 2/3] address comments --- .../drop/argument-validation-failure-closes-underlying.js | 1 + .../argument-validation-failure-closes-underlying.js | 1 + .../argument-validation-failure-closes-underlying.js | 1 + .../find/argument-validation-failure-closes-underlying.js | 1 + .../argument-validation-failure-closes-underlying.js | 1 + .../argument-validation-failure-closes-underlying.js | 1 + .../map/argument-validation-failure-closes-underlying.js | 1 + .../argument-validation-failure-closes-underlying.js | 1 + .../Iterator/prototype/reduce/non-callable-reducer.js | 8 ++++---- .../some/argument-validation-failure-closes-underlying.js | 1 + .../take/argument-validation-failure-closes-underlying.js | 1 + 11 files changed, 14 insertions(+), 4 deletions(-) diff --git a/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js index 9fa85f7c261..f9547f72a42 100644 --- a/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js index 3a4b198c851..c4202c46e0b 100644 --- a/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/every/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js index d80f4f5be70..821a849599a 100644 --- a/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/filter/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js index c2a0ec5473f..9edbee820c9 100644 --- a/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/find/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js index 38bece1e0cc..3f491c5deff 100644 --- a/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/flatMap/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js index 49dcac48923..f5b20b36c0a 100644 --- a/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/forEach/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js index c0a3ee1f04b..226620c233a 100644 --- a/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/map/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js index 61b35a32583..20e8fd10e57 100644 --- a/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/reduce/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js b/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js index b94d560197a..6a563606301 100644 --- a/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js +++ b/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js @@ -11,12 +11,12 @@ features: [iterator-helpers] flags: [] ---*/ let nonCallable = {}; -let iterator = (function* () { +function* gen() { yield 1; -})(); +} assert.throws(TypeError, function () { - iterator.reduce(nonCallable); + gen().reduce(nonCallable); }); -iterator.reduce(() => {}); +gen().reduce(() => {}); diff --git a/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js index fef1d13672c..0b6b8aa5f53 100644 --- a/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/some/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; diff --git a/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js index ba3c0e1f5c0..b09184386fe 100644 --- a/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js @@ -19,6 +19,7 @@ let closable = { }, return() { closed = true; + return {}; }, }; From 7722e98e0959e2cf1bab50d9dcd85f998894c446 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Mon, 3 Feb 2025 12:41:58 -0800 Subject: [PATCH 3/3] avoid re-using Test262Error --- .../drop/argument-validation-failure-closes-underlying.js | 5 +++-- .../take/argument-validation-failure-closes-underlying.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js index f9547f72a42..cc8367df129 100644 --- a/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/drop/argument-validation-failure-closes-underlying.js @@ -41,7 +41,8 @@ assert.throws(RangeError, function() { assert.sameValue(closed, true); closed = false; -assert.throws(Test262Error, function() { - closable.drop({ get valueOf() { throw new Test262Error(); }}); +class ShouldNotGetValueOf {} +assert.throws(ShouldNotGetValueOf, function() { + closable.drop({ get valueOf() { throw new ShouldNotGetValueOf(); }}); }); assert.sameValue(closed, true); diff --git a/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js b/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js index b09184386fe..7c9d4a32644 100644 --- a/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js +++ b/test/built-ins/Iterator/prototype/take/argument-validation-failure-closes-underlying.js @@ -41,7 +41,8 @@ assert.throws(RangeError, function() { assert.sameValue(closed, true); closed = false; -assert.throws(Test262Error, function() { - closable.take({ get valueOf() { throw new Test262Error(); }}); +class ShouldNotGetValueOf {} +assert.throws(ShouldNotGetValueOf, function() { + closable.take({ get valueOf() { throw new ShouldNotGetValueOf(); }}); }); assert.sameValue(closed, true);