From 9580cdd8a2f816ffbb266af67c10b442c0997f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Mon, 2 Oct 2023 11:47:40 +0200 Subject: [PATCH] Fix various crashes (#401) --- .../org/readium/r2/navigator/R2WebView.kt | 24 ++++++++++++++----- .../readium/r2/shared/asset/AssetRetriever.kt | 2 +- .../iterators/HtmlResourceContentIterator.kt | 13 ++++++---- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt index 4f3b9be446..509e768786 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt @@ -715,7 +715,7 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView if (!isSelecting && !mIsBeingDragged) { mInitialVelocity = getCurrentXVelocity() val pointerIndex = ev.findPointerIndex(mActivePointerId) - val x = ev.getX(pointerIndex) + val x = ev.safeGetX(pointerIndex) val xDiff = abs(x - mLastMotionX) if (xDiff > mTouchSlop) { @@ -736,8 +736,8 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView mHasAbortedScroller = false val activePointerIndex = ev.findPointerIndex(mActivePointerId) - val x = ev.getX(activePointerIndex) - val y = ev.getY(activePointerIndex) + val x = ev.safeGetX(activePointerIndex) + val y = ev.safeGetY(activePointerIndex) if (scrollMode) { val totalDelta = (y - mInitialMotionY).toInt() @@ -786,13 +786,13 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } MotionEvent.ACTION_POINTER_DOWN -> { val index = ev.actionIndex - val x = ev.getX(index) + val x = ev.safeGetX(index) mLastMotionX = x mActivePointerId = ev.getPointerId(index) } MotionEvent.ACTION_POINTER_UP -> { onSecondaryPointerUp(ev) - mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId)) + mLastMotionX = ev.safeGetX(ev.findPointerIndex(mActivePointerId)) } } @@ -878,7 +878,7 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. val newPointerIndex = if (pointerIndex == 0) 1 else 0 - mLastMotionX = ev.getX(newPointerIndex) + mLastMotionX = ev.safeGetX(newPointerIndex) mActivePointerId = ev.getPointerId(newPointerIndex) mVelocityTracker?.clear() } @@ -1092,3 +1092,15 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView } } } + +/** + * May crash with java.lang.IllegalArgumentException: pointerIndex out of range + */ +private fun MotionEvent.safeGetX(pointerIndex: Int): Float = + try { getX(pointerIndex) } catch (e: IllegalArgumentException) { 0F } + +/** + * May crash with java.lang.IllegalArgumentException: pointerIndex out of range + */ +private fun MotionEvent.safeGetY(pointerIndex: Int): Float = + try { getY(pointerIndex) } catch (e: IllegalArgumentException) { 0F } diff --git a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt index ffa426bfc1..2fbfafafd5 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/asset/AssetRetriever.kt @@ -303,7 +303,7 @@ public class AssetRetriever( if (url.isContent) { val contentHints = MediaTypeHints( mediaType = contentResolver.getType(url.uri) - ?.let { MediaType(it)!! } + ?.let { MediaType(it) } ?.takeUnless { it.matches(MediaType.BINARY) }, fileExtension = contentResolver .queryProjection(url.uri, MediaStore.MediaColumns.DISPLAY_NAME) diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt index 0e328ad298..f3ae6937fc 100644 --- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt +++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt @@ -32,9 +32,10 @@ import org.readium.r2.shared.resource.Resource import org.readium.r2.shared.resource.readAsString import org.readium.r2.shared.util.Language import org.readium.r2.shared.util.Url -import org.readium.r2.shared.util.getOrThrow +import org.readium.r2.shared.util.getOrElse import org.readium.r2.shared.util.mediatype.MediaType import org.readium.r2.shared.util.use +import timber.log.Timber /** * Iterates an HTML [resource], starting from the given [locator]. @@ -147,7 +148,11 @@ public class HtmlResourceContentIterator internal constructor( private suspend fun parseElements(): ParsedElements { val document = resource.use { res -> - val html = res.readAsString().getOrThrow() + val html = res.readAsString().getOrElse { + Timber.w(it, "Failed to read HTML resource") + return ParsedElements() + } + Jsoup.parse(html) } @@ -206,8 +211,8 @@ public class HtmlResourceContentIterator internal constructor( * possible. Defaults to 0. */ public data class ParsedElements( - val elements: List, - val startIndex: Int + val elements: List = emptyList(), + val startIndex: Int = 0 ) private class ContentParser(