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 aa822db..787b26e 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
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 843f395..de4b7d1 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.
index bf7d522..baa32df 100644 (file)
@@ -69,6 +69,7 @@
 #include "Rect.h"
 #include "RenderTheme.h"
 #include "RuntimeEnabledFeatures.h"
+#include "SVGParserUtilities.h"
 #include "Settings.h"
 #include "ShadowValue.h"
 #include "StylePropertySet.h"
@@ -8967,8 +8968,29 @@ restartAfterComment:
             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;
index be0c219..71e2a39 100644 (file)
@@ -142,6 +142,13 @@ template <typename FloatType> static bool genericParseNumber(const UChar*& ptr,
     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);
index ad35a07..e1ba0c8 100644 (file)
@@ -33,6 +33,7 @@ namespace WebCore {
 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);