From c1ba97eeae3171fb96283583c33f0238cedacab6 Mon Sep 17 00:00:00 2001
From: Gaming4JC <g4jc@hyperbola.info>
Date: Sun, 9 Jun 2019 17:20:09 -0400
Subject: 1340089 - Check the binding name in comprehensionFor.

---
 js/src/frontend/Parser.cpp                         |   2 +
 .../ecma_6/Comprehensions/for-reserved-word.js     | 107 +++++++++++++++++++++
 2 files changed, 109 insertions(+)
 create mode 100644 js/src/tests/ecma_6/Comprehensions/for-reserved-word.js

diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 322f428e5..fc4b0e965 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -8101,6 +8101,8 @@ Parser<ParseHandler>::comprehensionFor(GeneratorKind comprehensionKind)
 
     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();
diff --git a/js/src/tests/ecma_6/Comprehensions/for-reserved-word.js b/js/src/tests/ecma_6/Comprehensions/for-reserved-word.js
new file mode 100644
index 000000000..9b320fc91
--- /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);
-- 
cgit v1.2.3