Changeset 108082 in webkit


Ignore:
Timestamp:
Feb 17, 2012 8:50:13 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

chrome.dll!WebCore::SVGTRefElement::updateReferencedText ReadAV@NULL (e85cb8e140071fa7790cad215b0109dc)
https://bugs.webkit.org/show_bug.cgi?id=74858

Patch by Florin Malita <fmalita@google.com> on 2012-02-17
Reviewed by Nikolas Zimmermann.

Source/WebCore:

Tests: svg/custom/tref-remove-target-crash-expected.svg

svg/custom/tref-remove-target-crash.svg

Add a DOMNodeRemovedFromDocumentEvent listener to detect when the target element is removed. Upon removal,
cleanup all listeners and re-activate the pending resource to attach if the referenced ID is added
at a later time programmatically. Also move the DOMSubtreeModifiedEvent listener from the parent to
the target element to simplify the implementation and reduce the scope.

  • svg/SVGTRefElement.cpp:

(WebCore::TargetListener::create):
(WebCore::TargetListener::cast):
(WebCore::TargetListener::clear):
(WebCore::TargetListener::TargetListener):
(WebCore::TargetListener::operator==):
(WebCore::TargetListener::handleEvent):
(WebCore::SVGTRefElement::detachTarget):
(WebCore::SVGTRefElement::buildPendingResource):

  • svg/SVGTRefElement.h:

LayoutTests:

  • svg/custom/tref-remove-target-crash-expected.svg: Added.
  • svg/custom/tref-remove-target-crash.svg: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r108075 r108082  
     12012-02-17  Florin Malita  <fmalita@google.com>
     2
     3        chrome.dll!WebCore::SVGTRefElement::updateReferencedText ReadAV@NULL (e85cb8e140071fa7790cad215b0109dc)
     4        https://bugs.webkit.org/show_bug.cgi?id=74858
     5
     6        Reviewed by Nikolas Zimmermann.
     7
     8        * svg/custom/tref-remove-target-crash-expected.svg: Added.
     9        * svg/custom/tref-remove-target-crash.svg: Added.
     10
    1112012-02-17  Pavel Feldman  <pfeldman@google.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r108081 r108082  
     12012-02-17  Florin Malita  <fmalita@google.com>
     2
     3        chrome.dll!WebCore::SVGTRefElement::updateReferencedText ReadAV@NULL (e85cb8e140071fa7790cad215b0109dc)
     4        https://bugs.webkit.org/show_bug.cgi?id=74858
     5
     6        Reviewed by Nikolas Zimmermann.
     7
     8        Tests: svg/custom/tref-remove-target-crash-expected.svg
     9               svg/custom/tref-remove-target-crash.svg
     10
     11        Add a DOMNodeRemovedFromDocumentEvent listener to detect when the target element is removed. Upon removal,
     12        cleanup all listeners and re-activate the pending resource to attach if the referenced ID is added
     13        at a later time programmatically. Also move the DOMSubtreeModifiedEvent listener from the parent to
     14        the target element to simplify the implementation and reduce the scope.
     15
     16        * svg/SVGTRefElement.cpp:
     17        (WebCore::TargetListener::create):
     18        (WebCore::TargetListener::cast):
     19        (WebCore::TargetListener::clear):
     20        (WebCore::TargetListener::TargetListener):
     21        (WebCore::TargetListener::operator==):
     22        (WebCore::TargetListener::handleEvent):
     23        (WebCore::SVGTRefElement::detachTarget):
     24        (WebCore::SVGTRefElement::buildPendingResource):
     25        * svg/SVGTRefElement.h:
     26
    1272012-02-17  Simon Fraser  <simon.fraser@apple.com>
    228
  • trunk/Source/WebCore/svg/SVGTRefElement.cpp

    r107706 r108082  
    6363}
    6464
    65 class SubtreeModificationEventListener : public EventListener {
     65class TargetListener : public EventListener {
    6666public:
    67     static PassRefPtr<SubtreeModificationEventListener> create(SVGTRefElement* trefElement, String targetId)
    68     {
    69         return adoptRef(new SubtreeModificationEventListener(trefElement, targetId));
    70     }
    71 
    72     static const SubtreeModificationEventListener* cast(const EventListener* listener)
    73     {
    74         return listener->type() == CPPEventListenerType ? static_cast<const SubtreeModificationEventListener*>(listener) : 0;
     67    static PassRefPtr<TargetListener> create(SVGTRefElement* trefElement, String targetId)
     68    {
     69        return adoptRef(new TargetListener(trefElement, targetId));
     70    }
     71
     72    static const TargetListener* cast(const EventListener* listener)
     73    {
     74        return listener->type() == CPPEventListenerType ? static_cast<const TargetListener*>(listener) : 0;
    7575    }
    7676
     
    8080    {
    8181        Element* target = m_trefElement->treeScope()->getElementById(m_targetId);
    82         if (target && target->parentNode())
    83             target->parentNode()->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, false);
     82        if (target) {
     83            target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, false);
     84            target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false);
     85        }
    8486       
    8587        m_trefElement = 0;
     
    8890
    8991private:
    90     SubtreeModificationEventListener(SVGTRefElement* trefElement, String targetId)
     92    TargetListener(SVGTRefElement* trefElement, String targetId)
    9193        : EventListener(CPPEventListenerType)
    9294        , m_trefElement(trefElement)
     
    101103};
    102104
    103 bool SubtreeModificationEventListener::operator==(const EventListener& listener)
    104 {
    105     if (const SubtreeModificationEventListener* subtreeModificationEventListener = SubtreeModificationEventListener::cast(&listener))
     105bool TargetListener::operator==(const EventListener& listener)
     106{
     107    if (const TargetListener* subtreeModificationEventListener = TargetListener::cast(&listener))
    106108        return m_trefElement == subtreeModificationEventListener->m_trefElement;
    107109    return false;
    108110}
    109111
    110 void SubtreeModificationEventListener::handleEvent(ScriptExecutionContext*, Event* event)
     112void TargetListener::handleEvent(ScriptExecutionContext*, Event* event)
    111113{
    112114    if (m_trefElement && event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement != event->target())
    113115        m_trefElement->updateReferencedText();
     116
     117    if (m_trefElement && event->type() == eventNames().DOMNodeRemovedFromDocumentEvent)
     118        m_trefElement->detachTarget();
    114119}
    115120
     
    167172    else
    168173        root->firstChild()->setTextContent(textContent, ASSERT_NO_EXCEPTION);
     174}
     175
     176void SVGTRefElement::detachTarget()
     177{
     178    // Remove active listeners and clear the text content.
     179    clearEventListener();
     180
     181    String emptyContent;
     182    ExceptionCode ignore = 0;
     183
     184    ASSERT(hasShadowRoot());
     185    Node* container = shadowRootList()->oldestShadowRoot()->firstChild();
     186    if (container)
     187        container->setTextContent(emptyContent, ignore);
     188
     189    // Mark the referenced ID as pending.
     190    String id;
     191    SVGURIReference::targetElementFromIRIString(href(), document(), &id);
     192    if (!hasPendingResources() && !id.isEmpty())
     193        document()->accessSVGExtensions()->addPendingResource(id, this);
    169194}
    170195
     
    258283        return;
    259284
    260     m_eventListener = SubtreeModificationEventListener::create(this, id);
    261     ASSERT(target->parentNode());
    262     target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
     285    m_eventListener = TargetListener::create(this, id);
     286    target->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
     287    target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, m_eventListener.get(), false);
    263288}
    264289
  • trunk/Source/WebCore/svg/SVGTRefElement.h

    r107523 r108082  
    2828namespace WebCore {
    2929
    30 class SubtreeModificationEventListener;
     30class TargetListener;
    3131
    3232class SVGTRefElement : public SVGTextPositioningElement,
     
    3636
    3737private:
    38     friend class SubtreeModificationEventListener;
     38    friend class TargetListener;
    3939
    4040    SVGTRefElement(const QualifiedName&, Document*);
     
    5858    void updateReferencedText();
    5959
     60    void detachTarget();
     61
    6062    virtual void buildPendingResource();
    6163
     
    6466    END_DECLARE_ANIMATED_PROPERTIES
    6567
    66     RefPtr<SubtreeModificationEventListener> m_eventListener;
     68    RefPtr<TargetListener> m_eventListener;
    6769};
    6870
Note: See TracChangeset for help on using the changeset viewer.