From 6550289df631cd74cb43fa446bb107749e93ab18 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Sun, 23 Dec 2012 13:30:55 +1100 Subject: [PATCH] Bug 814566 - Allow invalid syntax (with balanced parentheses) inside @supports conditions. (v1.1.1) r=dbaron --- .../en-US/chrome/layout/css.properties | 10 ++-- .../conditional3/css-supports-015.xht | 2 +- .../conditional3/css-supports-022.xht | 10 ++-- .../conditional3/css-supports-023.xht | 10 ++-- .../conditional3/css-supports-031.xht | 10 ++-- .../conditional3/css-supports-032.xht | 19 +++++++ .../conditional3/css-supports-033.xht | 19 +++++++ .../conditional3/css-supports-034.xht | 19 +++++++ .../conditional3/css-supports-035.xht | 19 +++++++ .../conditional3/css-supports-036.xht | 19 +++++++ .../conditional3/css-supports-037.xht | 19 +++++++ .../conditional3/css-supports-038.xht | 19 +++++++ .../conditional3/css-supports-039.xht | 19 +++++++ .../conditional3/css-supports-040.xht | 18 ++++++ .../conditional3/css-supports-041.xht | 18 ++++++ .../submitted/conditional3/reftest.list | 10 ++++ layout/style/nsCSSParser.cpp | 57 ++++++++++++++----- 17 files changed, 262 insertions(+), 35 deletions(-) create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-032.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-033.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-034.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-035.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-036.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-037.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-038.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-039.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-040.xht create mode 100644 layout/reftests/w3c-css/submitted/conditional3/css-supports-041.xht diff --git a/dom/locales/en-US/chrome/layout/css.properties b/dom/locales/en-US/chrome/layout/css.properties index bec986fd1110..51bff218a190 100644 --- a/dom/locales/en-US/chrome/layout/css.properties +++ b/dom/locales/en-US/chrome/layout/css.properties @@ -12,7 +12,7 @@ PEDeclSkipped=Skipped to next declaration. PEUnknownProperty=Unknown property '%1$S'. PEValueParsingError=Error in parsing value for '%1$S'. PEExpectEndValue=Expected end of value but found '%1$S'. -PESkipAtRuleEOF=end of unknown at-rule +PESkipAtRuleEOF2=end of at-rule PEUnknownAtRule=Unrecognized at-rule or error parsing at-rule '%1$S'. PECharsetRuleEOF=charset string in @charset rule PECharsetRuleNotString=Expected charset string but found '%1$S'. @@ -115,11 +115,11 @@ PEBadFontBlockStart=Expected '{' to begin @font-face rule but found '%1$S'. PEBadFontBlockEnd=Expected '}' to end @font-face rule but found '%1$S'. PEAnonBoxNotAlone=Did not expect anonymous box. PEBadDirValue=Expected 'ltr' or 'rtl' in direction selector but found '%1$S'. -PESupportsConditionStartEOF='not' or '(' -PESupportsConditionInParensStartEOF='not', '(' or identifier +PESupportsConditionStartEOF2='not', '(', or function +PESupportsConditionInParensEOF=')' PESupportsConditionNotEOF='not' -PESupportsConditionExpectedOpenParen=Expected '(' while parsing supports condition but found '%1$S'. +PESupportsConditionExpectedOpenParenOrFunction=Expected '(' or function while parsing supports condition but found '%1$S'. PESupportsConditionExpectedCloseParen=Expected ')' while parsing supports condition but found '%1$S'. -PESupportsConditionExpectedStart=Expected 'not' or '(' while parsing supports condition but found '%1$S'. +PESupportsConditionExpectedStart2=Expected 'not', '(', or function while parsing supports condition but found '%1$S'. PESupportsConditionExpectedNot=Expected 'not' while parsing supports condition but found '%1$S'. PESupportsGroupRuleStart=Expected '{' to begin @supports rule but found '%1$S'. diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-015.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-015.xht index 8a696fdff8d2..66c7edbe5d31 100644 --- a/layout/reftests/w3c-css/submitted/conditional3/css-supports-015.xht +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-015.xht @@ -5,7 +5,7 @@ - + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-023.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-023.xht index b620b109c90f..e01f018427b6 100644 --- a/layout/reftests/w3c-css/submitted/conditional3/css-supports-023.xht +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-023.xht @@ -1,16 +1,16 @@ - CSS Test: An @supports rule with invalid syntax must not apply rules inside it + CSS Test: An @supports rule with balanced invalid syntax within parentheses must evaluate to false - - + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-031.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-031.xht index 85c582536944..9ff7c14c416f 100644 --- a/layout/reftests/w3c-css/submitted/conditional3/css-supports-031.xht +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-031.xht @@ -1,16 +1,16 @@ - CSS Test: An @supports rule with invalid syntax must not apply rules inside it + CSS Test: An @supports rule with balanced invalid syntax within parentheses must evaluate to false - - + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-032.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-032.xht new file mode 100644 index 000000000000..baae56576885 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-032.xht @@ -0,0 +1,19 @@ + + + + CSS Test: An @supports rule with balanced invalid syntax must evaluate to false + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-033.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-033.xht new file mode 100644 index 000000000000..c6c0c39f3a5f --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-033.xht @@ -0,0 +1,19 @@ + + + + CSS Test: An @supports rule with balanced invalid syntax must evaluate to false + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-034.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-034.xht new file mode 100644 index 000000000000..c6c0c39f3a5f --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-034.xht @@ -0,0 +1,19 @@ + + + + CSS Test: An @supports rule with balanced invalid syntax must evaluate to false + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-035.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-035.xht new file mode 100644 index 000000000000..471a71513183 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-035.xht @@ -0,0 +1,19 @@ + + + + CSS Test: An @supports rule with unbalanced invalid syntax must fail to parse + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-036.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-036.xht new file mode 100644 index 000000000000..c18ba6629435 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-036.xht @@ -0,0 +1,19 @@ + + + + CSS Test: An @supports rule with an unrecognized condition using functional notation must evaluate to false + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-037.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-037.xht new file mode 100644 index 000000000000..137be1b598ec --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-037.xht @@ -0,0 +1,19 @@ + + + + CSS Test: An @supports rule with an unrecognized condition using functional notation with unbalanced parentheses must fail to parse + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-038.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-038.xht new file mode 100644 index 000000000000..f6974a9b04bd --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-038.xht @@ -0,0 +1,19 @@ + + + + CSS Test: In an @supports rule "not(" must be parsed as a FUNCTION + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-039.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-039.xht new file mode 100644 index 000000000000..1032263b1c49 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-039.xht @@ -0,0 +1,19 @@ + + + + CSS Test: In an @supports rule "or(" must be parsed as a FUNCTION + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-040.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-040.xht new file mode 100644 index 000000000000..cda404996888 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-040.xht @@ -0,0 +1,18 @@ + + + + CSS Test: An @supports rule condition with empty parentheses should evaluates to false + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/css-supports-041.xht b/layout/reftests/w3c-css/submitted/conditional3/css-supports-041.xht new file mode 100644 index 000000000000..c49c66abda12 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/conditional3/css-supports-041.xht @@ -0,0 +1,18 @@ + + + + CSS Test: An @supports rule condition with empty parentheses should evaluates to false + + + + + + + + + + diff --git a/layout/reftests/w3c-css/submitted/conditional3/reftest.list b/layout/reftests/w3c-css/submitted/conditional3/reftest.list index 72507fb247c9..1de1cdde637f 100644 --- a/layout/reftests/w3c-css/submitted/conditional3/reftest.list +++ b/layout/reftests/w3c-css/submitted/conditional3/reftest.list @@ -31,3 +31,13 @@ default-preferences pref(layout.css.supports-rule.enabled,true) == css-supports-029.xht support/pass.xht == css-supports-030.xht support/pass.xht == css-supports-031.xht support/pass.xht +== css-supports-032.xht support/pass.xht +== css-supports-033.xht support/pass.xht +== css-supports-034.xht support/pass.xht +== css-supports-035.xht support/pass.xht +== css-supports-036.xht support/pass.xht +== css-supports-037.xht support/pass.xht +== css-supports-038.xht support/pass.xht +== css-supports-039.xht support/pass.xht +== css-supports-040.xht support/pass.xht +== css-supports-041.xht support/pass.xht diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 18ffb5a7c3e7..83986d9e962f 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -342,8 +342,11 @@ protected: bool ExpectEndProperty(); bool CheckEndProperty(); nsSubstring* NextIdent(); - void SkipUntil(PRUnichar aStopSymbol); + + // returns true when the stop symbol is found, and false for EOF + bool SkipUntil(PRUnichar aStopSymbol); void SkipUntilOneOf(const PRUnichar* aStopSymbolChars); + void SkipRuleSet(bool aInsideBraces); bool SkipAtRule(bool aInsideBlock); bool SkipDeclaration(bool aCheckForBraces); @@ -1505,7 +1508,7 @@ CSSParserImpl::SkipAtRule(bool aInsideBlock) { for (;;) { if (!GetToken(true)) { - REPORT_UNEXPECTED_EOF(PESkipAtRuleEOF); + REPORT_UNEXPECTED_EOF(PESkipAtRuleEOF2); return false; } if (eCSSToken_Symbol == mToken.mType) { @@ -2460,13 +2463,16 @@ bool CSSParserImpl::ParseSupportsCondition(bool& aConditionMet) { if (!GetToken(true)) { - REPORT_UNEXPECTED_EOF(PESupportsConditionStartEOF); + REPORT_UNEXPECTED_EOF(PESupportsConditionStartEOF2); return false; } UngetToken(); - if (mToken.IsSymbol('(')) { + if (mToken.IsSymbol('(') || + mToken.mType == eCSSToken_Function || + mToken.mType == eCSSToken_URL || + mToken.mType == eCSSToken_Bad_URL) { return ParseSupportsConditionInParens(aConditionMet) && ParseSupportsConditionTerms(aConditionMet); } @@ -2507,18 +2513,44 @@ CSSParserImpl::ParseSupportsConditionNegation(bool& aConditionMet) // supports_condition_in_parens // : '(' S* supports_condition_in_parens_inside_parens ')' S* +// | general_enclosed // ; bool CSSParserImpl::ParseSupportsConditionInParens(bool& aConditionMet) { - if (!ExpectSymbol('(', true)) { - REPORT_UNEXPECTED_TOKEN(PESupportsConditionExpectedOpenParen); + if (!GetToken(true)) { + REPORT_UNEXPECTED_EOF(PESupportsConditionInParensStartEOF); + return false; + } + + if (mToken.mType == eCSSToken_URL) { + aConditionMet = false; + return true; + } + + if (mToken.mType == eCSSToken_Function || + mToken.mType == eCSSToken_Bad_URL) { + if (!SkipUntil(')')) { + REPORT_UNEXPECTED_EOF(PESupportsConditionInParensEOF); + return false; + } + aConditionMet = false; + return true; + } + + if (!mToken.IsSymbol('(')) { + REPORT_UNEXPECTED_TOKEN(PESupportsConditionExpectedOpenParenOrFunction); + UngetToken(); return false; } if (!ParseSupportsConditionInParensInsideParens(aConditionMet)) { - SkipUntil(')'); - return false; + if (!SkipUntil(')')) { + REPORT_UNEXPECTED_EOF(PESupportsConditionInParensEOF); + return false; + } + aConditionMet = false; + return true; } if (!(ExpectSymbol(')', true))) { @@ -2539,7 +2571,6 @@ bool CSSParserImpl::ParseSupportsConditionInParensInsideParens(bool& aConditionMet) { if (!GetToken(true)) { - REPORT_UNEXPECTED_EOF(PESupportsConditionInParensStartEOF); return false; } @@ -2547,12 +2578,10 @@ CSSParserImpl::ParseSupportsConditionInParensInsideParens(bool& aConditionMet) if (!mToken.mIdent.LowerCaseEqualsLiteral("not")) { nsAutoString propertyName = mToken.mIdent; if (!ExpectSymbol(':', true)) { - REPORT_UNEXPECTED_TOKEN(PEParseDeclarationNoColon); return false; } if (ExpectSymbol(')', true)) { - REPORT_UNEXPECTED_P(PEValueParsingError, propertyName); UngetToken(); return false; } @@ -2643,7 +2672,7 @@ CSSParserImpl::ParseSupportsConditionTermsAfterOperator( } } -void +bool CSSParserImpl::SkipUntil(PRUnichar aStopSymbol) { nsCSSToken* tk = &mToken; @@ -2651,7 +2680,7 @@ CSSParserImpl::SkipUntil(PRUnichar aStopSymbol) stack.AppendElement(aStopSymbol); for (;;) { if (!GetToken(true)) { - break; + return false; } if (eCSSToken_Symbol == tk->mType) { PRUnichar symbol = tk->mSymbol; @@ -2659,7 +2688,7 @@ CSSParserImpl::SkipUntil(PRUnichar aStopSymbol) if (symbol == stack.ElementAt(stackTopIndex)) { stack.RemoveElementAt(stackTopIndex); if (stackTopIndex == 0) { - break; + return true; } // Just handle out-of-memory by parsing incorrectly. It's