WebKitCSSMatrix transformList with calculated relative length crashes Safari.
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Feb 2016 02:13:37 +0000 (02:13 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Feb 2016 02:13:37 +0000 (02:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153333
<rdar://problem/17198383>

Reviewed by Simon Fraser.

Source/WebCore:

WebKitCSSMatrix objects should fail to construct when not
using absolute lengths.

Updated existing tests:
- transforms/cssmatrix-2d-interface.xhtml
- transforms/cssmatrix-3d-interface.xhtml

* css/StyleBuilderConverter.h:
(WebCore::StyleBuilderConverter::convertTransform): Tell transformsForValue
that we don't require absolute lengths.
* css/TransformFunctions.cpp:
(WebCore::convertToFloatLength): Add an optional parameter that will
cause the conversion to fail if the primitive value has a non-absolute
length.
(WebCore::transformsForValue): Pass the parameter for requiring an
absolute length on to convertToFloatLength when necessary.
* css/TransformFunctions.h:
* css/WebKitCSSMatrix.cpp:
(WebCore::WebKitCSSMatrix::setMatrixValue): In this case we do
require all transform strings to have absolute lengths, not ones
that depend on the font size or are calculated.

LayoutTests:

Update existing tests to exercise the non-absolute lengths for translation
and perspective functions.

* transforms/cssmatrix-2d-interface-expected.txt:
* transforms/cssmatrix-2d-interface.xhtml:
* transforms/cssmatrix-3d-interface-expected.txt:
* transforms/cssmatrix-3d-interface.xhtml:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196738 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/transforms/cssmatrix-2d-interface-expected.txt
LayoutTests/transforms/cssmatrix-2d-interface.xhtml
LayoutTests/transforms/cssmatrix-3d-interface-expected.txt
LayoutTests/transforms/cssmatrix-3d-interface.xhtml
Source/WebCore/ChangeLog
Source/WebCore/css/StyleBuilderConverter.h
Source/WebCore/css/TransformFunctions.cpp
Source/WebCore/css/TransformFunctions.h
Source/WebCore/css/WebKitCSSMatrix.cpp

index 4b77cae..1c7b4fd 100644 (file)
@@ -1,3 +1,19 @@
+2016-02-17  Dean Jackson  <dino@apple.com>
+
+        WebKitCSSMatrix transformList with calculated relative length crashes Safari.
+        https://bugs.webkit.org/show_bug.cgi?id=153333
+        <rdar://problem/17198383>
+
+        Reviewed by Simon Fraser.
+
+        Update existing tests to exercise the non-absolute lengths for translation
+        and perspective functions.
+
+        * transforms/cssmatrix-2d-interface-expected.txt:
+        * transforms/cssmatrix-2d-interface.xhtml:
+        * transforms/cssmatrix-3d-interface-expected.txt:
+        * transforms/cssmatrix-3d-interface.xhtml:
+
 2016-02-17  Keith Miller  <keith_miller@apple.com>
 
         Spread operator should be allowed when not the first argument of parameter list
index e3850ea..57eedcf 100644 (file)
@@ -22,8 +22,17 @@ PASS parseFloat(a2[4]) is 0
 PASS parseFloat(a3[0]) is 0
 PASS a3[1] is ""
 
-Test bad input to string constructor
+Test bad input to constructor
 PASS new WebKitCSSMatrix("banana") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate(1em)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate(10px, 1em)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate(10px, calc(10px))") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate(1ex)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate(1%)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translatex(1em)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translatex(calc(10px))") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translatey(1em)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translatey(calc(10px))") threw exception Error: SyntaxError: DOM Exception 12.
 
 Test attributes on default matrix
 PASS m.a is 1
index 7ab4aac..ba92084 100644 (file)
@@ -40,8 +40,17 @@ shouldBe('parseFloat(a3[0])', '0');
 shouldBe('a3[1]', '""');
 
 debug("");
-debug("Test bad input to string constructor");
+debug("Test bad input to constructor");
 shouldThrow('new WebKitCSSMatrix("banana")');
+shouldThrow('new WebKitCSSMatrix("translate(1em)")');
+shouldThrow('new WebKitCSSMatrix("translate(10px, 1em)")');
+shouldThrow('new WebKitCSSMatrix("translate(10px, calc(10px))")');
+shouldThrow('new WebKitCSSMatrix("translate(1ex)")');
+shouldThrow('new WebKitCSSMatrix("translate(1%)")');
+shouldThrow('new WebKitCSSMatrix("translatex(1em)")');
+shouldThrow('new WebKitCSSMatrix("translatex(calc(10px))")');
+shouldThrow('new WebKitCSSMatrix("translatey(1em)")');
+shouldThrow('new WebKitCSSMatrix("translatey(calc(10px))")');
 
 debug("");
 debug("Test attributes on default matrix");
index 5beabfc..e1920e2 100644 (file)
@@ -28,8 +28,21 @@ PASS parseFloat(a2[14]) is 0
 PASS parseFloat(a3[0]) is 1
 PASS a3[1] is ""
 
-Test bad input to string constructor
+Test bad input to constructor
 PASS new WebKitCSSMatrix("banana") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate3d(1em, 0, 0)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate3d(10px, 1em, 0)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate3d(10px, 10px, calc(10px))") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate3d(calc(10px), 10px, 10px)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate3d(10px, calc(10px), 10px)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate3d(1ex, 0, 0)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translatez(1em)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translatez(calc(10px))") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("translate(1%, 0, 0)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("perspective(1em)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("perspective(calc(10px))") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("perspective(1ex)") threw exception Error: SyntaxError: DOM Exception 12.
+PASS new WebKitCSSMatrix("perspective(1%)") threw exception Error: SyntaxError: DOM Exception 12.
 
 Test attributes on default matrix
 PASS m.m11 is 1
index 4216ee0..0207ade 100644 (file)
@@ -59,8 +59,21 @@ shouldBe('parseFloat(a3[0])', '1');
 shouldBe('a3[1]', '""');
 
 debug("");
-debug("Test bad input to string constructor");
+debug("Test bad input to constructor");
 shouldThrow('new WebKitCSSMatrix("banana")');
+shouldThrow('new WebKitCSSMatrix("translate3d(1em, 0, 0)")');
+shouldThrow('new WebKitCSSMatrix("translate3d(10px, 1em, 0)")');
+shouldThrow('new WebKitCSSMatrix("translate3d(10px, 10px, calc(10px))")');
+shouldThrow('new WebKitCSSMatrix("translate3d(calc(10px), 10px, 10px)")');
+shouldThrow('new WebKitCSSMatrix("translate3d(10px, calc(10px), 10px)")');
+shouldThrow('new WebKitCSSMatrix("translate3d(1ex, 0, 0)")');
+shouldThrow('new WebKitCSSMatrix("translatez(1em)")');
+shouldThrow('new WebKitCSSMatrix("translatez(calc(10px))")');
+shouldThrow('new WebKitCSSMatrix("translate(1%, 0, 0)")');
+shouldThrow('new WebKitCSSMatrix("perspective(1em)")');
+shouldThrow('new WebKitCSSMatrix("perspective(calc(10px))")');
+shouldThrow('new WebKitCSSMatrix("perspective(1ex)")');
+shouldThrow('new WebKitCSSMatrix("perspective(1%)")');
 
 debug("");
 debug("Test attributes on default matrix");
index 8d6a87d..1d2bd80 100644 (file)
@@ -1,3 +1,33 @@
+2016-02-17  Dean Jackson  <dino@apple.com>
+
+        WebKitCSSMatrix transformList with calculated relative length crashes Safari.
+        https://bugs.webkit.org/show_bug.cgi?id=153333
+        <rdar://problem/17198383>
+
+        Reviewed by Simon Fraser.
+
+        WebKitCSSMatrix objects should fail to construct when not
+        using absolute lengths.
+
+        Updated existing tests:
+        - transforms/cssmatrix-2d-interface.xhtml
+        - transforms/cssmatrix-3d-interface.xhtml
+
+        * css/StyleBuilderConverter.h:
+        (WebCore::StyleBuilderConverter::convertTransform): Tell transformsForValue
+        that we don't require absolute lengths.
+        * css/TransformFunctions.cpp:
+        (WebCore::convertToFloatLength): Add an optional parameter that will
+        cause the conversion to fail if the primitive value has a non-absolute
+        length.
+        (WebCore::transformsForValue): Pass the parameter for requiring an
+        absolute length on to convertToFloatLength when necessary.
+        * css/TransformFunctions.h:
+        * css/WebKitCSSMatrix.cpp:
+        (WebCore::WebKitCSSMatrix::setMatrixValue): In this case we do
+        require all transform strings to have absolute lengths, not ones
+        that depend on the font size or are calculated.
+
 2016-02-17  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r196712.
index 1b084aa..e38d955 100644 (file)
@@ -355,7 +355,7 @@ inline PassRefPtr<StyleImage> StyleBuilderConverter::convertStyleImage(StyleReso
 inline TransformOperations StyleBuilderConverter::convertTransform(StyleResolver& styleResolver, CSSValue& value)
 {
     TransformOperations operations;
-    transformsForValue(value, styleResolver.state().cssToLengthConversionData(), operations);
+    transformsForValue(value, styleResolver.state().cssToLengthConversionData(), TransformConversion::Auto, operations);
     return operations;
 }
 
index 03be314..34a741f 100644 (file)
@@ -76,12 +76,14 @@ static TransformOperation::OperationType transformOperationType(WebKitCSSTransfo
     return TransformOperation::NONE;
 }
 
-Length convertToFloatLength(const CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData)
+Length convertToFloatLength(const CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData, TransformConversion transformConversion)
 {
-    return primitiveValue ? primitiveValue->convertToLength<FixedFloatConversion | PercentConversion | CalculatedConversion>(conversionData) : Length(Undefined);
+    if (transformConversion == TransformConversion::RequiresAbsoluteLength && !primitiveValue->isFontIndependentLength())
+        return Length(Undefined);
+    return primitiveValue ? primitiveValue->convertToLength<FixedFloatConversion | PercentConversion>(conversionData) : Length(Undefined);
 }
 
-bool transformsForValue(CSSValue& value, const CSSToLengthConversionData& conversionData, TransformOperations& outOperations)
+bool transformsForValue(CSSValue& value, const CSSToLengthConversionData& conversionData, TransformConversion transformConversion, TransformOperations& outOperations)
 {
     if (!is<CSSValueList>(value)) {
         outOperations.clear();
@@ -162,13 +164,13 @@ bool transformsForValue(CSSValue& value, const CSSToLengthConversionData& conver
             Length tx = Length(0, Fixed);
             Length ty = Length(0, Fixed);
             if (transformValue.operationType() == WebKitCSSTransformValue::TranslateYTransformOperation)
-                ty = convertToFloatLength(&firstValue, conversionData);
+                ty = convertToFloatLength(&firstValue, conversionData, transformConversion);
             else {
-                tx = convertToFloatLength(&firstValue, conversionData);
+                tx = convertToFloatLength(&firstValue, conversionData, transformConversion);
                 if (transformValue.operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) {
                     if (transformValue.length() > 1) {
                         CSSPrimitiveValue& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
-                        ty = convertToFloatLength(&secondValue, conversionData);
+                        ty = convertToFloatLength(&secondValue, conversionData, transformConversion);
                     }
                 }
             }
@@ -185,19 +187,19 @@ bool transformsForValue(CSSValue& value, const CSSToLengthConversionData& conver
             Length ty = Length(0, Fixed);
             Length tz = Length(0, Fixed);
             if (transformValue.operationType() == WebKitCSSTransformValue::TranslateZTransformOperation)
-                tz = convertToFloatLength(&firstValue, conversionData);
+                tz = convertToFloatLength(&firstValue, conversionData, transformConversion);
             else if (transformValue.operationType() == WebKitCSSTransformValue::TranslateYTransformOperation)
-                ty = convertToFloatLength(&firstValue, conversionData);
+                ty = convertToFloatLength(&firstValue, conversionData, transformConversion);
             else {
-                tx = convertToFloatLength(&firstValue, conversionData);
+                tx = convertToFloatLength(&firstValue, conversionData, transformConversion);
                 if (transformValue.operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) {
                     if (transformValue.length() > 2) {
                         CSSPrimitiveValue& thirdValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(2));
-                        tz = convertToFloatLength(&thirdValue, conversionData);
+                        tz = convertToFloatLength(&thirdValue, conversionData, transformConversion);
                     }
                     if (transformValue.length() > 1) {
                         CSSPrimitiveValue& secondValue = downcast<CSSPrimitiveValue>(*transformValue.itemWithoutBoundsCheck(1));
-                        ty = convertToFloatLength(&secondValue, conversionData);
+                        ty = convertToFloatLength(&secondValue, conversionData, transformConversion);
                     }
                 }
             }
@@ -300,7 +302,7 @@ bool transformsForValue(CSSValue& value, const CSSToLengthConversionData& conver
         case WebKitCSSTransformValue::PerspectiveTransformOperation: {
             Length p = Length(0, Fixed);
             if (firstValue.isLength())
-                p = convertToFloatLength(&firstValue, conversionData);
+                p = convertToFloatLength(&firstValue, conversionData, transformConversion);
             else {
                 // This is a quirk that should go away when 3d transforms are finalized.
                 double val = firstValue.getDoubleValue();
index 7e3d798..f432466 100644 (file)
@@ -42,8 +42,13 @@ class WebKitCSSTransformValue;
 
 struct Length;
 
-bool transformsForValue(CSSValue&, const CSSToLengthConversionData&, TransformOperations&);
-Length convertToFloatLength(const CSSPrimitiveValue*, const CSSToLengthConversionData&);
+enum class TransformConversion {
+    Auto,
+    RequiresAbsoluteLength
+};
+
+bool transformsForValue(CSSValue&, const CSSToLengthConversionData&, TransformConversion transformConversion, TransformOperations&);
+Length convertToFloatLength(const CSSPrimitiveValue*, const CSSToLengthConversionData&, TransformConversion transformConversion = TransformConversion::Auto);
 
 }
 #endif
index 46d3f3e..793113e 100644 (file)
@@ -67,7 +67,7 @@ void WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec)
             return;
 
         TransformOperations operations;
-        if (!transformsForValue(*value, CSSToLengthConversionData(), operations)) {
+        if (!transformsForValue(*value, CSSToLengthConversionData(), TransformConversion::RequiresAbsoluteLength, operations)) {
             ec = SYNTAX_ERR;
             return;
         }