Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2d3e735

Browse filesBrowse files
ofrobotsMylesBorins
authored andcommitted
deps: V8: backport e560815 from upstream
Original commit message: [runtime] Fix Array.prototype.concat with complex @@species Array.prototype.concat does not properly handle JSProxy species that will modify the currently visited array. BUG=682194 Review-Url: https://codereview.chromium.org/2655623004 Cr-Commit-Position: refs/heads/master@{#42640} Refs: #12779 PR-URL: #16133 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 9ec87dc commit 2d3e735
Copy full SHA for 2d3e735

File tree

Expand file treeCollapse file tree

2 files changed

+53
-9
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+53
-9
lines changed
Open diff view settings
Collapse file

‎deps/v8/src/builtins.cc‎

Copy file name to clipboardExpand all lines: deps/v8/src/builtins.cc
+18-9Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -795,14 +795,18 @@ namespace {
795795
*/
796796
class ArrayConcatVisitor {
797797
public:
798-
ArrayConcatVisitor(Isolate* isolate, Handle<Object> storage,
798+
ArrayConcatVisitor(Isolate* isolate, Handle<HeapObject> storage,
799799
bool fast_elements)
800800
: isolate_(isolate),
801801
storage_(isolate->global_handles()->Create(*storage)),
802802
index_offset_(0u),
803-
bit_field_(FastElementsField::encode(fast_elements) |
804-
ExceedsLimitField::encode(false) |
805-
IsFixedArrayField::encode(storage->IsFixedArray())) {
803+
bit_field_(
804+
FastElementsField::encode(fast_elements) |
805+
ExceedsLimitField::encode(false) |
806+
IsFixedArrayField::encode(storage->IsFixedArray()) |
807+
HasSimpleElementsField::encode(storage->IsFixedArray() ||
808+
storage->map()->instance_type() >
809+
LAST_CUSTOM_ELEMENTS_RECEIVER)) {
806810
DCHECK(!(this->fast_elements() && !is_fixed_array()));
807811
}
808812

@@ -891,12 +895,16 @@ class ArrayConcatVisitor {
891895
// (otherwise)
892896
Handle<FixedArray> storage_fixed_array() {
893897
DCHECK(is_fixed_array());
898+
DCHECK(has_simple_elements());
894899
return Handle<FixedArray>::cast(storage_);
895900
}
896901
Handle<JSReceiver> storage_jsreceiver() {
897902
DCHECK(!is_fixed_array());
898903
return Handle<JSReceiver>::cast(storage_);
899904
}
905+
bool has_simple_elements() const {
906+
return HasSimpleElementsField::decode(bit_field_);
907+
}
900908

901909
private:
902910
// Convert storage to dictionary mode.
@@ -929,12 +937,14 @@ class ArrayConcatVisitor {
929937

930938
inline void set_storage(FixedArray* storage) {
931939
DCHECK(is_fixed_array());
940+
DCHECK(has_simple_elements());
932941
storage_ = isolate_->global_handles()->Create(storage);
933942
}
934943

935944
class FastElementsField : public BitField<bool, 0, 1> {};
936945
class ExceedsLimitField : public BitField<bool, 1, 1> {};
937946
class IsFixedArrayField : public BitField<bool, 2, 1> {};
947+
class HasSimpleElementsField : public BitField<bool, 3, 1> {};
938948

939949
bool fast_elements() const { return FastElementsField::decode(bit_field_); }
940950
void set_fast_elements(bool fast) {
@@ -1166,8 +1176,6 @@ bool IterateElementsSlow(Isolate* isolate, Handle<JSReceiver> receiver,
11661176
visitor->increase_index_offset(length);
11671177
return true;
11681178
}
1169-
1170-
11711179
/**
11721180
* A helper function that visits "array" elements of a JSReceiver in numerical
11731181
* order.
@@ -1201,7 +1209,8 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
12011209
return IterateElementsSlow(isolate, receiver, length, visitor);
12021210
}
12031211

1204-
if (!HasOnlySimpleElements(isolate, *receiver)) {
1212+
if (!HasOnlySimpleElements(isolate, *receiver) ||
1213+
!visitor->has_simple_elements()) {
12051214
return IterateElementsSlow(isolate, receiver, length, visitor);
12061215
}
12071216
Handle<JSObject> array = Handle<JSObject>::cast(receiver);
@@ -1476,7 +1485,7 @@ Object* Slow_ArrayConcat(Arguments* args, Handle<Object> species,
14761485
// In case of failure, fall through.
14771486
}
14781487

1479-
Handle<Object> storage;
1488+
Handle<HeapObject> storage;
14801489
if (fast_case) {
14811490
// The backing storage array must have non-existing elements to preserve
14821491
// holes across concat operations.
@@ -1494,7 +1503,7 @@ Object* Slow_ArrayConcat(Arguments* args, Handle<Object> species,
14941503
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14951504
isolate, storage_object,
14961505
Execution::New(isolate, species, species, 1, &length));
1497-
storage = storage_object;
1506+
storage = Handle<HeapObject>::cast(storage_object);
14981507
}
14991508

15001509
ArrayConcatVisitor visitor(isolate, storage, fast_case);
Collapse file
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2017 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --expose-gc
6+
7+
var proxy = new Proxy([], {
8+
defineProperty() {
9+
w.length = 1; // shorten the array so the backstore pointer is relocated
10+
gc(); // force gc to move the array's elements backstore
11+
return Object.defineProperty.apply(this, arguments);
12+
}
13+
});
14+
15+
class MyArray extends Array {
16+
// custom constructor which returns a proxy object
17+
static get[Symbol.species](){
18+
return function() {
19+
return proxy;
20+
}
21+
};
22+
}
23+
24+
var w = new MyArray(100);
25+
w[1] = 0.1;
26+
w[2] = 0.1;
27+
28+
var result = Array.prototype.concat.call(w);
29+
30+
assertEquals(undefined, result[0]);
31+
assertEquals(0.1, result[1]);
32+
33+
for (var i = 2; i < 200; i++) {
34+
assertEquals(undefined, result[i]);
35+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.