From fa1cfe55157e7ab2866e03bc19532cd27e975eb7 Mon Sep 17 00:00:00 2001 From: null Date: Wed, 19 Aug 2026 04:04:25 -0500 Subject: [PATCH] fix: a stray NUL byte made a Kotlin source file binary to git MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AppLockViewModel.kt landed in 1d8d7cc with a single 0x00 at offset 5468, inside the char literal of pin.fill(...). It compiled — Kotlin accepted the raw byte as a character — and every test passed, so nothing caught it except the commit summary reporting "Bin 0 -> 7069 bytes" where every other file showed a line count. That matters more than a stray byte usually would. A source file git treats as binary produces no diff, so this file would have been unreviewable in every future change — and it is the file that decides whether the app is locked. It is written as an explicit unicode escape now, which is what was meant. The two fills in LockSettingsViewModel used a space, blanking a PIN rather than zeroing it, and now use the same escape: the whole point of the call is to leave nothing behind. Verified: `file` reports UTF-8 text, and no tracked source contains a NUL byte — only the images and the Gradle wrapper jar do. Co-Authored-By: Claude Opus 5 (1M context) --- .../feature/lock/LockSettingsViewModel.kt | 4 ++-- .../period/lock/AppLockViewModel.kt | Bin 7069 -> 7074 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/dev/privacyllc/period/feature/lock/LockSettingsViewModel.kt b/app/src/main/kotlin/dev/privacyllc/period/feature/lock/LockSettingsViewModel.kt index 171ccbc..750f6e2 100644 --- a/app/src/main/kotlin/dev/privacyllc/period/feature/lock/LockSettingsViewModel.kt +++ b/app/src/main/kotlin/dev/privacyllc/period/feature/lock/LockSettingsViewModel.kt @@ -76,7 +76,7 @@ class LockSettingsViewModel @Inject constructor( _busy.value = true viewModelScope.launch(handler) { val ok = lock.setPin(pin) - pin.fill(' ') + pin.fill('\u0000') // Stay unlocked in the session that just set the PIN. Without this // the gate flips shut the instant `hasPin` turns true, and the user // is asked for a PIN one second after choosing it — which reads as @@ -101,7 +101,7 @@ class LockSettingsViewModel @Inject constructor( _busy.value = true viewModelScope.launch(handler) { val outcome = lock.check(pin) - pin.fill(' ') + pin.fill('\u0000') if (outcome is UnlockResult.Unlocked) { onVerified() _busy.value = false diff --git a/app/src/main/kotlin/dev/privacyllc/period/lock/AppLockViewModel.kt b/app/src/main/kotlin/dev/privacyllc/period/lock/AppLockViewModel.kt index 1ecced0d9f838a4fa7b3a0818a1473fe7cc37b0c..f353a78fb2ab24e7676fa9179e396c10931c42e4 100644 GIT binary patch delta 19 ZcmbPhzQ}w-j3`@7sR0mdjumxa0{}u<1