aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/selectors/parser.rs54
-rw-r--r--ports/geckolib/error_reporter.rs25
2 files changed, 55 insertions, 24 deletions
diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs
index de87ae3cc4b..08ad801781d 100644
--- a/components/selectors/parser.rs
+++ b/components/selectors/parser.rs
@@ -49,7 +49,7 @@ fn to_ascii_lowercase(s: &str) -> Cow<str> {
#[derive(Clone, Debug, PartialEq)]
pub enum SelectorParseError<'i, T> {
PseudoElementInComplexSelector,
- NoQualifiedNameInAttributeSelector,
+ NoQualifiedNameInAttributeSelector(Token<'i>),
TooManyCompoundSelectorComponentsInNegation,
NegationSelectorComponentNotNamespace,
NegationSelectorComponentNotLocalName,
@@ -61,6 +61,9 @@ pub enum SelectorParseError<'i, T> {
UnsupportedPseudoClassOrElement(CowRcStr<'i>),
UnexpectedIdent(CowRcStr<'i>),
ExpectedNamespace(CowRcStr<'i>),
+ ExpectedBarInAttr(Token<'i>),
+ BadValueInAttr(Token<'i>),
+ InvalidQualNameInAttr(Token<'i>),
Custom(T),
}
@@ -1107,8 +1110,8 @@ fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<
S: Push<Component<Impl>>,
{
match parse_qualified_name(parser, input, /* in_attr_selector = */ false)? {
- None => Ok(false),
- Some((namespace, local_name)) => {
+ OptionalQName::None(_) => Ok(false),
+ OptionalQName::Some(namespace, local_name) => {
match namespace {
QNamePrefix::ImplicitAnyNamespace => {}
QNamePrefix::ImplicitDefaultNamespace(url) => {
@@ -1176,13 +1179,19 @@ enum QNamePrefix<Impl: SelectorImpl> {
ExplicitNamespace(Impl::NamespacePrefix, Impl::NamespaceUrl), // `prefix|foo`
}
+enum OptionalQName<'i, Impl: SelectorImpl> {
+ Some(QNamePrefix<Impl>, Option<CowRcStr<'i>>),
+ None(Token<'i>),
+}
+
/// * `Err(())`: Invalid selector, abort
-/// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed.
-/// * `Ok(Some((namespace, local_name)))`: `None` for the local name means a `*` universal selector
+/// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed,
+/// but the token is still returned.
+/// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector
fn parse_qualified_name<'i, 't, P, E, Impl>
(parser: &P, input: &mut CssParser<'i, 't>,
in_attr_selector: bool)
- -> Result<Option<(QNamePrefix<Impl>, Option<CowRcStr<'i>>)>,
+ -> Result<OptionalQName<'i, Impl>,
ParseError<'i, SelectorParseError<'i, E>>>
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
{
@@ -1191,17 +1200,18 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
Some(url) => QNamePrefix::ImplicitDefaultNamespace(url),
None => QNamePrefix::ImplicitAnyNamespace,
};
- Ok(Some((namespace, local_name)))
+ Ok(OptionalQName::Some(namespace, local_name))
};
let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| {
match input.next_including_whitespace() {
Ok(&Token::Delim('*')) if !in_attr_selector => {
- Ok(Some((namespace, None)))
+ Ok(OptionalQName::Some(namespace, None))
},
Ok(&Token::Ident(ref local_name)) => {
- Ok(Some((namespace, Some(local_name.clone()))))
+ Ok(OptionalQName::Some(namespace, Some(local_name.clone())))
},
+ Ok(t) if in_attr_selector => Err(SelectorParseError::InvalidQualNameInAttr(t.clone()).into()),
Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))),
Err(e) => Err(ParseError::Basic(e)),
}
@@ -1223,7 +1233,7 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
_ => {
input.reset(&after_ident);
if in_attr_selector {
- Ok(Some((QNamePrefix::ImplicitNoNamespace, Some(value))))
+ Ok(OptionalQName::Some(QNamePrefix::ImplicitNoNamespace, Some(value)))
} else {
default_namespace(Some(value))
}
@@ -1241,7 +1251,7 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
input.reset(&after_star);
if in_attr_selector {
match result {
- Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t))),
+ Ok(t) => Err(SelectorParseError::ExpectedBarInAttr(t).into()),
Err(e) => Err(ParseError::Basic(e)),
}
} else {
@@ -1253,9 +1263,13 @@ fn parse_qualified_name<'i, 't, P, E, Impl>
Ok(Token::Delim('|')) => {
explicit_namespace(input, QNamePrefix::ExplicitNoNamespace)
}
- _ => {
+ Ok(t) => {
input.reset(&start);
- Ok(None)
+ Ok(OptionalQName::None(t))
+ }
+ Err(e) => {
+ input.reset(&start);
+ Err(e.into())
}
}
}
@@ -1269,9 +1283,10 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
let namespace;
let local_name;
match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? {
- None => return Err(ParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector)),
- Some((_, None)) => unreachable!(),
- Some((ns, Some(ln))) => {
+ OptionalQName::None(t) =>
+ return Err(ParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(t))),
+ OptionalQName::Some(_, None) => unreachable!(),
+ OptionalQName::Some(ns, Some(ln)) => {
local_name = ln;
namespace = match ns {
QNamePrefix::ImplicitNoNamespace |
@@ -1328,7 +1343,12 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse
Ok(t) => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector(t.clone()).into())
};
- let value = input.expect_ident_or_string()?.clone();
+ let value = match input.expect_ident_or_string() {
+ Ok(t) => t.clone(),
+ Err(BasicParseError::UnexpectedToken(t)) =>
+ return Err(SelectorParseError::BadValueInAttr(t.clone()).into()),
+ Err(e) => return Err(e.into()),
+ };
let never_matches = match operator {
AttrSelectorOperator::Equal |
AttrSelectorOperator::DashMatch => false,
diff --git a/ports/geckolib/error_reporter.rs b/ports/geckolib/error_reporter.rs
index f82c41c8562..0518750271b 100644
--- a/ports/geckolib/error_reporter.rs
+++ b/ports/geckolib/error_reporter.rs
@@ -214,9 +214,6 @@ fn extract_error_param<'a>(err: ParseError<'a>) -> Option<ErrorString<'a>> {
CssParseError::Custom(SelectorParseError::UnexpectedIdent(ident)) =>
ErrorString::Ident(ident),
- CssParseError::Custom(SelectorParseError::ExpectedNamespace(namespace)) =>
- ErrorString::Ident(namespace),
-
CssParseError::Custom(SelectorParseError::Custom(
StyleParseError::PropertyDeclaration(
PropertyDeclarationParseError::UnknownProperty(property)))) =>
@@ -250,9 +247,16 @@ fn extract_error_params<'a>(err: ParseError<'a>) -> Option<ErrorParams<'a>> {
PropertyDeclarationParseError::InvalidValue(property, Some(e))))) =>
(Some(ErrorString::Snippet(property.into())), Some(extract_value_error_param(e))),
- CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(t)) =>
+ CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(t)) |
+ CssParseError::Custom(SelectorParseError::BadValueInAttr(t)) |
+ CssParseError::Custom(SelectorParseError::ExpectedBarInAttr(t)) |
+ CssParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(t)) |
+ CssParseError::Custom(SelectorParseError::InvalidQualNameInAttr(t)) =>
(None, Some(ErrorString::UnexpectedToken(t))),
+ CssParseError::Custom(SelectorParseError::ExpectedNamespace(namespace)) =>
+ (None, Some(ErrorString::Ident(namespace))),
+
CssParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(p)) =>
(None, Some(ErrorString::Ident(p))),
@@ -325,9 +329,6 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
ContextualParseError::UnsupportedKeyframePropertyDeclaration(..) =>
(b"PEBadSelectorKeyframeRuleIgnored\0", Action::Nothing),
ContextualParseError::InvalidRule(
- _, CssParseError::Custom(SelectorParseError::ExpectedNamespace(_))) =>
- (b"PEUnknownNamespacePrefix\0", Action::Nothing),
- ContextualParseError::InvalidRule(
_, CssParseError::Custom(SelectorParseError::Custom(
StyleParseError::UnexpectedTokenWithinNamespace(_)))) =>
(b"PEAtNSUnexpected\0", Action::Nothing),
@@ -335,6 +336,16 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
let prefix = match *err {
CssParseError::Custom(SelectorParseError::UnexpectedTokenInAttributeSelector(_)) =>
Some(&b"PEAttSelUnexpected\0"[..]),
+ CssParseError::Custom(SelectorParseError::ExpectedBarInAttr(_)) =>
+ Some(&b"PEAttSelNoBar\0"[..]),
+ CssParseError::Custom(SelectorParseError::BadValueInAttr(_)) =>
+ Some(&b"PEAttSelBadValue\0"[..]),
+ CssParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(_)) =>
+ Some(&b"PEAttributeNameOrNamespaceExpected\0"[..]),
+ CssParseError::Custom(SelectorParseError::InvalidQualNameInAttr(_)) =>
+ Some(&b"PEAttributeNameExpected\0"[..]),
+ CssParseError::Custom(SelectorParseError::ExpectedNamespace(_)) =>
+ Some(&b"PEUnknownNamespacePrefix\0"[..]),
CssParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(_)) =>
Some(&b"PEPseudoSelUnknown\0"[..]),
_ => None,