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:
glm-5.2 committed 2026-08-11 09:02:56 +00:00
1 parent a975befdd1
commit 5f88bca0d8
4 files changed
+62 -13

No files matched your search

+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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"),
}),
}
}