Title: [253463] trunk/Source/WebCore
Revision
253463
Author
[email protected]
Date
2019-12-12 20:01:35 -0800 (Thu, 12 Dec 2019)

Log Message

Protect lifetime of frame and frameView objects
https://bugs.webkit.org/show_bug.cgi?id=205128

Patch by Jack Lee <[email protected]> on 2019-12-12
Reviewed by Ryosuke Niwa.

Could not write a reproducible test case for this.

* page/DOMWindow.cpp:
(WebCore::DOMWindow::focus):
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::focusDocumentView):
* page/mac/EventHandlerMac.mm:
(WebCore::EventHandler::focusDocumentView):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (253462 => 253463)


--- trunk/Source/WebCore/ChangeLog	2019-12-13 02:13:30 UTC (rev 253462)
+++ trunk/Source/WebCore/ChangeLog	2019-12-13 04:01:35 UTC (rev 253463)
@@ -1,3 +1,19 @@
+2019-12-12  Jack Lee  <[email protected]>
+
+        Protect lifetime of frame and frameView objects
+        https://bugs.webkit.org/show_bug.cgi?id=205128
+
+        Reviewed by Ryosuke Niwa.
+
+        Could not write a reproducible test case for this.
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::focus):
+        * page/ios/EventHandlerIOS.mm:
+        (WebCore::EventHandler::focusDocumentView):
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::EventHandler::focusDocumentView):
+
 2019-12-12  Jer Noble  <[email protected]>
 
         Add logging for MediaCapabilities.decodeInfo()

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (253462 => 253463)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2019-12-13 02:13:30 UTC (rev 253462)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2019-12-13 04:01:35 UTC (rev 253463)
@@ -985,30 +985,27 @@
     if (!frame())
         return;
 
-    Page* page = frame()->page();
+    auto protectedFrame = makeRefPtr(frame());
+
+    Page* page = protectedFrame->page();
     if (!page)
         return;
 
-    allowFocus = allowFocus || WindowFocusAllowedIndicator::windowFocusAllowed() || !frame()->settings().windowFocusRestricted();
+    allowFocus = allowFocus || WindowFocusAllowedIndicator::windowFocusAllowed() || !protectedFrame->settings().windowFocusRestricted();
 
     // If we're a top level window, bring the window to the front.
-    if (frame()->isMainFrame() && allowFocus)
+    if (protectedFrame->isMainFrame() && allowFocus)
         page->chrome().focus();
 
-    if (!frame())
+    if (!protectedFrame->hasHadUserInteraction() && !isSameSecurityOriginAsMainFrame())
         return;
 
-    if (!frame()->hasHadUserInteraction() && !isSameSecurityOriginAsMainFrame())
-        return;
-
     // Clear the current frame's focused node if a new frame is about to be focused.
-    Frame* focusedFrame = page->focusController().focusedFrame();
-    if (focusedFrame && focusedFrame != frame())
+    auto focusedFrame = makeRefPtr(page->focusController().focusedFrame());
+    if (focusedFrame && focusedFrame != protectedFrame)
         focusedFrame->document()->setFocusedElement(nullptr);
 
-    // setFocusedElement may clear frame(), so recheck before using it.
-    if (auto* frame = this->frame())
-        frame->eventHandler().focusDocumentView();
+    protectedFrame->eventHandler().focusDocumentView();
 }
 
 void DOMWindow::blur()

Modified: trunk/Source/WebCore/page/ios/EventHandlerIOS.mm (253462 => 253463)


--- trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2019-12-13 02:13:30 UTC (rev 253462)
+++ trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2019-12-13 04:01:35 UTC (rev 253463)
@@ -174,13 +174,16 @@
     if (!page)
         return;
 
-    Ref<Frame> protectedFrame(m_frame);
-
-    if (FrameView* frameView = m_frame.view()) {
-        if (NSView *documentView = frameView->documentView())
+    if (auto frameView = makeRefPtr(m_frame.view())) {
+        if (NSView *documentView = frameView->documentView()) {
             page->chrome().focusNSView(documentView);
+            // Check page() again because focusNSView can cause reentrancy.
+            if (!m_frame.page())
+                return;
+        }
     }
 
+    RELEASE_ASSERT(page == m_frame.page());
     page->focusController().setFocusedFrame(&m_frame);
 }
 

Modified: trunk/Source/WebCore/page/mac/EventHandlerMac.mm (253462 => 253463)


--- trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2019-12-13 02:13:30 UTC (rev 253462)
+++ trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2019-12-13 04:01:35 UTC (rev 253463)
@@ -165,11 +165,16 @@
     if (!page)
         return;
 
-    if (FrameView* frameView = m_frame.view()) {
-        if (NSView *documentView = frameView->documentView())
+    if (auto frameView = makeRefPtr(m_frame.view())) {
+        if (NSView *documentView = frameView->documentView()) {
             page->chrome().focusNSView(documentView);
+            // Check page() again because focusNSView can cause reentrancy.
+            if (!m_frame.page())
+                return;
+        }
     }
 
+    RELEASE_ASSERT(page == m_frame.page());
     page->focusController().setFocusedFrame(&m_frame);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to