Bug 1090096 - Fix null crash in cloneParseTree with computed property names in destructuring. r=efaust.
authorJason Orendorff <jorendorff@mozilla.com>
Tue, 20 Jan 2015 15:46:13 -0600
changeset 225906 4c573585e7dc400ffd320a1918fe296a51365b06
parent 225905 1f3af5e261d1578f93470102a54a418275c5ada2
child 225907 f5c6c57fc11a3da2627648a654fcdf3cca525fa5
push id54689
push userjorendorff@mozilla.com
push dateTue, 27 Jan 2015 01:45:25 +0000
treeherdermozilla-inbound@4c573585e7dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1090096
milestone38.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 1090096 - Fix null crash in cloneParseTree with computed property names in destructuring. r=efaust.
js/src/frontend/ParseNode.cpp
js/src/frontend/Parser.cpp
js/src/jit-test/tests/parser/bug-1090096.js
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -346,41 +346,45 @@ Parser<FullParseHandler>::cloneParseTree
             ParseNode *pn2;
             NULLCHECK(pn2 = cloneParseTree(opn2));
             pn->append(pn2);
         }
         pn->pn_xflags = opn->pn_xflags;
         break;
 
       case PN_TERNARY:
-        NULLCHECK(pn->pn_kid1 = cloneParseTree(opn->pn_kid1));
-        NULLCHECK(pn->pn_kid2 = cloneParseTree(opn->pn_kid2));
-        NULLCHECK(pn->pn_kid3 = cloneParseTree(opn->pn_kid3));
+        if (opn->pn_kid1)
+            NULLCHECK(pn->pn_kid1 = cloneParseTree(opn->pn_kid1));
+        if (opn->pn_kid2)
+            NULLCHECK(pn->pn_kid2 = cloneParseTree(opn->pn_kid2));
+        if (opn->pn_kid3)
+            NULLCHECK(pn->pn_kid3 = cloneParseTree(opn->pn_kid3));
         break;
 
       case PN_BINARY:
-        NULLCHECK(pn->pn_left = cloneParseTree(opn->pn_left));
-        if (opn->pn_right != opn->pn_left)
-            NULLCHECK(pn->pn_right = cloneParseTree(opn->pn_right));
-        else
-            pn->pn_right = pn->pn_left;
-        pn->pn_iflags = opn->pn_iflags;
-        break;
-
       case PN_BINARY_OBJ:
-        NULLCHECK(pn->pn_left = cloneParseTree(opn->pn_left));
-        if (opn->pn_right != opn->pn_left)
-            NULLCHECK(pn->pn_right = cloneParseTree(opn->pn_right));
-        else
-            pn->pn_right = pn->pn_left;
-        pn->pn_binary_obj = opn->pn_binary_obj;
+        if (opn->pn_left)
+            NULLCHECK(pn->pn_left = cloneParseTree(opn->pn_left));
+        if (opn->pn_right) {
+            if (opn->pn_right != opn->pn_left)
+                NULLCHECK(pn->pn_right = cloneParseTree(opn->pn_right));
+            else
+                pn->pn_right = pn->pn_left;
+        }
+        if (opn->isArity(PN_BINARY)) {
+            pn->pn_iflags = opn->pn_iflags;
+        } else {
+            MOZ_ASSERT(opn->isArity(PN_BINARY_OBJ));
+            pn->pn_binary_obj = opn->pn_binary_obj;
+        }
         break;
 
       case PN_UNARY:
-        NULLCHECK(pn->pn_kid = cloneParseTree(opn->pn_kid));
+        if (opn->pn_kid)
+            NULLCHECK(pn->pn_kid = cloneParseTree(opn->pn_kid));
         break;
 
       case PN_NAME:
         // PN_NAME could mean several arms in pn_u, so copy the whole thing.
         pn->pn_u = opn->pn_u;
         if (opn->isUsed()) {
             /*
              * The old name is a use of its pn_lexdef. Make the clone also be a
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2259,17 +2259,16 @@ Parser<FullParseHandler>::finishFunction
             body->pn_tail = &item->pn_next;
         ++body->pn_count;
         body->pn_xflags |= PNX_DESTRUCT;
     }
 
     MOZ_ASSERT(pn->pn_funbox == funbox);
     MOZ_ASSERT(pn->pn_body->isKind(PNK_ARGSBODY));
     pn->pn_body->append(body);
-    pn->pn_body->pn_pos = body->pn_pos;
 
     return true;
 }
 
 template <>
 bool
 Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox *funbox,
                                                      Node prelude, Node body)
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parser/bug-1090096.js
@@ -0,0 +1,12 @@
+load(libdir + "asserts.js");
+
+assertThrowsInstanceOf(
+    () => Function(`
+for (let {
+    [
+        function(x) {;
+        }
+    ]: {}
+} in 0
+`),
+    SyntaxError)