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 { ...@@ -281,6 +281,7 @@ extern enum MessageTemplate {
kFirstArgumentNotRegExp, kFirstArgumentNotRegExp,
kBigIntMixedTypes, kBigIntMixedTypes,
kTypedArrayTooShort, kTypedArrayTooShort,
kTypedArrayTooLargeToSort,
kInvalidCountValue, kInvalidCountValue,
kConstructorNotFunction, kConstructorNotFunction,
kSymbolToString, kSymbolToString,
......
...@@ -114,6 +114,14 @@ transitioning javascript builtin TypedArrayPrototypeSort( ...@@ -114,6 +114,14 @@ transitioning javascript builtin TypedArrayPrototypeSort(
return TypedArraySortFast(context, obj); 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 = const comparefn: Callable =
Cast<Callable>(comparefnObj) otherwise unreachable; Cast<Callable>(comparefnObj) otherwise unreachable;
const accessor: TypedArrayAccessor = const accessor: TypedArrayAccessor =
......
...@@ -364,6 +364,8 @@ namespace internal { ...@@ -364,6 +364,8 @@ namespace internal {
T(ToRadixFormatRange, "toString() radix argument must be between 2 and 36") \ T(ToRadixFormatRange, "toString() radix argument must be between 2 and 36") \
T(TypedArraySetOffsetOutOfBounds, "offset is out of bounds") \ T(TypedArraySetOffsetOutOfBounds, "offset is out of bounds") \
T(TypedArraySetSourceTooLarge, "Source is too large") \ T(TypedArraySetSourceTooLarge, "Source is too large") \
T(TypedArrayTooLargeToSort, \
"Custom comparefn not supported for huge TypedArrays") \
T(ValueOutOfRange, "Value % out of range for % options property %") \ T(ValueOutOfRange, "Value % out of range for % options property %") \
/* SyntaxError */ \ /* SyntaxError */ \
T(AmbiguousExport, \ T(AmbiguousExport, \
......
...@@ -84,7 +84,7 @@ bytecodes: [ ...@@ -84,7 +84,7 @@ bytecodes: [
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 48 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 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(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
...@@ -115,7 +115,7 @@ bytecodes: [ ...@@ -115,7 +115,7 @@ bytecodes: [
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 41 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 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(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
...@@ -146,7 +146,7 @@ bytecodes: [ ...@@ -146,7 +146,7 @@ bytecodes: [
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 48 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 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(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
...@@ -177,7 +177,7 @@ bytecodes: [ ...@@ -177,7 +177,7 @@ bytecodes: [
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 41 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 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(Star), R(4),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(5), B(Star), R(5),
......
...@@ -57,7 +57,7 @@ bytecodes: [ ...@@ -57,7 +57,7 @@ bytecodes: [
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 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(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
...@@ -89,7 +89,7 @@ bytecodes: [ ...@@ -89,7 +89,7 @@ bytecodes: [
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 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(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
......
...@@ -25,7 +25,7 @@ bytecodes: [ ...@@ -25,7 +25,7 @@ bytecodes: [
B(TestReferenceEqual), R(this), B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1), B(Mov), R(this), R(1),
B(JumpIfTrue), U8(18), B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(264), B(Wide), B(LdaSmi), I16(265),
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(3), B(Star), R(3),
...@@ -56,7 +56,7 @@ frame size: 2 ...@@ -56,7 +56,7 @@ frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 16
bytecodes: [ bytecodes: [
/* 56 S> */ B(Wide), B(LdaSmi), I16(266), /* 56 S> */ B(Wide), B(LdaSmi), I16(267),
B(Star), R(0), B(Star), R(0),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(1),
...@@ -83,7 +83,7 @@ frame size: 2 ...@@ -83,7 +83,7 @@ frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 16
bytecodes: [ bytecodes: [
/* 56 S> */ B(Wide), B(LdaSmi), I16(266), /* 56 S> */ B(Wide), B(LdaSmi), I16(267),
B(Star), R(0), B(Star), R(0),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(1),
...@@ -122,7 +122,7 @@ bytecodes: [ ...@@ -122,7 +122,7 @@ bytecodes: [
/* 94 E> */ B(TestReferenceEqual), R(this), /* 94 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(JumpIfTrue), U8(18), B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(264), B(Wide), B(LdaSmi), I16(265),
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(3), B(Star), R(3),
...@@ -144,7 +144,7 @@ bytecodes: [ ...@@ -144,7 +144,7 @@ bytecodes: [
/* 109 E> */ B(TestReferenceEqual), R(this), /* 109 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1), B(Mov), R(this), R(1),
B(JumpIfTrue), U8(18), B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(265), B(Wide), B(LdaSmi), I16(266),
B(Star), R(3), B(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
...@@ -159,7 +159,7 @@ bytecodes: [ ...@@ -159,7 +159,7 @@ bytecodes: [
/* 133 E> */ B(TestReferenceEqual), R(this), /* 133 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(JumpIfTrue), U8(18), B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(264), B(Wide), B(LdaSmi), I16(265),
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(3), B(Star), R(3),
...@@ -189,7 +189,7 @@ frame size: 2 ...@@ -189,7 +189,7 @@ frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 16
bytecodes: [ bytecodes: [
/* 60 S> */ B(Wide), B(LdaSmi), I16(268), /* 60 S> */ B(Wide), B(LdaSmi), I16(269),
B(Star), R(0), B(Star), R(0),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(1),
...@@ -215,7 +215,7 @@ frame size: 2 ...@@ -215,7 +215,7 @@ frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 16
bytecodes: [ bytecodes: [
/* 53 S> */ B(Wide), B(LdaSmi), I16(267), /* 53 S> */ B(Wide), B(LdaSmi), I16(268),
B(Star), R(0), B(Star), R(0),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(1),
...@@ -241,7 +241,7 @@ frame size: 2 ...@@ -241,7 +241,7 @@ frame size: 2
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 16
bytecodes: [ bytecodes: [
/* 60 S> */ B(Wide), B(LdaSmi), I16(268), /* 60 S> */ B(Wide), B(LdaSmi), I16(269),
B(Star), R(0), B(Star), R(0),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(1),
...@@ -267,7 +267,7 @@ frame size: 3 ...@@ -267,7 +267,7 @@ frame size: 3
parameter count: 1 parameter count: 1
bytecode array length: 16 bytecode array length: 16
bytecodes: [ bytecodes: [
/* 46 S> */ B(Wide), B(LdaSmi), I16(267), /* 46 S> */ B(Wide), B(LdaSmi), I16(268),
B(Star), R(1), B(Star), R(1),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(2), 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