Bug 1287520 - Check IsPackedArray for the result array in Array.prototype.concat. r=efaust
authorTooru Fujisawa <arai_a@mac.com>
Fri, 29 Jul 2016 13:55:26 +0900
changeset 347243 b40a60e2a4e138d4b99805b5471bcff268817f9a
parent 347242 75976803569d9626c1ac5f495a69b0936321ed9e
child 347244 0d0a2960686a335eb09de6edbe1dfe573e212701
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1287520
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1287520 - Check IsPackedArray for the result array in Array.prototype.concat. r=efaust
js/src/builtin/Array.js
js/src/tests/ecma_6/Array/concat-proxy.js
--- a/js/src/builtin/Array.js
+++ b/js/src/builtin/Array.js
@@ -985,17 +985,17 @@ function ArrayConcat(arg1) {
         if (IsConcatSpreadable(E)) {
             // Step 5.c.ii.
             len = ToLength(E.length);
 
             // Step 5.c.iii.
             if (n + len > MAX_NUMERIC_INDEX)
                 ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
 
-            if (IsPackedArray(E)) {
+            if (IsPackedArray(A) && IsPackedArray(E)) {
                 // Step 5.c.i, 5.c.iv, and 5.c.iv.5.
                 for (k = 0; k < len; k++) {
                     // Steps 5.c.iv.1-3.
                     // IsPackedArray(E) ensures that |k in E| is always true.
                     _DefineDataProperty(A, n, E[k]);
 
                     // Step 5.c.iv.4.
                     n++;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Array/concat-proxy.js
@@ -0,0 +1,25 @@
+var BUGNUMBER = 1287520;
+var summary = 'Array.prototype.concat should check HasProperty everytime for non-dense array';
+
+print(BUGNUMBER + ": " + summary);
+
+var a = [1, 2, 3];
+a.constructor = {
+  [Symbol.species]: function(...args) {
+    var p = new Proxy(new Array(...args), {
+      defineProperty(target, propertyKey, receiver) {
+        if (propertyKey === "0") delete a[1];
+        return Reflect.defineProperty(target, propertyKey, receiver);
+      }
+    });
+    return p;
+  }
+};
+
+var p = a.concat();
+assertEq(0 in p, true);
+assertEq(1 in p, false);
+assertEq(2 in p, true);
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);