Bug 1250560 Part 1 - Fix crash in HandleTouchEvent. r?roc draft
authorTing-Yu Lin <tlin@mozilla.com>
Sun, 28 Feb 2016 19:50:03 +0800
changeset 335283 07f1fcd6cac98fd8d7621fa0bd963cca89265270
parent 335282 a721ee7b70bc5c325b6bb557eea333ebbb452546
child 335284 a2329108c00a0d3b9151c24ca6441318d745a674
push id11755
push usertlin@mozilla.com
push dateSun, 28 Feb 2016 11:50:41 +0000
reviewersroc
bugs1250560
milestone47.0a1
Bug 1250560 Part 1 - Fix crash in HandleTouchEvent. r?roc When enabling "dom.w3c_pointer_events.enabled", we might get a eTouchCancel event without any touch data. That is, aEvent->touches is an empty array. Since |id| and |point| are used only in eTouchStart, I move them into the eTouchStart to fix the crash. MozReview-Commit-ID: I766x5y1Smq
layout/base/AccessibleCaretEventHub.cpp
--- a/layout/base/AccessibleCaretEventHub.cpp
+++ b/layout/base/AccessibleCaretEventHub.cpp
@@ -542,31 +542,35 @@ AccessibleCaretEventHub::HandleMouseEven
   return rv;
 }
 
 nsEventStatus
 AccessibleCaretEventHub::HandleTouchEvent(WidgetTouchEvent* aEvent)
 {
   nsEventStatus rv = nsEventStatus_eIgnore;
 
-  int32_t id =
-    (mActiveTouchId == kInvalidTouchId ? aEvent->touches[0]->Identifier()
-                                       : mActiveTouchId);
-  nsPoint point = GetTouchEventPosition(aEvent, id);
-
   switch (aEvent->mMessage) {
     case eTouchStart:
       AC_LOGV("Before eTouchStart, state: %s", mState->Name());
-      rv = mState->OnPress(this, point, id);
+      MOZ_ASSERT(!aEvent->touches.IsEmpty(),
+                 "Got eTouchStart without any touch data!");
+      if (!aEvent->touches.IsEmpty()) {
+        int32_t id =
+          (mActiveTouchId == kInvalidTouchId ? aEvent->touches[0]->Identifier()
+                                             : mActiveTouchId);
+        rv = mState->OnPress(this, GetTouchEventPosition(aEvent, id), id);
+      }
       AC_LOGV("After eTouchStart, state: %s, consume: %d", mState->Name(), rv);
       break;
 
     case eTouchMove:
       AC_LOGV("Before eTouchMove, state: %s", mState->Name());
-      rv = mState->OnMove(this, point);
+      MOZ_ASSERT(mActiveTouchId != kInvalidTouchId,
+                 "mActiveTouchId should be set in previous mState->OnPress()!");
+      rv = mState->OnMove(this, GetTouchEventPosition(aEvent, mActiveTouchId));
       AC_LOGV("After eTouchMove, state: %s, consume: %d", mState->Name(), rv);
       break;
 
     case eTouchEnd:
       AC_LOGV("Before eTouchEnd, state: %s", mState->Name());
       rv = mState->OnRelease(this);
       AC_LOGV("After eTouchEnd, state: %s, consume: %d", mState->Name(), rv);
       break;
@@ -773,17 +777,17 @@ AccessibleCaretEventHub::NotifyBlur(bool
   mState->OnBlur(this, aIsLeavingDocument);
 }
 
 nsPoint
 AccessibleCaretEventHub::GetTouchEventPosition(WidgetTouchEvent* aEvent,
                                                int32_t aIdentifier) const
 {
   for (dom::Touch* touch : aEvent->touches) {
-    if (touch->Identifier() == aIdentifier) {
+    if (touch && touch->Identifier() == aIdentifier) {
       LayoutDeviceIntPoint touchIntPoint = touch->mRefPoint;
 
       // Get event coordinate relative to root frame.
       nsIFrame* rootFrame = mPresShell->GetRootFrame();
       return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touchIntPoint,
                                                           rootFrame);
     }
   }