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:
1 parent
ee6e773123
commit
a975befdd1
5 files changed
+187
-15
No files matched your search
+20
-4
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user