[rab/gsab] Now really fix the destination being resizable in TA.p.slice

Cancel the unnecessary fix
https://chromium-review.googlesource.com/c/v8/v8/+/4028559
and fix the problem at its root, TypedArraySpeciesCreateByLength.

This fix also fixes other variants of this bug (see tests).

Drive by: harden by setting length = 0 (not only byte_length) for length
tracking TAs.

Bug: v8:11111,chromium:1384474
Change-Id: I3ba660f7f600c0b946c75e7f13276703394c7df2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4030259
Auto-Submit: Marja Hölttä <marja@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84312}
This commit is contained in:
Marja Hölttä 2022-11-16 11:56:59 +01:00 committed by V8 LUCI CQ
parent 3e0c51309f
commit 47aaddc508
7 changed files with 36 additions and 12 deletions

View File

@ -59,13 +59,14 @@ transitioning macro AllocateTypedArray(implicit context: Context)(
typedArray.byte_offset = byteOffset;
if (isLengthTracking) {
dcheck(IsResizableArrayBuffer(buffer));
// Make the byte_length of length-tracking TAs zero, so that we won't
// accidentally use it and access invalid data.
// Set the byte_length and length fields of length-tracking TAs to zero, so
// that we won't accidentally use them and access invalid data.
typedArray.byte_length = 0;
typedArray.length = 0;
} else {
typedArray.byte_length = byteLength;
typedArray.length = length;
}
typedArray.length = length;
typedArray.bit_field.is_length_tracking = isLengthTracking;
typedArray.bit_field.is_backed_by_rab =
IsResizableArrayBuffer(buffer) && !IsSharedArrayBuffer(buffer);
@ -477,7 +478,7 @@ transitioning macro TypedArraySpeciesCreateByLength(implicit context: Context)(
const typedArray: JSTypedArray = TypedArraySpeciesCreate(
methodName, numArgs, exemplar, Convert<Number>(length), Undefined,
Undefined);
if (typedArray.length < length) deferred {
if (LoadJSTypedArrayLength(typedArray) < length) deferred {
ThrowTypeError(MessageTemplate::kTypedArrayTooShort);
}
return typedArray;

View File

@ -3657,11 +3657,7 @@ class TypedElementsAccessor
DCHECK_LE(start, end);
DCHECK_LE(end, source.GetLength());
size_t count = end - start;
auto dest_length = destination.GetLength();
if (V8_UNLIKELY(count > dest_length)) {
DCHECK(destination.is_backed_by_rab());
count = dest_length;
}
DCHECK_LE(count, destination.GetLength());
ElementType* dest_data = static_cast<ElementType*>(destination.DataPtr());
auto is_shared =
source.buffer().is_shared() || destination.buffer().is_shared()

View File

@ -13,7 +13,7 @@ class MyFloat64Array extends Float64Array {
super(rab);
if (callSlice) {
callSlice = false; // Prevent recursion
super.slice()
assertThrows(() => { super.slice(); }, TypeError);
}
}
};

View File

@ -13,4 +13,4 @@ class MyInt8Array extends Int8Array {
const rab2 = new ArrayBuffer(1000, {'maxByteLength': 4000});
const ta = new Int8Array(rab2);
ta.constructor = MyInt8Array;
ta.slice();
assertThrows(() => { ta.slice(); }, TypeError);

View File

@ -0,0 +1,13 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-rab-gsab
const rab1 = new ArrayBuffer(4, {"maxByteLength": 100});
const ta = new Int8Array(rab1);
const rab2 = new ArrayBuffer(10, {"maxByteLength": 20});
const lengthTracking = new Int8Array(rab2);
rab2.resize(0);
ta.constructor = { [Symbol.species]: function() { return lengthTracking; } };
assertThrows(() => { ta.slice(); }, TypeError);

View File

@ -0,0 +1,14 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-rab-gsab
const rab1 = new ArrayBuffer(4, {"maxByteLength": 100});
const ta = new Int8Array(rab1);
const rab2 = new ArrayBuffer(10, {"maxByteLength": 20});
const lengthTracking = new Int8Array(rab2);
rab2.resize(0);
ta.constructor = { [Symbol.species]: function() { return lengthTracking; } };
assertThrows(() => { ta.filter(() => { return true; }); },
TypeError);

View File

@ -9,4 +9,4 @@ const rab = new ArrayBuffer(10, {"maxByteLength": 20});
const lengthTracking = new Int8Array(rab);
rab.resize(0);
ta.constructor = { [Symbol.species]: function() { return lengthTracking; } };
ta.slice();
assertThrows(() => { ta.slice(); }, TypeError);