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
--- 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);
}
}