External <use> xlink:href references do not work
https://bugs.webkit.org/show_bug.cgi?id=12499
Reviewed by Zoltan Herczeg.
Rebaseline tests after r110676 using Generic RGB Profile on Lion, and update them after my fixes.
Replace xml:id with id everywhere, to make the new tiny tests work.
* platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.png:
* platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt:
* platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.png:
* platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt:
* platform/mac/svg/batik/filters/feTile-expected.png:
* platform/mac/svg/batik/filters/filterRegions-expected.png:
* platform/mac/svg/batik/text/textEffect-expected.png:
* platform/mac/svg/batik/text/textEffect3-expected.png:
* platform/mac/svg/dynamic-updates/SVGUseElement-svgdom-href1-prop-expected.png:
* svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t.svg:
* svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t.svg:
* svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t.svg:
* svg/custom/use-external-crash-expected.txt: Added.
* svg/custom/use-external-crash.svg: Added.
2012-03-14 Nikolas Zimmermann <nzimmermann@rim.com>
External <use> xlink:href references do not work
https://bugs.webkit.org/show_bug.cgi?id=12499
Reviewed by Zoltan Herczeg.
Follow-up fix after r110676.
Assertions are firing due last minute changes in isExternalURIReference.
Fix detecting local resources properly, when the given iri contains a /complex/path.
Use document->completeURL() instead, and compare with the document->url() to decide
if its a local reference or not.
If an external document load fails with an error (eg. file missing) don't assert
in debug builds, instead handle it gracefully.
I decided to clean the code up as well, to make it more safe & obvious.
Test: svg/custom/use-external-crash.svg
* svg/SVGURIReference.cpp:
(WebCore::SVGURIReference::targetElementFromIRIString):
* svg/SVGURIReference.h:
(WebCore::SVGURIReference::isExternalURIReference):
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::externalDocument):
(WebCore::SVGUseElement::buildPendingResource):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@110692
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-03-14 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ External <use> xlink:href references do not work
+ https://bugs.webkit.org/show_bug.cgi?id=12499
+
+ Reviewed by Zoltan Herczeg.
+
+ Rebaseline tests after r110676 using Generic RGB Profile on Lion, and update them after my fixes.
+ Replace xml:id with id everywhere, to make the new tiny tests work.
+
+ * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.png:
+ * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt:
+ * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.png:
+ * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt:
+ * platform/mac/svg/batik/filters/feTile-expected.png:
+ * platform/mac/svg/batik/filters/filterRegions-expected.png:
+ * platform/mac/svg/batik/text/textEffect-expected.png:
+ * platform/mac/svg/batik/text/textEffect3-expected.png:
+ * platform/mac/svg/dynamic-updates/SVGUseElement-svgdom-href1-prop-expected.png:
+ * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t.svg:
+ * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t.svg:
+ * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t.svg:
+ * svg/custom/use-external-crash-expected.txt: Added.
+ * svg/custom/use-external-crash.svg: Added.
+
2012-03-14 Ádám Kallai <kadam@inf.u-szeged.hu>
[Qt] Rebaseline after r110667.
layer at (0,0) size 800x600
RenderSVGRoot {svg} at (0,0) size 800x600
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
- RenderSVGContainer {g} at (150,25) size 484x452
- RenderSVGContainer {g} at (150,25) size 34x34
+ RenderSVGContainer {g} at (150,25) size 502x452
+ RenderSVGContainer {g} at (150,25) size 502x77
RenderSVGPath {circle} at (150,25) size 34x34 [fill={[type=SOLID] [color=#FF7F00]}] [cx=100.00] [cy=25.00] [r=10.00]
- RenderSVGContainer {use} at (0,0) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,25.00)}]
+ RenderSVGContainer {use} at (614,64) size 38x38 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,25.00)}]
+ RenderSVGContainer {g} at (614,64) size 38x38
+ RenderSVGContainer {g} at (0,0) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,25.00)}]
+ RenderSVGPath {circle} at (614,64) size 38x38 [stroke={[type=SOLID] [color=#808080] [stroke width=2.00] [line cap=ROUND] [dash array={4.00}]}] [fill={[type=SOLID] [color=#FFFF00]}] [cx=380.00] [cy=25.00] [r=10.00]
RenderSVGText {text} at (100,257) size 280x28 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,0) size 280x28
chunk 1 (middle anchor) text run 1 at (100.20,280.00) startOffset 0 endOffset 28 width 279.60: "This text should be visible."
layer at (0,0) size 800x600
RenderSVGRoot {svg} at (0,0) size 800x600
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
- RenderSVGContainer {g} at (166,25) size 484x452
- RenderSVGContainer {g} at (616,25) size 34x34
- RenderSVGContainer {use} at (0,0) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,25.00)}]
+ RenderSVGContainer {g} at (148,25) size 502x452
+ RenderSVGContainer {g} at (148,25) size 502x77
+ RenderSVGContainer {use} at (148,64) size 37x38 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,25.00)}]
+ RenderSVGContainer {g} at (148,64) size 37x38
+ RenderSVGPath {circle} at (148,64) size 37x38 [stroke={[type=SOLID] [color=#808080] [stroke width=2.00] [line cap=ROUND] [dash array={4.00}]}] [fill={[type=SOLID] [color=#FF7F00]}] [cx=100.00] [cy=25.00] [r=10.00]
+ RenderSVGContainer {g} at (0,0) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,25.00)}]
RenderSVGPath {circle} at (616,25) size 34x34 [fill={[type=SOLID] [color=#FFFF00]}] [cx=380.00] [cy=25.00] [r=10.00]
RenderSVGText {text} at (100,257) size 280x28 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,0) size 280x28
<?xml version="1.0" encoding="UTF-8"?>
-<svg version="1.2" baseProfile="tiny" xml:id="svg-root" width="100%" height="100%"
+<svg version="1.2" baseProfile="tiny" id="svg-root" width="100%" height="100%"
viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xe="http://www.w3.org/2001/xml-events">
<!--======================================================================-->
</p>
</d:OperatorScript>
</SVGTestCase>
- <title xml:id="test-title">$RCSfile: struct-use-recursion-01-t.svg,v $</title>
+ <title id="test-title">$RCSfile: struct-use-recursion-01-t.svg,v $</title>
<defs>
<font-face
font-family="SVGFreeSansASCII"
</font-face-src>
</font-face>
</defs>
- <g xml:id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+ <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
- <g xml:id="group-1">
- <circle xml:id="circle-1" cx='100' cy='25' r='10' fill='#FF7F00' />
- <use xml:id="use-1" x="0" y="25" xlink:href="#group-2" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
+ <g id="group-1">
+ <circle id="circle-1" cx='100' cy='25' r='10' fill='#FF7F00' />
+ <use id="use-1" x="0" y="25" xlink:href="#group-2" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
</g>
- <g xml:id="group-2">
- <circle xml:id="circle-2" cx='380' cy='25' r='10' fill='#FFFF00' />
- <use xml:id="use-2" x="0" y="25" xlink:href="#group-1" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
+ <g id="group-2">
+ <circle id="circle-2" cx='380' cy='25' r='10' fill='#FFFF00' />
+ <use id="use-2" x="0" y="25" xlink:href="#group-1" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
</g>
- <text xml:id="pass" x="240" y="280" text-anchor="middle" fill="green" font-size="24">This text should be visible.</text>
+ <text id="pass" x="240" y="280" text-anchor="middle" fill="green" font-size="24">This text should be visible.</text>
</g>
<g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
- <text xml:id="revision" x="10" y="340" stroke="none"
+ <text id="revision" x="10" y="340" stroke="none"
fill="black">$Revision: 1.5 $</text>
</g>
- <rect xml:id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
+ <rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
-<svg version="1.2" baseProfile="tiny" xml:id="svg-root" width="100%" height="100%"
+<svg version="1.2" baseProfile="tiny" id="svg-root" width="100%" height="100%"
viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xe="http://www.w3.org/2001/xml-events">
<!--======================================================================-->
</p>
</d:OperatorScript>
</SVGTestCase>
- <title xml:id="test-title">$RCSfile: struct-use-recursion-02-t.svg,v $</title>
+ <title id="test-title">$RCSfile: struct-use-recursion-02-t.svg,v $</title>
<defs>
<font-face
font-family="SVGFreeSansASCII"
</font-face-src>
</font-face>
</defs>
- <g xml:id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+ <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
- <g xml:id="group-1">
- <circle xml:id="circle-1" cx='100' cy='25' r='10' fill='#FF7F00' />
- <use xml:id="use-1" x="0" y="25" xlink:href="struct-use-recursion-03-t.svg#group-2" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
+ <g id="group-1">
+ <circle id="circle-1" cx='100' cy='25' r='10' fill='#FF7F00' />
+ <use id="use-1" x="0" y="25" xlink:href="struct-use-recursion-03-t.svg#group-2" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
</g>
- <text xml:id="pass" x="240" y="280" text-anchor="middle" fill="green" font-size="24">This text should be visible.</text>
+ <text id="pass" x="240" y="280" text-anchor="middle" fill="green" font-size="24">This text should be visible.</text>
</g>
<g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
- <text xml:id="revision" x="10" y="340" stroke="none"
+ <text id="revision" x="10" y="340" stroke="none"
fill="black">$Revision: 1.5 $</text>
</g>
- <rect xml:id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
+ <rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
-<svg version="1.2" baseProfile="tiny" xml:id="svg-root" width="100%" height="100%"
+<svg version="1.2" baseProfile="tiny" id="svg-root" width="100%" height="100%"
viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xe="http://www.w3.org/2001/xml-events">
<!--======================================================================-->
</p>
</d:OperatorScript>
</SVGTestCase>
- <title xml:id="test-title">$RCSfile: struct-use-recursion-03-t.svg,v $</title>
+ <title id="test-title">$RCSfile: struct-use-recursion-03-t.svg,v $</title>
<defs>
<font-face
font-family="SVGFreeSansASCII"
</font-face-src>
</font-face>
</defs>
- <g xml:id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+ <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
- <g xml:id="group-2">
- <use xml:id="use-2" x="0" y="25" xlink:href="struct-use-recursion-02-t.svg#group-1" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
- <circle xml:id="circle-2" cx='380' cy='25' r='10' fill='#FFFF00' />
+ <g id="group-2">
+ <use id="use-2" x="0" y="25" xlink:href="struct-use-recursion-02-t.svg#group-1" stroke="gray" stroke-width="2" stroke-dasharray="4" stroke-linecap="round"/>
+ <circle id="circle-2" cx='380' cy='25' r='10' fill='#FFFF00' />
</g>
- <text xml:id="pass" x="240" y="280" text-anchor="middle" fill="green" font-size="24">This text should be visible.</text>
+ <text id="pass" x="240" y="280" text-anchor="middle" fill="green" font-size="24">This text should be visible.</text>
</g>
<g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
- <text xml:id="revision" x="10" y="340" stroke="none"
+ <text id="revision" x="10" y="340" stroke="none"
fill="black">$Revision: 1.5 $</text>
</g>
- <rect xml:id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
+ <rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000"/>
</svg>
--- /dev/null
+PASS if it doesn't assert in debug builds.
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs><text>PASS if it doesn't assert in debug builds.</text></defs>
+<use xlink:href="../W3C-SVG-1.2-Tiny/struct-use-recursion-02-t.svg#NONEXISTING"/>
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+if (window.gcController)
+ gcController.collect();
+</script>
+</svg>
+2012-03-14 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ External <use> xlink:href references do not work
+ https://bugs.webkit.org/show_bug.cgi?id=12499
+
+ Reviewed by Zoltan Herczeg.
+
+ Follow-up fix after r110676.
+ Assertions are firing due last minute changes in isExternalURIReference.
+
+ Fix detecting local resources properly, when the given iri contains a /complex/path.
+ Use document->completeURL() instead, and compare with the document->url() to decide
+ if its a local reference or not.
+
+ If an external document load fails with an error (eg. file missing) don't assert
+ in debug builds, instead handle it gracefully.
+
+ I decided to clean the code up as well, to make it more safe & obvious.
+
+ Test: svg/custom/use-external-crash.svg
+
+ * svg/SVGURIReference.cpp:
+ (WebCore::SVGURIReference::targetElementFromIRIString):
+ * svg/SVGURIReference.h:
+ (WebCore::SVGURIReference::isExternalURIReference):
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::externalDocument):
+ (WebCore::SVGUseElement::buildPendingResource):
+
2012-03-14 Lars Knudsen <lars.knudsen@nokia.com>
3D transformed surfaces with z>0 gets cropped
if (url == KURL())
return 0;
- // If we're requesting an external resources, and externalDocument is non-zero, the load already succeeded.
- // Go ahead and check if the externalDocuments URL matches the expected URL, that we resolved using the
- // host document before in urlFromIRIStringWithFragmentIdentifier(). For internal resources, the same
- // assumption must hold true, just with the host documents URL, not the external documents URL.
- if (!equalIgnoringFragmentIdentifier(url, externalDocument ? externalDocument->url() : document->url()))
- return 0;
-
if (fragmentIdentifier)
*fragmentIdentifier = id;
if (id.isEmpty())
return 0;
- if (externalDocument)
+ if (externalDocument) {
+ // Enforce that the referenced url matches the url of the document that we've loaded for it!
+ ASSERT(equalIgnoringFragmentIdentifier(url, externalDocument->url()));
return externalDocument->getElementById(id);
+ }
+
+ // Exit early if the referenced url is external, and we have no externalDocument given.
if (isExternalURIReference(iri, document))
- return 0; // Non-existing external resource
+ return 0;
return document->getElementById(id);
}
static String fragmentIdentifierFromIRIString(const String&, Document*);
static Element* targetElementFromIRIString(const String&, Document*, String* = 0, Document* = 0);
- static inline bool isExternalURIReference(const String& uri, Document* baseDocument)
+ static inline bool isExternalURIReference(const String& uri, Document* document)
{
- if (uri.startsWith("#"))
+ // If the URI matches our documents URL, early exit, we're dealing with a local reference.
+ ASSERT(document);
+ KURL url = document->completeURL(uri);
+ if (equalIgnoringFragmentIdentifier(url, document->url()))
return false;
- size_t startOfFragmentIdentifier = uri.find('#');
- // If the target document is the base document but its path is given in format href="thisDocument.svg#targetTag"
- // then we should handle it as internal.
- if (uri.substring(0, startOfFragmentIdentifier) != baseDocument->url().lastPathComponent())
- return true;
- return false;
+ // If the URI doesn't contain a base string, just see if it starts with a fragment-identifier.
+ return uri.find('#') != notFound;
}
protected:
Document* SVGUseElement::externalDocument() const
{
if (m_cachedDocument && m_cachedDocument->isLoaded()) {
+ // Gracefully handle error condition.
+ if (m_cachedDocument->errorOccurred())
+ return 0;
ASSERT(m_cachedDocument->document());
return m_cachedDocument->document();
}
String id;
Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id, externalDocument());
if (!target) {
+ // If we can't find the target of an external element, just give up.
+ // We can't observe if the target somewhen enters the external document, nor should we do it.
+ if (externalDocument())
+ return;
if (hasPendingResources() || id.isEmpty())
return;