diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-20 20:58:23 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-20 20:58:23 +0800 |
| commit | 5cb4970e2410a43e528b4b3e44dda15fac0a219a (patch) | |
| tree | 84c2c7618f18c92367c13d8e3667068961c72b9f /src/LivingVillage.Kernel | |
| parent | 6f904d6f8528bd13941894af3db16d0bc3b0aeb3 (diff) | |
| download | living-village-5cb4970e2410a43e528b4b3e44dda15fac0a219a.tar.gz | |
feat(m6a): add file save acceptance smoke
[Change Nature]
This commit adds the bounded M6a file-save acceptance path.
[New Capability]
- Add file-level round-trip and deterministic continuation coverage.
- Add Headless --m6a-smoke with digest checks and explicit PASS/FAIL output.
[Implementation]
- Reject non-finite numeric values and negative inventory quantities.
- Exercise dialogue, chat/rumor, trade, events, annals, time, and RNG state.
[Impact]
- Affects Kernel save parsing, Kernel tests, and Headless smoke tooling.
- Preserves the existing save format and M5 smoke behavior.
Diffstat (limited to 'src/LivingVillage.Kernel')
| -rw-r--r-- | src/LivingVillage.Kernel/WorldSave.fs | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/LivingVillage.Kernel/WorldSave.fs b/src/LivingVillage.Kernel/WorldSave.fs index 726170b..8a47c7d 100644 --- a/src/LivingVillage.Kernel/WorldSave.fs +++ b/src/LivingVillage.Kernel/WorldSave.fs @@ -72,13 +72,13 @@ module WorldSave = let private readFloat (reader: TokenReader) label = let token = reader.Take(label) match Double.TryParse(token, NumberStyles.Float, invariant) with - | true, value -> value + | true, value when not (Double.IsNaN(value) || Double.IsInfinity(value)) -> value | _ -> invalid (sprintf "invalid %s" label) let private readFloat32 (reader: TokenReader) label = let token = reader.Take(label) match Single.TryParse(token, NumberStyles.Float, invariant) with - | true, value -> value + | true, value when not (Single.IsNaN(value) || Single.IsInfinity(value)) -> value | _ -> invalid (sprintf "invalid %s" label) let private readBool (reader: TokenReader) label = @@ -450,6 +450,8 @@ module WorldSave = [ for index in 0 .. count - 1 do let item = readItemKind reader (sprintf "%s[%d].item" label index) let quantity = readInt reader (sprintf "%s[%d].quantity" label index) + if quantity < 0 then + invalid (sprintf "invalid %s[%d].quantity" label index) yield item, quantity ] |> Map.ofList |
