[rab/gsab] Fix JSTypedArray::Validate to throw for oob rab/gsab
This will change the behavior of %TypedArray%.prototype.fill. Bug: v8:11111 Change-Id: I66e7d3decf07663a6497c3c86374b3c77ab6a682 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3056977 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#75988}
This commit is contained in:
parent
bce81d6be0
commit
df45384de4
@ -200,17 +200,20 @@ bool JSTypedArray::IsVariableLength() const {
|
||||
return is_length_tracking() || is_backed_by_rab();
|
||||
}
|
||||
|
||||
size_t JSTypedArray::GetLength() const {
|
||||
size_t JSTypedArray::GetLengthOrOutOfBounds(bool& out_of_bounds) const {
|
||||
DCHECK(!out_of_bounds);
|
||||
if (WasDetached()) return 0;
|
||||
if (is_length_tracking()) {
|
||||
if (is_backed_by_rab()) {
|
||||
if (byte_offset() >= buffer().byte_length()) {
|
||||
out_of_bounds = true;
|
||||
return 0;
|
||||
}
|
||||
return (buffer().byte_length() - byte_offset()) / element_size();
|
||||
}
|
||||
if (byte_offset() >=
|
||||
buffer().GetBackingStore()->byte_length(std::memory_order_seq_cst)) {
|
||||
out_of_bounds = true;
|
||||
return 0;
|
||||
}
|
||||
return (buffer().GetBackingStore()->byte_length(std::memory_order_seq_cst) -
|
||||
@ -223,12 +226,18 @@ size_t JSTypedArray::GetLength() const {
|
||||
// JSTypedArray.
|
||||
if (byte_offset() + array_length * element_size() >
|
||||
buffer().byte_length()) {
|
||||
out_of_bounds = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return array_length;
|
||||
}
|
||||
|
||||
size_t JSTypedArray::GetLength() const {
|
||||
bool out_of_bounds = false;
|
||||
return GetLengthOrOutOfBounds(out_of_bounds);
|
||||
}
|
||||
|
||||
void JSTypedArray::AllocateExternalPointerEntries(Isolate* isolate) {
|
||||
InitExternalPointerField(kExternalPointerOffset, isolate);
|
||||
}
|
||||
@ -364,6 +373,17 @@ MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
|
||||
THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
|
||||
}
|
||||
|
||||
if (V8_UNLIKELY(array->IsVariableLength())) {
|
||||
bool out_of_bounds = false;
|
||||
array->GetLengthOrOutOfBounds(out_of_bounds);
|
||||
if (out_of_bounds) {
|
||||
const MessageTemplate message = MessageTemplate::kDetachedOperation;
|
||||
Handle<String> operation =
|
||||
isolate->factory()->NewStringFromAsciiChecked(method_name);
|
||||
THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
|
||||
}
|
||||
}
|
||||
|
||||
// spec describes to return `buffer`, but it may disrupt current
|
||||
// implementations, and it's much useful to return array for now.
|
||||
return array;
|
||||
|
@ -307,6 +307,7 @@ class JSTypedArray
|
||||
DECL_BOOLEAN_ACCESSORS(is_length_tracking)
|
||||
DECL_BOOLEAN_ACCESSORS(is_backed_by_rab)
|
||||
inline bool IsVariableLength() const;
|
||||
inline size_t GetLengthOrOutOfBounds(bool& out_of_bounds) const;
|
||||
inline size_t GetLength() const;
|
||||
|
||||
static size_t LengthTrackingGsabBackedTypedArrayLength(Isolate* isolate,
|
||||
|
@ -996,10 +996,10 @@ function TestIterationAndResize(ta, expected, rab, resize_after,
|
||||
// Shrink so that fixed length TAs go out of bounds.
|
||||
rab.resize(3 * ctor.BYTES_PER_ELEMENT);
|
||||
|
||||
FillHelper(fixedLength, 5);
|
||||
assertThrows(() => FillHelper(fixedLength, 5), TypeError);
|
||||
assertEquals([3, 3, 4], ReadDataFromBuffer(rab, ctor));
|
||||
|
||||
FillHelper(fixedLengthWithOffset, 6);
|
||||
assertThrows(() => FillHelper(fixedLengthWithOffset, 6), TypeError);
|
||||
assertEquals([3, 3, 4], ReadDataFromBuffer(rab, ctor));
|
||||
|
||||
FillHelper(lengthTracking, 7);
|
||||
@ -1011,16 +1011,16 @@ function TestIterationAndResize(ta, expected, rab, resize_after,
|
||||
// Shrink so that the TAs with offset go out of bounds.
|
||||
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
|
||||
|
||||
FillHelper(fixedLength, 9);
|
||||
assertThrows(() => FillHelper(fixedLength, 9), TypeError);
|
||||
assertEquals([7], ReadDataFromBuffer(rab, ctor));
|
||||
|
||||
FillHelper(fixedLengthWithOffset, 10);
|
||||
assertThrows(() => FillHelper(fixedLengthWithOffset, 10), TypeError);
|
||||
assertEquals([7], ReadDataFromBuffer(rab, ctor));
|
||||
|
||||
FillHelper(lengthTracking, 11);
|
||||
assertEquals([11], ReadDataFromBuffer(rab, ctor));
|
||||
|
||||
FillHelper(lengthTrackingWithOffset, 12);
|
||||
assertThrows(() => FillHelper(lengthTrackingWithOffset, 12), TypeError);
|
||||
assertEquals([11], ReadDataFromBuffer(rab, ctor));
|
||||
|
||||
// Grow so that all TAs are back in-bounds.
|
||||
|
Loading…
Reference in New Issue
Block a user