Crashes in ViewGestureController::beginSwipeGesture when swiping in rapid succession
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Aug 2014 00:16:52 +0000 (00:16 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Aug 2014 00:16:52 +0000 (00:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136271
<rdar://problem/17923694>

Reviewed by Simon Fraser.

It was possible to get into trackSwipeGesture while another swipe was still
occurring, because the guard against this happening depended on m_pendingSwipeReason
never being set while a swipe was occurring. However, if the very first scroll event
had sufficient magnitude, we would still set m_pendingSwipeReason to InsufficientMagnitude,
and then *never clear it*, leading to a path around the guard against multiple live swipes.
This in turn allowed stale layers in m_liveSwipeLayers, which lead to the crash.

* UIProcess/mac/ViewGestureControllerMac.mm:
(WebKit::ViewGestureController::handleScrollWheelEvent):
Don't unset m_pendingSwipeReason before calling trackSwipeGesture;
trackSwipeGesture will do it itself.

Don't set m_pendingSwipeReason to InsufficientMagnitude
if the event actually *has* sufficient magnitude to start a swipe.

(WebKit::ViewGestureController::trackSwipeGesture):
Assert that we don't have an active gesture while starting a swipe.

Reset m_pendingSwipeReason, because the swipe is no longer pending!

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172988 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm

index da259fab0c9639d43826341bf16e2cab17ddea0c..68e1f544644952ea5c786becf671f0eeba8ccc47 100644 (file)
@@ -1,3 +1,31 @@
+2014-08-26  Tim Horton  <timothy_horton@apple.com>
+
+        Crashes in ViewGestureController::beginSwipeGesture when swiping in rapid succession
+        https://bugs.webkit.org/show_bug.cgi?id=136271
+        <rdar://problem/17923694>
+
+        Reviewed by Simon Fraser.
+
+        It was possible to get into trackSwipeGesture while another swipe was still
+        occurring, because the guard against this happening depended on m_pendingSwipeReason
+        never being set while a swipe was occurring. However, if the very first scroll event
+        had sufficient magnitude, we would still set m_pendingSwipeReason to InsufficientMagnitude,
+        and then *never clear it*, leading to a path around the guard against multiple live swipes.
+        This in turn allowed stale layers in m_liveSwipeLayers, which lead to the crash.
+
+        * UIProcess/mac/ViewGestureControllerMac.mm:
+        (WebKit::ViewGestureController::handleScrollWheelEvent):
+        Don't unset m_pendingSwipeReason before calling trackSwipeGesture;
+        trackSwipeGesture will do it itself.
+
+        Don't set m_pendingSwipeReason to InsufficientMagnitude
+        if the event actually *has* sufficient magnitude to start a swipe.
+
+        (WebKit::ViewGestureController::trackSwipeGesture):
+        Assert that we don't have an active gesture while starting a swipe.
+
+        Reset m_pendingSwipeReason, because the swipe is no longer pending!
+
 2014-08-26  Andy Estes  <aestes@apple.com>
 
         [Cocoa] Some projects are incorrectly installed to $BUILT_PRODUCTS_DIR
index 6c7ecaa753d2daf0494643c7fe8ece10cadeea4a..041d521edcb65d5e14366f014ab8a208f12c5eb8 100644 (file)
@@ -324,7 +324,6 @@ bool ViewGestureController::handleScrollWheelEvent(NSEvent *event)
 
     if (m_pendingSwipeReason == PendingSwipeReason::InsufficientMagnitude) {
         if (deltaIsSufficientToBeginSwipe(event)) {
-            m_pendingSwipeReason = PendingSwipeReason::None;
             trackSwipeGesture(event, m_pendingSwipeDirection);
             return true;
         }
@@ -343,8 +342,8 @@ bool ViewGestureController::handleScrollWheelEvent(NSEvent *event)
         return false;
     }
 
-    m_pendingSwipeReason = PendingSwipeReason::InsufficientMagnitude;
     if (!deltaIsSufficientToBeginSwipe(event)) {
+        m_pendingSwipeReason = PendingSwipeReason::InsufficientMagnitude;
         m_pendingSwipeDirection = direction;
         return true;
     }
@@ -375,6 +374,9 @@ void ViewGestureController::wheelEventWasNotHandledByWebCore(NSEvent *event)
 
 void ViewGestureController::trackSwipeGesture(NSEvent *event, SwipeDirection direction)
 {
+    ASSERT(m_activeGestureType == ViewGestureType::None);
+    m_pendingSwipeReason = PendingSwipeReason::None;
+
     m_webPageProxy.recordNavigationSnapshot();
 
     CGFloat maxProgress = (direction == SwipeDirection::Left) ? 1 : 0;