<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[187504] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/187504">187504</a></dd>
<dt>Author</dt> <dd>said@apple.com</dd>
<dt>Date</dt> <dd>2015-07-28 13:10:03 -0700 (Tue, 28 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Crash happens when calling removeEventListener for an SVG element which has an instance inside a &lt;defs&gt; element of shadow tree
https://bugs.webkit.org/show_bug.cgi?id=147290

Reviewed by Daniel Bates.

Source/WebCore:

When the shadow tree is built for a &lt;use&gt; element, all the SVG elements
are allowed to be cloned in the shadow tree but later some of the elements
are disallowed and removed. Make sure, when disallowing an element in the
shadow tree, to reset the correspondingElement relationship between all
the disallowed descendant SVG elements and all their original elements.
        
Test: svg/custom/remove-event-listener-shadow-disallowed-element.svg

*svg/SVGElement.cpp:
(WebCore::SVGElement::setCorrespondingElement)
* svg/SVGUseElement.cpp:
(WebCore::removeDisallowedElementsFromSubtree):

LayoutTests:

Make sure we do not crash when when calling removeEventListener() for an
element which is cloned under a disallowed parent inside the shadow tree
of another &lt;use&gt; element.

* svg/custom/remove-event-listener-shadow-disallowed-element-expected.txt: Added.
* svg/custom/remove-event-listener-shadow-disallowed-element.svg: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoresvgSVGElementcpp">trunk/Source/WebCore/svg/SVGElement.cpp</a></li>
<li><a href="#trunkSourceWebCoresvgSVGUseElementcpp">trunk/Source/WebCore/svg/SVGUseElement.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestssvgcustomremoveeventlistenershadowdisallowedelementexpectedtxt">trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element-expected.txt</a></li>
<li><a href="#trunkLayoutTestssvgcustomremoveeventlistenershadowdisallowedelementsvg">trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element.svg</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (187503 => 187504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-07-28 19:48:03 UTC (rev 187503)
+++ trunk/LayoutTests/ChangeLog        2015-07-28 20:10:03 UTC (rev 187504)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-07-28  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Crash happens when calling removeEventListener for an SVG element which has an instance inside a &lt;defs&gt; element of shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=147290
+
+        Reviewed by Daniel Bates.
+
+        Make sure we do not crash when when calling removeEventListener() for an
+        element which is cloned under a disallowed parent inside the shadow tree
+        of another &lt;use&gt; element.
+
+        * svg/custom/remove-event-listener-shadow-disallowed-element-expected.txt: Added.
+        * svg/custom/remove-event-listener-shadow-disallowed-element.svg: Added.
+
</ins><span class="cx"> 2015-07-27  David Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ASSERTION FAILED: !currBox-&gt;needsLayout() loading bing maps (and apple.com/music and nytimes)
</span></span></pre></div>
<a id="trunkLayoutTestssvgcustomremoveeventlistenershadowdisallowedelementexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element-expected.txt (0 => 187504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element-expected.txt                                (rev 0)
+++ trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element-expected.txt        2015-07-28 20:10:03 UTC (rev 187504)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+Pass.
</ins></span></pre></div>
<a id="trunkLayoutTestssvgcustomremoveeventlistenershadowdisallowedelementsvg"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element.svg (0 => 187504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element.svg                                (rev 0)
+++ trunk/LayoutTests/svg/custom/remove-event-listener-shadow-disallowed-element.svg        2015-07-28 20:10:03 UTC (rev 187504)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+&lt;svg version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;
+
+  &lt;defs&gt;
+    &lt;svg id=&quot;green-svg&quot; width=&quot;100&quot; height=&quot;100&quot;&gt;
+      &lt;defs&gt;
+         &lt;rect id=&quot;green-rect&quot; fill=&quot;green&quot; width=&quot;100&quot; height=&quot;100&quot;/&gt;
+      &lt;/defs&gt;
+      &lt;use id=&quot;use-green-rect&quot; xlink:href=&quot;#green-rect&quot;/&gt;
+    &lt;/svg&gt;
+  &lt;/defs&gt;  
+
+  &lt;use id=&quot;use-green-svg&quot; x=&quot;10&quot; y=&quot;10&quot; xlink:href=&quot;#green-svg&quot;/&gt;
+  &lt;text&gt;Pass.&lt;/text&gt;
+
+  &lt;script&gt;
+   if (window.testRunner)
+      testRunner.dumpAsText();
+    
+    var onAlert = function() {
+      alert(&quot;test&quot;);
+    }
+
+    // This removeEventListener() has to be called before the onload fires. Before
+    // onload fires, the shadow tree of the SVGUseElement is not built. So this
+    // call should affect the original element only. Once the shadow tree is built,
+    // the SVGUseElement calls updateShadowTree() and this is where we want to make
+    // sure the eventListeners of all the cloned elements in the shadow tree are
+    // updated correctly and the disallowed cloned elements and their descendants
+    // are disconnected from their corresponding elements.
+    document.getElementById(&quot;green-rect&quot;).addEventListener(&quot;click&quot;, onAlert);
+    
+    window.addEventListener(&quot;load&quot;, function () {
+      document.getElementById(&quot;green-rect&quot;).removeEventListener(&quot;click&quot;, onAlert);
+    }, false);
+  &lt;/script&gt;
+
+&lt;/svg&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (187503 => 187504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-07-28 19:48:03 UTC (rev 187503)
+++ trunk/Source/WebCore/ChangeLog        2015-07-28 20:10:03 UTC (rev 187504)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2015-07-28  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Crash happens when calling removeEventListener for an SVG element which has an instance inside a &lt;defs&gt; element of shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=147290
+
+        Reviewed by Daniel Bates.
+
+        When the shadow tree is built for a &lt;use&gt; element, all the SVG elements
+        are allowed to be cloned in the shadow tree but later some of the elements
+        are disallowed and removed. Make sure, when disallowing an element in the
+        shadow tree, to reset the correspondingElement relationship between all
+        the disallowed descendant SVG elements and all their original elements.
+        
+        Test: svg/custom/remove-event-listener-shadow-disallowed-element.svg
+
+        *svg/SVGElement.cpp:
+        (WebCore::SVGElement::setCorrespondingElement)
+        * svg/SVGUseElement.cpp:
+        (WebCore::removeDisallowedElementsFromSubtree):
+
</ins><span class="cx"> 2015-07-28  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, follow-up nit fix after r187489.
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGElement.cpp (187503 => 187504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGElement.cpp        2015-07-28 19:48:03 UTC (rev 187503)
+++ trunk/Source/WebCore/svg/SVGElement.cpp        2015-07-28 20:10:03 UTC (rev 187504)
</span><span class="lines">@@ -502,7 +502,8 @@
</span><span class="cx">         if (SVGElement* oldCorrespondingElement = m_svgRareData-&gt;correspondingElement())
</span><span class="cx">             oldCorrespondingElement-&gt;m_svgRareData-&gt;instances().remove(this);
</span><span class="cx">     }
</span><del>-    ensureSVGRareData().setCorrespondingElement(correspondingElement);
</del><ins>+    if (m_svgRareData || correspondingElement)
+        ensureSVGRareData().setCorrespondingElement(correspondingElement);
</ins><span class="cx">     if (correspondingElement)
</span><span class="cx">         correspondingElement-&gt;ensureSVGRareData().instances().add(this);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGUseElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGUseElement.cpp (187503 => 187504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGUseElement.cpp        2015-07-28 19:48:03 UTC (rev 187503)
+++ trunk/Source/WebCore/svg/SVGUseElement.cpp        2015-07-28 20:10:03 UTC (rev 187504)
</span><span class="lines">@@ -329,8 +329,11 @@
</span><span class="cx">         }
</span><span class="cx">         ++it;
</span><span class="cx">     }
</span><del>-    for (auto* element : disallowedElements)
</del><ins>+    for (auto* element : disallowedElements) {
+        for (auto&amp; descendant : descendantsOfType&lt;SVGElement&gt;(*element))
+            descendant.setCorrespondingElement(nullptr);
</ins><span class="cx">         element-&gt;parentNode()-&gt;removeChild(element);
</span><ins>+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void associateClonesWithOriginals(SVGElement&amp; clone, SVGElement&amp; original)
</span></span></pre>
</div>
</div>

</body>
</html>