From 87f0a581c9c4c40add4c98a6995f2f1bda67aba6 Mon Sep 17 00:00:00 2001 From: Cole Munz Date: Sun, 30 Aug 2026 12:49:53 -0500 Subject: [PATCH] catch SecurityException from contentResolver.openInputStream in the share flow ContentResolver.openInputStream() throws SecurityException, not FileNotFoundException, when the app no longer has access to a content:// URI - e.g. a MediaStore URI shared in from another app whose temporary read grant already expired. The share screen only caught FileNotFoundException around these calls, so an expired grant crashed the app instead of failing gracefully like every other already-handled read error. Catch SecurityException the same way FileNotFoundException is already handled in checkProof/proofExists, generateProof, and generateMultiProof - treat it as can't-read-this-media and let the UI fall back to its existing no-proof/error state instead of dying. Fixes #137 --- .../org/witness/proofmode/share/ShareProofActivity.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/org/witness/proofmode/share/ShareProofActivity.kt b/app/src/main/java/org/witness/proofmode/share/ShareProofActivity.kt index 7a56f39e..e05ee520 100644 --- a/app/src/main/java/org/witness/proofmode/share/ShareProofActivity.kt +++ b/app/src/main/java/org/witness/proofmode/share/ShareProofActivity.kt @@ -267,6 +267,8 @@ class ShareProofActivity : AppCompatActivity() { generateProof(mediaUri, proofHash, mimeType!!) } catch (fe: FileNotFoundException) { proofHash = null + } catch (se: SecurityException) { + proofHash = null } } } @@ -1175,6 +1177,8 @@ class ShareProofActivity : AppCompatActivity() { ) } catch (fe: FileNotFoundException) { Timber.d("FileNotFound: %s", mediaUri) + } catch (se: SecurityException) { + Timber.d("no access to media URI: %s", mediaUri) } } @@ -1196,6 +1200,13 @@ class ShareProofActivity : AppCompatActivity() { } catch (e: FileNotFoundException) { Timber.w(e) null + } catch (e: SecurityException) { + // The URI's read grant can be gone by the time we get here (e.g. a + // MediaStore URI shared from another app whose temporary permission + // already expired). Treat it the same as "no proof yet" instead of + // crashing the share screen. + Timber.w(e, "no access to media URI: %s", mediaUri) + null } }