Files
go-kv/.omo
dailz 57e7525ddf fix: validate physical record length > 0 and type (H1+H2)
DecodePhysicalRecord only checked length upper bound, not lower bound
(length > 0 per design §3.2 line 389). It also didn't validate the
fragment type field (RecInvalid=0 and types > RecLast are corruption
indicators per design §3.2 line 366-372).

Corrupt data with length=0 could pass CRC (payload is empty, CRC only
covers length+type bytes) and inject empty records into the fragment
collector. Invalid type values would only be caught at the collector
level, wrapped as TailCorruptionError, rather than rejected at the
parser level.

Changes:
- wal/record.go: DecodePhysicalRecord now rejects length=0 and
  type ∉ {RecFull..RecLast} before payload copy and CRC check.
  Checks are ordered to reject invalid records ASAP.
- wal/record_test.go: 5 tests:
  - TestDecodePhysicalRecord_RejectZeroLength (H1)
  - TestDecodePhysicalRecord_RejectInvalidType (H2, type=0)
  - TestDecodePhysicalRecord_RejectUnknownType (H2, type>RecLast)
  - TestDecodePhysicalRecord_ValidRecordsUnaffected (regression for
    all 4 valid types)
  - TestParseBlockWrapsInvalidRecordAsTailCorruption (integration:
    ParseBlock wraps H1/H2 errors as TailCorruptionError)

Verified: all existing tests pass. Full suite green including
go test -race ./... .

Audit context: docs/audit-3.2.md H1+H2.
2026-06-18 13:59:04 +08:00
..