Bug 1336769 - Make Angle constructors return a finite value.
It is possible to input an extra large angle, e.g. rotate(9.5e+307rad),
so we need to clamp it to avoid any assertion in Gecko.
MozReview-Commit-ID: 46afm6lUe16
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -8,16 +8,17 @@
use app_units::Au;
use cssparser::{self, Parser, Token};
use euclid::size::Size2D;
use parser::{ParserContext, Parse};
use self::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize};
use self::url::SpecifiedUrl;
use std::ascii::AsciiExt;
+use std::f32;
use std::f32::consts::PI;
use std::fmt;
use std::ops::Mul;
use style_traits::ToCss;
use super::{Auto, CSSFloat, CSSInteger, HasViewportPercentage, Either, None_};
use super::computed::{self, Context};
use super::computed::{Shadow as ComputedShadow, ToComputedValue};
@@ -227,18 +228,16 @@ pub fn parse_integer(input: &mut Parser)
}
}
_ => Err(())
}
}
#[allow(missing_docs)]
pub fn parse_number(input: &mut Parser) -> Result<Number, ()> {
- use std::f32;
-
match try!(input.next()) {
Token::Number(ref value) => {
Ok(Number {
value: value.value.min(f32::MAX).max(f32::MIN),
was_calc: false,
})
},
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
@@ -358,25 +357,25 @@ impl Angle {
pub fn zero() -> Self {
Self::from_radians(0.0)
}
#[inline]
#[allow(missing_docs)]
pub fn from_radians(r: f32) -> Self {
Angle {
- radians: r,
+ radians: r.min(f32::MAX).max(f32::MIN),
was_calc: false,
}
}
/// Returns an `Angle` parsed from a `calc()` expression.
pub fn from_calc(radians: CSSFloat) -> Self {
Angle {
- radians: radians,
+ radians: radians.min(f32::MAX).max(f32::MIN),
was_calc: true,
}
}
}
const RAD_PER_DEG: CSSFloat = PI / 180.0;
const RAD_PER_GRAD: CSSFloat = PI / 200.0;
const RAD_PER_TURN: CSSFloat = PI * 2.0;
@@ -401,20 +400,17 @@ impl Angle {
let radians = match_ignore_ascii_case! { unit,
"deg" => value * RAD_PER_DEG,
"grad" => value * RAD_PER_GRAD,
"turn" => value * RAD_PER_TURN,
"rad" => value,
_ => return Err(())
};
- Ok(Angle {
- radians: radians,
- was_calc: false,
- })
+ Ok(Angle::from_radians(radians))
}
}
#[allow(missing_docs)]
pub fn parse_border_radius(context: &ParserContext, input: &mut Parser) -> Result<BorderRadiusSize, ()> {
input.try(|i| BorderRadiusSize::parse(context, i)).or_else(|_| {
match_ignore_ascii_case! { &try!(input.expect_ident()),
"thin" => Ok(BorderRadiusSize::circle(