fix(github): a multibyte char after < no longer panics the markdown sanitizer (#1076)

`starts_with_tag` sliced `rest[..name.len()]` by bytes, so an issue or
PR body with `<` followed by a multibyte char (e.g. `<日本`) panicked the
GitHub panel's render and quit the app. It now uses `str::get`, so a
non-boundary is just "not a tag". A regression test fails on the old
code and passes now.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Adam Hitchcock
2026-10-03 20:29:57 +08:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 3990a05795
commit dd4bd806c6
+10 -2
View File
@@ -256,8 +256,9 @@ fn starts_with_tag(s: &str, name: &str) -> bool {
let Some(rest) = s.strip_prefix('<') else {
return false;
};
rest.len() > name.len()
&& rest[..name.len()].eq_ignore_ascii_case(name)
// `get`, not a slice: `name.len()` can land inside a multibyte char.
rest.get(..name.len())
.is_some_and(|head| head.eq_ignore_ascii_case(name))
&& rest[name.len()..]
.chars()
.next()
@@ -609,6 +610,13 @@ mod tests {
sanitize(src, "image")
}
#[test]
fn a_multibyte_char_after_lt_is_prose() {
assert!(s("a <日本 b").contains("日本"));
assert!(!starts_with_tag("<日本", "img"));
assert!(starts_with_tag("<IMG src=x>", "img"));
}
#[test]
fn github_hosted_images_stay_images() {
let pasted = "https://github.com/user-attachments/assets/352d14e0-d11c";