fix(AppConfig): prevent config loss on unclean shutdown - #5613
Open
moumoum0 wants to merge 1 commit into
Open
Conversation
Two-layer fix for intermittent total config reset (all settings wiped) caused by NUL-byte corruption of both config.json and its .bak on machines where opening the lid can trigger a spontaneous reboot (Asus TUF / Tian Xuan series ACPI hardware quirk). Layer 1 - dirty-check in Set / Remove Before scheduling a debounced write, compare the incoming value to what is already stored. Skip Write() when nothing changed. This significantly reduces the frequency of disk writes triggered by periodic re-apply calls (ReapplyTimer, fan sensor loop, lid-open / monitor-power events), shrinking the window in which a crash mid-write can corrupt the file. Layer 2 - harden SyncFallbackConfig Previously it did File.Copy(configFile, fallback), so a zeroed primary file would silently overwrite the fallback, destroying the last recovery copy. Now it receives the in-memory JSON string that was just serialized (guaranteed valid) and writes it through WriteAtomic. An additional guard skips the write entirely if the content is empty or contains NUL bytes, ensuring the fallback can never be polluted by a corrupted source.
seerge
force-pushed
the
main
branch
2 times, most recently
from
July 2, 2026 11:17
027e4b6 to
2107c5f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Asus TUF/Tian Xuan laptops have a long-standing hardware bug: opening the lid from sleep can trigger a spontaneous hard reboot — essentially a sudden power loss.
G-Helper's config write logic had a flaw: any call to
Set()would schedule a disk write after 2 seconds, regardless of whether the value actually changed. Lid-open events fire a cascade of system events (monitor wake, power state changes, mode re-application) that all callSet(), but most of them write the exact same values already in memory.The result: lid-open = trigger disk write + trigger reboot, both dangerous operations tied to the same user action. The reboot lands during that brief write window, corrupting both
config.jsonand its.bakbackup into 0x00 bytes. Next launch sees both files trashed, falls through all recovery paths, and resets everything to defaults.Fix (Two layers)
Layer 1: Dirty-check before writing
Added a value-comparison guard in
Set()/Remove(). If the new value equals the existing one, skip the write entirely. This eliminates the vast majority of redundant disk writes triggered by system events, drastically reducing the chance of a crash mid-write.Layer 2: Harden the fallback backup
Previously
SyncFallbackConfigusedFile.Copy(source, fallback), meaning a corrupted primary file would silently overwrite and destroy the backup copy.Now it receives the freshly serialized JSON string (guaranteed valid) and writes it atomically via
WriteAtomic. An additional guard aborts the write if the JSON string is empty or contains NUL bytes, preventing the fallback from being poisoned by corrupted data from the primary file.