str_to_bytes32 / bytes32_to_str (crates/cli/src/meta/mod.rs:918-936 at bba50a7) are not inverses in the presence of NUL bytes:
str_to_bytes32 accepts any string up to 32 bytes, including strings with embedded \0, and right-pads with 0u8.
bytes32_to_str truncates at the FIRST zero byte (find_position(|b| **b == 0u8)).
So the round trip silently loses data:
let b = str_to_bytes32("a\0b")?; // Ok: [0x61, 0x00, 0x62, 0, 0, ...]
assert_eq!(bytes32_to_str(&b)?, "a"); // "b" is gone
Additionally, a string whose own bytes end in \0 (e.g. "a\0") and its unpadded form ("a") map to the same bytes32, so distinct inputs collide.
These functions back word/symbol packing for on-chain interop; a NUL-bearing input is likely invalid there, but nothing rejects it — str_to_bytes32 only errors on length > 32. Options: reject embedded NULs in str_to_bytes32, or document the truncating/collapsing behavior as intended.
Found during round-2 adversarial mutation testing (adjudication A-4).
str_to_bytes32/bytes32_to_str(crates/cli/src/meta/mod.rs:918-936at bba50a7) are not inverses in the presence of NUL bytes:str_to_bytes32accepts any string up to 32 bytes, including strings with embedded\0, and right-pads with0u8.bytes32_to_strtruncates at the FIRST zero byte (find_position(|b| **b == 0u8)).So the round trip silently loses data:
Additionally, a string whose own bytes end in
\0(e.g."a\0") and its unpadded form ("a") map to the same bytes32, so distinct inputs collide.These functions back word/symbol packing for on-chain interop; a NUL-bearing input is likely invalid there, but nothing rejects it —
str_to_bytes32only errors on length > 32. Options: reject embedded NULs instr_to_bytes32, or document the truncating/collapsing behavior as intended.Found during round-2 adversarial mutation testing (adjudication A-4).