Commit 8ced37b
## Summary
`skip_cartouche_end` advanced its byte index by 1 in the no-open /
no-close branch, which puts `j` inside a multi-byte UTF-8 sequence when
the cartouche body contains non-ASCII (`¬`, `∀`, `⟹`, `🎉`, etc.). The
next iteration's `haystack[j..].starts_with(open)` then panics:
```
thread 'main' panicked at src/assail/analyzer.rs:5648:20:
start byte index 89 is not a char boundary; it is inside '¬' (bytes 88..90)
```
## Discovery
`./target/release/panic-attack assail
/home/hyperpolymath/developer/repos/echidna` from the 2026-05-26 estate
reconnaissance crashed on a real `.thy` file inside echidna:
```
text \<open>
Double negation elimination: ¬¬A is equivalent to A.
...
\<close>
```
Subsetting echidna to `src/` worked around it; this is the proper fix.
## Fix
In the no-open / no-close branch, advance by `len_utf8()` of the current
char rather than 1 byte. `chars().next()` is guaranteed non-empty there
because `j < haystack.len()`.
## Tests
Two new regression tests in `assail::analyzer::tests`:
- `isabelle_cartouche_with_non_ascii_does_not_panic` — sampled body from
the actual crash (`¬¬A`, `∀x`, `⟹`).
- `isabelle_cartouche_emoji_grapheme_clusters` — 4-byte UTF-8 (🎉)
exercises the full multi-byte range, including the path that 2/3-byte
chars wouldn't catch.
## Test plan
- [x] `cargo test --lib assail::analyzer::tests::isabelle` — **10/10
pass** (8 existing + 2 new).
- [x] `cargo build --release` clean.
- [x] Reproducer: `./target/release/panic-attack assail
/home/hyperpolymath/developer/repos/echidna` now completes cleanly with
**44 weak points** (was: panic).
- [ ] CI on this PR.
Regression from #49 (Isabelle prose-stripper added in 2026-05-26).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c7e7fb0 commit 8ced37b
1 file changed
Lines changed: 40 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5641 | 5641 | | |
5642 | 5642 | | |
5643 | 5643 | | |
| 5644 | + | |
| 5645 | + | |
| 5646 | + | |
| 5647 | + | |
| 5648 | + | |
5644 | 5649 | | |
5645 | 5650 | | |
5646 | 5651 | | |
| |||
5652 | 5657 | | |
5653 | 5658 | | |
5654 | 5659 | | |
5655 | | - | |
| 5660 | + | |
| 5661 | + | |
| 5662 | + | |
| 5663 | + | |
| 5664 | + | |
| 5665 | + | |
| 5666 | + | |
5656 | 5667 | | |
5657 | 5668 | | |
5658 | 5669 | | |
| |||
5924 | 5935 | | |
5925 | 5936 | | |
5926 | 5937 | | |
| 5938 | + | |
| 5939 | + | |
| 5940 | + | |
| 5941 | + | |
| 5942 | + | |
| 5943 | + | |
| 5944 | + | |
| 5945 | + | |
| 5946 | + | |
| 5947 | + | |
| 5948 | + | |
| 5949 | + | |
| 5950 | + | |
| 5951 | + | |
| 5952 | + | |
| 5953 | + | |
| 5954 | + | |
| 5955 | + | |
| 5956 | + | |
| 5957 | + | |
| 5958 | + | |
| 5959 | + | |
| 5960 | + | |
| 5961 | + | |
| 5962 | + | |
| 5963 | + | |
| 5964 | + | |
| 5965 | + | |
5927 | 5966 | | |
5928 | 5967 | | |
5929 | 5968 | | |
| |||
0 commit comments