Skip to content

cargo -Zscript panics on frontmatter including Unicode chars #17270

Closed

Description

@ChayimFriedman2

Problem

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

  1. Create a file script.rs containing:
    ---  
    -│
    (The │ is a Unicode char and not ASCII).
  2. 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.

Version

cargo 1.99.0-nightly (59800466c 2026-07-07)
release: 1.99.0-nightly
commit-hash: 59800466c5c41c444d264b1010b4d57e85a7117f
commit-date: 2026-07-07
host: x86_64-unknown-linux-gnu
libgit2: 1.9.4 (sys:0.21.0 vendored)
libcurl: 8.21.0-DEV (sys:0.4.90+curl-8.21.0 vendored ssl:OpenSSL/3.6.3)
ssl: OpenSSL 3.6.3 9 Jun 2026
os: Ubuntu 24.4.0 (noble) [64-bit]

Activity

  1. winklemad commented on Jul 30, 2026

    @winklemad
    Contributor

    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.

  2. added a commit that references this issue on Aug 15, 2026
    2305ac9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bugS-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions