proofs.rs

Checked decoding changes buffer bytes after the returned length

Checked decoding changes buffer bytes after the returned length

Found in Report #19 v1 · Updated 2026-11-03 23:44 UTC

Description

Checked DecodeBuilder::onto modifies bytes after the returned payload length.

Steps to Reproduce

With bs58 0.5.1 and the check feature enabled, run this example. Its success reproduces the discrepancy:

let encoded = bs58::encode([42]).with_check().into_string();
let mut output = [0xa5; 16];
let len = bs58::decode(encoded).with_check(None).onto(&mut output).unwrap();
assert_eq!(len, 1);
assert_eq!(&output[..5], &[42, 255, 18, 44, 14]);
assert_eq!(&output[5..], &[0xa5; 11]);
Expected Behavior

DecodeBuilder::onto documents the return value as the length written and promises not to touch bytes after the decoded output.

Actual Behavior

Checked decoding writes the four checksum bytes after the payload and then returns only the payload length. The same behavior occurs with cb58; a buffer large enough for just the returned payload is rejected as too small. The demonstrated writes are within the supplied buffer.

Environment

bs58 0.5.1 with check; the analogous path uses cb58.

Additional Context

See upstream issue #133.

Change history
  1. v1 · created · 2026-11-03 23:44 UTC
    {
      "title": "Checked decoding changes buffer bytes after the returned length",
      "body": "## Description\n\nChecked `DecodeBuilder::onto` modifies bytes after the returned payload length.\n\n## Steps to Reproduce\n\nWith bs58 0.5.1 and the `check` feature enabled, run this example. Its success reproduces the discrepancy:\n\n```rust\nlet encoded = bs58::encode([42]).with_check().into_string();\nlet mut output = [0xa5; 16];\nlet len = bs58::decode(encoded).with_check(None).onto(&mut output).unwrap();\nassert_eq!(len, 1);\nassert_eq!(&output[..5], &[42, 255, 18, 44, 14]);\nassert_eq!(&output[5..], &[0xa5; 11]);\n```\n\n## Expected Behavior\n\n`DecodeBuilder::onto` documents the return value as the length written and promises not to touch bytes after the decoded output.\n\n## Actual Behavior\n\nChecked decoding writes the four checksum bytes after the payload and then returns only the payload length. The same behavior occurs with `cb58`; a buffer large enough for just the returned payload is rejected as too small. The demonstrated writes are within the supplied buffer.\n\n## Environment\n\nbs58 0.5.1 with `check`; the analogous path uses `cb58`.\n\n## Additional Context\n\nSee [upstream issue #133](https://github.com/Nullus157/bs58-rs/issues/133).",
      "validity": "reported",
      "upstream_status": "not_reported"
    }

Read and join the discussion on the report →