Check length in Array.prototype.concat.
Throw a TypeError if the length of a concat-spreadable object makes the total length too large, as specified. Bug: v8:7652 Change-Id: Ie3f694d64c949703edd733c0310cfb3f64b78a15 Reviewed-on: https://chromium-review.googlesource.com/1013714 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#52644}
This commit is contained in:
parent
c3da929020
commit
92cde630df
@ -377,6 +377,8 @@ class ArrayConcatVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t index_offset() const { return index_offset_; }
|
||||
|
||||
void increase_index_offset(uint32_t delta) {
|
||||
if (JSObject::kMaxElementCount - index_offset_ < delta) {
|
||||
index_offset_ = JSObject::kMaxElementCount;
|
||||
@ -709,6 +711,11 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
Handle<Object> val;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, val, Object::GetLengthFromArrayLike(isolate, receiver), false);
|
||||
if (visitor->index_offset() + val->Number() > kMaxSafeInteger) {
|
||||
isolate->Throw(*isolate->factory()->NewTypeError(
|
||||
MessageTemplate::kInvalidArrayLength));
|
||||
return false;
|
||||
}
|
||||
// TODO(caitp): Support larger element indexes (up to 2^53-1).
|
||||
if (!val->ToUint32(&length)) {
|
||||
length = 0;
|
||||
|
@ -2,13 +2,25 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
let a = {length: 2**53 - 1};
|
||||
|
||||
const unshift = Array.prototype.unshift;
|
||||
assertThrows(() => unshift.call(a, 42), TypeError);
|
||||
assertEquals(unshift.call(a), 2**53 - 1);
|
||||
|
||||
const splice = Array.prototype.splice;
|
||||
assertThrows(() => splice.call(a, 0, 0, 42), TypeError);
|
||||
assertEquals(splice.call(a, 0, 1, 42).length, 1);
|
||||
assertEquals(a[0], 42);
|
||||
const unshift = Array.prototype.unshift;
|
||||
|
||||
{
|
||||
let a = {length: 2**53 - 1};
|
||||
assertThrows(() => unshift.call(a, 42), TypeError);
|
||||
assertEquals(unshift.call(a), 2**53 - 1);
|
||||
}
|
||||
|
||||
{
|
||||
let a = {length: 2**53 - 1};
|
||||
assertThrows(() => splice.call(a, 0, 0, 42), TypeError);
|
||||
assertEquals(splice.call(a, 0, 1, 42).length, 1);
|
||||
assertEquals(a[0], 42);
|
||||
}
|
||||
|
||||
{
|
||||
let a = {length: 2**53 - 1, [Symbol.isConcatSpreadable]: true};
|
||||
assertThrows(() => [42].concat(a), TypeError);
|
||||
assertThrows(() => [, ].concat(a), TypeError);
|
||||
assertThrows(() => [].concat(42, a), TypeError);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user