From 2885a1c490c531b8686a6e17e3f28ee5fa34d66a Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Thu, 2 Jun 2022 22:57:50 +0000 Subject: [PATCH] Add MotionEvent information to exception When indices are validated and an invalid index is encountered, currently there is a Java exception raised. The caller may be able to catch that exception in Java. However, we are also finding crashes in the wild where these exceptions are unchecked. As a first pass, let's simply add event information to understand exactly how this could happen. Bug: 233163975 Test: atest libinput_tests inputflinger_tests Change-Id: If717b9ca90d85338752a0f911d6fb66bbbf4fe4a --- core/jni/android_view_MotionEvent.cpp | 60 ++++++++++++--------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index 07e1a6c4e3a78..a30935b621a2e 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "MotionEvent-JNI" -#include +#include "android_view_MotionEvent.h" #include #include @@ -24,12 +24,12 @@ #include #include #include +#include +#include #include -#include + #include "android_os_Parcel.h" #include "android_util_Binder.h" -#include "android_view_MotionEvent.h" - #include "core_jni_helpers.h" namespace android { @@ -158,19 +158,21 @@ static bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoord return true; } -static bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) { - if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) { - jniThrowException(env, "java/lang/IllegalArgumentException", - "pointerIndex out of range"); +static bool validatePointerIndex(JNIEnv* env, jint pointerIndex, const MotionEvent& event) { + if (pointerIndex < 0 || size_t(pointerIndex) >= event.getPointerCount()) { + std::stringstream message; + message << "invalid pointerIndex " << pointerIndex << " for " << event; + jniThrowException(env, "java/lang/IllegalArgumentException", message.str().c_str()); return false; } return true; } -static bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) { - if (historyPos < 0 || size_t(historyPos) >= historySize) { - jniThrowException(env, "java/lang/IllegalArgumentException", - "historyPos out of range"); +static bool validateHistoryPos(JNIEnv* env, jint historyPos, const MotionEvent& event) { + if (historyPos < 0 || size_t(historyPos) >= event.getHistorySize()) { + std::stringstream message; + message << "historyPos " << historyPos << " out of range for " << event; + jniThrowException(env, "java/lang/IllegalArgumentException", message.str().c_str()); return false; } return true; @@ -399,13 +401,11 @@ static void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz, static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz, jlong nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) { MotionEvent* event = reinterpret_cast(nativePtr); - size_t pointerCount = event->getPointerCount(); - if (!validatePointerIndex(env, pointerIndex, pointerCount) - || !validatePointerCoords(env, outPointerCoordsObj)) { + if (!validatePointerIndex(env, pointerIndex, *event) || + !validatePointerCoords(env, outPointerCoordsObj)) { return; } - if (historyPos != HISTORY_CURRENT && - !validateHistoryPos(env, historyPos, event->getHistorySize())) { + if (historyPos != HISTORY_CURRENT && !validateHistoryPos(env, historyPos, *event)) { return; } @@ -445,9 +445,8 @@ static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz, jlong nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) { MotionEvent* event = reinterpret_cast(nativePtr); - size_t pointerCount = event->getPointerCount(); - if (!validatePointerIndex(env, pointerIndex, pointerCount) - || !validatePointerProperties(env, outPointerPropertiesObj)) { + if (!validatePointerIndex(env, pointerIndex, *event) || + !validatePointerProperties(env, outPointerPropertiesObj)) { return; } @@ -502,8 +501,7 @@ static jint android_view_MotionEvent_nativeAxisFromString(JNIEnv* env, jclass cl static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz, jlong nativePtr, jint pointerIndex) { MotionEvent* event = reinterpret_cast(nativePtr); - size_t pointerCount = event->getPointerCount(); - if (!validatePointerIndex(env, pointerIndex, pointerCount)) { + if (!validatePointerIndex(env, pointerIndex, *event)) { return -1; } return event->getPointerId(pointerIndex); @@ -512,8 +510,7 @@ static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass claz static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz, jlong nativePtr, jint pointerIndex) { MotionEvent* event = reinterpret_cast(nativePtr); - size_t pointerCount = event->getPointerCount(); - if (!validatePointerIndex(env, pointerIndex, pointerCount)) { + if (!validatePointerIndex(env, pointerIndex, *event)) { return -1; } return event->getToolType(pointerIndex); @@ -525,8 +522,7 @@ static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclas if (historyPos == HISTORY_CURRENT) { return event->getEventTime(); } else { - size_t historySize = event->getHistorySize(); - if (!validateHistoryPos(env, historyPos, historySize)) { + if (!validateHistoryPos(env, historyPos, *event)) { return 0; } return event->getHistoricalEventTime(historyPos); @@ -537,16 +533,14 @@ static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass jlong nativePtr, jint axis, jint pointerIndex, jint historyPos) { MotionEvent* event = reinterpret_cast(nativePtr); - size_t pointerCount = event->getPointerCount(); - if (!validatePointerIndex(env, pointerIndex, pointerCount)) { + if (!validatePointerIndex(env, pointerIndex, *event)) { return 0; } if (historyPos == HISTORY_CURRENT) { return event->getRawAxisValue(axis, pointerIndex); } else { - size_t historySize = event->getHistorySize(); - if (!validateHistoryPos(env, historyPos, historySize)) { + if (!validateHistoryPos(env, historyPos, *event)) { return 0; } return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos); @@ -556,16 +550,14 @@ static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass static jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz, jlong nativePtr, jint axis, jint pointerIndex, jint historyPos) { MotionEvent* event = reinterpret_cast(nativePtr); - size_t pointerCount = event->getPointerCount(); - if (!validatePointerIndex(env, pointerIndex, pointerCount)) { + if (!validatePointerIndex(env, pointerIndex, *event)) { return 0; } if (historyPos == HISTORY_CURRENT) { return event->getAxisValue(axis, pointerIndex); } else { - size_t historySize = event->getHistorySize(); - if (!validateHistoryPos(env, historyPos, historySize)) { + if (!validateHistoryPos(env, historyPos, (*event))) { return 0; } return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);