The running validate_pair campaign found a third crash: in aligned
mode a maxLength reservation (ADR-003 strategy 2, VARCHAR(N)) stores
RAW zero-padded data with no length prefix — materialize and
validate_bytes implement exactly that — but read_field read the entry
through data_access::read_string, i.e. parsed the window's first four
bytes as a u32 length prefix. Raw reservation bytes that look like a
large prefix then fail bounds with Access while validate_bytes says
Ok: the validate⇒read agreement lattice breaks on every aligned
maxLength string/bytes field (any schema declaring maxLength in
aligned mode). write_field had the same mismatch (prefix+data into a
raw window).
Engine fix:
- VariableEncoding gains MaxLengthReserved (additive variant, ADR-003
strategy 2). OffsetMap::compute records it for maxLength fields with
the default encoding; maxLength+offset-indirect stays OffsetIndirect
(the pair read is intentional, the window reserves max_len bytes),
preserving the W3-1 combination semantics.
- read_field String/Bytes arms dispatch on MaxLengthReserved → new
data_access::read_reservation_string / read_reservation (raw window
inside-buffer check + NUL trim — the materializer's exact semantics).
- write_field dispatches → new data_access::write_reservation (zero-
pads the window, rejects oversized values with Access).
- materialize_aligned reads MaxLengthReserved through the same new
read_reservation paths (single source of truth; replaces the inline
trim logic with an identical implementation).
- offset_map compute rejects a MaxLengthReserved encoding reaching the
walk with a clean Offset error (recorded, never declared).
- builder round-trips: MaxLengthReserved serializes via maxLength (the
document form), never as an encoding value.
- three engine regression tests: raw-not-prefixed read, zero-pad
write + oversize rejection, validate⇒read_field agreement.
- fuzz/shared validate_pair invariant updated: the W3-1
shorter-than-reservation exemption now applies to offset-indirect
only; reservations assert the full window in-bounds (fixed engine).
- corpus regenerated for generator-consistent numbering (seeds 037-044
relabeled; W3-1/W3-2 artifacts remain 044/045-047 → now 044, 048-050
region) — 48 seeds, replay 30/30 green.
Verification: main crate 573 tests pass; clippy -D warnings clean
(crate + shared); wasm clean; cargo fuzz build clean.