Repository navigation
Write verify.json atomically, refuse corrupt files and fix database storage - #5
Merged
Merged
Conversation
…torage writeJson now encodes first, writes to a temporary file in the same directory and renames it into place, so a crash or full disk mid-write cannot leave a truncated list. Invalid UTF-8 in a record is substituted instead of making json_encode fail and writing an empty file. loadJsonFile used to turn any unreadable JSON into an empty list, which the next registration then persisted, silently wiping every verified account. It now throws; the request fails with a clear error instead. JSON_PATH may be absolute (Unix, drive-letter or UNC); it was always prefixed with the working directory. Database storage was unusable past the first record: rows read back carry an uid=0(root) gid=0(root) groups=0(root) column, and feeding them to the named-parameter insert failed with HY000/HY093. The table is now rewritten in a transaction with only the record columns, database mode no longer also writes the JSON file, and the connection is opened through an overridable connect() so the behaviour is covered by an in-memory SQLite test. Also fixes a by-reference return notice in the SS14 state's database read. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WTP2S4qKEFT8a6a6yFEL4
Member
Author
|
2026-11-06: head 09d03ab. Local: Generated by Claude Code |
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.
Requested by Val · project thread
Problem
writeJsondid a plainfile_put_contents. A crash or full disk mid-write leaves a truncatedverify.json.loadJsonFileturned any undecodable file into[](reproduced with a truncated file). The next registration then persisted that empty list, silently wiping every verified account. The bot would keep its cached copy, but the server would start over from zero.json_encodefailure (invalid UTF-8 in a key) wrote an empty file.JSON_PATHwas always prefixed withgetcwd(), so an absolute path such asD:/Civilizationbot/json/verified.jsonwas unusable.HY000 column index out of range): rows read back carry anidcolumn that was fed into the named-parameter insert. It also still wrote the JSON file on every change.SS14PersistentState::getVerifyList()returned an expression by reference (notice).Change
writeJsonencodes first (withJSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR), writes a temporary file beside the target and renames it into place.loadJsonFilethrows on invalid JSON; empty or missing files still load as[].JSON_PATHvalues are used as-is.PersistentState::saveVerifyList()is the single write path for both endpoints: filesystem writes JSON, database rewrites the table in one transaction using only the record columns. The connection comes from an overridableconnect(), so database mode is now covered by an in-memory SQLite test.writeJsonstays static, so the existing offline test subclasses keep working.Compatibility with Civilizationbot
The bot only calls
getState()->getVerifyList(),handleEndpoint, and the SS14 endpoint'sadd/remove/fetch/getIndex; none of those signatures change. Its integration call pattern was replayed against this branch and passed.Verification
New
tests/isolated/StorageIntegrityTest.php.Generated by Claude Code