[Webkit-unassigned] [Bug 147290] Crash happens when calling removeEventListener for an SVG element which has an instance inside a <defs> element of shadow tree

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Mon Jul 27 12:07:02 PDT 2015


https://bugs.webkit.org/show_bug.cgi?id=147290

--- Comment #4 from Said Abou-Hallawa <sabouhallawa at apple.com> ---
This crash happens under these conditions:

1. An element 'parent' is defined to be referenced later 
2. A <defs> element 'parent-defs' is included inside 'parent'
3. An element 'child' is defined inside 'parent-defs'
4. A visible <use> element 'use-parent' references 'parent'
5. A addEventListener is made for 'child' before the onload fires
6. A removeEventListener is made for 'child' after the onload fires

Here is the explanation of why the crash happens in this case:

1. Because addEventListener() was called before onload fires, the event is only added to the element itself. No instances are created before the onload event.
2. SVGUseElement::updateShadowTree() is called as part of resolving the style of 'use-parent'. It calls cloneTarget() and then calls transferEventListenersToShadowTree().
3. 'use-parent' references 'parent' so the whole 'parent' tree is cloned as a shadow tree for 'use-parent'
4. 'parent-defs' is a child of 'parent' so it is cloned and its subtree which includes the cloned 'child'
5. The cloned 'child' is added to the instances()  of 'child' and its correspondingElement is set to 'child'
6. After finishing the cloning, removeDisallowedElementsFromSubtree() is called which removes the cloned 'parent-defs' from the shadow subtree. The cloned 'parent-defs' includes the clone of 'child' which is now inaccessible from 'use-parent'.
7. When transferEventListenersToShadowTree() is called we fail to transfer the EventListener from the 'child' to the cloned 'child' since its parent cloned 'parent-defs' was removed from the shadow tree of the 'parent' element. Yet the 'child' instances() list still contains the cloned 'child'
8. When SVGElement::removeEventListener() is called for 'child' 'element', it loops through its instances() list and calls Node::removeEventListener() for each instance. We fail to removeEventListener() for the cloned 'child' since addEventListener() was never called for it. So we end up crashing when calling EventListenerMap::removeFirstEventListenerCreatedFromMarkup() since instance->eventTargetData() is null. The only way to get it valid is to call addEventListener() which did not happen.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20150727/015bd640/attachment.html>


More information about the webkit-unassigned mailing list