summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-20 20:58:23 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-20 20:58:23 +0800
commit5cb4970e2410a43e528b4b3e44dda15fac0a219a (patch)
tree84c2c7618f18c92367c13d8e3667068961c72b9f /src/LivingVillage.Kernel
parent6f904d6f8528bd13941894af3db16d0bc3b0aeb3 (diff)
downloadliving-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.fs6
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