LayoutTests:
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jan 2007 15:33:28 +0000 (15:33 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jan 2007 15:33:28 +0000 (15:33 +0000)
        Reviewed by Maciej.

        - test for bugs found by code inspection in the SVGPreserveAspectRatio parser

        * svg/dom/preserve-aspect-ratio-parser-expected.txt: Added.
        * svg/dom/preserve-aspect-ratio-parser.html: Added.

WebCore:

        Reviewed by Maciej.

        - fix http://bugs.webkit.org/show_bug.cgi?id=12365
          Reproducible crash in WebCore::SVGPreserveAspectRatio::parsePreserveAspectRatio
          in svg/W3C-SVG-1.1/animate-elem-40-t.svg under guard malloc
        - fix bug where the parser accepts "meet" or "slice" as an entire string
        - fix bug where "slice" is ignored if the old alignment was "none"
          even if the newly-parsed alignment is something other than "none", and
          "slice" is not ignored if the old alignment was not "none", but the
          newly-parsed alignment is "none"
        - optimize to only call notifyAttributeChange if the attribute actually changed

        Test: svg/dom/preserve-aspect-ratio-parser-test.html

        * ksvg2/svg/SVGPreserveAspectRatio.cpp:
        (WebCore::checkString): Added an overload for using char* constants which is
        much simpler than the old one, and almost as fast.
        (WebCore::SVGPreserveAspectRatio::parsePreserveAspectRatio): Fail if there's no
        more text after "defer". Fail if there's neither "none" nor an x/y specified.
        Check that there's more text before looking at the "m" and "s" for "meet" and
        "slice". Merged the failure and success cases. Only call notifyAttributeChange
        if something changed.

        I think all the "optimized" code where we check the first character before
        calling checkString isn't really helpful, but I decided to leave it as-is
        for now.

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

LayoutTests/ChangeLog
LayoutTests/svg/dom/preserve-aspect-ratio-parser-expected.txt [new file with mode: 0644]
LayoutTests/svg/dom/preserve-aspect-ratio-parser.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/ksvg2/svg/SVGPreserveAspectRatio.cpp

index 077a6bd5cfc7a2115ca0fae4bf0942ee3cb9f635..f3aad5f6a44d932e4155e9a6763b321f38283df5 100644 (file)
@@ -1,3 +1,12 @@
+2007-01-25  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - test for bugs found by code inspection in the SVGPreserveAspectRatio parser
+
+        * svg/dom/preserve-aspect-ratio-parser-expected.txt: Added.
+        * svg/dom/preserve-aspect-ratio-parser.html: Added.
+
 2007-01-25  Rob Buis  <buis@kde.org>
 
         Reviewed by Maciej.
diff --git a/LayoutTests/svg/dom/preserve-aspect-ratio-parser-expected.txt b/LayoutTests/svg/dom/preserve-aspect-ratio-parser-expected.txt
new file mode 100644 (file)
index 0000000..d70384c
--- /dev/null
@@ -0,0 +1,357 @@
+This tests the parser for preserve aspect ratio attribute values.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Test string: 'none'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMidYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 3
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMaxYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 4
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMid'
+PASS imageElement.preserveAspectRatio.baseVal.align is 5
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMidYMid'
+PASS imageElement.preserveAspectRatio.baseVal.align is 6
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMaxYMid'
+PASS imageElement.preserveAspectRatio.baseVal.align is 7
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMax'
+PASS imageElement.preserveAspectRatio.baseVal.align is 8
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMidYMax'
+PASS imageElement.preserveAspectRatio.baseVal.align is 9
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMaxYMax'
+PASS imageElement.preserveAspectRatio.baseVal.align is 10
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMidYMin meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 3
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMaxYMin meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 4
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMid meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 5
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMidYMid meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 6
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMaxYMid meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 7
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMax meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 8
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMidYMax meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 9
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMaxYMax meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 10
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMidYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 3
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMaxYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 4
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMinYMid slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 5
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMidYMid slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 6
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMaxYMid slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 7
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMinYMax slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 8
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMidYMax slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 9
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMaxYMax slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 10
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMinYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMidYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 3
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMaxYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 4
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMinYMid'
+PASS imageElement.preserveAspectRatio.baseVal.align is 5
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMidYMid'
+PASS imageElement.preserveAspectRatio.baseVal.align is 6
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMaxYMid'
+PASS imageElement.preserveAspectRatio.baseVal.align is 7
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMinYMax'
+PASS imageElement.preserveAspectRatio.baseVal.align is 8
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMidYMax'
+PASS imageElement.preserveAspectRatio.baseVal.align is 9
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMaxYMax'
+PASS imageElement.preserveAspectRatio.baseVal.align is 10
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMinYMin meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMidYMin meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 3
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMaxYMin meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 4
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMinYMid meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 5
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMidYMid meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 6
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMaxYMid meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 7
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMinYMax meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 8
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMidYMax meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 9
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMaxYMax meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 10
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer xMinYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMidYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 3
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMaxYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 4
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMinYMid slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 5
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMidYMid slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 6
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMaxYMid slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 7
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMinYMax slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 8
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMidYMax slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 9
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'defer xMaxYMax slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 10
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Tests for some whitespace cases.
+
+Test string: ' xMinYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: ' xMinYMin '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: '         xMinYMin        '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin
+'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin
+'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMinslice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMinYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMinYMinslice '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMinYMin        slice        '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: ' xMinYMinslice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: ' xMinYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: ' xMinYMinslice '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: '        xMinYMin        slice        '
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Tests for bug where "slice" parsing was based on the old value rather than the parsed value.
+
+Test string: 'none'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 2
+
+Test string: 'xMinYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'none slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 2
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Strings that fail to parse, and hence parse as "none".
+
+Test string: ''
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'defer'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'meet'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xminymin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'refer xMinYMin slice'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin defer'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'slice xMinYMin'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+Test string: 'xMinYMin¬†'
+PASS imageElement.preserveAspectRatio.baseVal.align is 1
+PASS imageElement.preserveAspectRatio.baseVal.meetOrSlice is 1
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/dom/preserve-aspect-ratio-parser.html b/LayoutTests/svg/dom/preserve-aspect-ratio-parser.html
new file mode 100644 (file)
index 0000000..9e0d1f3
--- /dev/null
@@ -0,0 +1,136 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("This tests the parser for preserve aspect ratio attribute values.");
+
+var imageElement = document.createElementNS("http://www.w3.org/2000/svg", "image");
+
+function parsePreserveAspectRatio(string, alignValue, meetOrSliceValue)
+{
+    imageElement.setAttributeNS(null, "preserveAspectRatio", string);
+    debug("Test string: '" + string + "'");
+    shouldBe("imageElement.preserveAspectRatio.baseVal.align", "" + alignValue);
+    shouldBe("imageElement.preserveAspectRatio.baseVal.meetOrSlice", "" + meetOrSliceValue);
+    debug("");
+}
+
+parsePreserveAspectRatio("none", 1, 1);
+
+parsePreserveAspectRatio("xMinYMin", 2, 1);
+parsePreserveAspectRatio("xMidYMin", 3, 1);
+parsePreserveAspectRatio("xMaxYMin", 4, 1);
+parsePreserveAspectRatio("xMinYMid", 5, 1);
+parsePreserveAspectRatio("xMidYMid", 6, 1);
+parsePreserveAspectRatio("xMaxYMid", 7, 1);
+parsePreserveAspectRatio("xMinYMax", 8, 1);
+parsePreserveAspectRatio("xMidYMax", 9, 1);
+parsePreserveAspectRatio("xMaxYMax", 10, 1);
+
+parsePreserveAspectRatio("xMinYMin meet", 2, 1);
+parsePreserveAspectRatio("xMidYMin meet", 3, 1);
+parsePreserveAspectRatio("xMaxYMin meet", 4, 1);
+parsePreserveAspectRatio("xMinYMid meet", 5, 1);
+parsePreserveAspectRatio("xMidYMid meet", 6, 1);
+parsePreserveAspectRatio("xMaxYMid meet", 7, 1);
+parsePreserveAspectRatio("xMinYMax meet", 8, 1);
+parsePreserveAspectRatio("xMidYMax meet", 9, 1);
+parsePreserveAspectRatio("xMaxYMax meet", 10, 1);
+
+parsePreserveAspectRatio("xMinYMin slice", 2, 2);
+parsePreserveAspectRatio("xMidYMin slice", 3, 2);
+parsePreserveAspectRatio("xMaxYMin slice", 4, 2);
+parsePreserveAspectRatio("xMinYMid slice", 5, 2);
+parsePreserveAspectRatio("xMidYMid slice", 6, 2);
+parsePreserveAspectRatio("xMaxYMid slice", 7, 2);
+parsePreserveAspectRatio("xMinYMax slice", 8, 2);
+parsePreserveAspectRatio("xMidYMax slice", 9, 2);
+parsePreserveAspectRatio("xMaxYMax slice", 10, 2);
+
+parsePreserveAspectRatio("defer xMinYMin", 2, 1);
+parsePreserveAspectRatio("defer xMidYMin", 3, 1);
+parsePreserveAspectRatio("defer xMaxYMin", 4, 1);
+parsePreserveAspectRatio("defer xMinYMid", 5, 1);
+parsePreserveAspectRatio("defer xMidYMid", 6, 1);
+parsePreserveAspectRatio("defer xMaxYMid", 7, 1);
+parsePreserveAspectRatio("defer xMinYMax", 8, 1);
+parsePreserveAspectRatio("defer xMidYMax", 9, 1);
+parsePreserveAspectRatio("defer xMaxYMax", 10, 1);
+
+parsePreserveAspectRatio("defer xMinYMin meet", 2, 1);
+parsePreserveAspectRatio("defer xMidYMin meet", 3, 1);
+parsePreserveAspectRatio("defer xMaxYMin meet", 4, 1);
+parsePreserveAspectRatio("defer xMinYMid meet", 5, 1);
+parsePreserveAspectRatio("defer xMidYMid meet", 6, 1);
+parsePreserveAspectRatio("defer xMaxYMid meet", 7, 1);
+parsePreserveAspectRatio("defer xMinYMax meet", 8, 1);
+parsePreserveAspectRatio("defer xMidYMax meet", 9, 1);
+parsePreserveAspectRatio("defer xMaxYMax meet", 10, 1);
+
+parsePreserveAspectRatio("defer xMinYMin slice", 2, 2);
+parsePreserveAspectRatio("defer xMidYMin slice", 3, 2);
+parsePreserveAspectRatio("defer xMaxYMin slice", 4, 2);
+parsePreserveAspectRatio("defer xMinYMid slice", 5, 2);
+parsePreserveAspectRatio("defer xMidYMid slice", 6, 2);
+parsePreserveAspectRatio("defer xMaxYMid slice", 7, 2);
+parsePreserveAspectRatio("defer xMinYMax slice", 8, 2);
+parsePreserveAspectRatio("defer xMidYMax slice", 9, 2);
+parsePreserveAspectRatio("defer xMaxYMax slice", 10, 2);
+
+debug('Tests for some whitespace cases.');
+debug('');
+
+parsePreserveAspectRatio(" xMinYMin", 2, 1);
+parsePreserveAspectRatio("xMinYMin ", 2, 1);
+parsePreserveAspectRatio(" xMinYMin ", 2, 1);
+parsePreserveAspectRatio("         xMinYMin        ", 2, 1);
+parsePreserveAspectRatio("xMinYMin" + String.fromCharCode(9), 2, 1);
+parsePreserveAspectRatio("xMinYMin" + String.fromCharCode(10), 2, 1);
+parsePreserveAspectRatio("xMinYMin" + String.fromCharCode(13), 2, 1);
+
+parsePreserveAspectRatio("xMinYMinslice", 2, 2);
+parsePreserveAspectRatio("xMinYMin slice", 2, 2);
+parsePreserveAspectRatio("xMinYMinslice ", 2, 2);
+parsePreserveAspectRatio("xMinYMin        slice        ", 2, 2);
+parsePreserveAspectRatio(" xMinYMinslice", 2, 2);
+parsePreserveAspectRatio(" xMinYMin slice", 2, 2);
+parsePreserveAspectRatio(" xMinYMinslice ", 2, 2);
+parsePreserveAspectRatio("        xMinYMin        slice        ", 2, 2);
+
+debug('Tests for bug where "slice" parsing was based on the old value rather than the parsed value.');
+debug('');
+
+parsePreserveAspectRatio("none", 1, 1);
+parsePreserveAspectRatio("xMinYMin slice", 2, 2);
+
+parsePreserveAspectRatio("xMinYMin", 2, 1);
+parsePreserveAspectRatio("none slice", 1, 1);
+
+parsePreserveAspectRatio("xMinYMin", 2, 1);
+parsePreserveAspectRatio("slice", 1, 1);
+
+debug('Strings that fail to parse, and hence parse as "none".');
+debug('');
+
+parsePreserveAspectRatio("", 1, 1);
+parsePreserveAspectRatio("defer", 1, 1);
+parsePreserveAspectRatio("meet", 1, 1);
+parsePreserveAspectRatio("slice", 1, 1);
+parsePreserveAspectRatio("xminymin", 1, 1);
+parsePreserveAspectRatio("refer xMinYMin slice", 1, 1);
+parsePreserveAspectRatio("xMinYMin defer", 1, 1);
+parsePreserveAspectRatio("slice xMinYMin", 1, 1);
+parsePreserveAspectRatio("xMinYMin" + String.fromCharCode(0xa0), 1, 1);
+
+successfullyParsed = true;
+
+</script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index f82c839ed6e09ec122573b7a8b45b2666ae2a006..b0ada1b45ab94b0d686b240d097a278db3239dc1 100644 (file)
@@ -1,3 +1,32 @@
+2007-01-25  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=12365
+          Reproducible crash in WebCore::SVGPreserveAspectRatio::parsePreserveAspectRatio
+          in svg/W3C-SVG-1.1/animate-elem-40-t.svg under guard malloc
+        - fix bug where the parser accepts "meet" or "slice" as an entire string
+        - fix bug where "slice" is ignored if the old alignment was "none"
+          even if the newly-parsed alignment is something other than "none", and
+          "slice" is not ignored if the old alignment was not "none", but the
+          newly-parsed alignment is "none"
+        - optimize to only call notifyAttributeChange if the attribute actually changed
+
+        Test: svg/dom/preserve-aspect-ratio-parser-test.html
+
+        * ksvg2/svg/SVGPreserveAspectRatio.cpp:
+        (WebCore::checkString): Added an overload for using char* constants which is
+        much simpler than the old one, and almost as fast.
+        (WebCore::SVGPreserveAspectRatio::parsePreserveAspectRatio): Fail if there's no
+        more text after "defer". Fail if there's neither "none" nor an x/y specified.
+        Check that there's more text before looking at the "m" and "s" for "meet" and
+        "slice". Merged the failure and success cases. Only call notifyAttributeChange
+        if something changed.
+
+        I think all the "optimized" code where we check the first character before
+        calling checkString isn't really helpful, but I decided to leave it as-is
+        for now.
+
 2007-01-25  Lars Knoll <lars@trolltech.com>
 
         Reviewed by Zack
index f64bd0e63ae541188949d7c5a1d491a7a383d33b..5ead0e5852d86c74cf9d2ebfce94cdbfba587bbc 100644 (file)
 
 namespace WebCore {
 
+static bool checkString(const UChar*& ptr, const UChar*& end, const char* str)
+{
+    int length = strlen(str);
+    if (end - ptr < length)
+        return false;
+    for (int i = 0; i < length; ++i)
+        if (ptr[i] != str[i])
+            return false;
+    ptr += length;
+    return true;
+}
+
 SVGPreserveAspectRatio::SVGPreserveAspectRatio(const SVGStyledElement* context)
     : Shared<SVGPreserveAspectRatio>()
     , m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
@@ -44,6 +56,7 @@ SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
 void SVGPreserveAspectRatio::setAlign(unsigned short align)
 {
     m_align = align;
+    // FIXME: Do we need a call to notifyAttributeChange here?
 }
 
 unsigned short SVGPreserveAspectRatio::align() const
@@ -54,6 +67,7 @@ unsigned short SVGPreserveAspectRatio::align() const
 void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice)
 {
     m_meetOrSlice = meetOrSlice;
+    // FIXME: Do we need a call to notifyAttributeChange here?
 }
 
 unsigned short SVGPreserveAspectRatio::meetOrSlice() const
@@ -61,23 +75,8 @@ unsigned short SVGPreserveAspectRatio::meetOrSlice() const
     return m_meetOrSlice;
 }
 
-static const UChar deferDesc[] =  {'d', 'e', 'f', 'e', 'r'};
-static const UChar noneDesc[] =  {'n', 'o', 'n', 'e'};
-static const UChar meetDesc[] =  {'m', 'e', 'e', 't'};
-static const UChar sliceDesc[] =  {'s', 'l', 'i', 'c', 'e'};
-static const UChar xMinYMinDesc[] =  {'x', 'M', 'i', 'n', 'Y', 'M', 'i', 'n'};
-static const UChar xMinYMidDesc[] =  {'x', 'M', 'i', 'n', 'Y', 'M', 'i', 'd'};
-static const UChar xMinYMaxDesc[] =  {'x', 'M', 'i', 'n', 'Y', 'M', 'a', 'x'};
-static const UChar xMidYMinDesc[] =  {'x', 'M', 'i', 'd', 'Y', 'M', 'i', 'n'};
-static const UChar xMidYMidDesc[] =  {'x', 'M', 'i', 'd', 'Y', 'M', 'i', 'd'};
-static const UChar xMidYMaxDesc[] =  {'x', 'M', 'i', 'd', 'Y', 'M', 'a', 'x'};
-static const UChar xMaxYMinDesc[] =  {'x', 'M', 'a', 'x', 'Y', 'M', 'i', 'n'};
-static const UChar xMaxYMidDesc[] =  {'x', 'M', 'a', 'x', 'Y', 'M', 'i', 'd'};
-static const UChar xMaxYMaxDesc[] =  {'x', 'M', 'a', 'x', 'Y', 'M', 'a', 'x'};
-
 void SVGPreserveAspectRatio::parsePreserveAspectRatio(const String& string)
 {
-    // Spec: set the defaults
     SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_NONE;
     SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET;
 
@@ -88,16 +87,17 @@ void SVGPreserveAspectRatio::parsePreserveAspectRatio(const String& string)
         goto bail_out;
 
     if (*currParam == 'd') {
-        if (!checkString(currParam, end, deferDesc, sizeof(deferDesc) / sizeof(UChar)))
+        if (!checkString(currParam, end, "defer"))
+            goto bail_out;
+        // FIXME: We just ignore the "defer" here.
+        if (!skipOptionalSpaces(currParam, end))
             goto bail_out;
-        skipOptionalSpaces(currParam, end);
     }
 
     if (*currParam == 'n') {
-        if (!checkString(currParam, end, noneDesc, sizeof(noneDesc) / sizeof(UChar)))
+        if (!checkString(currParam, end, "none"))
             goto bail_out;
         skipOptionalSpaces(currParam, end);
-        align = SVG_PRESERVEASPECTRATIO_NONE;
     } else if (*currParam == 'x') {
         if ((end - currParam) < 8)
             goto bail_out;
@@ -146,35 +146,34 @@ void SVGPreserveAspectRatio::parsePreserveAspectRatio(const String& string)
             goto bail_out;
         currParam += 8;
         skipOptionalSpaces(currParam, end);
+    } else
+        goto bail_out;
+
+    if (currParam < end) {
+        if (*currParam == 'm') {
+            if (!checkString(currParam, end, "meet"))
+                goto bail_out;
+            skipOptionalSpaces(currParam, end);
+        } else if (*currParam == 's') {
+            if (!checkString(currParam, end, "slice"))
+                goto bail_out;
+            skipOptionalSpaces(currParam, end);
+            if (align != SVG_PRESERVEASPECTRATIO_NONE)
+                meetOrSlice = SVG_MEETORSLICE_SLICE;    
+        }
     }
 
-    if (*currParam == 'm') {
-        if (!checkString(currParam, end, meetDesc, sizeof(meetDesc) / sizeof(UChar)))
-            goto bail_out;
-        skipOptionalSpaces(currParam, end);
+    if (end != currParam) {
+bail_out:
+        align = SVG_PRESERVEASPECTRATIO_NONE;
         meetOrSlice = SVG_MEETORSLICE_MEET;
-    } else if (*currParam == 's') {
-        if (!checkString(currParam, end, sliceDesc, sizeof(sliceDesc) / sizeof(UChar)))
-            goto bail_out;
-        skipOptionalSpaces(currParam, end);
-        if (m_align != SVG_PRESERVEASPECTRATIO_NONE)
-            meetOrSlice = SVG_MEETORSLICE_SLICE;    
     }
 
-    if (end != currParam)
-        goto bail_out; // FIXME: may need to print an error here
-
-    setAlign(align);
-    setMeetOrSlice(meetOrSlice);
-
-    if (m_context)
-        m_context->notifyAttributeChange();
-    return;
-
-bail_out:
-    setAlign(SVG_PRESERVEASPECTRATIO_NONE);
-    setMeetOrSlice(SVG_MEETORSLICE_MEET);
+    if (m_align == align && m_meetOrSlice == meetOrSlice)
+        return;
 
+    m_align = align;
+    m_meetOrSlice = meetOrSlice;
     if (m_context)
         m_context->notifyAttributeChange();
 }
@@ -222,4 +221,3 @@ AffineTransform SVGPreserveAspectRatio::getCTM(float logicX, float logicY,
 
 // vim:ts=4:noet
 #endif // SVG_SUPPORT
-