<!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>[201417] trunk/Source/WebCore</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/201417">201417</a></dd>
<dt>Author</dt> <dd>cfleizach@apple.com</dd>
<dt>Date</dt> <dd>2016-05-26 00:54:41 -0700 (Thu, 26 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>AX: crash at AccessibilityRenderObject::remoteSVGRootElement const
https://bugs.webkit.org/show_bug.cgi?id=158098

Reviewed by Joanmarie Diggs.

What looks like happens here is that when a document is torn down and we try to detach, we end up creating an accessibility element during detachment phase.
So instead of just clearing the callback pointer on an existing AXObject, we make a new object and access properties of an object being deallocated.

I tried very hard to make a test but it looks like this can really only be triggered during document tear down which also tears down the AXObjectCache. I didn't
have luck reproducing because of that.

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::remoteSVGElementHitTest):
(WebCore::AccessibilityRenderObject::isSVGImage):
(WebCore::AccessibilityRenderObject::detachRemoteSVGRoot):
(WebCore::AccessibilityRenderObject::remoteSVGRootElement):
(WebCore::AccessibilityRenderObject::addRemoteSVGChildren):
* accessibility/AccessibilityRenderObject.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityRenderObjectcpp">trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityRenderObjecth">trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201416 => 201417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-26 06:50:26 UTC (rev 201416)
+++ trunk/Source/WebCore/ChangeLog        2016-05-26 07:54:41 UTC (rev 201417)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2016-05-26  Chris Fleizach  &lt;cfleizach@apple.com&gt;
+
+        AX: crash at AccessibilityRenderObject::remoteSVGRootElement const
+        https://bugs.webkit.org/show_bug.cgi?id=158098
+
+        Reviewed by Joanmarie Diggs.
+
+        What looks like happens here is that when a document is torn down and we try to detach, we end up creating an accessibility element during detachment phase.
+        So instead of just clearing the callback pointer on an existing AXObject, we make a new object and access properties of an object being deallocated.
+
+        I tried very hard to make a test but it looks like this can really only be triggered during document tear down which also tears down the AXObjectCache. I didn't
+        have luck reproducing because of that.
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::remoteSVGElementHitTest):
+        (WebCore::AccessibilityRenderObject::isSVGImage):
+        (WebCore::AccessibilityRenderObject::detachRemoteSVGRoot):
+        (WebCore::AccessibilityRenderObject::remoteSVGRootElement):
+        (WebCore::AccessibilityRenderObject::addRemoteSVGChildren):
+        * accessibility/AccessibilityRenderObject.h:
+
</ins><span class="cx"> 2016-05-25  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Invalidate style for newly added nodes in Node::insertedInto
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityRenderObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (201416 => 201417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp        2016-05-26 06:50:26 UTC (rev 201416)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp        2016-05-26 07:54:41 UTC (rev 201417)
</span><span class="lines">@@ -2255,7 +2255,7 @@
</span><span class="cx"> 
</span><span class="cx"> AccessibilityObject* AccessibilityRenderObject::remoteSVGElementHitTest(const IntPoint&amp; point) const
</span><span class="cx"> {
</span><del>-    AccessibilityObject* remote = remoteSVGRootElement();
</del><ins>+    AccessibilityObject* remote = remoteSVGRootElement(Create);
</ins><span class="cx">     if (!remote)
</span><span class="cx">         return nullptr;
</span><span class="cx">     
</span><span class="lines">@@ -2968,16 +2968,16 @@
</span><span class="cx">     
</span><span class="cx"> bool AccessibilityRenderObject::isSVGImage() const
</span><span class="cx"> {
</span><del>-    return remoteSVGRootElement();
</del><ins>+    return remoteSVGRootElement(Create);
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> void AccessibilityRenderObject::detachRemoteSVGRoot()
</span><span class="cx"> {
</span><del>-    if (AccessibilitySVGRoot* root = remoteSVGRootElement())
</del><ins>+    if (AccessibilitySVGRoot* root = remoteSVGRootElement(Retrieve))
</ins><span class="cx">         root-&gt;setParent(nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-AccessibilitySVGRoot* AccessibilityRenderObject::remoteSVGRootElement() const
</del><ins>+AccessibilitySVGRoot* AccessibilityRenderObject::remoteSVGRootElement(CreationChoice createIfNecessary) const
</ins><span class="cx"> {
</span><span class="cx">     if (!is&lt;RenderImage&gt;(m_renderer))
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -3009,11 +3009,11 @@
</span><span class="cx">     AXObjectCache* cache = frame.document()-&gt;axObjectCache();
</span><span class="cx">     if (!cache)
</span><span class="cx">         return nullptr;
</span><del>-    AccessibilityObject* rootSVGObject = cache-&gt;getOrCreate(rendererRoot);
</del><ins>+    AccessibilityObject* rootSVGObject = createIfNecessary == Create ? cache-&gt;getOrCreate(rendererRoot) : cache-&gt;get(rendererRoot);
</ins><span class="cx"> 
</span><span class="cx">     // In order to connect the AX hierarchy from the SVG root element from the loaded resource
</span><span class="cx">     // the parent must be set, because there's no other way to get back to who created the image.
</span><del>-    ASSERT(rootSVGObject);
</del><ins>+    ASSERT(!createIfNecessary || rootSVGObject);
</ins><span class="cx">     if (!is&lt;AccessibilitySVGRoot&gt;(*rootSVGObject))
</span><span class="cx">         return nullptr;
</span><span class="cx">     
</span><span class="lines">@@ -3022,7 +3022,7 @@
</span><span class="cx">     
</span><span class="cx"> void AccessibilityRenderObject::addRemoteSVGChildren()
</span><span class="cx"> {
</span><del>-    AccessibilitySVGRoot* root = remoteSVGRootElement();
</del><ins>+    AccessibilitySVGRoot* root = remoteSVGRootElement(Create);
</ins><span class="cx">     if (!root)
</span><span class="cx">         return;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityRenderObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (201416 => 201417)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h        2016-05-26 06:50:26 UTC (rev 201416)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h        2016-05-26 07:54:41 UTC (rev 201417)
</span><span class="lines">@@ -245,7 +245,8 @@
</span><span class="cx">     
</span><span class="cx">     bool isSVGImage() const;
</span><span class="cx">     void detachRemoteSVGRoot();
</span><del>-    AccessibilitySVGRoot* remoteSVGRootElement() const;
</del><ins>+    enum CreationChoice { Create, Retrieve };
+    AccessibilitySVGRoot* remoteSVGRootElement(CreationChoice createIfNecessary) const;
</ins><span class="cx">     AccessibilityObject* remoteSVGElementHitTest(const IntPoint&amp;) const;
</span><span class="cx">     void offsetBoundingBoxForRemoteSVGElement(LayoutRect&amp;) const;
</span><span class="cx">     bool supportsPath() const override;
</span></span></pre>
</div>
</div>

</body>
</html>