Bug 1336769 - Make Angle constructors return a finite value. draft
authorBoris Chiou <boris.chiou@gmail.com>
Wed, 29 Mar 2017 15:05:44 +0800
changeset 552919 e36fcfea6d27426ea492543a4fa42049964b2f64
parent 552691 272ce6c2572164f5f6a9fba2a980ba9ccf50770c
child 552920 857aa912878796592e6bead709b8f4e54c909e56
push id51509
push userbmo:boris.chiou@gmail.com
push dateWed, 29 Mar 2017 07:44:48 +0000
bugs1336769
milestone55.0a1
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
servo/components/style/values/specified/mod.rs
--- 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(