Changeset 83322 in webkit


Ignore:
Timestamp:
Apr 8, 2011 12:29:13 PM (13 years ago)
Author:
rniwa@webkit.org
Message:

2011-04-08 Ryosuke Niwa <rniwa@webkit.org>

Reviewed by Tony Chang, Darin Adler, and Enrica Casucci.

REGRESSION(r81887): Crash in SplitElement
https://bugs.webkit.org/show_bug.cgi?id=57743

The crash was caused by ReplaceSelectionCommand::doApply's calling splitElement with computeNodeAfterPosition
even when the position was after the last node in it container. Since all we are doing here is to splitting tree
up until the highest ancestor with isInlineNodeWithStyle, replaced the while loop by calls to splitTreeToNode
and highestEnclosingNodeOfType.

Also fixed a bug in splitTreeToNode not to check the difference in visible position when splitting the ancestor,
which would have introduced unnecessary nodes when splitting tree and a bug in highestEnclosingNodeOfType that
it incorrectly called deprecatedNode instead of containerNode.

Test: editing/inserting/insert-images-in-pre-x-crash.html

  • editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::splitTreeToNode):
  • editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::doApply):
  • editing/htmlediting.cpp: (WebCore::highestEnclosingNodeOfType):

2011-04-08 Ryosuke Niwa <rniwa@webkit.org>

Reviewed by Tony Chang, Darin Adler, and Enrica Casucci.

REGRESSION(r81887): Crash in SplitElement
https://bugs.webkit.org/show_bug.cgi?id=57743

Added a regression test for a crash in ReplaceSelectionCommand.

  • editing/inserting/insert-images-in-pre-x-crash-expected.txt: Added.
  • editing/inserting/insert-images-in-pre-x-crash.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r83321 r83322  
     12011-04-08  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Tony Chang, Darin Adler, and Enrica Casucci.
     4
     5        REGRESSION(r81887): Crash in SplitElement
     6        https://bugs.webkit.org/show_bug.cgi?id=57743
     7
     8        Added a regression test for a crash in ReplaceSelectionCommand.
     9
     10        * editing/inserting/insert-images-in-pre-x-crash-expected.txt: Added.
     11        * editing/inserting/insert-images-in-pre-x-crash.html: Added.
     12
    1132011-04-08  Antti Koivisto  <antti@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r83321 r83322  
     12011-04-08  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Tony Chang, Darin Adler, and Enrica Casucci.
     4
     5        REGRESSION(r81887): Crash in SplitElement
     6        https://bugs.webkit.org/show_bug.cgi?id=57743
     7
     8        The crash was caused by ReplaceSelectionCommand::doApply's calling splitElement with computeNodeAfterPosition
     9        even when the position was after the last node in it container. Since all we are doing here is to splitting tree
     10        up until the highest ancestor with isInlineNodeWithStyle, replaced the while loop by calls to splitTreeToNode
     11        and highestEnclosingNodeOfType.
     12
     13        Also fixed a bug in splitTreeToNode not to check the difference in visible position when splitting the ancestor,
     14        which would have introduced unnecessary nodes when splitting tree and a bug in highestEnclosingNodeOfType that
     15        it incorrectly called deprecatedNode instead of containerNode.
     16
     17        Test: editing/inserting/insert-images-in-pre-x-crash.html
     18
     19        * editing/CompositeEditCommand.cpp:
     20        (WebCore::CompositeEditCommand::splitTreeToNode):
     21        * editing/ReplaceSelectionCommand.cpp:
     22        (WebCore::ReplaceSelectionCommand::doApply):
     23        * editing/htmlediting.cpp:
     24        (WebCore::highestEnclosingNodeOfType):
     25
    1262011-04-08  Antti Koivisto  <antti@apple.com>
    227
  • trunk/Source/WebCore/editing/CompositeEditCommand.cpp

    r81965 r83322  
    12181218// Splits the tree parent by parent until we reach the specified ancestor. We use VisiblePositions
    12191219// to determine if the split is necessary. Returns the last split node.
    1220 PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, bool splitAncestor)
    1221 {
     1220PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, bool shouldSplitAncestor)
     1221{
     1222    ASSERT(start);
     1223    ASSERT(end);
    12221224    ASSERT(start != end);
    12231225
    12241226    RefPtr<Node> node;
    1225     for (node = start; node && node->parentNode() != end; node = node->parentNode()) {
     1227    if (shouldSplitAncestor && end->parentNode())
     1228        end = end->parentNode();
     1229
     1230    RefPtr<Node> endNode = end;
     1231    for (node = start; node && node->parentNode() != endNode; node = node->parentNode()) {
    12261232        if (!node->parentNode()->isElementNode())
    12271233            break;
    1228         VisiblePosition positionInParent(firstPositionInNode(node->parentNode()), DOWNSTREAM);
    1229         VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get()), DOWNSTREAM);
     1234        // Do not split a node when doing so introduces an empty node.
     1235        VisiblePosition positionInParent = firstPositionInNode(node->parentNode());
     1236        VisiblePosition positionInNode = firstPositionInOrBeforeNode(node.get());
    12301237        if (positionInParent != positionInNode)
    1231             applyCommandToComposite(SplitElementCommand::create(static_cast<Element*>(node->parentNode()), node));
    1232     }
    1233     if (splitAncestor) {
    1234         splitElement(static_cast<Element*>(end), node);
    1235         return node->parentNode();
    1236     }
     1238            splitElement(static_cast<Element*>(node->parentNode()), node);
     1239    }
     1240
    12371241    return node.release();
    12381242}
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp

    r81965 r83322  
    953953    // our style spans and for positions inside list items
    954954    // since insertAsListItems already does the right thing.
    955     if (!m_matchStyle && !enclosingList(insertionPos.anchorNode()) && isStyleSpan(fragment.firstChild())) {
    956         Node* parentNode = insertionPos.anchorNode()->parentNode();
    957         while (parentNode && parentNode->renderer() && isInlineNodeWithStyle(parentNode)) {
    958             // If we are in the middle of a text node, we need to split it before we can
    959             // move the insertion position.
    960             if (insertionPos.anchorNode()->isTextNode() && insertionPos.anchorType() == Position::PositionIsOffsetInAnchor && insertionPos.offsetInContainerNode() && !insertionPos.atLastEditingPositionForNode())
    961                 splitTextNodeContainingElement(static_cast<Text*>(insertionPos.anchorNode()), insertionPos.offsetInContainerNode());
    962            
    963             // If the style element has more than one child, we need to split it.
    964             if (parentNode->firstChild()->nextSibling())
    965                 splitElement(static_cast<Element*>(parentNode), insertionPos.computeNodeAfterPosition());
    966            
    967             insertionPos = positionInParentBeforeNode(parentNode);
    968             parentNode = parentNode->parentNode();
     955    if (!m_matchStyle && !enclosingList(insertionPos.containerNode()) && isStyleSpan(fragment.firstChild())) {
     956        if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) {
     957            splitTextNodeContainingElement(static_cast<Text*>(insertionPos.containerNode()), insertionPos.offsetInContainerNode());
     958            insertionPos = firstPositionInNode(insertionPos.containerNode());
     959        }
     960
     961        // FIXME: isInlineNodeWithStyle does not check editability.
     962        if (RefPtr<Node> nodeToSplitTo = highestEnclosingNodeOfType(insertionPos, isInlineNodeWithStyle)) {
     963            if (insertionPos.containerNode() != nodeToSplitTo)
     964                nodeToSplitTo = splitTreeToNode(insertionPos.anchorNode(), nodeToSplitTo.get(), true).get();
     965            insertionPos = positionInParentBeforeNode(nodeToSplitTo.get());
    969966        }
    970967    }
  • trunk/Source/WebCore/editing/htmlediting.cpp

    r83247 r83322  
    639639    Node* highest = 0;
    640640    Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0;
    641     for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) {
     641    for (Node* n = p.containerNode(); n; n = n->parentNode()) {
    642642        if (root && !n->rendererIsEditable())
    643643            continue;
Note: See TracChangeset for help on using the changeset viewer.