servo: Merge #14347 - Only allow border-image-outset to use non-negative numbers (from jcdyer:cdyer/len-parsing); r=Wafflespeanut
authorJ. Cliff Dyer <jcd@sdf.org>
Wed, 23 Nov 2016 12:30:41 -0800
changeset 340212 0e8508d060455b04712106c7db14562146fc2e4d
parent 340211 3d20e0dcc018725671497b8743d509b94c983f3a
child 340213 d334362e9defefe12985d668d13f9968cac8f824
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWafflespeanut
servo: Merge #14347 - Only allow border-image-outset to use non-negative numbers (from jcdyer:cdyer/len-parsing); r=Wafflespeanut Restricts border-image-outline to only allow positive values. Fixes #14295 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #14295. <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 210b1be1d093adf3a4fb4d4360c6e016676f34be
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/values/specified/length.rs
servo/tests/unit/style/parsing/border.rs
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -237,17 +237,17 @@
                                 ToComputedValue::from_computed_value(&computed.2),
                                 ToComputedValue::from_computed_value(&computed.3)])
         }
     }
 
     pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
         let mut values = vec![];
         for _ in 0..4 {
-            let value = input.try(|input| LengthOrNumber::parse(input));
+            let value = input.try(|input| LengthOrNumber::parse_non_negative(input));
             match value {
                 Ok(val) => values.push(val),
                 Err(_) => break,
             }
         }
 
         if values.len() > 0 {
             Ok(SpecifiedValue(values))
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -1004,8 +1004,18 @@ impl Parse for LengthOrPercentageOrAutoO
                 Ok(LengthOrPercentageOrAutoOrContent::Calc(calc))
             },
             _ => Err(())
         }
     }
 }
 
 pub type LengthOrNumber = Either<Length, Number>;
+
+impl LengthOrNumber {
+    pub fn parse_non_negative(input: &mut Parser) -> Result<Self, ()> {
+        if let Ok(v) = input.try(|i| Length::parse_non_negative(i)) {
+            Ok(Either::First(v))
+        } else {
+            Number::parse_non_negative(input).map(Either::Second)
+        }
+    }
+}
--- a/servo/tests/unit/style/parsing/border.rs
+++ b/servo/tests/unit/style/parsing/border.rs
@@ -7,82 +7,100 @@ use media_queries::CSSErrorReporterTest;
 use servo_url::ServoUrl;
 use style::parser::ParserContext;
 use style::properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
 use style::properties::longhands::{border_image_source, border_image_width};
 use style::properties::shorthands::border_image;
 use style::stylesheets::Origin;
 
 #[test]
-fn border_image_shorhand_should_parse_when_all_properties_specified() {
+fn border_image_shorthand_should_parse_when_all_properties_specified() {
     let url = ServoUrl::parse("http://localhost").unwrap();
     let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
     let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / 20px 40px / 10px \
                                  round stretch");
     let result = border_image::parse_value(&context, &mut parser).unwrap();
 
     assert_eq!(result.border_image_source.unwrap(),
                parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
     assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill"));
     assert_eq!(result.border_image_width.unwrap(), parse_longhand!(border_image_width, "20px 40px"));
     assert_eq!(result.border_image_outset.unwrap(), parse_longhand!(border_image_outset, "10px"));
     assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round stretch"));
 }
 
 #[test]
-fn border_image_shorhand_should_parse_without_width() {
+fn border_image_shorthand_should_parse_without_width() {
     let url = ServoUrl::parse("http://localhost").unwrap();
     let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
     let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / / 10px round stretch");
     let result = border_image::parse_value(&context, &mut parser).unwrap();
 
     assert_eq!(result.border_image_source.unwrap(),
                parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
     assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill"));
     assert_eq!(result.border_image_outset.unwrap(), parse_longhand!(border_image_outset, "10px"));
     assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round stretch"));
     assert_eq!(result.border_image_width.unwrap(), border_image_width::get_initial_specified_value());
 }
 
 #[test]
-fn border_image_shorhand_should_parse_without_outset() {
+fn border_image_shorthand_should_parse_without_outset() {
     let url = ServoUrl::parse("http://localhost").unwrap();
     let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
     let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / 20px 40px round");
     let result = border_image::parse_value(&context, &mut parser).unwrap();
 
     assert_eq!(result.border_image_source.unwrap(),
                parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
     assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill"));
     assert_eq!(result.border_image_width.unwrap(), parse_longhand!(border_image_width, "20px 40px"));
     assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round"));
     assert_eq!(result.border_image_outset.unwrap(), border_image_outset::get_initial_specified_value());
 }
 
 #[test]
-fn border_image_shorhand_should_parse_without_width_or_outset() {
+fn border_image_shorthand_should_parse_without_width_or_outset() {
     let url = ServoUrl::parse("http://localhost").unwrap();
     let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
     let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill round");
     let result = border_image::parse_value(&context, &mut parser).unwrap();
 
     assert_eq!(result.border_image_source.unwrap(),
                parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
     assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill"));
     assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round"));
     assert_eq!(result.border_image_width.unwrap(), border_image_width::get_initial_specified_value());
     assert_eq!(result.border_image_outset.unwrap(), border_image_outset::get_initial_specified_value());
 }
 
 #[test]
-fn border_image_shorhand_should_parse_with_just_source() {
+fn border_image_shorthand_should_parse_with_just_source() {
     let url = ServoUrl::parse("http://localhost").unwrap();
     let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
     let mut parser = Parser::new("linear-gradient(red, blue)");
     let result = border_image::parse_value(&context, &mut parser).unwrap();
 
     assert_eq!(result.border_image_source.unwrap(),
                parse_longhand!(border_image_source, "linear-gradient(red, blue)"));
     assert_eq!(result.border_image_slice.unwrap(), border_image_slice::get_initial_specified_value());
     assert_eq!(result.border_image_width.unwrap(), border_image_width::get_initial_specified_value());
     assert_eq!(result.border_image_outset.unwrap(), border_image_outset::get_initial_specified_value());
     assert_eq!(result.border_image_repeat.unwrap(), border_image_repeat::get_initial_specified_value());
 }
+
+#[test]
+fn border_image_outset_should_error_on_negative_length() {
+    let url = ServoUrl::parse("http://localhost").unwrap();
+    let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
+    let mut parser = Parser::new("-1em");
+    let result = border_image_outset::parse(&context, &mut parser);
+    assert_eq!(result, Err(()));
+}
+
+#[test]
+fn border_image_outset_should_error_on_negative_number() {
+    let url = ServoUrl::parse("http://localhost").unwrap();
+    let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
+    let mut parser = Parser::new("-15");
+    let result = border_image_outset::parse(&context, &mut parser);
+    assert_eq!(result, Err(()));
+}