Fix L2: replace unreachable! with Err for untrusted-schema safety
The immediate downstream consumer (alkcall) accepts schemas from
arbitrary internet peers in its hub/spoke topology. A panic is the
wrong failure mode for a malicious or unsupported schema - an Err
the caller can handle is correct.
Three sites converted:
- offset_map.rs: _ => Err(Offset { unsupported AlkType kind for
aligned offset computation })
- layout_builder.rs: _ => Err(Offset { unsupported AlkType kind
for packed layout computation })
- materialize.rs: _ => Err(Schema { internal: union discriminator
type N is not a supported byte discriminator })
The materialize.rs site uses Schema (not Access) because a wrong
disc_type is a schema-authoring bug (parse_discriminator should have
caught it), not a buffer-access error. The sibling sites in
sequential_reader.rs and tunion.rs already returned Err(Schema) -
only materialize.rs was the holdout.
Note: the k if k.is_fixed_size() guard in offset_map and
layout_builder means the compiler cannot enforce exhaustiveness at
compile time. Converting _ from unreachable! to Err is the runtime
mitigation. A future refactor could list all fixed-size kinds
explicitly to restore compile-time checking. Deferred to a separate
cleanup pass.
Verified: no unreachable! remains in production code (the one
remaining hit at offset_map.rs:688 is inside a #[test] fn).
cargo test --release: 396 tests pass, 0 failures
cargo clippy --all-targets -- -D warnings: clean
cargo build --target wasm32-unknown-unknown --release: clean (prior)
This commit is contained in:
1 parent
a975befdd1
commit
5f88bca0d8
4 files changed
+62
-13
No files matched your search
@@ -282,7 +282,10 @@ impl<'a> BuildCtx<'a> {
|
||||
self.push(field_path, start, size, k);
|
||||
Ok(())
|
||||
}
|
||||
_ => unreachable!("all AlkTypeKind variants are covered above"),
|
||||
other => Err(AlkTypeError::Offset {
|
||||
field_path: field_path.to_string(),
|
||||
reason: format!("unsupported AlkType kind {other} for packed layout computation"),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -329,7 +329,12 @@ fn materialize_union_packed(
|
||||
AlkTypeKind::Uint32 => {
|
||||
data_access::read_u32(buffer, disc_abs_offset, field_path, endian)?
|
||||
}
|
||||
_ => unreachable!("disc_type restricted by parse_discriminator"),
|
||||
other => {
|
||||
return Err(AlkTypeError::Schema(format!(
|
||||
"internal: union discriminator type {other} is not a supported byte \
|
||||
discriminator (parse_discriminator should have rejected this)"
|
||||
)));
|
||||
}
|
||||
};
|
||||
let mapping = field_schema.get("mapping").and_then(Value::as_object).ok_or_else(|| {
|
||||
AlkTypeError::Schema(format!(
|
||||
|
||||
+4
-1
@@ -274,7 +274,10 @@ impl<'a> ComputeCtx<'a> {
|
||||
k if k.is_fixed_size() => {
|
||||
self.compute_fixed_field(k, field_schema, field_path, struct_default_align)
|
||||
}
|
||||
_ => unreachable!("all AlkTypeKind variants are covered above"),
|
||||
other => Err(AlkTypeError::Offset {
|
||||
field_path: field_path.to_string(),
|
||||
reason: format!("unsupported AlkType kind {other} for aligned offset computation"),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user