fix(crash): keep event/calendar content out of exception messages

Audit of our own throw sites, since exception messages land verbatim in
the stack trace a crash report carries. Redacts the three that could hold
user content; the rest only carry numeric ids/timestamps (metadata, kept
for debugging):

- create-local-calendar: drop the user-typed calendar name.
- toContentValues unsupported-type: log the value's type, never the value
  (a cell can be an event title/description/location).
- ics export open-failure: log only the Uri scheme, not the full Uri
  (which can embed the user's chosen filename).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-18 17:13:26 +02:00
parent 701077f25b
commit 2431abe912
2 changed files with 6 additions and 3 deletions

View File

@@ -204,7 +204,8 @@ class AndroidCalendarDataSource @Inject constructor(
putDescription(description) putDescription(description)
} }
val uri = resolver.insert(localCalendarsUri(), values) val uri = resolver.insert(localCalendarsUri(), values)
?: throw WriteFailedException("create local calendar '$name'") // No calendar name in the message — it can reach a crash report.
?: throw WriteFailedException("create local calendar")
return ContentUris.parseId(uri) return ContentUris.parseId(uri)
} }
@@ -685,7 +686,8 @@ class AndroidCalendarDataSource @Inject constructor(
is String -> cv.put(column, value) is String -> cv.put(column, value)
is Long -> cv.put(column, value) is Long -> cv.put(column, value)
is Int -> cv.put(column, value) is Int -> cv.put(column, value)
else -> error("Unsupported value for $column: $value") // Only the type, never the value — a cell value can be event content.
else -> error("Unsupported value type for column '$column': ${value::class.simpleName}")
} }
} }
} }

View File

@@ -24,7 +24,8 @@ class IcsExporter @Inject constructor(
fun writeDocument(uri: Uri, content: String) { fun writeDocument(uri: Uri, content: String) {
context.contentResolver.openOutputStream(uri)?.use { out -> context.contentResolver.openOutputStream(uri)?.use { out ->
out.write(content.toByteArray(Charsets.UTF_8)) out.write(content.toByteArray(Charsets.UTF_8))
} ?: throw IOException("Could not open $uri for writing") // Only the scheme — the full Uri can embed the user's chosen filename.
} ?: throw IOException("Could not open output stream for export (scheme=${uri.scheme})")
} }
/** /**