Bug 1340089 - Check the binding name in comprehensionFor. r=till
authorTooru Fujisawa <arai_a@mac.com>
Sat, 18 Feb 2017 07:59:57 +0900
changeset 486589 e1850269c2e0f4509d5b82931a7c1a3feba5054b
parent 486588 fad2e60d78431950805f24a73797e7528a4f39fc
child 486590 e319d3fd614a71056cce9deb07a530abe825bfba
push id46031
push userbmo:cam@mcc.id.au
push dateSun, 19 Feb 2017 01:42:46 +0000
reviewerstill
bugs1340089
milestone54.0a1
Bug 1340089 - Check the binding name in comprehensionFor. r=till
js/src/frontend/Parser.cpp
js/src/tests/ecma_6/Comprehensions/for-reserved-word.js
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -8047,16 +8047,18 @@ Parser<ParseHandler>::comprehensionFor(G
     uint32_t begin = pos().begin;
 
     MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
 
     // FIXME: Destructuring binding (bug 980828).
 
     MUST_MATCH_TOKEN_FUNC(TokenKindIsPossibleIdentifier, JSMSG_NO_VARIABLE_NAME);
     RootedPropertyName name(context, bindingIdentifier(YieldIsKeyword));
+    if (!name)
+        return null();
     if (name == context->names().let) {
         error(JSMSG_LET_COMP_BINDING);
         return null();
     }
     TokenPos namePos = pos();
     Node lhs = newName(name);
     if (!lhs)
         return null();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Comprehensions/for-reserved-word.js
@@ -0,0 +1,107 @@
+var BUGNUMBER = 1340089;
+var summary = "Comprehension should check the binding names";
+
+print(BUGNUMBER + ": " + summary);
+
+// Non strict mode.
+// Keywords, literals, 'let', and 'yield' are not allowed.
+
+assertThrowsInstanceOf(function () {
+    eval("[for (true of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    eval("(for (true of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    eval("[for (throw of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    eval("(for (throw of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    eval("[for (let of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    eval("(for (let of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    eval("[for (yield of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    eval("(for (yield of [1]) 2)");
+}, SyntaxError);
+
+eval("[for (public of [1]) 2]");
+eval("(for (public of [1]) 2)");
+
+eval("[for (static of [1]) 2]");
+eval("(for (static of [1]) 2)");
+
+// Strict mode.
+// All reserved words are not allowed.
+
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("[for (true of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("(for (true of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("[for (throw of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("(for (throw of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("[for (let of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("(for (let of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("[for (yield of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("(for (yield of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("[for (public of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("(for (public of [1]) 2)");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("[for (static of [1]) 2]");
+}, SyntaxError);
+assertThrowsInstanceOf(function () {
+    "use strict";
+    eval("(for (static of [1]) 2)");
+}, SyntaxError);
+
+(function () {
+    "use strict";
+    eval("[for (await of [1]) 2]");
+    eval("(for (await of [1]) 2)");
+})();
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);