(#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
parent 2205cd8c
Pipeline #105513 failed with stages
in 8 minutes and 46 seconds
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();
}
......@@ -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),
......
......@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment