From 1f75e63c37ee3ff0c25506389dc8a56ec7f141a6 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 2 Aug 2019 01:16:04 -0700 Subject: [PATCH] Fix crashes in MarkdownWindow Fix #1628 --- app/build.gradle | 2 +- .../topjohnwu/magisk/view/MarkDownWindow.kt | 49 ++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fff945444..2baf3e63f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,7 +39,7 @@ android { exclude '/META-INF/*.kotlin_module' exclude '/META-INF/rxkotlin.properties' exclude '/androidsupportmultidexversion.txt' - exclude '/org/**' + exclude '/org/bouncycastle/**' exclude '/kotlin/**' exclude '/kotlinx/**' } diff --git a/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.kt b/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.kt index 1a1f82b67..4a814104a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.kt @@ -8,11 +8,13 @@ import com.skoumal.teanity.extensions.subscribeK import com.topjohnwu.magisk.R import com.topjohnwu.magisk.data.repository.StringRepository import com.topjohnwu.magisk.extensions.inject +import io.reactivex.Completable import io.reactivex.Single import ru.noties.markwon.Markwon import ru.noties.markwon.html.HtmlPlugin import ru.noties.markwon.image.ImagesPlugin import ru.noties.markwon.image.svg.SvgPlugin +import timber.log.Timber import java.io.InputStream import java.util.* @@ -33,26 +35,35 @@ object MarkDownWindow { } fun show(activity: Context, title: String?, content: Single) { - content.subscribeK { - val markwon = Markwon.builder(activity) - .usePlugin(HtmlPlugin.create()) - .usePlugin(ImagesPlugin.create(activity)) - .usePlugin(SvgPlugin.create(activity.resources)) - .build() - val alert = AlertDialog.Builder(activity) - alert.setTitle(title) - val mv = LayoutInflater.from(activity).inflate(R.layout.markdown_window, null) - val tv = mv.findViewById(R.id.md_txt) - try { - markwon.setMarkdown(tv, it) - } catch (e: ExceptionInInitializerError) { - //Nothing we can do about this error other than show error message - tv.setText(R.string.download_file_error) - } + val markwon = Markwon.builder(activity) + .usePlugin(HtmlPlugin.create()) + .usePlugin(ImagesPlugin.create(activity)) + .usePlugin(SvgPlugin.create(activity.resources)) + .build() + val mv = LayoutInflater.from(activity).inflate(R.layout.markdown_window, null) + val tv = mv.findViewById(R.id.md_txt) - alert.setView(mv) - alert.setNegativeButton(R.string.close) { dialog, _ -> dialog.dismiss() } - alert.show() + content.map { + runCatching { + markwon.setMarkdown(tv, it) + }.onFailure { + Timber.e(it) + // Always wrap the actual exception as it could be ExceptionInInitializerError, + // which is a fatal error and RxJava will send it to the global handler and crash + throw MarkwonException(it) + } + }.ignoreElement().onErrorResumeNext { + // Nothing we can actually do other than show error message + tv.setText(R.string.download_file_error) + Completable.complete() + }.subscribeK { + AlertDialog.Builder(activity) + .setTitle(title) + .setView(mv) + .setNegativeButton(R.string.close) { dialog, _ -> dialog.dismiss() } + .show() } } + + class MarkwonException(e: Throwable): Exception(e) }