From 95356c62d19245154b052efd9f7a485fd88d7fc4 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 13 Apr 2017 10:28:14 +0800 Subject: [PATCH] style: Disallow all CSS-wide keywords in animation shorthand and counter-increment/counter-reset. Fixes #15054. --- .../style/properties/longhand/box.mako.rs | 28 +++++++++++++------ .../properties/longhand/counters.mako.rs | 18 ++++++------ .../style/properties/properties.mako.rs | 18 ++++++++---- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index ff6ec0b102f..f0ad19713d9 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -816,16 +816,26 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", impl Parse for SpecifiedValue { fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result { use cssparser::Token; - Ok(match input.next() { - Ok(Token::Ident(ref value)) => SpecifiedValue(if value == "none" { - // FIXME We may want to support `@keyframes ""` at some point. - atom!("") - } else { - Atom::from(&**value) - }), - Ok(Token::QuotedString(value)) => SpecifiedValue(Atom::from(&*value)), + use properties::CSSWideKeyword; + use std::ascii::AsciiExt; + + let atom = match input.next() { + Ok(Token::Ident(ref value)) => { + if CSSWideKeyword::from_ident(value).is_some() { + // We allow any ident for the animation-name except one + // of the CSS-wide keywords. + return Err(()); + } else if value.eq_ignore_ascii_case("none") { + // FIXME We may want to support `@keyframes ""` at some point. + atom!("") + } else { + Atom::from(&**value) + } + } + Ok(Token::QuotedString(value)) => Atom::from(&*value), _ => return Err(()), - }) + }; + Ok(SpecifiedValue(atom)) } } no_viewport_percentage!(SpecifiedValue); diff --git a/components/style/properties/longhand/counters.mako.rs b/components/style/properties/longhand/counters.mako.rs index f9a5aacd3a0..6d0c26808da 100644 --- a/components/style/properties/longhand/counters.mako.rs +++ b/components/style/properties/longhand/counters.mako.rs @@ -134,11 +134,6 @@ computed_value::T::normal } - pub fn counter_name_is_illegal(name: &str) -> bool { - name.eq_ignore_ascii_case("none") || name.eq_ignore_ascii_case("inherit") || - name.eq_ignore_ascii_case("initial") - } - // normal | none | [ | | open-quote | close-quote | no-open-quote | // no-close-quote ]+ // TODO: , attr() @@ -335,6 +330,8 @@ } pub fn parse_common(context: &ParserContext, default_value: i32, input: &mut Parser) -> Result { + use std::ascii::AsciiExt; + if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(SpecifiedValue(Vec::new())) } @@ -342,13 +339,16 @@ let mut counters = Vec::new(); loop { let counter_name = match input.next() { - Ok(Token::Ident(ident)) => (*ident).to_owned(), + Ok(Token::Ident(ident)) => { + if CSSWideKeyword::from_ident(&ident).is_some() || ident.eq_ignore_ascii_case("none") { + // Don't accept CSS-wide keywords or none as the counter name. + return Err(()); + } + (*ident).to_owned() + } Ok(_) => return Err(()), Err(_) => break, }; - if content::counter_name_is_illegal(&counter_name) { - return Err(()) - } let counter_delta = input.try(|input| specified::parse_integer(context, input)) .unwrap_or(specified::Integer::new(default_value)); counters.push((counter_name, counter_delta)) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index e8582d407da..15a75c8d02d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -390,6 +390,17 @@ impl CSSWideKeyword { CSSWideKeyword::Unset => "unset", } } + + /// Takes the result of cssparser::Parser::expect_ident() and converts it + /// to a CSSWideKeyword. + pub fn from_ident<'i>(ident: &Cow<'i, str>) -> Option { + match_ignore_ascii_case! { ident, + "initial" => Some(CSSWideKeyword::Initial), + "inherit" => Some(CSSWideKeyword::Inherit), + "unset" => Some(CSSWideKeyword::Unset), + _ => None + } + } } impl ToCss for CSSWideKeyword { @@ -402,12 +413,7 @@ impl Parse for CSSWideKeyword { fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let ident = input.expect_ident()?; input.expect_exhausted()?; - match_ignore_ascii_case! { &ident, - "initial" => Ok(CSSWideKeyword::Initial), - "inherit" => Ok(CSSWideKeyword::Inherit), - "unset" => Ok(CSSWideKeyword::Unset), - _ => Err(()) - } + CSSWideKeyword::from_ident(&ident).ok_or(()) } }