SVG CSS property types with <number> don't support exponents
authorkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jul 2012 15:42:40 +0000 (15:42 +0000)
committerkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jul 2012 15:42:40 +0000 (15:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=52542

Reviewed by Nikolas Zimmermann.

Source/WebCore:

Parse numbers in SVG presentation attributes with SVG parser to support scientific notations.
The SVG parser is already well tested and has some extra checks for edge like protection from
overflow.

The patch is based upon a patch of Bear Travis.

Test: svg/css/scientific-numbers.html

* css/CSSParser.cpp:
(WebCore::CSSParser::lex): Use SVG parser to parse numbers of SVG attributes.
* svg/SVGParserUtilities.cpp:
(WebCore::parseSVGNumber): Added accessor to call from CSSParser with double value.
(WebCore):
* svg/SVGParserUtilities.h:
(WebCore):

LayoutTests:

Test scientific number values on SVG presentation attributes.

* svg/css/scientific-numbers-expected.txt: Added.
* svg/css/scientific-numbers.html: Added.
* svg/css/script-tests/scientific-numbers.js: Added.

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

LayoutTests/ChangeLog
LayoutTests/svg/css/scientific-numbers-expected.txt [new file with mode: 0644]
LayoutTests/svg/css/scientific-numbers.html [new file with mode: 0644]
LayoutTests/svg/css/script-tests/scientific-numbers.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/svg/SVGParserUtilities.cpp
Source/WebCore/svg/SVGParserUtilities.h

index aa822db8ceda4e9cb36d7e0c2b276623f6a5b839..787b26ef4ff05b93372c678936d4ef977fc775f1 100644 (file)
@@ -1,3 +1,16 @@
+2012-07-18  Dirk Schulze  <krit@webkit.org>
+
+        SVG CSS property types with <number> don't support exponents
+        https://bugs.webkit.org/show_bug.cgi?id=52542
+
+        Reviewed by Nikolas Zimmermann.
+
+        Test scientific number values on SVG presentation attributes.
+
+        * svg/css/scientific-numbers-expected.txt: Added.
+        * svg/css/scientific-numbers.html: Added.
+        * svg/css/script-tests/scientific-numbers.js: Added.
+
 2012-07-18  Douglas Stockwell  <dstockwell@chromium.org>
 
         WebCore::StylePropertySet::addParsedProperties - crash
 2012-07-18  Douglas Stockwell  <dstockwell@chromium.org>
 
         WebCore::StylePropertySet::addParsedProperties - crash
diff --git a/LayoutTests/svg/css/scientific-numbers-expected.txt b/LayoutTests/svg/css/scientific-numbers-expected.txt
new file mode 100644 (file)
index 0000000..d4debbd
--- /dev/null
@@ -0,0 +1,115 @@
+Test scientific numbers on values for SVG presentation attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Test positive exponent values with 'e'
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+
+Test positive exponent values with 'E'
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+
+Test negative exponent values with 'e'
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+
+Test negative exponent values with 'E'
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+
+Test negative numbers with exponents
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "-50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "-50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "-50px"
+
+Test if value and 'em' still works
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50em"
+
+Test if value and 'ex' still works
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50ex"
+
+Trailing and leading whitespaces
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "50px"
+
+Test behavior on overflow
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+
+Invalid values
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS getComputedStyle(text).baselineShift is "baseline"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/css/scientific-numbers.html b/LayoutTests/svg/css/scientific-numbers.html
new file mode 100644 (file)
index 0000000..25573d4
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../svg/dynamic-updates/resources/SVGTestCase.js"></script>
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/scientific-numbers.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/svg/css/script-tests/scientific-numbers.js b/LayoutTests/svg/css/script-tests/scientific-numbers.js
new file mode 100644 (file)
index 0000000..4b7155f
--- /dev/null
@@ -0,0 +1,95 @@
+description("Test scientific numbers on <length> values for SVG presentation attributes.")
+createSVGTestCase();
+
+var text = createSVGElement("text");
+text.setAttribute("id", "text");
+text.setAttribute("x", "100px");
+text.setAttribute("y", "100px");
+rootSVGElement.appendChild(text);
+
+function test(valueString, expectedValue) {
+       // Reset baseline-shift to baseline.
+       text.setAttribute("baseline-shift", "baseline");
+       shouldBeEqualToString("getComputedStyle(text).baselineShift", "baseline");
+
+       // Run test
+       text.setAttribute("baseline-shift", valueString);
+       shouldBeEqualToString("getComputedStyle(text).baselineShift", expectedValue);
+}
+
+debug("");
+debug("Test positive exponent values with 'e'");
+test(".5e2", "50px");
+test("5e1", "50px");
+test("0.5e2", "50px");
+test("+.5e2", "50px");
+test("+5e1", "50px");
+test("+0.5e2", "50px");
+test(".5e+2", "50px");
+test("5e+1", "50px");
+test("0.5e+2", "50px");
+
+debug("");
+debug("Test positive exponent values with 'E'");
+test(".5E2", "50px");
+test("5E1", "50px");
+test("0.5E2", "50px");
+test("+.5E2", "50px");
+test("+5E1", "50px");
+test("+0.5E2", "50px");
+test(".5E+2", "50px");
+test("5E+1", "50px");
+test("0.5E+2", "50px");
+
+debug("");
+debug("Test negative exponent values with 'e'");
+test("5000e-2", "50px");
+test("500e-1", "50px");
+test("+5000e-2", "50px");
+test("+500e-1", "50px");
+test("+5000e-2px", "50px");
+test("+500e-1px", "50px");
+
+debug("");
+debug("Test negative exponent values with 'E'");
+test("5000E-2", "50px");
+test("500E-1", "50px");
+test("+5000E-2", "50px");
+test("+500E-1", "50px");
+test("+5000.00E-2px", "50px");
+test("+500E-1px", "50px");
+
+debug("");
+debug("Test negative numbers with exponents");
+test("-.5e2px", "-50px");
+test("-0.5e2px", "-50px");
+test("-500e-1px", "-50px");
+
+debug("");
+debug("Test if value and 'em' still works");
+test("50em", "50em");
+
+debug("");
+debug("Test if value and 'ex' still works");
+test("50ex", "50ex");
+
+debug("");
+debug("Trailing and leading whitespaces");
+test("       5e1", "50px");
+test("5e1      ", "50px");
+
+debug("");
+debug("Test behavior on overflow");
+test("2E+500", "baseline");
+test("-2E+500", "baseline");
+
+debug("");
+debug("Invalid values");
+test("50e0.0", "baseline");
+test("50 e0", "baseline");
+test("50e 0", "baseline");
+test("50.e0", "baseline");
+
+var successfullyParsed = true;
+
+completeTest();
\ No newline at end of file
index 843f395610b7a4d375ee2b55d192082db8fc6df4..de4b7d1e4d254dc86738e33888f809860262d664 100644 (file)
@@ -1,3 +1,27 @@
+2012-07-18  Dirk Schulze  <krit@webkit.org>
+
+        SVG CSS property types with <number> don't support exponents
+        https://bugs.webkit.org/show_bug.cgi?id=52542
+
+        Reviewed by Nikolas Zimmermann.
+
+        Parse numbers in SVG presentation attributes with SVG parser to support scientific notations.
+        The SVG parser is already well tested and has some extra checks for edge like protection from
+        overflow.
+        
+        The patch is based upon a patch of Bear Travis.
+
+        Test: svg/css/scientific-numbers.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::lex): Use SVG parser to parse numbers of SVG attributes.
+        * svg/SVGParserUtilities.cpp:
+        (WebCore::parseSVGNumber): Added accessor to call from CSSParser with double value.
+        (WebCore):
+        * svg/SVGParserUtilities.h:
+        (WebCore):
+
+
 2012-07-18  Pavel Feldman  <pfeldman@chromium.org>
 
         Web Inspector: beautify the paused in debugger message, make it configurable from the front-end.
 2012-07-18  Pavel Feldman  <pfeldman@chromium.org>
 
         Web Inspector: beautify the paused in debugger message, make it configurable from the front-end.
index bf7d52217ab4506a2b9c511779ad7423e7bb265c..baa32df3f320beb9a64eda9c84ba2b870c97afd4 100644 (file)
@@ -69,6 +69,7 @@
 #include "Rect.h"
 #include "RenderTheme.h"
 #include "RuntimeEnabledFeatures.h"
 #include "Rect.h"
 #include "RenderTheme.h"
 #include "RuntimeEnabledFeatures.h"
+#include "SVGParserUtilities.h"
 #include "Settings.h"
 #include "ShadowValue.h"
 #include "StylePropertySet.h"
 #include "Settings.h"
 #include "ShadowValue.h"
 #include "StylePropertySet.h"
@@ -8967,8 +8968,29 @@ restartAfterComment:
             break;
         }
 
             break;
         }
 
-        yylval->number = charactersToDouble(m_tokenStart, m_currentCharacter - m_tokenStart);
-
+#if ENABLE(SVG)
+        // Use SVG parser for numbers on SVG presentation attributes.
+        if (m_context.mode == SVGAttributeMode) {
+            // We need to take care of units like 'em' or 'ex'.
+            UChar* currentCharacter = m_currentCharacter;
+            if (isASCIIAlphaCaselessEqual(*currentCharacter, 'e')) {
+                ASSERT(currentCharacter - m_tokenStart > 0);
+                ++currentCharacter;
+                if (*currentCharacter == '-' || *currentCharacter == '+' || isASCIIDigit(*currentCharacter)) {
+                    ++currentCharacter;
+                    while (isASCIIDigit(*currentCharacter))
+                        ++currentCharacter;
+                    // Use FLOATTOKEN if the string contains exponents.
+                    dotSeen = true;
+                    m_currentCharacter = currentCharacter;
+                }
+            }
+            if (!parseSVGNumber(m_tokenStart, currentCharacter - m_tokenStart, yylval->number))
+                break;
+        } else
+#endif
+            yylval->number = charactersToDouble(m_tokenStart, m_currentCharacter - m_tokenStart);
         // Type of the function.
         if (isIdentifierStart()) {
             UChar* type = m_currentCharacter;
         // Type of the function.
         if (isIdentifierStart()) {
             UChar* type = m_currentCharacter;
index be0c2199b88ec3c3fbc893f16bc75320643a1d3f..71e2a39e2374548363b3238cb7210f3325a3955a 100644 (file)
@@ -142,6 +142,13 @@ template <typename FloatType> static bool genericParseNumber(const UChar*& ptr,
     return true;
 }
 
     return true;
 }
 
+bool parseSVGNumber(UChar*& begin, size_t length, double& number)
+{
+    const UChar* ptr = begin;
+    const UChar* end = ptr + length;
+    return genericParseNumber(ptr, end, number, false);
+}
+
 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip) 
 {
     return genericParseNumber(ptr, end, number, skip);
 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip) 
 {
     return genericParseNumber(ptr, end, number, skip);
index ad35a07ba3ab81dfd3ea42422729fa13fc16ae39..e1ba0c8c95003d0f73058ff94ffb33a75d1676fa 100644 (file)
@@ -33,6 +33,7 @@ namespace WebCore {
 class FloatRect;
 class SVGPointList;
 
 class FloatRect;
 class SVGPointList;
 
+bool parseSVGNumber(UChar*& ptr, size_t length, double& number);
 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip = true);
 bool parseNumberFromString(const String&, float& number, bool skip = true);
 bool parseNumberOptionalNumber(const String& s, float& h, float& v);
 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip = true);
 bool parseNumberFromString(const String&, float& number, bool skip = true);
 bool parseNumberOptionalNumber(const String& s, float& h, float& v);