From d804eb4399850fe828462b3a1832a4c9df1541f8 Mon Sep 17 00:00:00 2001 From: Lena Date: Wed, 1 Jul 2026 00:00:00 +0000 Subject: app: write config atomically A crash mid-write corrupted config.json, and every later load then threw on parse, crash-looping the app until its data was cleared, losing the key and pinned host. Write to a temp file and rename. --- app/src/main/java/invalid/lena/rsend/Config.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/invalid/lena/rsend/Config.kt b/app/src/main/java/invalid/lena/rsend/Config.kt index 8c9c22c..d7f17eb 100644 --- a/app/src/main/java/invalid/lena/rsend/Config.kt +++ b/app/src/main/java/invalid/lena/rsend/Config.kt @@ -4,6 +4,7 @@ import android.content.Context import org.json.JSONArray import org.json.JSONObject import java.io.File +import java.io.IOException // Config is rsend's whole state: the remote target, the schedule, and the // folders to push. It is stored as plain JSON in app-private storage. @@ -64,8 +65,13 @@ data class Config( return fromJson(JSONObject(f.readText())) } + // save writes tmp-then-rename so a crash mid-write cannot corrupt the + // config and brick every later load. fun save(ctx: Context, c: Config) { - file(ctx).writeText(c.toJson().toString(2)) + val f = file(ctx) + val tmp = File(f.path + ".tmp") + tmp.writeText(c.toJson().toString(2)) + if (!tmp.renameTo(f)) throw IOException("rename ${tmp.path} failed") } fun fromJson(o: JSONObject): Config { -- cgit v1.2.3