Title: [261018] trunk
Revision
261018
Author
[email protected]
Date
2020-05-01 13:50:18 -0700 (Fri, 01 May 2020)

Log Message

Nullptr crash in EditCommand::EditCommand via CompositeEditCommand::removeNode
https://bugs.webkit.org/show_bug.cgi?id=207600
Source/WebCore:

<rdar://problem/56969450>

Reviewed by Geoffrey Garen.

Second part of the fix. Remove m_frame in FrameSelection so it will not be
inadvertently used and cause this crash.

No new tests, covered by existing test.

* editing/AlternativeTextController.cpp:
(WebCore::AlternativeTextController::rootViewRectForRange const):
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::FrameSelection):
(WebCore::FrameSelection::setSelectionWithoutUpdatingAppearance):
(WebCore::FrameSelection::modify):
(WebCore::FrameSelection::selectFrameElementInParentIfFullySelected):
(WebCore::FrameSelection::setFocusedElementIfNeeded):
(WebCore::FrameSelection::shouldDeleteSelection const):
(WebCore::FrameSelection::shouldDeleteSelection):
(WebCore::FrameSelection::revealSelection):
(WebCore::FrameSelection:: shouldChangeSelection):
(WebCore::FrameSelection::shouldChangeSelection const):
* editing/FrameSelection.h:
* editing/atk/FrameSelectionAtk.cpp:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* editing/mac/FrameSelectionMac.mm:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):

LayoutTests:

Reviewed by Geoffrey Garen.

Reduce run time for this test case.

* editing/inserting/insert-list-then-edit-command-crash.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (261017 => 261018)


--- trunk/LayoutTests/ChangeLog	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/LayoutTests/ChangeLog	2020-05-01 20:50:18 UTC (rev 261018)
@@ -1,3 +1,14 @@
+2020-05-01  Jack Lee  <[email protected]>
+
+        Nullptr crash in EditCommand::EditCommand via CompositeEditCommand::removeNode
+        https://bugs.webkit.org/show_bug.cgi?id=207600
+
+        Reviewed by Geoffrey Garen.
+
+        Reduce run time for this test case.
+
+        * editing/inserting/insert-list-then-edit-command-crash.html:
+
 2020-05-01  Eric Carlson  <[email protected]>
 
         [MSE] Audio session category is sometimes not set correctly after changing video source

Modified: trunk/LayoutTests/editing/inserting/insert-list-then-edit-command-crash.html (261017 => 261018)


--- trunk/LayoutTests/editing/inserting/insert-list-then-edit-command-crash.html	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/LayoutTests/editing/inserting/insert-list-then-edit-command-crash.html	2020-05-01 20:50:18 UTC (rev 261018)
@@ -1,19 +1,17 @@
-<body><image></image><form id=form contentEditable=true><object data=? _onload_=objectOnLoad()></object></form><dialog open="true">a</dialog>
+<div style="width: 1px; height: 1px;"></div><div contentEditable=true><object data="" _onload_=objectOnLoad()></object></div><span>text</span>
 <script>
-    document.getSelection().empty();
-    document.execCommand("selectAll", false);
     if (window.testRunner) {
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
     }
 
+    document.getSelection().empty();
+    document.execCommand("selectAll", false);
+
     function objectOnLoad() {
         document.execCommand("insertUnorderedList", false);
         document.execCommand("italic", false);
-        requestAnimationFrame(function () {
-            document.body.innerHTML = "<p> Tests inserting list followed by an edit command. The test passes if WebKit doesn't crash or hit an assertion.</p>";
-            if (window.testRunner)
-                testRunner.notifyDone();
-        });
+        document.body.innerHTML = "<p> Tests inserting list followed by an edit command. The test passes if WebKit doesn't crash or hit an assertion.</p>";
+        testRunner.notifyDone();
     }
 </script>

Modified: trunk/Source/WebCore/ChangeLog (261017 => 261018)


--- trunk/Source/WebCore/ChangeLog	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/Source/WebCore/ChangeLog	2020-05-01 20:50:18 UTC (rev 261018)
@@ -1,3 +1,35 @@
+2020-05-01  Jack Lee  <[email protected]>
+
+        Nullptr crash in EditCommand::EditCommand via CompositeEditCommand::removeNode
+        https://bugs.webkit.org/show_bug.cgi?id=207600
+        <rdar://problem/56969450>
+
+        Reviewed by Geoffrey Garen.
+
+        Second part of the fix. Remove m_frame in FrameSelection so it will not be
+        inadvertently used and cause this crash.
+
+        No new tests, covered by existing test.
+
+        * editing/AlternativeTextController.cpp:
+        (WebCore::AlternativeTextController::rootViewRectForRange const):
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::FrameSelection):
+        (WebCore::FrameSelection::setSelectionWithoutUpdatingAppearance):
+        (WebCore::FrameSelection::modify):
+        (WebCore::FrameSelection::selectFrameElementInParentIfFullySelected):
+        (WebCore::FrameSelection::setFocusedElementIfNeeded):
+        (WebCore::FrameSelection::shouldDeleteSelection const):
+        (WebCore::FrameSelection::shouldDeleteSelection):
+        (WebCore::FrameSelection::revealSelection):
+        (WebCore::FrameSelection:: shouldChangeSelection):
+        (WebCore::FrameSelection::shouldChangeSelection const):
+        * editing/FrameSelection.h:
+        * editing/atk/FrameSelectionAtk.cpp:
+        (WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
+        * editing/mac/FrameSelectionMac.mm:
+        (WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
+
 2020-05-01  Darin Adler  <[email protected]>
 
         REGRESSION (r260739): Crash when pasting into Mail

Modified: trunk/Source/WebCore/editing/AlternativeTextController.cpp (261017 => 261018)


--- trunk/Source/WebCore/editing/AlternativeTextController.cpp	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/Source/WebCore/editing/AlternativeTextController.cpp	2020-05-01 20:50:18 UTC (rev 261018)
@@ -342,7 +342,7 @@
 
 FloatRect AlternativeTextController::rootViewRectForRange(const SimpleRange& range) const
 {
-    auto* view = m_document.frame()->view();
+    auto* view = m_document.view();
     if (!view)
         return { };
     return view->contentsToRootView(unitedBoundingBoxes(RenderObject::absoluteTextQuads(range)));

Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (261017 => 261018)


--- trunk/Source/WebCore/editing/FrameSelection.cpp	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp	2020-05-01 20:50:18 UTC (rev 261018)
@@ -146,7 +146,6 @@
 
 FrameSelection::FrameSelection(Document* document)
     : m_document(document)
-    , m_frame(document? document->frame() : nullptr)
     , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
     , m_granularity(CharacterGranularity)
 #if ENABLE(TEXT_CARET)
@@ -157,7 +156,7 @@
     , m_absCaretBoundsDirty(true)
     , m_caretPaint(true)
     , m_isCaretBlinkingSuspended(false)
-    , m_focused(m_frame && m_frame->page() && m_frame->page()->focusController().focusedFrame() == m_frame)
+    , m_focused(document && document->frame() && document->page() && document->page()->focusController().focusedFrame() == document->frame())
     , m_shouldShowBlockCursor(false)
     , m_pendingSelectionUpdate(false)
     , m_alwaysAlignCursorOnScrollWhenRevealingSelection(false)
@@ -336,17 +335,17 @@
     if (shouldAlwaysUseDirectionalSelection(m_document))
         newSelection.setIsDirectional(true);
 
-    if (!m_frame) {
+    if (!m_document || !m_document->frame()) {
         m_selection = newSelection;
         return false;
     }
 
     // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at FrameSelection::setSelection
-    // if document->frame() == m_frame we can get into an infinite loop
+    // if document->frame() == m_document->frame() we can get into an infinite loop
     if (Document* newSelectionDocument = newSelection.base().document()) {
         if (RefPtr<Frame> newSelectionFrame = newSelectionDocument->frame()) {
-            if (newSelectionFrame != m_frame && newSelectionDocument != m_document) {
-                newSelectionFrame->selection().setSelection(newSelection, options, AXTextStateChangeIntent(), align, granularity);
+            if (newSelectionFrame != m_document->frame() && newSelectionDocument != m_document) {
+                newSelectionDocument->selection().setSelection(newSelection, options, AXTextStateChangeIntent(), align, granularity);
                 // It's possible that during the above set selection, this FrameSelection has been modified by
                 // selectFrameElementInParentIfFullySelected, but that the selection is no longer valid since
                 // the frame is about to be destroyed. If this is the case, clear our selection.
@@ -384,6 +383,8 @@
     if (!newSelection.isNone() && !(options & DoNotSetFocus)) {
         auto* oldFocusedElement = m_document->focusedElement();
         setFocusedElementIfNeeded();
+        if (!m_document->frame())
+            return false;
         // FIXME: Should not be needed.
         if (m_document->focusedElement() != oldFocusedElement)
             m_document->updateStyleIfNeeded();
@@ -1377,9 +1378,10 @@
     if (position.isNull())
         return false;
 
-    if (isSpatialNavigationEnabled(m_frame))
+    if (m_document && isSpatialNavigationEnabled(m_document->frame())) {
         if (!wasRange && alter == AlterationMove && position == originalStartPosition)
             return false;
+    }
 
     if (m_document && AXObjectCache::accessibilityEnabled()) {
         if (AXObjectCache* cache = m_document->existingAXObjectCache())
@@ -1932,10 +1934,10 @@
 void FrameSelection::selectFrameElementInParentIfFullySelected()
 {
     // Find the parent frame; if there is none, then we have nothing to do.
-    Frame* parent = m_frame->tree().parent();
+    Frame* parent = m_document->frame()->tree().parent();
     if (!parent)
         return;
-    Page* page = m_frame->page();
+    Page* page = m_document->page();
     if (!page)
         return;
 
@@ -1948,7 +1950,7 @@
         return;
 
     // Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
-    Element* ownerElement = m_frame->ownerElement();
+    Element* ownerElement = m_document->ownerElement();
     if (!ownerElement)
         return;
     ContainerNode* ownerElementParent = ownerElement->parentNode();
@@ -2253,7 +2255,7 @@
     bool caretBrowsing = m_document->settings().caretBrowsingEnabled();
     if (caretBrowsing) {
         if (Element* anchor = enclosingAnchorElement(m_selection.base())) {
-            m_document->page()->focusController().setFocusedElement(anchor, *m_frame);
+            m_document->page()->focusController().setFocusedElement(anchor, *m_document->frame());
             return;
         }
     }
@@ -2265,7 +2267,7 @@
             // so add the !isFrameElement check here. There's probably a better way to make this
             // work in the long term, but this is the safest fix at this time.
             if (target->isMouseFocusable() && !isFrameElement(target)) {
-                m_document->page()->focusController().setFocusedElement(target, *m_frame);
+                m_document->page()->focusController().setFocusedElement(target, *m_document->frame());
                 return;
             }
             target = target->parentOrShadowHostElement();
@@ -2274,7 +2276,7 @@
     }
 
     if (caretBrowsing)
-        m_document->page()->focusController().setFocusedElement(nullptr, *m_frame);
+        m_document->page()->focusController().setFocusedElement(nullptr, *m_document->frame());
 }
 
 void DragCaretController::paintDragCaret(Frame* frame, GraphicsContext& p, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
@@ -2300,7 +2302,7 @@
 bool FrameSelection::shouldDeleteSelection(const VisibleSelection& selection) const
 {
 #if PLATFORM(IOS_FAMILY)
-    if (m_frame->selectionChangeCallbacksDisabled())
+    if (m_document->frame() && m_document->frame()->selectionChangeCallbacksDisabled())
         return true;
 #endif
     return m_document->editor().client()->shouldDeleteRange(createLiveRange(selection.toNormalizedRange()).get());
@@ -2411,7 +2413,7 @@
                 layer->setAdjustForIOSCaretWhenScrolling(false);
                 updateAppearance();
                 if (m_document->page())
-                    m_document->page()->chrome().client().notifyRevealedSelectionByScrollingFrame(*m_frame);
+                    m_document->page()->chrome().client().notifyRevealedSelectionByScrollingFrame(*m_document->frame());
             }
         }
 #else
@@ -2445,7 +2447,7 @@
 bool FrameSelection::shouldChangeSelection(const VisibleSelection& newSelection) const
 {
 #if PLATFORM(IOS_FAMILY)
-    if (m_frame->selectionChangeCallbacksDisabled())
+    if (m_document->frame() && m_document->frame()->selectionChangeCallbacksDisabled())
         return true;
 #endif
     return m_document->editor().shouldChangeSelection(selection(), newSelection, newSelection.affinity(), false);

Modified: trunk/Source/WebCore/editing/FrameSelection.h (261017 => 261018)


--- trunk/Source/WebCore/editing/FrameSelection.h	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/Source/WebCore/editing/FrameSelection.h	2020-05-01 20:50:18 UTC (rev 261018)
@@ -338,7 +338,6 @@
 #endif
 
     Document* m_document;
-    Frame* m_frame;
 
     LayoutUnit m_xPosForVerticalArrowNavigation;
 

Modified: trunk/Source/WebCore/editing/atk/FrameSelectionAtk.cpp (261017 => 261018)


--- trunk/Source/WebCore/editing/atk/FrameSelectionAtk.cpp	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/Source/WebCore/editing/atk/FrameSelectionAtk.cpp	2020-05-01 20:50:18 UTC (rev 261018)
@@ -97,7 +97,7 @@
     if (!focusedNode)
         return;
 
-    AXObjectCache* cache = m_frame->document()->existingAXObjectCache();
+    AXObjectCache* cache = m_document->existingAXObjectCache();
     if (!cache)
         return;
 

Modified: trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm (261017 => 261018)


--- trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm	2020-05-01 20:46:38 UTC (rev 261017)
+++ trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm	2020-05-01 20:50:18 UTC (rev 261018)
@@ -34,10 +34,8 @@
 
 void FrameSelection::notifyAccessibilityForSelectionChange(const AXTextStateChangeIntent& intent)
 {
-    Document* document = m_frame->document();
-
     if (m_selection.start().isNotNull() && m_selection.end().isNotNull()) {
-        if (AXObjectCache* cache = document->existingAXObjectCache())
+        if (AXObjectCache* cache = m_document->existingAXObjectCache())
             cache->postTextStateChangeNotification(m_selection.start(), intent, m_selection);
     }
 
@@ -46,10 +44,10 @@
     if (!UAZoomEnabled() || !m_selection.isCaret())
         return;
 
-    RenderView* renderView = document->renderView();
+    RenderView* renderView = m_document->renderView();
     if (!renderView)
         return;
-    FrameView* frameView = m_frame->view();
+    FrameView* frameView = m_document->view();
     if (!frameView)
         return;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to