Title: [256933] trunk/Source/WebKit
Revision
256933
Author
[email protected]
Date
2020-02-19 12:04:56 -0800 (Wed, 19 Feb 2020)

Log Message

[iOS] Safari sometimes crashes under ViewGestureController::beginSwipeGesture
https://bugs.webkit.org/show_bug.cgi?id=207929
<rdar://problem/59493326>

Reviewed by Tim Horton.

Make ViewGestureController::beginSwipeGesture robust in the case where the target back/forward item no longer
exists. This means that a back/forward target item existed when UIKit called into us in canSwipeInDirection, but
this item was removed by the time beginSwipeGesture is called.

A couple of conditions could make this possible, such as handling incoming synchronous IPC in the UI process
that could change the back/forward list before sending outgoing IPC to the web process; alternately, an SPI
client could be overriding -_webViewDidBeginNavigationGesture: to run some logic that removes the would-be
target back/forward item.

To protect against these scenarios, null-check targetItem before attempting to dereference it; if it is null,
then reset some state that might've been set as a result of beginning the swipe (that is, m_activeGestureType
and m_currentGestureID) and then immediately bail before attempting to install the snapshot view and proceed
with the swipe.

* UIProcess/ios/ViewGestureControllerIOS.mm:
(WebKit::ViewGestureController::beginSwipeGesture):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (256932 => 256933)


--- trunk/Source/WebKit/ChangeLog	2020-02-19 20:01:51 UTC (rev 256932)
+++ trunk/Source/WebKit/ChangeLog	2020-02-19 20:04:56 UTC (rev 256933)
@@ -1,3 +1,28 @@
+2020-02-18  Wenson Hsieh  <[email protected]>
+
+        [iOS] Safari sometimes crashes under ViewGestureController::beginSwipeGesture
+        https://bugs.webkit.org/show_bug.cgi?id=207929
+        <rdar://problem/59493326>
+
+        Reviewed by Tim Horton.
+
+        Make ViewGestureController::beginSwipeGesture robust in the case where the target back/forward item no longer
+        exists. This means that a back/forward target item existed when UIKit called into us in canSwipeInDirection, but
+        this item was removed by the time beginSwipeGesture is called.
+
+        A couple of conditions could make this possible, such as handling incoming synchronous IPC in the UI process
+        that could change the back/forward list before sending outgoing IPC to the web process; alternately, an SPI
+        client could be overriding -_webViewDidBeginNavigationGesture: to run some logic that removes the would-be
+        target back/forward item.
+
+        To protect against these scenarios, null-check targetItem before attempting to dereference it; if it is null,
+        then reset some state that might've been set as a result of beginning the swipe (that is, m_activeGestureType
+        and m_currentGestureID) and then immediately bail before attempting to install the snapshot view and proceed
+        with the swipe.
+
+        * UIProcess/ios/ViewGestureControllerIOS.mm:
+        (WebKit::ViewGestureController::beginSwipeGesture):
+
 2020-02-19  Chris Dumez  <[email protected]>
 
         Disable the process cache when process-per-tab is disabled in the debug menu

Modified: trunk/Source/WebKit/UIProcess/ios/ViewGestureControllerIOS.mm (256932 => 256933)


--- trunk/Source/WebKit/UIProcess/ios/ViewGestureControllerIOS.mm	2020-02-19 20:01:51 UTC (rev 256932)
+++ trunk/Source/WebKit/UIProcess/ios/ViewGestureControllerIOS.mm	2020-02-19 20:04:56 UTC (rev 256933)
@@ -182,12 +182,18 @@
     RefPtr<WebPageProxy> alternateBackForwardListSourcePage = m_alternateBackForwardListSourcePage.get();
     m_webPageProxyForBackForwardListForCurrentSwipe = alternateBackForwardListSourcePage ? alternateBackForwardListSourcePage.get() : &m_webPageProxy;
 
+    auto& backForwardList = m_webPageProxyForBackForwardListForCurrentSwipe->backForwardList();
+    auto targetItem = makeRefPtr(direction == SwipeDirection::Back ? backForwardList.backItem() : backForwardList.forwardItem());
+    if (!targetItem) {
+        RELEASE_LOG_ERROR(ViewGestures, "Failed to find %s item when beginning swipe.", direction == SwipeDirection::Back ? "back" : "forward");
+        didEndGesture();
+        return;
+    }
+
     m_webPageProxyForBackForwardListForCurrentSwipe->navigationGestureDidBegin();
     if (&m_webPageProxy != m_webPageProxyForBackForwardListForCurrentSwipe)
         m_webPageProxy.navigationGestureDidBegin();
 
-    auto& backForwardList = m_webPageProxyForBackForwardListForCurrentSwipe->backForwardList();
-
     // Copy the snapshot from this view to the one that owns the back forward list, so that
     // swiping forward will have the correct snapshot.
     if (m_webPageProxyForBackForwardListForCurrentSwipe != &m_webPageProxy) {
@@ -195,8 +201,6 @@
             backForwardList.currentItem()->setSnapshot(currentViewHistoryItem->snapshot());
     }
 
-    RefPtr<WebBackForwardListItem> targetItem = direction == SwipeDirection::Back ? backForwardList.backItem() : backForwardList.forwardItem();
-
     CGRect liveSwipeViewFrame = [m_liveSwipeView frame];
 
     RetainPtr<UIViewController> snapshotViewController = adoptNS([[UIViewController alloc] init]);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to