Commit 6c07d6e3 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[typedarray] Throw rather than crash when too large to sort

Sorting a TypedArray with a custom compare function requires us to
copy the array's contents to a FixedArray. When the TypedArray is
larger than FixedArray::kMaxLength, we should throw a RangeError
rather than crashing with an OOM message.

Fixed: v8:10931
Change-Id: I8a27cc0ac80a9172bc5e8e154fdf4ccce5974317
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2440575
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70232}
parent 74f3665c
......@@ -281,6 +281,7 @@ extern enum MessageTemplate {
kFirstArgumentNotRegExp,
kBigIntMixedTypes,
kTypedArrayTooShort,
kTypedArrayTooLargeToSort,
kInvalidCountValue,
kConstructorNotFunction,
kSymbolToString,
......
......@@ -114,6 +114,14 @@ transitioning javascript builtin TypedArrayPrototypeSort(
return TypedArraySortFast(context, obj);
}
// Throw rather than crash if the TypedArray's size exceeds max FixedArray
// size (which we need below).
// TODO(4153): Consider redesigning the sort implementation such that we
// don't have such a limit.
if (len > kFixedArrayMaxLength) {
ThrowTypeError(MessageTemplate::kTypedArrayTooLargeToSort);
}
const comparefn: Callable =
Cast<Callable>(comparefnObj) otherwise unreachable;
const accessor: TypedArrayAccessor =
......
......@@ -364,6 +364,8 @@ namespace internal {
T(ToRadixFormatRange, "toString() radix argument must be between 2 and 36") \
T(TypedArraySetOffsetOutOfBounds, "offset is out of bounds") \
T(TypedArraySetSourceTooLarge, "Source is too large") \
T(TypedArrayTooLargeToSort, \
"Custom comparefn not supported for huge TypedArrays") \
T(ValueOutOfRange, "Value % out of range for % options property %") \
/* SyntaxError */ \
T(AmbiguousExport, \
......
......@@ -84,7 +84,7 @@ bytecodes: [
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 48 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 53 S> */ B(Wide), B(LdaSmi), I16(268),
/* 53 S> */ B(Wide), B(LdaSmi), I16(269),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......@@ -115,7 +115,7 @@ bytecodes: [
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 41 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 46 S> */ B(Wide), B(LdaSmi), I16(267),
/* 46 S> */ B(Wide), B(LdaSmi), I16(268),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......@@ -146,7 +146,7 @@ bytecodes: [
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 48 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 53 S> */ B(Wide), B(LdaSmi), I16(268),
/* 53 S> */ B(Wide), B(LdaSmi), I16(269),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......@@ -177,7 +177,7 @@ bytecodes: [
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 41 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 46 S> */ B(Wide), B(LdaSmi), I16(267),
/* 46 S> */ B(Wide), B(LdaSmi), I16(268),
B(Star), R(4),
B(LdaConstant), U8(0),
B(Star), R(5),
......
......@@ -57,7 +57,7 @@ bytecodes: [
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 49 S> */ B(Wide), B(LdaSmi), I16(266),
/* 49 S> */ B(Wide), B(LdaSmi), I16(267),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......@@ -89,7 +89,7 @@ bytecodes: [
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 49 S> */ B(Wide), B(LdaSmi), I16(266),
/* 49 S> */ B(Wide), B(LdaSmi), I16(267),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......
......@@ -25,7 +25,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(264),
B(Wide), B(LdaSmi), I16(265),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
......@@ -56,7 +56,7 @@ frame size: 2
parameter count: 1
bytecode array length: 16
bytecodes: [
/* 56 S> */ B(Wide), B(LdaSmi), I16(266),
/* 56 S> */ B(Wide), B(LdaSmi), I16(267),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -83,7 +83,7 @@ frame size: 2
parameter count: 1
bytecode array length: 16
bytecodes: [
/* 56 S> */ B(Wide), B(LdaSmi), I16(266),
/* 56 S> */ B(Wide), B(LdaSmi), I16(267),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -122,7 +122,7 @@ bytecodes: [
/* 94 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(264),
B(Wide), B(LdaSmi), I16(265),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
......@@ -144,7 +144,7 @@ bytecodes: [
/* 109 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(265),
B(Wide), B(LdaSmi), I16(266),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......@@ -159,7 +159,7 @@ bytecodes: [
/* 133 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(264),
B(Wide), B(LdaSmi), I16(265),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
......@@ -189,7 +189,7 @@ frame size: 2
parameter count: 1
bytecode array length: 16
bytecodes: [
/* 60 S> */ B(Wide), B(LdaSmi), I16(268),
/* 60 S> */ B(Wide), B(LdaSmi), I16(269),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -215,7 +215,7 @@ frame size: 2
parameter count: 1
bytecode array length: 16
bytecodes: [
/* 53 S> */ B(Wide), B(LdaSmi), I16(267),
/* 53 S> */ B(Wide), B(LdaSmi), I16(268),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -241,7 +241,7 @@ frame size: 2
parameter count: 1
bytecode array length: 16
bytecodes: [
/* 60 S> */ B(Wide), B(LdaSmi), I16(268),
/* 60 S> */ B(Wide), B(LdaSmi), I16(269),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
......@@ -267,7 +267,7 @@ frame size: 3
parameter count: 1
bytecode array length: 16
bytecodes: [
/* 46 S> */ B(Wide), B(LdaSmi), I16(267),
/* 46 S> */ B(Wide), B(LdaSmi), I16(268),
B(Star), R(1),
B(LdaConstant), U8(0),
B(Star), R(2),
......
// Copyright 2020 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.
const kLargerThanFixedArrayMaxLength = 200_000_000;
var x = new Int8Array(kLargerThanFixedArrayMaxLength);
try {
var y = x.sort((a, b) => b - a);
} catch (e) {
// Throwing is okay, crashing is not.
assertInstanceof(e, TypeError);
assertMatches(
/not supported for huge TypedArrays/, e.message, 'Error message');
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment