[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:
parent
3e0c51309f
commit
47aaddc508
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -13,7 +13,7 @@ class MyFloat64Array extends Float64Array {
|
||||
super(rab);
|
||||
if (callSlice) {
|
||||
callSlice = false; // Prevent recursion
|
||||
super.slice()
|
||||
assertThrows(() => { super.slice(); }, TypeError);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
|
13
test/mjsunit/regress/regress-crbug-1384474-variant2.js
Normal file
13
test/mjsunit/regress/regress-crbug-1384474-variant2.js
Normal 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);
|
14
test/mjsunit/regress/regress-crbug-1384474-variant3.js
Normal file
14
test/mjsunit/regress/regress-crbug-1384474-variant3.js
Normal 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);
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user