Bug 616137. Skip to the nearest ']' when parsing an attr selector fails. r=dbaron
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 04 Mar 2011 10:27:02 -0500
changeset 63577 52e34cbb1d4e6daf77ac86be9420767f127fe9b6
parent 63576 fc9ae5be228cb436927ba23e9f344769b3b59b3f
child 63578 bdcc73acab08850940531a29b708c312d36d9f78
push idunknown
push userunknown
push dateunknown
reviewersdbaron
bugs616137
milestone2.0b13pre
Bug 616137. Skip to the nearest ']' when parsing an attr selector fails. r=dbaron
layout/reftests/css-parsing/invalid-attr-1-ref.html
layout/reftests/css-parsing/invalid-attr-1.html
layout/reftests/css-parsing/reftest.list
layout/style/nsCSSParser.cpp
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-parsing/invalid-attr-1-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      p { color: green; }
+    </style>
+    <style>
+      div { color: green; }
+    </style>
+  </head>
+  <body>
+    <p>This text should be green.</p>
+    <div>This text should be green.</p>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-parsing/invalid-attr-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      p { color: red; }
+      [
+      p { color: red !important; }
+      p { color: red !important; }
+      ] p { color: red !important; }
+      p { color: green; }
+    </style>
+    <style>
+      div { color: red; }
+      :not([)
+      div { color: red !important; }
+      div { color: red !important; }
+      ]) div { color: red !important; }
+      div { color: green; }
+    </style>
+  </head>
+  <body>
+    <p>This text should be green.</p>
+    <div>This text should be green.</p>
+  </body>
+</html>
--- a/layout/reftests/css-parsing/reftest.list
+++ b/layout/reftests/css-parsing/reftest.list
@@ -1,3 +1,4 @@
 == at-rule-013.html at-rule-013-ref.html
 == invalid-url-handling.xhtml invalid-url-handling-ref.xhtml
 == pseudo-elements-1.html pseudo-elements-1-ref.html
+== invalid-attr-1.html invalid-attr-1-ref.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3227,16 +3227,20 @@ CSSParserImpl::ParseNegatedSimpleSelecto
     parsingStatus = ParseClassSelector(aDataMask, *newSel);
   }
   else if (mToken.IsSymbol(':')) {    // :pseudo
     parsingStatus = ParsePseudoSelector(aDataMask, *newSel, PR_TRUE,
                                         nsnull, nsnull, nsnull);
   }
   else if (mToken.IsSymbol('[')) {    // [attribute
     parsingStatus = ParseAttributeSelector(aDataMask, *newSel);
+    if (eSelectorParsingStatus_Error == parsingStatus) {
+      // Skip forward to the matching ']'
+      SkipUntil(']');
+    }
   }
   else {
     // then it should be a type element or universal selector
     parsingStatus = ParseTypeOrUniversalSelector(aDataMask, *newSel, PR_TRUE);
   }
   if (eSelectorParsingStatus_Error == parsingStatus) {
     REPORT_UNEXPECTED_TOKEN(PENegationBadInner);
     SkipUntil(')');
@@ -3485,16 +3489,19 @@ CSSParserImpl::ParseSelector(nsCSSSelect
     else if (mToken.IsSymbol(':')) {    // :pseudo
       parsingStatus = ParsePseudoSelector(dataMask, *selector, PR_FALSE,
                                           getter_AddRefs(pseudoElement),
                                           getter_Transfers(pseudoElementArgs),
                                           &pseudoElementType);
     }
     else if (mToken.IsSymbol('[')) {    // [attribute
       parsingStatus = ParseAttributeSelector(dataMask, *selector);
+      if (eSelectorParsingStatus_Error == parsingStatus) {
+        SkipUntil(']');
+      }
     }
     else {  // not a selector token, we're done
       parsingStatus = eSelectorParsingStatus_Done;
       UngetToken();
       break;
     }
 
     if (parsingStatus != eSelectorParsingStatus_Continue) {