mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Report an error for invalid CSS color values (bug 1381143).
This commit is contained in:
parent
cf5602e84f
commit
4b736354c4
6 changed files with 154 additions and 82 deletions
|
@ -2881,10 +2881,15 @@ extern "C" {
|
|||
param:
|
||||
*const ::std::os::raw::c_char,
|
||||
paramLen: u32,
|
||||
prefix:
|
||||
*const ::std::os::raw::c_char,
|
||||
prefixParam:
|
||||
*const ::std::os::raw::c_char,
|
||||
prefixParamLen: u32,
|
||||
suffix:
|
||||
*const ::std::os::raw::c_char,
|
||||
source:
|
||||
*const ::std::os::raw::c_char,
|
||||
sourceLen: u32, lineNumber: u32,
|
||||
colNumber: u32, aURI: *mut nsIURI,
|
||||
followup:
|
||||
*const ::std::os::raw::c_char);
|
||||
colNumber: u32);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ use selectors::parser::SelectorParseError;
|
|||
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
||||
use shared_lock::StylesheetGuards;
|
||||
use style_traits::{PARSING_MODE_DEFAULT, HasViewportPercentage, ToCss, ParseError};
|
||||
use style_traits::{PropertyDeclarationParseError, StyleParseError};
|
||||
use style_traits::{PropertyDeclarationParseError, StyleParseError, ValueParseError};
|
||||
use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData};
|
||||
#[cfg(feature = "servo")] use values::Either;
|
||||
use values::generics::text::LineHeight;
|
||||
|
@ -1489,7 +1489,8 @@ impl PropertyDeclaration {
|
|||
Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword),
|
||||
Err(_) => match ::custom_properties::SpecifiedValue::parse(context, input) {
|
||||
Ok(value) => DeclaredValueOwned::Value(value),
|
||||
Err(_) => return Err(PropertyDeclarationParseError::InvalidValue(name.to_string().into())),
|
||||
Err(e) => return Err(PropertyDeclarationParseError::InvalidValue(name.to_string().into(),
|
||||
ValueParseError::from_parse_error(e))),
|
||||
}
|
||||
};
|
||||
declarations.push(PropertyDeclaration::Custom(name, value));
|
||||
|
@ -1502,13 +1503,14 @@ impl PropertyDeclaration {
|
|||
input.look_for_var_functions();
|
||||
let start = input.position();
|
||||
input.parse_entirely(|input| id.parse_value(context, input))
|
||||
.or_else(|_| {
|
||||
.or_else(|err| {
|
||||
while let Ok(_) = input.next() {} // Look for var() after the error.
|
||||
if input.seen_var_functions() {
|
||||
input.reset(start);
|
||||
let (first_token_type, css) =
|
||||
::custom_properties::parse_non_custom_with_var(input).map_err(|_| {
|
||||
PropertyDeclarationParseError::InvalidValue(id.name().into())
|
||||
::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
|
||||
PropertyDeclarationParseError::InvalidValue(id.name().into(),
|
||||
ValueParseError::from_parse_error(e))
|
||||
})?;
|
||||
Ok(PropertyDeclaration::WithVariables(id, Arc::new(UnparsedValue {
|
||||
css: css.into_owned(),
|
||||
|
@ -1517,7 +1519,8 @@ impl PropertyDeclaration {
|
|||
from_shorthand: None,
|
||||
})))
|
||||
} else {
|
||||
Err(PropertyDeclarationParseError::InvalidValue(id.name().into()))
|
||||
Err(PropertyDeclarationParseError::InvalidValue(id.name().into(),
|
||||
ValueParseError::from_parse_error(err)))
|
||||
}
|
||||
})
|
||||
}).map(|declaration| {
|
||||
|
@ -1539,13 +1542,14 @@ impl PropertyDeclaration {
|
|||
let start = input.position();
|
||||
// Not using parse_entirely here: each ${shorthand.ident}::parse_into function
|
||||
// needs to do so *before* pushing to `declarations`.
|
||||
id.parse_into(declarations, context, input).or_else(|_| {
|
||||
id.parse_into(declarations, context, input).or_else(|err| {
|
||||
while let Ok(_) = input.next() {} // Look for var() after the error.
|
||||
if input.seen_var_functions() {
|
||||
input.reset(start);
|
||||
let (first_token_type, css) =
|
||||
::custom_properties::parse_non_custom_with_var(input).map_err(|_| {
|
||||
PropertyDeclarationParseError::InvalidValue(id.name().into())
|
||||
::custom_properties::parse_non_custom_with_var(input).map_err(|e| {
|
||||
PropertyDeclarationParseError::InvalidValue(id.name().into(),
|
||||
ValueParseError::from_parse_error(e))
|
||||
})?;
|
||||
let unparsed = Arc::new(UnparsedValue {
|
||||
css: css.into_owned(),
|
||||
|
@ -1564,7 +1568,8 @@ impl PropertyDeclaration {
|
|||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(PropertyDeclarationParseError::InvalidValue(id.name().into()))
|
||||
Err(PropertyDeclarationParseError::InvalidValue(id.name().into(),
|
||||
ValueParseError::from_parse_error(err)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use parser::{ParserContext, Parse};
|
|||
use properties::longhands::color::SystemColor;
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
use style_traits::{ToCss, ParseError, StyleParseError};
|
||||
use style_traits::{ToCss, ParseError, StyleParseError, ValueParseError};
|
||||
use super::AllowQuirks;
|
||||
use values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
||||
|
||||
|
@ -76,24 +76,28 @@ impl Parse for Color {
|
|||
_ => None,
|
||||
};
|
||||
input.reset(start_position);
|
||||
if let Ok(value) = input.try(CSSParserColor::parse) {
|
||||
Ok(match value {
|
||||
CSSParserColor::CurrentColor => Color::CurrentColor,
|
||||
CSSParserColor::RGBA(rgba) => Color::Numeric {
|
||||
parsed: rgba,
|
||||
authored: authored,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
#[cfg(feature = "gecko")] {
|
||||
if let Ok(system) = input.try(SystemColor::parse) {
|
||||
Ok(Color::System(system))
|
||||
} else {
|
||||
gecko::SpecialColorKeyword::parse(input).map(Color::Special)
|
||||
match input.try(CSSParserColor::parse) {
|
||||
Ok(value) =>
|
||||
Ok(match value {
|
||||
CSSParserColor::CurrentColor => Color::CurrentColor,
|
||||
CSSParserColor::RGBA(rgba) => Color::Numeric {
|
||||
parsed: rgba,
|
||||
authored: authored,
|
||||
},
|
||||
}),
|
||||
Err(e) => {
|
||||
#[cfg(feature = "gecko")] {
|
||||
if let Ok(system) = input.try(SystemColor::parse) {
|
||||
return Ok(Color::System(system));
|
||||
} else if let Ok(c) = gecko::SpecialColorKeyword::parse(input) {
|
||||
return Ok(Color::Special(c));
|
||||
}
|
||||
}
|
||||
match e {
|
||||
BasicParseError::UnexpectedToken(t) =>
|
||||
Err(StyleParseError::ValueError(ValueParseError::InvalidColor(t)).into()),
|
||||
e => Err(e.into())
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "gecko"))] {
|
||||
Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,11 +165,13 @@ impl Color {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
input.try(|i| Self::parse(context, i)).or_else(|_| {
|
||||
input.try(|i| Self::parse(context, i)).or_else(|e| {
|
||||
if !allow_quirks.allowed(context.quirks_mode) {
|
||||
return Err(StyleParseError::UnspecifiedError.into());
|
||||
return Err(e);
|
||||
}
|
||||
Color::parse_quirky_color(input).map(|rgba| Color::rgba(rgba))
|
||||
Color::parse_quirky_color(input)
|
||||
.map(|rgba| Color::rgba(rgba))
|
||||
.map_err(|_| e)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -124,10 +124,31 @@ pub enum StyleParseError<'i> {
|
|||
UnspecifiedError,
|
||||
/// An unexpected token was found within a namespace rule.
|
||||
UnexpectedTokenWithinNamespace(Token<'i>),
|
||||
/// An error was encountered while parsing a property value.
|
||||
ValueError(ValueParseError<'i>),
|
||||
}
|
||||
|
||||
/// Specific errors that can be encountered while parsing property values.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ValueParseError<'i> {
|
||||
/// An invalid token was encountered while parsing a color value.
|
||||
InvalidColor(Token<'i>),
|
||||
}
|
||||
|
||||
impl<'i> ValueParseError<'i> {
|
||||
/// Attempt to extract a ValueParseError value from a ParseError.
|
||||
pub fn from_parse_error(this: ParseError<'i>) -> Option<ValueParseError<'i>> {
|
||||
match this {
|
||||
cssparser::ParseError::Custom(
|
||||
SelectorParseError::Custom(
|
||||
StyleParseError::ValueError(e))) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of parsing a property declaration.
|
||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub enum PropertyDeclarationParseError<'i> {
|
||||
/// The property declaration was for an unknown property.
|
||||
UnknownProperty(CowRcStr<'i>),
|
||||
|
@ -136,7 +157,7 @@ pub enum PropertyDeclarationParseError<'i> {
|
|||
/// The property declaration was for a disabled experimental property.
|
||||
ExperimentalProperty,
|
||||
/// The property declaration contained an invalid value.
|
||||
InvalidValue(CowRcStr<'i>),
|
||||
InvalidValue(CowRcStr<'i>, Option<ValueParseError<'i>>),
|
||||
/// The declaration contained an animation property, and we were parsing
|
||||
/// this as a keyframe block (so that property should be ignored).
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue