[librsvg] (#496): Ensure all lengths and angles parse as finite numbers



commit 6475ffbde97e8546a843fa7aa5a85d94293f92e1
Author: Federico Mena Quintero <federico gnome org>
Date:   Sat Aug 17 13:54:56 2019 -0500

    (#496): Ensure all lengths and angles parse as finite numbers
    
    The example crasher, found via fuzzing, yields an <svg width="BIGNUM">
    which rust-cssparser puts as an Infinity in an f32 value.  This ends
    up being in a non-invertible Cairo matrix, which panics.
    
    We need to catch all such cases early, so we run all parsed numbers
    through finite_f32() right as they come out of rust-cssparser.
    
    Thanks to Bastien Orivel for the fuzz-testing runs!
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/496

 librsvg_crate/tests/bugs.rs  | 30 ++++++++++++++++++++++++++++++
 rsvg_internals/src/angle.rs  |  6 +++---
 rsvg_internals/src/length.rs |  8 ++++----
 3 files changed, 37 insertions(+), 7 deletions(-)
---
diff --git a/librsvg_crate/tests/bugs.rs b/librsvg_crate/tests/bugs.rs
new file mode 100644
index 00000000..7b755d8a
--- /dev/null
+++ b/librsvg_crate/tests/bugs.rs
@@ -0,0 +1,30 @@
+use cairo;
+
+mod utils;
+
+use self::utils::{load_svg, render_document, SurfaceSize};
+
+// https://gitlab.gnome.org/GNOME/librsvg/issues/496
+#[test]
+fn inf_width() {
+    let svg = load_svg(
+        br#"<?xml version="1.0" encoding="UTF-8"?>
+<svg s="Pg" 
width="1001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
 heiNht=" 00">
+ [l<g mask="url(sHaf:ax-fwiw0\inside\ax-ide\ax-flow#o0" styli="fility:!.5;">>
+  </g>
+</svg>"#,
+    );
+
+    let _output_surf = render_document(
+        &svg,
+        SurfaceSize(150, 150),
+        |cr| cr.translate(50.0, 50.0),
+        cairo::Rectangle {
+            x: 0.0,
+            y: 0.0,
+            width: 50.0,
+            height: 50.0,
+        },
+    )
+    .unwrap();
+}
diff --git a/rsvg_internals/src/angle.rs b/rsvg_internals/src/angle.rs
index 4dbd064f..4078b2cc 100644
--- a/rsvg_internals/src/angle.rs
+++ b/rsvg_internals/src/angle.rs
@@ -3,7 +3,7 @@ use std::f64::consts::*;
 use cssparser::{Parser, Token};
 
 use crate::error::ValueErrorKind;
-use crate::parsers::{Parse, ParseError};
+use crate::parsers::{Parse, ParseError, finite_f32};
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct Angle(f64);
@@ -69,12 +69,12 @@ impl Parse for Angle {
                 .map_err(|_| ParseError::new("expected angle"))?;
 
             match *token {
-                Token::Number { value, .. } => Angle::from_degrees(value as f64),
+                Token::Number { value, .. } => Angle::from_degrees(finite_f32(value)? as f64),
 
                 Token::Dimension {
                     value, ref unit, ..
                 } => {
-                    let value = f64::from(value);
+                    let value = f64::from(finite_f32(value)?);
 
                     match unit.as_ref() {
                         "deg" => Angle::from_degrees(value),
diff --git a/rsvg_internals/src/length.rs b/rsvg_internals/src/length.rs
index 61dce675..80b86b8b 100644
--- a/rsvg_internals/src/length.rs
+++ b/rsvg_internals/src/length.rs
@@ -4,7 +4,7 @@ use std::f64::consts::*;
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
 use crate::parsers::Parse;
-use crate::parsers::ParseError;
+use crate::parsers::{ParseError, finite_f32};
 use crate::properties::ComputedValues;
 
 pub type RsvgLength = Length;
@@ -234,19 +234,19 @@ impl Length {
 
             match *token {
                 Token::Number { value, .. } => Length {
-                    length: f64::from(value),
+                    length: f64::from(finite_f32(value)?),
                     unit: LengthUnit::Px,
                 },
 
                 Token::Percentage { unit_value, .. } => Length {
-                    length: f64::from(unit_value),
+                    length: f64::from(finite_f32(unit_value)?),
                     unit: LengthUnit::Percent,
                 },
 
                 Token::Dimension {
                     value, ref unit, ..
                 } => {
-                    let value = f64::from(value);
+                    let value = f64::from(finite_f32(value)?);
 
                     match unit.as_ref() {
                         "px" => Length {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]