fix(prefs): recover a preference store whose bytes are not valid UTF-8
`File.readAsString` reports a UTF-8 decode failure as a FileSystemException, not a FormatException, so three guards written for that case never ran. The preflight's `on FormatException` branch was unreachable and its `on FileSystemException` sibling waved the document through; the plugin then threw the same FileSystemException, which failed the FormatException/TypeError test that decides repairability; and quarantine's lossy-decode fallback sat dead behind a rethrow. A store with one bad high byte — a UTF-16 BOM, a stray 0x80 — therefore reached the user as a failure screen with no Repair button and no way forward at all. Read bytes and decode explicitly instead, at both sites. Classification moves into describeStoreDamage, so a failure that surfaces after the preflight passed is judged by re-reading the file rather than by the error's type: a denied or locked store is indistinguishable from a decode failure by type or message, and offering a destructive repair for a permissions problem would reset every setting and risk the vault key over something a chmod fixes. isCorruptStoreError went with it, having no remaining callers. A repair that quarantines the store and then cannot reopen it no longer strands the process either. The repaired future was built straight from the cache loader, bypassing the self-healing reset sharedCache installs, so a failed reopen parked a rejected future in _cacheFuture and every later attempt replayed that stale error — with the damaged file already moved aside, so a restart would have booted cleanly. CorruptPreferenceStoreException now carries reopenSafe and a derived, content-free shape: byte length, whether it decoded, whether every byte is zero. #1732 arrived as "FormatException at offset 0" and nothing else, which cannot separate an all-zero file from a non-JSON first character from bytes that are not UTF-8; these can, and never quote the document. Cover the loop against the real desktop backend rather than a fake. shared_preferences_linux is pure Dart, byte-identical to the Windows implementation, and exposes fs/pathProvider, so pointing it at a temp directory exercises the genuine read, parse, cache and write path on any host — the join between preflight, classification and reopen where every one of these defects lived, and which had no coverage at all.
This commit is contained in:
@@ -99,6 +99,11 @@ dev_dependencies:
|
||||
drift_dev: ^2.28.3
|
||||
shared_preferences_platform_interface: ^2.4.0
|
||||
path_provider_platform_interface: ^2.1.0
|
||||
# Drives the real desktop preference backend against a temp file in tests, so
|
||||
# the #1732 corrupt-store repair loop is covered on any host and not only on
|
||||
# a Windows/Linux runner. Both classes expose `fs`/`pathProvider` for this.
|
||||
shared_preferences_linux: ^2.4.1
|
||||
path_provider_linux: ^2.2.1
|
||||
plugin_platform_interface: ^2.1.0
|
||||
freezed: ^3.2.5
|
||||
analyzer: 10.2.0
|
||||
|
||||
Reference in New Issue
Block a user