From 7dd234de37da68f6edbcd1857af225ce2f685fd5 Mon Sep 17 00:00:00 2001 From: xhon-pelushi Date: Thu, 13 Aug 2026 00:43:52 -0400 Subject: [PATCH] Avoid crash opening large text files in built-in editor BrowseFilesPresenter.viewFile() routed .txt/.md/.todo files to the built-in text editor with no size check. TextEditorPresenter reads the whole file into a String for the EditText, so memory use scales with file size; a ~15 MB file kills the process and locks all vaults. Skip the internal editor for files above 2 MiB and fall back to opening them with an external app instead, matching the existing behavior for other unsupported file types. Fixes #654 --- .../presentation/presenter/BrowseFilesPresenter.kt | 9 +++++++++ presentation/src/main/res/values/strings.xml | 1 + 2 files changed, 10 insertions(+) diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt index 913a931672..3d1f1b38ef 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt @@ -509,6 +509,11 @@ class BrowseFilesPresenter @Inject constructor( // private fun viewFile(cloudFile: CloudFileModel) { val lowerFileName = cloudFile.name.lowercase() if (lowerFileName.endsWith(".txt") || lowerFileName.endsWith(".md") || lowerFileName.endsWith(".todo")) { + if ((cloudFile.size ?: 0) > MAX_TEXT_EDITOR_FILE_SIZE) { + view?.showMessage(R.string.screen_file_browser_msg_text_file_too_large_for_editor) + viewExternalFile(cloudFile) + return + } val intent = Intents.textEditorIntent() .withTextFile(cloudFile) .withHubWriteAllowed(licenseEnforcer.hasWriteAccessForVault(view?.folder?.vault())) @@ -1273,6 +1278,10 @@ class BrowseFilesPresenter @Inject constructor( // const val OPEN_FILE_FINISHED = 12 + // The built-in text editor reads the whole file into a String and hands it to an EditText, + // so memory use scales with file size. Files above this size are opened with an external app instead. + private const val MAX_TEXT_EDITOR_FILE_SIZE = 2L shl 20 // 2 MiB + val EXPORT_AFTER_APP_CHOOSER: ExportOperation = object : ExportOperation { override fun export(presenter: BrowseFilesPresenter, downloadFiles: List) { presenter.copyFile(downloadFiles) diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index b5c41279c3..3bd2bcb079 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -174,6 +174,7 @@ Move Empty folder + File is too large for the built-in editor, opening with another app %1$s modified %1$s ago