Repository navigation
Commit f72722a
authored
Unrolled build for #160232
Rollup merge of #160232 - lazureykis:fix/rustdoc-escape-char-boundary, r=notriddle
rustdoc: fix ICE when a grapheme cluster joins a Prepend-class character to `_` or `:`
Fixes #160231
`EscapeBodyTextWithWbr` iterates `text.grapheme_indices(true)`, so `i` is the start of a grapheme cluster, but the `_`/`:` word-break arm sliced at `i + 1` — hard-coding the assumption that a cluster containing `_` or `:` is exactly one byte long.
UAX#29 GB9b joins a `Prepend`-class character (`U+0600`–`U+0605`, `U+0D4E`, `U+111C2`, …) with the character that follows it, so a cluster can start with a multi-byte character and still contain `_`. `i + 1` then lands inside that character and `str` indexing panics. `U+0D4E` is `XID_Continue`, so this is reachable from an ordinary item name that rustc accepts:
```rust
pub struct abcൎ_defgh;
```
rustdoc ICEs on that with `end byte index 4 is not a char boundary; it is inside 'ൎ' (bytes 3..6 of string)`, which means `cargo doc` cannot document the crate at all.
Break after the whole cluster (`i + s.len()`) instead. The adjacent CamelCase arm already slices at `i`, which is always a cluster boundary, so it needed no change.
The `i + 1` dates to 3bf8bcf (which added the `:` arm) and was extended to `_` by ac303df, both in #126247.
This also fixes a smaller, non-panicking case: when a combining mark trails the `_` (`first_◌̀second`), the old code inserted the `<wbr>` between `_` and its combining mark, splitting a grapheme cluster.
Tests: unit cases in `src/librustdoc/html/escape/tests.rs` covering a `Prepend`+`_` cluster, a `Prepend`+`:` cluster, and the trailing-combining-mark case; plus an end-to-end regression test in `tests/rustdoc-html/` so the ICE itself stays fixed.
The existing tests missed this because they only cover `Extend`-class clusters, which join backwards onto an ASCII base character and so keep `i + 1` on a boundary (`E("ṼẽçÑñéå")`, `E("V\u{0300}e\u{0300}…")`). `Prepend` is the one class that joins forwards. The property test `escape_body_text_with_wbr_makes_sense` can't reach it either — its alphabet is `[b'a', b'A', b'_']`.
r? rustdoc3 files changed
Lines changed: 17 additions & 2 deletions
File tree
- src/librustdoc/html
- escape
- tests/rustdoc-html
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
83 | 86 | | |
84 | | - | |
| 87 | + | |
85 | 88 | | |
86 | 89 | | |
87 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
43 | 47 | | |
44 | 48 | | |
45 | 49 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
0 commit comments