Report an error for invalid CSS color values (bug 1381143).

This commit is contained in:
Josh Matthews 2017-07-31 15:34:29 -04:00
parent cf5602e84f
commit 4b736354c4
6 changed files with 154 additions and 82 deletions

View file

@ -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);
}

View file

@ -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)))
}
})
}

View file

@ -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)
})
}