Commit 823224f3 authored by cbruni's avatar cbruni Committed by Commit bot

[elements] Fix length bounds precheck for Array.prototype.concat

BUG=chromium:599414
LOG=n

Review URL: https://codereview.chromium.org/1863553003

Cr-Commit-Position: refs/heads/master@{#35269}
parent 9e39a9ff
......@@ -1528,6 +1528,12 @@ Object* Slow_ArrayConcat(Arguments* args, Handle<Object> species,
MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
// We shouldn't overflow when adding another len.
const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
STATIC_ASSERT(FixedDoubleArray::kMaxLength < kHalfOfMaxInt);
USE(kHalfOfMaxInt);
int n_arguments = args->length();
int result_len = 0;
{
......@@ -1547,16 +1553,14 @@ MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
if (HasConcatSpreadableModifier(isolate, array)) {
return MaybeHandle<JSArray>();
}
int len = Smi::cast(array->length())->value();
// We shouldn't overflow when adding another len.
const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
USE(kHalfOfMaxInt);
result_len += len;
// The Array length is guaranted to be <= kHalfOfMaxInt thus we won't
// overflow.
result_len += Smi::cast(array->length())->value();
DCHECK(result_len >= 0);
// Throw an Error if we overflow the FixedArray limits
if (FixedArray::kMaxLength < result_len) {
if (FixedDoubleArray::kMaxLength < result_len ||
FixedArray::kMaxLength < result_len) {
AllowHeapAllocation allow_gc;
THROW_NEW_ERROR(isolate,
NewRangeError(MessageTemplate::kInvalidArrayLength),
JSArray);
......
......@@ -2978,6 +2978,9 @@ void ElementsAccessor::TearDown() {
Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args,
uint32_t concat_size) {
const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
STATIC_ASSERT(FixedDoubleArray::kMaxLength < kHalfOfMaxInt);
USE(kHalfOfMaxInt);
uint32_t result_len = 0;
bool has_raw_doubles = false;
ElementsKind result_elements_kind = GetInitialFastElementsKind();
......@@ -2992,9 +2995,6 @@ Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args,
array->length()->ToArrayLength(&len);
// We shouldn't overflow when adding another len.
const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
USE(kHalfOfMaxInt);
result_len += len;
DCHECK(0 <= result_len);
DCHECK(result_len <= FixedDoubleArray::kMaxLength);
......
// Copyright 2016 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.
var largeArray = 'x'.repeat(999).split('');
var a = largeArray;
assertThrows(() => {
for (;;) {
a = a.concat(a, a, a, a, a, a);
}}, RangeError);
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