Changeset 117463 in webkit


Ignore:
Timestamp:
May 17, 2012 10:54:40 AM (12 years ago)
Author:
caio.oliveira@openbossa.org
Message:

[Qt] REGRESSION(101967): It made editing/style/iframe-onload-crash-mac.html timeout
https://bugs.webkit.org/show_bug.cgi?id=73802

Reviewed by Ryosuke Niwa.

Source/WebCore:

Timeout was caused by an infinite in the outer loop of
pushDownInlineStyleAroundNode(). The outer loop variable 'current' should point at the
node containing 'targetNode'. The inner loop traverse the children of 'current'
and discover the children that contains 'targetNode'.

However, before the inner loop, we call removeInlineStyleFromElement() that can
potentially remove the 'current' node from the tree, moving its children to
'current' former parent. For that reason 'child' and 'lastChild' are collected
before this call.

The tricky part is that changing the 'current' children parent, we might trigger
further side-effects, that can remove either 'child' or 'lastChild' from the tree
too. The infinite loop was due to 'child' being off the document, so it's
nextSibling() is 0, and we go another run of outer loop without changing
'current' because the 'targetNode' wasn't in the first child that inner loop
couldn't reach.

When testing Qt on Mac, there was also a crash in RenderTextControl when the font
family was empty, this patch fixes it as well.

  • editing/ApplyStyleCommand.cpp:

(WebCore::ApplyStyleCommand::pushDownInlineStyleAroundNode): Use NodeVector
instead of relying on first/last child being valid after
removeInlineStyleFromElement() is called. Skip the child if it has no parent,
this is an indication that it was removed from the tree.

  • rendering/RenderTextControl.cpp:

(WebCore::RenderTextControl::hasValidAvgCharWidth): Empty AtomicStrings aren't
supported by HashSet, so we have to early return in this case.

LayoutTests:

  • platform/qt/Skipped: Unskipped. Note that it is still skipped for wk2 because

setEditingBehavior is not implemented for WebKitTestRunner yet.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r117461 r117463  
     12012-05-17  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
     2
     3        [Qt] REGRESSION(101967): It made editing/style/iframe-onload-crash-mac.html timeout
     4        https://bugs.webkit.org/show_bug.cgi?id=73802
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        * platform/qt/Skipped: Unskipped. Note that it is still skipped for wk2 because
     9        setEditingBehavior is not implemented for WebKitTestRunner yet.
     10
    1112012-05-17  Raphael Kubo da Costa  <rakuco@webkit.org>
    212
  • trunk/LayoutTests/platform/qt/Skipped

    r117438 r117463  
    23232323fast/forms/select/listbox-in-multi-column.html
    23242324
    2325 # [Qt] REGRESSION(101967): It made editing/style/iframe-onload-crash-mac.html timeout
    2326 # https://bugs.webkit.org/show_bug.cgi?id=73802
    2327 editing/style/iframe-onload-crash-mac.html
    2328 
    23292325# [Qt] fails fast/inline/nested-text-descendants.html
    23302326# https://bugs.webkit.org/show_bug.cgi?id=75321
  • trunk/Source/WebCore/ChangeLog

    r117462 r117463  
     12012-05-17  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
     2
     3        [Qt] REGRESSION(101967): It made editing/style/iframe-onload-crash-mac.html timeout
     4        https://bugs.webkit.org/show_bug.cgi?id=73802
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Timeout was caused by an infinite in the outer loop of
     9        pushDownInlineStyleAroundNode(). The outer loop variable 'current' should point at the
     10        node containing 'targetNode'. The inner loop traverse the children of 'current'
     11        and discover the children that contains 'targetNode'.
     12
     13        However, before the inner loop, we call removeInlineStyleFromElement() that can
     14        potentially remove the 'current' node from the tree, moving its children to
     15        'current' former parent. For that reason 'child' and 'lastChild' are collected
     16        before this call.
     17
     18        The tricky part is that changing the 'current' children parent, we might trigger
     19        further side-effects, that can remove either 'child' or 'lastChild' from the tree
     20        too. The infinite loop was due to 'child' being off the document, so it's
     21        nextSibling() is 0, and we go another run of outer loop without changing
     22        'current' because the 'targetNode' wasn't in the first child that inner loop
     23        couldn't reach.
     24
     25        When testing Qt on Mac, there was also a crash in RenderTextControl when the font
     26        family was empty, this patch fixes it as well.
     27
     28        * editing/ApplyStyleCommand.cpp:
     29        (WebCore::ApplyStyleCommand::pushDownInlineStyleAroundNode): Use NodeVector
     30        instead of relying on first/last child being valid after
     31        removeInlineStyleFromElement() is called. Skip the child if it has no parent,
     32        this is an indication that it was removed from the tree.
     33
     34        * rendering/RenderTextControl.cpp:
     35        (WebCore::RenderTextControl::hasValidAvgCharWidth): Empty AtomicStrings aren't
     36        supported by HashSet, so we have to early return in this case.
     37
    1382012-05-17  Pavel Feldman  <pfeldman@chromium.org>
    239
  • trunk/Source/WebCore/editing/ApplyStyleCommand.cpp

    r116669 r117463  
    978978        ASSERT(current);
    979979        ASSERT(current->contains(targetNode));
    980         Node* child = current->firstChild();
    981         Node* lastChild = current->lastChild();
     980        NodeVector currentChildren;
     981        getChildNodes(current, currentChildren);
    982982        RefPtr<StyledElement> styledElement;
    983983        if (current->isStyledElement() && isStyledInlineElementToRemove(static_cast<Element*>(current))) {
     
    992992        // The inner loop will go through children on each level
    993993        // FIXME: we should aggregate inline child elements together so that we don't wrap each child separately.
    994         while (child) {
    995             Node* nextChild = child->nextSibling();
    996 
     994        for (size_t i = 0; i < currentChildren.size(); ++i) {
     995            Node* child = currentChildren[i].get();
     996            if (!child->parentNode())
     997                continue;
    997998            if (!child->contains(targetNode) && elementsToPushDown.size()) {
    998999                for (size_t i = 0; i < elementsToPushDown.size(); i++) {
     
    10121013            if (child == targetNode || child->contains(targetNode))
    10131014                current = child;
    1014 
    1015             if (child == lastChild || child->contains(lastChild))
    1016                 break;
    1017             child = nextChild;
    10181015        }
    10191016    }
  • trunk/Source/WebCore/rendering/RenderTextControl.cpp

    r112425 r117463  
    209209    static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
    210210
     211    if (family.isEmpty())
     212        return false;
     213
    211214    if (!fontFamiliesWithInvalidCharWidthMap) {
    212215        fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
Note: See TracChangeset for help on using the changeset viewer.