From 73e903ad3cc78f7bfb4c2d3989e071c1494067c6 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 28 Aug 2017 17:20:17 -0700 Subject: [PATCH] Report unexpected attribute selector tokens (bug 1384216). --- components/selectors/parser.rs | 59 +++++++++++++------------------- ports/geckolib/error_reporter.rs | 5 +++ 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 6d15a741ca4..de87ae3cc4b 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -55,7 +55,7 @@ pub enum SelectorParseError<'i, T> { NegationSelectorComponentNotLocalName, EmptySelector, NonSimpleSelectorInNegation, - UnexpectedTokenInAttributeSelector, + UnexpectedTokenInAttributeSelector(Token<'i>), PseudoElementExpectedColon, PseudoElementExpectedIdent, UnsupportedPseudoClassOrElement(CowRcStr<'i>), @@ -1292,10 +1292,7 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse } } - let operator; - let value; - let never_matches; - match input.next() { + let operator = match input.next() { // [foo] Err(_) => { let local_name_lower = to_ascii_lowercase(&local_name).as_ref().into(); @@ -1317,43 +1314,33 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse } // [foo=bar] - Ok(&Token::Delim('=')) => { - value = input.expect_ident_or_string()?.clone(); - never_matches = false; - operator = AttrSelectorOperator::Equal; - } + Ok(&Token::Delim('=')) => AttrSelectorOperator::Equal, // [foo~=bar] - Ok(&Token::IncludeMatch) => { - value = input.expect_ident_or_string()?.clone(); - never_matches = value.is_empty() || value.contains(SELECTOR_WHITESPACE); - operator = AttrSelectorOperator::Includes; - } + Ok(&Token::IncludeMatch) => AttrSelectorOperator::Includes, // [foo|=bar] - Ok(&Token::DashMatch) => { - value = input.expect_ident_or_string()?.clone(); - never_matches = false; - operator = AttrSelectorOperator::DashMatch; - } + Ok(&Token::DashMatch) => AttrSelectorOperator::DashMatch, // [foo^=bar] - Ok(&Token::PrefixMatch) => { - value = input.expect_ident_or_string()?.clone(); - never_matches = value.is_empty(); - operator = AttrSelectorOperator::Prefix; - } + Ok(&Token::PrefixMatch) => AttrSelectorOperator::Prefix, // [foo*=bar] - Ok(&Token::SubstringMatch) => { - value = input.expect_ident_or_string()?.clone(); - never_matches = value.is_empty(); - operator = AttrSelectorOperator::Substring; - } + Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring, // [foo$=bar] - Ok(&Token::SuffixMatch) => { - value = input.expect_ident_or_string()?.clone(); - never_matches = value.is_empty(); - operator = AttrSelectorOperator::Suffix; + Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix, + Ok(t) => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector(t.clone()).into()) + }; + + let value = input.expect_ident_or_string()?.clone(); + let never_matches = match operator { + AttrSelectorOperator::Equal | + AttrSelectorOperator::DashMatch => false, + + AttrSelectorOperator::Includes => { + value.is_empty() || value.contains(SELECTOR_WHITESPACE) } - _ => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector.into()) - } + + AttrSelectorOperator::Prefix | + AttrSelectorOperator::Substring | + AttrSelectorOperator::Suffix => value.is_empty() + }; let mut case_sensitivity = parse_attribute_flags(input)?; diff --git a/ports/geckolib/error_reporter.rs b/ports/geckolib/error_reporter.rs index d487f649fef..f82c41c8562 100644 --- a/ports/geckolib/error_reporter.rs +++ b/ports/geckolib/error_reporter.rs @@ -250,6 +250,9 @@ fn extract_error_params<'a>(err: ParseError<'a>) -> Option> { PropertyDeclarationParseError::InvalidValue(property, Some(e))))) => (Some(ErrorString::Snippet(property.into())), Some(extract_value_error_param(e))), + CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(t)) => + (None, Some(ErrorString::UnexpectedToken(t))), + CssParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(p)) => (None, Some(ErrorString::Ident(p))), @@ -330,6 +333,8 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> { (b"PEAtNSUnexpected\0", Action::Nothing), ContextualParseError::InvalidRule(_, ref err) => { let prefix = match *err { + CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(_)) => + Some(&b"PEAttSelUnexpected\0"[..]), CssParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(_)) => Some(&b"PEPseudoSelUnknown\0"[..]), _ => None,