Hi!
We are a team of researchers studying memory safety in Rust. As part of our ongoing research, we tested str_stack (version: 0.1.0) and found that the following code snippet is reported as undefined behavior by Miri:
Minimal Problematic Snippet
#![feature(allocator_api)]
extern crate alloc;
use str_stack::*;
fn main() {
let mut v4 = <StrStack as std::default::Default>::default();
println!("v4: {:?}",v4);
}
Miri Error Excerpt
error: Undefined Behavior: `assume` called with `false`
--> /workspace/src/lib.rs:63:30
|
63 | let start = *self.ends.get_unchecked(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `<str_stack::Iter<'_> as std::iter::Iterator>::next` at /workspace/src/lib.rs:63:30: 63:56
= note: inside `std::fmt::DebugList::<'_, '_>::entries::<&str, str_stack::Iter<'_>>` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:787:22: 787:29
= note: inside `<str_stack::StrStack as std::fmt::Debug>::fmt` at /workspace/src/lib.rs:50:9: 50:44
= note: inside `core::fmt::rt::Argument::<'_>::fmt` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/rt.rs:152:76: 152:95
= note: inside `std::fmt::write` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:1684:17: 1686:80
= note: inside `std::io::default_write_fmt::<std::io::StdoutLock<'_>>` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:614:11: 614:40
= note: inside `<std::io::StdoutLock<'_> as std::io::Write>::write_fmt` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:1969:13: 1969:42
= note: inside `<&std::io::Stdout as std::io::Write>::write_fmt` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:834:9: 834:36
= note: inside `<std::io::Stdout as std::io::Write>::write_fmt` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:808:9: 808:33
= note: inside `std::io::stdio::print_to::<std::io::Stdout>` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:1164:21: 1164:47
= note: inside `std::io::_print` at /root/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:1275:5: 1275:37
note: inside `main`
--> src/main.rs:12:5
|
12 | println!("v4: {:?}",v4);
| ^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error
Root-Cause Hypothesis
After analyzing the Miri report and the source code, we assume the UB is rooted in:
- Suspect location: src/lib.rs:63 (Iter::next) and src/lib.rs:50 (StrStack::fmt)
- Invariant being broken: Iter assumes ends.len() >= 1, but the derived Default leaves ends empty ([]).
- Causality chain: input creates StrStack::default() -> Debug formatting calls StrStack::fmt -> Iter::next runs get_unchecked(0/1) on an empty ends vector -> Miri reports Undefined Behavior (
assume called with false).
Command used:
MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-tree-borrows" RUSTFLAGS=-Awarnings RUST_BACKTRACE=1 cargo miri run
Possible Fix
- Implement
Default manually as StrStack::new() (or initialize ends with [0]) so iterator invariants hold before any safe API reads.
- Add a regression test that calls
format!("{:?}", StrStack::default()) and runs under Miri in CI.
We would appreciate it if you could take a look and confirm whether this behavior indicates a real issue, or if it is a false positive / expected limitation of Miri.
Thank you very much for your time and for maintaining this great project!
Hi!
We are a team of researchers studying memory safety in Rust. As part of our ongoing research, we tested str_stack (version: 0.1.0) and found that the following code snippet is reported as undefined behavior by Miri:
Minimal Problematic Snippet
Miri Error Excerpt
Root-Cause Hypothesis
After analyzing the Miri report and the source code, we assume the UB is rooted in:
assumecalled with false).Command used:
MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-tree-borrows" RUSTFLAGS=-Awarnings RUST_BACKTRACE=1 cargo miri runPossible Fix
Defaultmanually asStrStack::new()(or initializeendswith[0]) so iterator invariants hold before any safe API reads.format!("{:?}", StrStack::default())and runs under Miri in CI.We would appreciate it if you could take a look and confirm whether this behavior indicates a real issue, or if it is a false positive / expected limitation of Miri.
Thank you very much for your time and for maintaining this great project!