Bug 1340145 - Don't allow HTML comments in module scripts r=anba
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 21 Feb 2017 17:18:04 +0000
changeset 373117 c7a4c2e34e6e1c888976fd9857fe816804f83550
parent 373116 c6a0ab52c21e7c3addc6e233447945c785085490
child 373118 9f871c40b36f164a3413c5aea5c4434f080a7bf0
child 373174 a6aebb9814445268db688d5dbcb5cac511f23686
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1340145
milestone54.0a1
Bug 1340145 - Don't allow HTML comments in module scripts r=anba
js/src/builtin/ReflectParse.cpp
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/TokenStream.cpp
js/src/jsapi.h
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -3691,16 +3691,17 @@ reflect_parse(JSContext* cx, uint32_t ar
 
     AutoStableStringChars linearChars(cx);
     if (!linearChars.initTwoByte(cx, linear))
         return false;
 
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
     options.setCanLazilyParse(false);
+    options.allowHTMLComments = target == ParseTarget::Script;
     mozilla::Range<const char16_t> chars = linearChars.twoByteRange();
     UsedNameTracker usedNames(cx);
     if (!usedNames.init())
         return false;
     Parser<FullParseHandler> parser(cx, cx->tempLifoAlloc(), options, chars.begin().get(),
                                     chars.length(), /* foldConstants = */ false, usedNames,
                                     nullptr, nullptr);
     if (!parser.checkOptions())
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -584,16 +584,17 @@ frontend::CompileModule(JSContext* cx, c
                         ScriptSourceObject** sourceObjectOut /* = nullptr */)
 {
     MOZ_ASSERT(srcBuf.get());
     MOZ_ASSERT_IF(sourceObjectOut, *sourceObjectOut == nullptr);
 
     CompileOptions options(cx, optionsInput);
     options.maybeMakeStrictMode(true); // ES6 10.2.1 Module code is always strict mode code.
     options.setIsRunOnce(true);
+    options.allowHTMLComments = false;
 
     RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
     BytecodeCompiler compiler(cx, alloc, options, srcBuf, emptyGlobalScope,
                               TraceLogger_ParserCompileModule);
     AutoInitializeSourceObject autoSSO(compiler, sourceObjectOut);
     return compiler.compileModule();
 }
 
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1714,24 +1714,26 @@ TokenStream::getTokenInternal(TokenKind*
       case '!':
         if (matchChar('='))
             tp->type = matchChar('=') ? TOK_STRICTNE : TOK_NE;
         else
             tp->type = TOK_NOT;
         goto out;
 
       case '<':
-        // NB: treat HTML begin-comment as comment-till-end-of-line.
-        if (matchChar('!')) {
-            if (matchChar('-')) {
-                if (matchChar('-'))
-                    goto skipline;
-                ungetChar('-');
+        if (options().allowHTMLComments) {
+            // Treat HTML begin-comment as comment-till-end-of-line.
+            if (matchChar('!')) {
+                if (matchChar('-')) {
+                    if (matchChar('-'))
+                        goto skipline;
+                    ungetChar('-');
+                }
+                ungetChar('!');
             }
-            ungetChar('!');
         }
         if (matchChar('<')) {
             tp->type = matchChar('=') ? TOK_LSHASSIGN : TOK_LSH;
         } else {
             tp->type = matchChar('=') ? TOK_LE : TOK_LT;
         }
         goto out;
 
@@ -1861,22 +1863,24 @@ TokenStream::getTokenInternal(TokenKind*
         goto out;
 
       case '%':
         tp->type = matchChar('=') ? TOK_MODASSIGN : TOK_MOD;
         goto out;
 
       case '-':
         if (matchChar('-')) {
-            int32_t c2;
-            if (!peekChar(&c2))
-                goto error;
+            if (options().allowHTMLComments && !flags.isDirtyLine) {
+                int32_t c2;
+                if (!peekChar(&c2))
+                    goto error;
 
-            if (c2 == '>' && !flags.isDirtyLine)
-                goto skipline;
+                if (c2 == '>')
+                    goto skipline;
+            }
 
             tp->type = TOK_DEC;
         } else {
             tp->type = matchChar('=') ? TOK_SUBASSIGN : TOK_SUB;
         }
         goto out;
 
       badchar:
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3849,16 +3849,17 @@ class JS_FRIEND_API(TransitiveCompileOpt
         extraWarningsOption(false),
         forEachStatementOption(false),
         werrorOption(false),
         asmJSOption(AsmJSOption::Disabled),
         throwOnAsmJSValidationFailureOption(false),
         forceAsync(false),
         installedFile(false),
         sourceIsLazy(false),
+        allowHTMLComments(true),
         introductionType(nullptr),
         introductionLineno(0),
         introductionOffset(0),
         hasIntroductionInfo(false)
     { }
 
     // Set all POD options (those not requiring reference counts, copies,
     // rooting, or other hand-holding) to their values in |rhs|.
@@ -3885,16 +3886,17 @@ class JS_FRIEND_API(TransitiveCompileOpt
     bool extraWarningsOption;
     bool forEachStatementOption;
     bool werrorOption;
     AsmJSOption asmJSOption;
     bool throwOnAsmJSValidationFailureOption;
     bool forceAsync;
     bool installedFile;  // 'true' iff pre-compiling js file in packaged app
     bool sourceIsLazy;
+    bool allowHTMLComments;
 
     // |introductionType| is a statically allocated C string:
     // one of "eval", "Function", or "GeneratorFunction".
     const char* introductionType;
     unsigned introductionLineno;
     uint32_t introductionOffset;
     bool hasIntroductionInfo;