Skip to content

Commit e8fa381

Browse files
Gumichocopengin8sosukesuzuki
authored andcommitted
[JSC] Align %TypedArray%.prototype.includes with ECMA-262
https://bugs.webkit.org/show_bug.cgi?id=304149 Reviewed by Yusuke Suzuki and Sosuke Suzuki. This patch fixes `%TypedArray%.prototype.includes` by adding range check to ensure the `index` is less than the array length, aligning the behavior with ECMA-262[1]. [1]: https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes Test: JSTests/stress/typedarray-resize-includes.js * JSTests/stress/typedarray-resize-includes.js: Added. (shouldBe): (throw.new.Error): * JSTests/test262/expectations.yaml: * Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h: (JSC::genericTypedArrayViewProtoFuncIncludes): Canonical link: https://commits.webkit.org/304485@main
1 parent dfea1c8 commit e8fa381

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
function shouldBe(actual, expected) {
2+
if (actual !== expected) {
3+
throw new Error(`actual: ${actual}, expected: ${expected}`);
4+
}
5+
}
6+
7+
{
8+
var arraybuffer = new ArrayBuffer(4, { maxByteLength: 20 });
9+
var byteOffset = 1; // Uses byteOffset to make typed array out-of-bounds when shrinking size to zero.
10+
var int8array = new Int8Array(arraybuffer, byteOffset);
11+
var index = {
12+
valueOf() {
13+
arraybuffer.resize(0);
14+
return 10;
15+
},
16+
};
17+
shouldBe(int8array.length, 3);
18+
var result = int8array.includes(undefined, index);
19+
shouldBe(int8array.length, 0);
20+
shouldBe(result, false);
21+
}
22+
23+
{
24+
var arraybuffer = new ArrayBuffer(2, { maxByteLength: 20 });
25+
var intarray = new Int8Array(arraybuffer);
26+
intarray[0] = 21;
27+
intarray[1] = 31;
28+
shouldBe(intarray.length, 2);
29+
arraybuffer.resize(1);
30+
shouldBe(intarray.length, 1);
31+
shouldBe(intarray.includes(21), true);
32+
shouldBe(intarray.includes(31), false);
33+
arraybuffer.resize(0);
34+
shouldBe(intarray.length, 0);
35+
shouldBe(intarray.includes(21), false);
36+
shouldBe(intarray.includes(31), false);
37+
}

JSTests/test262/expectations.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,6 @@ test/built-ins/Temporal/PlainTime/prototype/until/order-of-operations.js:
409409
test/built-ins/Temporal/getOwnPropertyNames.js:
410410
default: 'Test262Error: ZonedDateTime'
411411
strict mode: 'Test262Error: ZonedDateTime'
412-
test/built-ins/TypedArray/prototype/includes/index-compared-against-initial-length-out-of-bounds.js:
413-
default: 'Test262Error: Expected SameValue(«true», «false») to be true'
414-
strict mode: 'Test262Error: Expected SameValue(«true», «false») to be true'
415412
test/built-ins/TypedArray/prototype/includes/index-compared-against-initial-length.js:
416413
default: 'Test262Error: Expected SameValue(«true», «false») to be true'
417414
strict mode: 'Test262Error: Expected SameValue(«true», «false») to be true'

Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncIncludes(VM& vm, JSGl
455455
IdempotentArrayBufferByteLengthGetter<std::memory_order_seq_cst> getter;
456456
auto lengthValue = integerIndexedObjectLength(thisObject, getter);
457457
if (!lengthValue) [[unlikely]]
458-
return JSValue::encode(jsBoolean(valueToFind.isUndefined()));
458+
return JSValue::encode(jsBoolean(index < length && valueToFind.isUndefined()));
459459

460460
updatedLength = lengthValue.value();
461461
}

0 commit comments

Comments
 (0)