From 4ded0b06035d9e69ef88c5ccd0a794eb3104ad5c Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Thu, 26 May 2022 00:36:48 +0000 Subject: Validate indices when requesting PointerCoords We are investigating a crash in PointerCoords. To further understand what kind of MotionEvents we are dealing with, let's add some assertions to the PointerCoords that we are producing. It's possible that pointerCount is zero, for example. This would help us further narrow down the issue. In this CL, we are also adding a way to dump MotionEvent. This was loosely following MotionEvent.java::toString() method. At some point, we should remove the Java method implementation and replace it with a single jni call to native. That work is out of scope for this CL. In the jni layer, we can't remove the error checking/exception raising, because someone might be catching an exception and moving on, and a native crash would break this pattern. We can consider doing that in the future under an experiment flag, though. Bug: 233163975 Test: printed MotionEvent in log to see the formatting Change-Id: I4f641c0cb89526a06146e4c0cf3a5fab2faa42f8 --- libs/input/Input.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) (limited to 'libs/input/Input.cpp') diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index fe1754c78b..13ca9ecd35 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -22,7 +22,9 @@ #include #include +#include #include +#include #include #include #include @@ -542,7 +544,14 @@ void MotionEvent::setCursorPosition(float x, float y) { } const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const { - return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex]; + if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) { + LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this; + } + const size_t position = getHistorySize() * getPointerCount() + pointerIndex; + if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) { + LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this; + } + return &mSamplePointerCoords[position]; } float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { @@ -555,7 +564,18 @@ float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { const PointerCoords* MotionEvent::getHistoricalRawPointerCoords( size_t pointerIndex, size_t historicalIndex) const { - return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex]; + if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) { + LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this; + } + if (CC_UNLIKELY(historicalIndex < 0 || historicalIndex > getHistorySize())) { + LOG(FATAL) << __func__ << ": Invalid historical index " << historicalIndex << " for " + << *this; + } + const size_t position = historicalIndex * getPointerCount() + pointerIndex; + if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) { + LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this; + } + return &mSamplePointerCoords[position]; } float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, @@ -903,6 +923,53 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source, return out; } +std::ostream& operator<<(std::ostream& out, const MotionEvent& event) { + out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction()); + if (event.getActionButton() != 0) { + out << ", actionButton=" << std::to_string(event.getActionButton()); + } + const size_t pointerCount = event.getPointerCount(); + for (size_t i = 0; i < pointerCount; i++) { + out << ", id[" << i << "]=" << event.getPointerId(i); + float x = event.getX(i); + float y = event.getY(i); + if (x != 0 || y != 0) { + out << ", x[" << i << "]=" << x; + out << ", y[" << i << "]=" << y; + } + int toolType = event.getToolType(i); + if (toolType != AMOTION_EVENT_TOOL_TYPE_FINGER) { + out << ", toolType[" << i << "]=" << toolType; + } + } + if (event.getButtonState() != 0) { + out << ", buttonState=" << event.getButtonState(); + } + if (event.getClassification() != MotionClassification::NONE) { + out << ", classification=" << motionClassificationToString(event.getClassification()); + } + if (event.getMetaState() != 0) { + out << ", metaState=" << event.getMetaState(); + } + if (event.getEdgeFlags() != 0) { + out << ", edgeFlags=" << event.getEdgeFlags(); + } + if (pointerCount != 1) { + out << ", pointerCount=" << pointerCount; + } + if (event.getHistorySize() != 0) { + out << ", historySize=" << event.getHistorySize(); + } + out << ", eventTime=" << event.getEventTime(); + out << ", downTime=" << event.getDownTime(); + out << ", deviceId=" << event.getDeviceId(); + out << ", source=" << inputEventSourceToString(event.getSource()); + out << ", displayId=" << event.getDisplayId(); + out << ", eventId=" << event.getId(); + out << "}"; + return out; +} + // --- FocusEvent --- void FocusEvent::initialize(int32_t id, bool hasFocus) { -- cgit v1.2.3-59-g8ed1b