Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions crates/bytes-str/RUSTSEC-0000-0000.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
```toml
[advisory]
id = "RUSTSEC-0000-0000"
package = "bytes-str"
date = "2026-03-11"
url = "https://github.com/dudykr/ddbase/issues/90"
informational = "unsound"
categories = ["memory-corruption"]
keywords = ["soundness", "utf-8", "char-boundary", "invalid-str"]

[versions]
patched = []
unaffected = []
```

# `BytesString::split_off` can break UTF-8 invariants

`BytesString::split_off` does not validate UTF-8 character boundaries, but `BytesString::as_str` uses `from_utf8_unchecked` and assumes the internal buffer remains valid UTF-8. Safe code can construct a valid `BytesString`, split at a non-character boundary, then obtain an invalid `&str` through `as_str`, leading to undefined behavior when the string is iterated. The upstream issue suggests adding character-boundary checks (or panicking) in `split_off` and similar index-based operations.

No patched version is currently available. The issue affects the reported version `0.2.7`.

In addition, the crate appears to be unmaintained. The maintainer has been contacted via this public issue and has not responded for over three months, and the repository shows no visible maintenance activity for roughly eleven months.

## Example

```rust
use bytes_str::BytesString;

fn main() {
// Valid UTF-8 for "é" = [0xC3, 0xA9]
let mut s = BytesString::from_utf8_slice(b"\xC3\xA9").unwrap();

// Split inside a multi-byte code point (safe call)
let _ = s.split_off(1);

// as_str assumes UTF-8 invariant and returns &str
let corrupted = s.as_str();

// This triggers UB under Miri
let _ = corrupted.chars().next();
}
```

## Miri output

```text
Corrupted bytes: [195]
error: Undefined Behavior: entering unreachable code
--> /home/yilin/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/str/validations.rs:48:23
|
48 | let y = unsafe { *bytes.next().unwrap_unchecked() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `core::str::validations::next_code_point::<'_, std::slice::Iter<'_, u8>>` at /home/yilin/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/str/validations.rs:48:23: 48:54
= note: inside `<std::str::Chars<'_> as std::iter::Iterator>::next` at /home/yilin/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/str/iter.rs:42:18: 42:49
note: inside `main`
--> src/main.rs:13:46
|
13 | ...ng chars: {:?}", corrupted_str.chars().next());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error
```