Remove oob elements collected from the prototype chain by trimming in GetArrayKeys
BUG=chromium:594953 LOG=n Review URL: https://codereview.chromium.org/1817443003 Cr-Commit-Position: refs/heads/master@{#34893}
This commit is contained in:
parent
b3bda50ddd
commit
c6f9883d53
@ -272,12 +272,10 @@ function SparseSlice(array, start_i, del_count, len, deleted_elements) {
|
||||
var length = indices.length;
|
||||
for (var k = 0; k < length; ++k) {
|
||||
var key = indices[k];
|
||||
if (!IS_UNDEFINED(key)) {
|
||||
if (key >= start_i) {
|
||||
var current = array[key];
|
||||
if (!IS_UNDEFINED(current) || key in array) {
|
||||
DefineIndexedProperty(deleted_elements, key - start_i, current);
|
||||
}
|
||||
if (key >= start_i) {
|
||||
var current = array[key];
|
||||
if (!IS_UNDEFINED(current) || key in array) {
|
||||
DefineIndexedProperty(deleted_elements, key - start_i, current);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,21 +312,19 @@ function SparseMove(array, start_i, del_count, len, num_additional_args) {
|
||||
var length = indices.length;
|
||||
for (var k = 0; k < length; ++k) {
|
||||
var key = indices[k];
|
||||
if (!IS_UNDEFINED(key)) {
|
||||
if (key < start_i) {
|
||||
var current = array[key];
|
||||
if (!IS_UNDEFINED(current) || key in array) {
|
||||
new_array[key] = current;
|
||||
}
|
||||
} else if (key >= start_i + del_count) {
|
||||
var current = array[key];
|
||||
if (!IS_UNDEFINED(current) || key in array) {
|
||||
var new_key = key - del_count + num_additional_args;
|
||||
new_array[new_key] = current;
|
||||
if (new_key > 0xfffffffe) {
|
||||
big_indices = big_indices || new InternalArray();
|
||||
big_indices.push(new_key);
|
||||
}
|
||||
if (key < start_i) {
|
||||
var current = array[key];
|
||||
if (!IS_UNDEFINED(current) || key in array) {
|
||||
new_array[key] = current;
|
||||
}
|
||||
} else if (key >= start_i + del_count) {
|
||||
var current = array[key];
|
||||
if (!IS_UNDEFINED(current) || key in array) {
|
||||
var new_key = key - del_count + num_additional_args;
|
||||
new_array[new_key] = current;
|
||||
if (new_key > 0xfffffffe) {
|
||||
big_indices = big_indices || new InternalArray();
|
||||
big_indices.push(new_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1066,8 +1062,7 @@ function InnerArraySort(array, length, comparefn) {
|
||||
} else {
|
||||
for (var i = 0; i < indices.length; i++) {
|
||||
var index = indices[i];
|
||||
if (!IS_UNDEFINED(index) && !HAS_OWN_PROPERTY(obj, index)
|
||||
&& HAS_OWN_PROPERTY(proto, index)) {
|
||||
if (!HAS_OWN_PROPERTY(obj, index) && HAS_OWN_PROPERTY(proto, index)) {
|
||||
obj[index] = proto[index];
|
||||
if (index >= max) { max = index + 1; }
|
||||
}
|
||||
@ -1094,8 +1089,7 @@ function InnerArraySort(array, length, comparefn) {
|
||||
} else {
|
||||
for (var i = 0; i < indices.length; i++) {
|
||||
var index = indices[i];
|
||||
if (!IS_UNDEFINED(index) && from <= index &&
|
||||
HAS_OWN_PROPERTY(proto, index)) {
|
||||
if (from <= index && HAS_OWN_PROPERTY(proto, index)) {
|
||||
obj[index] = UNDEFINED;
|
||||
}
|
||||
}
|
||||
@ -1379,7 +1373,7 @@ function InnerArrayIndexOf(array, element, index, length) {
|
||||
while (i < n && sortedKeys[i] < index) i++;
|
||||
while (i < n) {
|
||||
var key = sortedKeys[i];
|
||||
if (!IS_UNDEFINED(key) && array[key] === element) return key;
|
||||
if (array[key] === element) return key;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
@ -1438,7 +1432,7 @@ function InnerArrayLastIndexOf(array, element, index, length, argumentsLength) {
|
||||
var i = sortedKeys.length - 1;
|
||||
while (i >= 0) {
|
||||
var key = sortedKeys[i];
|
||||
if (!IS_UNDEFINED(key) && array[key] === element) return key;
|
||||
if (array[key] === element) return key;
|
||||
i--;
|
||||
}
|
||||
return -1;
|
||||
|
@ -211,12 +211,19 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
|
||||
JSObject::CollectOwnElementKeys(current, &accumulator, ALL_PROPERTIES);
|
||||
}
|
||||
// Erase any keys >= length.
|
||||
// TODO(adamk): Remove this step when the contract of %GetArrayKeys
|
||||
// is changed to let this happen on the JS side.
|
||||
Handle<FixedArray> keys = accumulator.GetKeys(KEEP_NUMBERS);
|
||||
int j = 0;
|
||||
for (int i = 0; i < keys->length(); i++) {
|
||||
if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
|
||||
if (NumberToUint32(keys->get(i)) >= length) continue;
|
||||
if (i != j) keys->set(j, keys->get(i));
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j != keys->length()) {
|
||||
isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
|
||||
*keys, keys->length() - j);
|
||||
}
|
||||
|
||||
return *isolate->factory()->NewJSArrayWithElements(keys);
|
||||
}
|
||||
|
||||
|
6
test/mjsunit/regress/get-array-keys-oob.js
Normal file
6
test/mjsunit/regress/get-array-keys-oob.js
Normal file
@ -0,0 +1,6 @@
|
||||
// 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.
|
||||
|
||||
Array.prototype[10000000] = 1;
|
||||
Array(1000).join();
|
Loading…
Reference in New Issue
Block a user