Bug 1137984. When parsing attribute selectors, treat EOF as ']' any place ']' is allowed. r=dbaron

This commit is contained in:
Boris Zbarsky 2015-03-03 07:12:00 -05:00
parent 8c12d790ae
commit b9c0d6a241
5 changed files with 57 additions and 10 deletions

View File

@ -5326,18 +5326,29 @@ CSSParserImpl::ParseAttributeSelector(int32_t& aDataMask,
return eSelectorParsingStatus_Error;
}
bool gotEOF = false;
if (! GetToken(true)) { // premature EOF
// Treat this just like we saw a ']', but do still output the
// warning, similar to what ExpectSymbol does.
REPORT_UNEXPECTED_EOF(PEAttSelInnerEOF);
return eSelectorParsingStatus_Error;
gotEOF = true;
}
if ((eCSSToken_Symbol == mToken.mType) ||
if (gotEOF ||
(eCSSToken_Symbol == mToken.mType) ||
(eCSSToken_Includes == mToken.mType) ||
(eCSSToken_Dashmatch == mToken.mType) ||
(eCSSToken_Beginsmatch == mToken.mType) ||
(eCSSToken_Endsmatch == mToken.mType) ||
(eCSSToken_Containsmatch == mToken.mType)) {
uint8_t func;
if (eCSSToken_Includes == mToken.mType) {
// Important: Check the EOF/']' case first, since if gotEOF we
// don't want to be examining mToken.
if (gotEOF || ']' == mToken.mSymbol) {
aDataMask |= SEL_MASK_ATTRIB;
aSelector.AddAttribute(nameSpaceID, attr);
func = NS_ATTR_FUNC_SET;
}
else if (eCSSToken_Includes == mToken.mType) {
func = NS_ATTR_FUNC_INCLUDES;
}
else if (eCSSToken_Dashmatch == mToken.mType) {
@ -5352,11 +5363,6 @@ CSSParserImpl::ParseAttributeSelector(int32_t& aDataMask,
else if (eCSSToken_Containsmatch == mToken.mType) {
func = NS_ATTR_FUNC_CONTAINSMATCH;
}
else if (']' == mToken.mSymbol) {
aDataMask |= SEL_MASK_ATTRIB;
aSelector.AddAttribute(nameSpaceID, attr);
func = NS_ATTR_FUNC_SET;
}
else if ('=' == mToken.mSymbol) {
func = NS_ATTR_FUNC_EQUALS;
}
@ -5372,11 +5378,15 @@ CSSParserImpl::ParseAttributeSelector(int32_t& aDataMask,
}
if ((eCSSToken_Ident == mToken.mType) || (eCSSToken_String == mToken.mType)) {
nsAutoString value(mToken.mIdent);
bool gotClosingBracket;
if (! GetToken(true)) { // premature EOF
// Report a warning, but then treat it as a closing bracket.
REPORT_UNEXPECTED_EOF(PEAttSelCloseEOF);
return eSelectorParsingStatus_Error;
gotClosingBracket = true;
} else {
gotClosingBracket = mToken.IsSymbol(']');
}
if (mToken.IsSymbol(']')) {
if (gotClosingBracket) {
bool isCaseSensitive = true;
// For cases when this style sheet is applied to an HTML

View File

@ -262,3 +262,4 @@ support-files = bug732209-css.sjs
[test_animations_async_tests.html]
support-files = ../../reftests/fonts/Ahem.ttf
[test_setPropertyWithNull.html]
[test_attribute_selector_eof_behavior.html]

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test for EOF behavior of attribute selectors in selectors API</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
assert_equals(document.querySelector("[id"),
document.getElementById("log"),
"We only have one element with an id");
}, "']' should be implied if EOF after attribute name");
test(function() {
assert_equals(document.querySelector('[id="log"'),
document.getElementById("log"),
"We should find the element with id=log");
}, "']' should be implied if EOF after attribute value");
</script>

View File

@ -292,6 +292,9 @@ function run() {
test_unparseable_via_api(selector);
}
// [attr] selector
test_parseable("[attr]")
test_parseable_via_api("[attr");
// [attr= ] selector
test_parseable("[attr=\"x\"]");
@ -300,6 +303,7 @@ function run() {
test_parseable("[attr=\"\"]");
test_parseable("[attr='']");
test_parseable("[attr=\"foo bar\"]");
test_parseable_via_api("[attr=x");
test_balanced_unparseable("[attr=]");
test_balanced_unparseable("[attr=foo bar]");
@ -319,6 +323,7 @@ function run() {
test_parseable("[attr~=\"\"]");
test_parseable("[attr~='']");
test_parseable("[attr~=\"foo bar\"]");
test_parseable_via_api("[attr~=x");
test_balanced_unparseable("[attr~=]");
test_balanced_unparseable("[attr~=foo bar]");
@ -334,6 +339,7 @@ function run() {
test_parseable('[attr|="x"]');
test_parseable("[attr|='x']");
test_parseable('[attr|=x]');
test_parseable_via_api("[attr|=x");
test_parseable('[attr|=""]');
test_parseable("[attr|='']");
@ -354,6 +360,7 @@ function run() {
test_parseable("[attr$=\"\"]");
test_parseable("[attr$='']");
test_parseable("[attr$=\"foo bar\"]");
test_parseable_via_api("[attr$=x");
test_balanced_unparseable("[attr$=]");
test_balanced_unparseable("[attr$=foo bar]");
@ -365,6 +372,7 @@ function run() {
test_parseable("[attr^=\"\"]");
test_parseable("[attr^='']");
test_parseable("[attr^=\"foo bar\"]");
test_parseable_via_api("[attr^=x");
test_balanced_unparseable("[attr^=]");
test_balanced_unparseable("[attr^=foo bar]");
@ -376,6 +384,7 @@ function run() {
test_parseable("[attr*=\"\"]");
test_parseable("[attr*='']");
test_parseable("[attr*=\"foo bar\"]");
test_parseable_via_api("[attr^=x");
test_balanced_unparseable("[attr*=]");
test_balanced_unparseable("[attr*=foo bar]");

View File

@ -1,5 +1,8 @@
[syntax.html]
type: testharness
[[foo /* sanity check (invalid) */ with querySelector in standards mode]
expected: FAIL
[[foo=\'bar\' i\] in standards mode]
expected: FAIL
@ -120,6 +123,9 @@
[[*|foo=\'bar\' i\] with querySelector in standards mode]
expected: FAIL
[[foo /* sanity check (invalid) */ with querySelector in quirks mode]
expected: FAIL
[[foo=\'bar\' i\] in quirks mode]
expected: FAIL
@ -240,6 +246,9 @@
[[*|foo=\'bar\' i\] with querySelector in quirks mode]
expected: FAIL
[[foo /* sanity check (invalid) */ with querySelector in XML]
expected: FAIL
[[foo=\'bar\' i\] in XML]
expected: FAIL