Changeset 235863 in webkit


Ignore:
Timestamp:
Sep 10, 2018 2:42:45 PM (6 years ago)
Author:
Simon Fraser
Message:

Many textarea tests leak documents because Document::removeFocusNavigationNodeOfSubtree() can trigger a Document retain cycle
https://bugs.webkit.org/show_bug.cgi?id=188722

Reviewed by Ryosuke Niwa.

Fix a retain cycle created when Document::adjustFocusNavigationNodeOnNodeRemoval() sets
m_focusNavigationStartingNode to itself. m_focusNavigationStartingNode is a Node* (not sure why it's not an Element*),
making it possible to assign the Document to it, which creates a reference to the document which prevents
Document::removedLastRef() ever running and doing the necessary cleanup.

Fix by setting m_focusNavigationStartingNode to null if code tries to set it to the Document. This can happen
when an element is focused and the page calls document.write(), which removes all children.

Will be tested by future leak testing. Fixes the document leak in at least the following tests:

fast/forms/append-children-during-form-submission.html
fast/forms/empty-textarea-toggle-disabled.html
fast/forms/textarea-paste-newline.html
fast/forms/textarea-trailing-newline.html

  • dom/Document.cpp:

(WebCore::Document::setFocusNavigationStartingNode):
(WebCore::Document::adjustFocusNavigationNodeOnNodeRemoval):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r235862 r235863  
     12018-09-10  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Many textarea tests leak documents because Document::removeFocusNavigationNodeOfSubtree() can trigger a Document retain cycle
     4        https://bugs.webkit.org/show_bug.cgi?id=188722
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Fix a retain cycle created when Document::adjustFocusNavigationNodeOnNodeRemoval() sets
     9        m_focusNavigationStartingNode to itself. m_focusNavigationStartingNode is a Node* (not sure why it's not an Element*),
     10        making it possible to assign the Document to it, which creates a reference to the document which prevents
     11        Document::removedLastRef() ever running and doing the necessary cleanup.
     12       
     13        Fix by setting m_focusNavigationStartingNode to null if code tries to set it to the Document. This can happen
     14        when an element is focused and the page calls document.write(), which removes all children.
     15       
     16        Will be tested by future leak testing. Fixes the document leak in at least the following tests:
     17          fast/forms/append-children-during-form-submission.html
     18          fast/forms/empty-textarea-toggle-disabled.html
     19          fast/forms/textarea-paste-newline.html
     20          fast/forms/textarea-trailing-newline.html
     21
     22        * dom/Document.cpp:
     23        (WebCore::Document::setFocusNavigationStartingNode):
     24        (WebCore::Document::adjustFocusNavigationNodeOnNodeRemoval):
     25
    1262018-09-10  Simon Fraser  <simon.fraser@apple.com>
    227
  • trunk/Source/WebCore/dom/Document.cpp

    r235862 r235863  
    40754075    }
    40764076
     4077    ASSERT(!node || node != this);
    40774078    m_focusNavigationStartingNode = node;
    40784079}
     
    42724273
    42734274    if (isNodeInSubtree(*m_focusNavigationStartingNode, node, nodeRemoval)) {
    4274         m_focusNavigationStartingNode = (nodeRemoval == NodeRemoval::ChildrenOfNode) ? &node : fallbackFocusNavigationStartingNodeAfterRemoval(node);
     4275        auto* newNode = (nodeRemoval == NodeRemoval::ChildrenOfNode) ? &node : fallbackFocusNavigationStartingNodeAfterRemoval(node);
     4276        m_focusNavigationStartingNode = (newNode != this) ? newNode : nullptr;
    42754277        m_focusNavigationStartingNodeIsRemoved = true;
    42764278    }
Note: See TracChangeset for help on using the changeset viewer.