#3: SocketIoFrame.Parse now range-checks the packet type char (was
unchecked cast — any char outside 0-6 produced an undefined enum
value) and uses int.TryParse for ack-id (was int.Parse — a >10-digit
ack-id threw OverflowException, tearing down the WS mid-game). Both
now throw ArgumentException consistently. The read loop in
RealParticipant wraps both EIO and SIO parse calls with try-catch so
a malformed frame is logged and skipped instead of killing the battle.
#4: MatchedSelfInfo/MatchedOppoInfo OppoId and Seed narrowed from
long to int. The client reads both with Convert.ToInt32 inside a
swallowing try/catch — any value > int.MaxValue silently dropped the
Matched event, preventing the battle from starting. Seed was already
int-range (BattleSeeds.Stable returns int); OppoId (viewer ID) is
~847M in captures, well under int.MaxValue. The narrowing cast now
happens explicitly in ServerBattleFrames.BuildMatched at the wire
boundary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Wrap all JsonDocument.Parse calls in using blocks and Clone() each
retained JsonElement to eliminate UAF hazard after GC.
- Use JsonSerializer.Serialize with UnsafeRelaxedJsonEscaping so event
names with " or \ produce \" / \ rather than " / plain \;
avoids malformed JSON on Encode().
- Guard the [ ] block in Encode() behind EventName-or-args check so
Connect/Disconnect packets round-trip as bare "0"/"1" not "0[]".
- Add three regression tests: Connect no-bracket, Event round-trip,
special-char event name escaping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace inaccurate GenerateKey docstring (it claimed to port Cryptographer.generateKeyString
directly but the input shape differs: server uses one hex digit per call, client uses
Random.Next(0,65535) per call). New doc is honest about the difference and explains why
it's safe. Add EncryptForNode_FixedVector_ProducesStableOutput: a pinned AES-CBC vector
that catches encoding/IV/padding regressions that would slip past the roundtrip test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>