You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cargo -Zscript panics on frontmatter including Unicode chars #17270
When running cargo -Zscript on file whose frontmatter contains Unicode chars, Cargo panics with:
thread 'main' (166781) panicked at /rustc/375b1431b7d89d1c2e2bc168c011848ae12b7d14/library/core/src/str/mod.rs:861:21:
end byte index 2 is not a char boundary; it is inside '│' (bytes 1..4 of string)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Steps
Create a file script.rs containing:
---
-│
(The │ is a Unicode char and not ASCII).
Run cargo +nightly -Zscript script.rs. Observe Cargo panics.
Possible Solution(s)
No response
Notes
This was originally reported against rust-analyzer (that copied frontmatter detection from Cargo), in rust-lang/rust-analyzer#22880.
The panic is an off-by-one in the "closing fence has fewer dashes" recovery path in src/util/frontmatter.rs.
nl_fence_pattern is "\n" plus the opening dashes, so the search slice &nl_fence_pattern[0..len] on line 109 is a newline followed by len - 1 dashes. Line 112 consumes up to and including that newline, which leaves only len - 1 dashes guaranteed — but line 114 consumes len bytes. The extra byte is whatever text follows the short fence, and slicing there splits a multi-byte char, which is the panic in the report.
The same off-by-one shows up twice more:
Line 116 computes fewer_dashes = fence_length - len, treating a pattern length as a dash count. ----\n[dependencies]\n--\n reports "1 less" for a fence that is 2 short. The count is one too low whenever the closing fence is short by two or more; it happens to come out right when it is short by exactly one.
The range on line 108 stops at nl_fence_pattern.len() - 1, so len never reaches the value that would match a fence exactly one dash short.
Treating len - 1 as the dash count in all three places fixes the panic and gives the right count for every combination I tried (4/3, 4/2, 4/1, 3/2, 3/1, 5/4, 5/1). Reproduces on current master. There's currently no test covering the fewer-dashes path.
Also worth noting that rust-analyzer vendors this file, so the same panic is rust-lang/rust-analyzer#22880 — fixing it here covers both on their next sync.
Happy to put up a PR with a test if this gets accepted.
Activity
winklemad commentedon Jul 30, 2026
The panic is an off-by-one in the "closing fence has fewer dashes" recovery path in
src/util/frontmatter.rs.nl_fence_patternis"\n"plus the opening dashes, so the search slice&nl_fence_pattern[0..len]on line 109 is a newline followed bylen - 1dashes. Line 112 consumes up to and including that newline, which leaves onlylen - 1dashes guaranteed — but line 114 consumeslenbytes. The extra byte is whatever text follows the short fence, and slicing there splits a multi-byte char, which is the panic in the report.The same off-by-one shows up twice more:
fewer_dashes = fence_length - len, treating a pattern length as a dash count.----\n[dependencies]\n--\nreports "1 less" for a fence that is 2 short. The count is one too low whenever the closing fence is short by two or more; it happens to come out right when it is short by exactly one.nl_fence_pattern.len() - 1, solennever reaches the value that would match a fence exactly one dash short.Treating
len - 1as the dash count in all three places fixes the panic and gives the right count for every combination I tried (4/3, 4/2, 4/1, 3/2, 3/1, 5/4, 5/1). Reproduces on current master. There's currently no test covering the fewer-dashes path.Also worth noting that rust-analyzer vendors this file, so the same panic is rust-lang/rust-analyzer#22880 — fixing it here covers both on their next sync.
Happy to put up a PR with a test if this gets accepted.
test(frontmatter): cover a closing fence shorter than the opening
test(frontmatter): show current behavior for a short closing fence
test(frontmatter): show current behavior for a short closing fence
fix(frontmatter): Don't panic on a short closing fence before a non-A…