Skip to content

str_to_bytes32 accepts embedded NULs that bytes32_to_str silently truncates: round trip loses data and distinct inputs collide #233

Description

@thedavidmeister

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    adversarialFound by adversarial review/mutation testingauditAudit finding; counted by the org health scan

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions