fix(data): align android_keystore temp extension with cleanup glob (M-21)

The keystore atomic write used path.with_extension("tmp") producing
auth_tokens.tmp, while cleanup_orphaned_tmp_files only matched *.json.tmp.
A crash after the write but before the rename left an orphaned file
invisible to cleanup.

Fix: use path.with_extension("bin.tmp") to produce auth_tokens.bin.tmp,
and broaden the cleanup glob from ends_with(".json.tmp") to
ends_with(".tmp") so both JSON and binary temp files are caught.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-17 21:26:23 -07:00
parent 0ecc1a92fd
commit 2301cc65d3
2 changed files with 5 additions and 5 deletions
+2 -2
View File
@@ -295,9 +295,9 @@ fn read_file_bytes() -> Result<Vec<u8>, TokenError> {
fn write_file_bytes(data: &[u8]) -> Result<(), TokenError> { fn write_file_bytes(data: &[u8]) -> Result<(), TokenError> {
let path = token_file_path() let path = token_file_path()
.ok_or_else(|| TokenError::KeychainUnavailable("no data dir".into()))?; .ok_or_else(|| TokenError::KeychainUnavailable("no data dir".into()))?;
let tmp = path.with_extension("tmp"); let tmp = path.with_extension("bin.tmp");
std::fs::write(&tmp, data) std::fs::write(&tmp, data)
.map_err(|e| TokenError::Keyring(format!("write auth_tokens.tmp: {e}")))?; .map_err(|e| TokenError::Keyring(format!("write auth_tokens.bin.tmp: {e}")))?;
std::fs::rename(&tmp, &path) std::fs::rename(&tmp, &path)
.map_err(|e| TokenError::Keyring(format!("rename auth_tokens: {e}"))) .map_err(|e| TokenError::Keyring(format!("rename auth_tokens: {e}")))
} }
+3 -3
View File
@@ -122,7 +122,7 @@ pub fn delete_game_state_at(path: &Path) -> io::Result<()> {
} }
} }
/// Remove any leftover `*.json.tmp` files in the app data directory. /// Remove any leftover `*.tmp` files in the app data directory.
/// ///
/// These can be left behind if the process crashes between the write and rename /// These can be left behind if the process crashes between the write and rename
/// in an atomic save. Safe to call on startup; missing or unreadable entries /// in an atomic save. Safe to call on startup; missing or unreadable entries
@@ -266,7 +266,7 @@ pub fn time_attack_session_with_now(remaining_secs: f32, wins: u32) -> TimeAttac
} }
} }
/// Inner helper: delete `*.json.tmp` entries inside `dir`. /// Inner helper: delete `*.tmp` entries inside `dir`.
/// ///
/// Per-file errors (already deleted, permission denied) are silently ignored. /// Per-file errors (already deleted, permission denied) are silently ignored.
fn cleanup_tmp_files_in(dir: &Path) { fn cleanup_tmp_files_in(dir: &Path) {
@@ -276,7 +276,7 @@ fn cleanup_tmp_files_in(dir: &Path) {
if path if path
.file_name() .file_name()
.and_then(|n| n.to_str()) .and_then(|n| n.to_str())
.is_some_and(|n| n.ends_with(".json.tmp")) .is_some_and(|n| n.ends_with(".tmp"))
{ {
let _ = fs::remove_file(&path); let _ = fs::remove_file(&path);
} }