mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
style: Disallow all CSS-wide keywords in animation shorthand and counter-increment/counter-reset.
Fixes #15054.
This commit is contained in:
parent
9c0d8e44a0
commit
95356c62d1
3 changed files with 40 additions and 24 deletions
|
@ -816,16 +816,26 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
||||||
impl Parse for SpecifiedValue {
|
impl Parse for SpecifiedValue {
|
||||||
fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
|
fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<Self, ()> {
|
||||||
use cssparser::Token;
|
use cssparser::Token;
|
||||||
Ok(match input.next() {
|
use properties::CSSWideKeyword;
|
||||||
Ok(Token::Ident(ref value)) => SpecifiedValue(if value == "none" {
|
use std::ascii::AsciiExt;
|
||||||
// FIXME We may want to support `@keyframes ""` at some point.
|
|
||||||
atom!("")
|
let atom = match input.next() {
|
||||||
} else {
|
Ok(Token::Ident(ref value)) => {
|
||||||
Atom::from(&**value)
|
if CSSWideKeyword::from_ident(value).is_some() {
|
||||||
}),
|
// We allow any ident for the animation-name except one
|
||||||
Ok(Token::QuotedString(value)) => SpecifiedValue(Atom::from(&*value)),
|
// 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(()),
|
_ => return Err(()),
|
||||||
})
|
};
|
||||||
|
Ok(SpecifiedValue(atom))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
no_viewport_percentage!(SpecifiedValue);
|
no_viewport_percentage!(SpecifiedValue);
|
||||||
|
|
|
@ -134,11 +134,6 @@
|
||||||
computed_value::T::normal
|
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 | [ <string> | <counter> | open-quote | close-quote | no-open-quote |
|
// normal | none | [ <string> | <counter> | open-quote | close-quote | no-open-quote |
|
||||||
// no-close-quote ]+
|
// no-close-quote ]+
|
||||||
// TODO: <uri>, attr(<identifier>)
|
// TODO: <uri>, attr(<identifier>)
|
||||||
|
@ -335,6 +330,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_common(context: &ParserContext, default_value: i32, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse_common(context: &ParserContext, default_value: i32, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(SpecifiedValue(Vec::new()))
|
return Ok(SpecifiedValue(Vec::new()))
|
||||||
}
|
}
|
||||||
|
@ -342,13 +339,16 @@
|
||||||
let mut counters = Vec::new();
|
let mut counters = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
let counter_name = match input.next() {
|
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(()),
|
Ok(_) => return Err(()),
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
};
|
};
|
||||||
if content::counter_name_is_illegal(&counter_name) {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
let counter_delta = input.try(|input| specified::parse_integer(context, input))
|
let counter_delta = input.try(|input| specified::parse_integer(context, input))
|
||||||
.unwrap_or(specified::Integer::new(default_value));
|
.unwrap_or(specified::Integer::new(default_value));
|
||||||
counters.push((counter_name, counter_delta))
|
counters.push((counter_name, counter_delta))
|
||||||
|
|
|
@ -390,6 +390,17 @@ impl CSSWideKeyword {
|
||||||
CSSWideKeyword::Unset => "unset",
|
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<Self> {
|
||||||
|
match_ignore_ascii_case! { ident,
|
||||||
|
"initial" => Some(CSSWideKeyword::Initial),
|
||||||
|
"inherit" => Some(CSSWideKeyword::Inherit),
|
||||||
|
"unset" => Some(CSSWideKeyword::Unset),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for CSSWideKeyword {
|
impl ToCss for CSSWideKeyword {
|
||||||
|
@ -402,12 +413,7 @@ impl Parse for CSSWideKeyword {
|
||||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
input.expect_exhausted()?;
|
input.expect_exhausted()?;
|
||||||
match_ignore_ascii_case! { &ident,
|
CSSWideKeyword::from_ident(&ident).ok_or(())
|
||||||
"initial" => Ok(CSSWideKeyword::Initial),
|
|
||||||
"inherit" => Ok(CSSWideKeyword::Inherit),
|
|
||||||
"unset" => Ok(CSSWideKeyword::Unset),
|
|
||||||
_ => Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue