Fix M1, M2, L1, L3 from code review #002

Four of seven review findings resolved. 5 new tests (391 -> 396 crate
tests; 438 -> 443 total). cargo test, clippy, wasm32 all green.

M2 (data_access.rs): write_bytes now validates data_len fits in u32
before the length-prefix cast. A >4GiB blob returns Access error
instead of silently writing a truncated length prefix (silent data
corruption on read-back).

M1 (builder.rs): Definitions::merge_into rewritten to access self.defs
directly instead of round-tripping through self.build() with a double-
cloned/unwrap_or_default chain that could silently drop definitions
on a shape mismatch. 4 new tests: insert-when-absent, merge-into-
existing, overwrite-duplicate-keys, no-op-on-non-object-top.

L1 (materialize.rs): byte-offset discriminator arm of
materialize_union_packed now uses checked_add for offset+disc_offset
and disc_abs_offset+disc_size, returning Access error on overflow.
Mirrors the existing sequential_reader.rs::read_union_value pattern.

L3 (error.rs): AlkTypeError::source() now returns Some(inner) for the
Validation variant (jsonschema::ValidationError implements
std::error::Error). Existing source_returns_none_for_all_variants
test split into source_returns_none_for_schema_offset_access and
source_returns_some_for_validation_variant.

Deferred: L2 (unreachable! -> Err, defense-in-depth), N1 (non-strict
RFC 3339 validator, docs-only), N2 (FieldValue::Bytes for Record,
API asymmetry). Review doc updated with resolution section.
This commit is contained in:
glm-5.2 committed 2026-08-11 08:41:15 +00:00
1 parent ee6e773123
commit a975befdd1
5 files changed
+187 -15

No files matched your search

+20 -4
View File
@@ -311,15 +311,23 @@ fn materialize_union_packed(
offset: disc_offset,
disc_type,
} => {
let disc_abs_offset = offset.checked_add(disc_offset).ok_or_else(|| {
AlkTypeError::Access {
field_path: field_path.to_string(),
reason: format!(
"discriminator offset {offset} + {disc_offset} overflows usize"
),
}
})?;
let disc_value = match disc_type {
AlkTypeKind::Uint8 => {
data_access::read_u8(buffer, offset + disc_offset, field_path)? as u32
data_access::read_u8(buffer, disc_abs_offset, field_path)? as u32
}
AlkTypeKind::Uint16 => {
data_access::read_u16(buffer, offset + disc_offset, field_path, endian)? as u32
data_access::read_u16(buffer, disc_abs_offset, field_path, endian)? as u32
}
AlkTypeKind::Uint32 => {
data_access::read_u32(buffer, offset + disc_offset, field_path, endian)?
data_access::read_u32(buffer, disc_abs_offset, field_path, endian)?
}
_ => unreachable!("disc_type restricted by parse_discriminator"),
};
@@ -333,7 +341,15 @@ fn materialize_union_packed(
field_path: field_path.to_string(),
reason: format!("union discriminator value {key} not in mapping"),
})?;
let variant_offset = offset + disc_offset + disc_type.type_size().unwrap_or(1);
let disc_size = disc_type.type_size().unwrap_or(1);
let variant_offset = disc_abs_offset.checked_add(disc_size).ok_or_else(|| {
AlkTypeError::Access {
field_path: field_path.to_string(),
reason: format!(
"variant offset {disc_abs_offset} + disc size {disc_size} overflows usize"
),
}
})?;
let (variant_value, new_offset) = materialize_field_packed(
buffer,
root,