Reviewers: adamk,
Description:
Fix Array.prototype.concat for arguments object with getter.
R=ad...@chromium.org
BUG=crbug:516775
LOG=N
Please review this at https://codereview.chromium.org/1270403002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+35, -7 lines):
M src/runtime/runtime-array.cc
A test/mjsunit/regress/regress-crbug-516775.js
Index: src/runtime/runtime-array.cc
diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc
index
b5655db611a5ce34161d45990718872fa7f02916..4f8bc05cb6e43d9e36506bab216fc991a702992c
100644
--- a/src/runtime/runtime-array.cc
+++ b/src/runtime/runtime-array.cc
@@ -362,7 +362,8 @@ static int compareUInt32(const uint32_t* ap, const
uint32_t* bp) {
}
-static void CollectElementIndices(Handle<JSObject> object, uint32_t range,
+// Return false on exception.
+static bool CollectElementIndices(Handle<JSObject> object, uint32_t range,
List<uint32_t>* indices) {
Isolate* isolate = object->GetIsolate();
ElementsKind kind = object->GetElementsKind();
@@ -432,14 +433,20 @@ static void CollectElementIndices(Handle<JSObject>
object, uint32_t range,
for (uint32_t i = 0; i < length; i++) {
indices->Add(i);
}
- if (length == range) return; // All indices accounted for already.
+ if (length == range) return true; // All indices accounted for
already.
break;
}
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
- MaybeHandle<Object> length_obj =
- Object::GetProperty(object, isolate->factory()->length_string());
- double length_num = length_obj.ToHandleChecked()->Number();
+ Handle<Object> length_obj;
+ // See ES6 22.1.3.1 step 7-a-ii
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, length_obj,
+ Object::GetProperty(object, isolate->factory()->length_string()),
+ false);
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, length_obj, Execution::ToLength(isolate, length_obj),
false);
+ double length_num = length_obj->Number();
uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num));
ElementsAccessor* accessor = object->GetElementsAccessor();
for (uint32_t i = 0; i < length; i++) {
@@ -455,10 +462,11 @@ static void CollectElementIndices(Handle<JSObject>
object, uint32_t range,
if (!iter.IsAtEnd()) {
// The prototype will usually have no inherited element indices,
// but we have to check.
- CollectElementIndices(
+ return CollectElementIndices(
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
indices);
}
+ return true;
}
@@ -589,7 +597,7 @@ static bool IterateElements(Isolate* isolate,
Handle<JSObject> receiver,
List<uint32_t> indices(dict->Capacity() / 2);
// Collect all indices in the object and the prototypes less
// than length. This might introduce duplicates in the indices list.
- CollectElementIndices(receiver, length, &indices);
+ if (!CollectElementIndices(receiver, length, &indices)) return false;
indices.Sort(&compareUInt32);
int j = 0;
int n = indices.length();
Index: test/mjsunit/regress/regress-crbug-516775.js
diff --git a/test/mjsunit/regress/regress-crbug-516775.js
b/test/mjsunit/regress/regress-crbug-516775.js
new file mode 100644
index
0000000000000000000000000000000000000000..f956109a2f9529b3c140ec9d09f059f20bcb4ec0
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-516775.js
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// Flags: --allow-natives-syntax
+
+function argument_with_length_getter(f) {
+ arguments.__defineGetter__('length', f);
+ return arguments;
+}
+
+var a1 = [];
+%NormalizeElements(a1);
+a1.__proto__ = argument_with_length_getter(function() { return 'boom' });
+[].concat(a1);
+
+var a2 = [];
+%NormalizeElements(a2);
+a2.__proto__ = argument_with_length_getter(function() { throw 'boom' });
+assertThrows(function() { [].concat(a2); });
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.