fix(proxy): stop mask_url panicking on multi-byte UTF-8 near the truncation boundary

mask_url's fallback branch (used when the proxy URL fails Url::parse) sliced the raw string at byte 20 and panicked when a multi-byte UTF-8 character straddled that offset, e.g. a CJK string pasted into the global proxy address. Snap the cut to the nearest char boundary at or before 20 and add a regression test.
This commit is contained in:
xu-kai-quan authored and GitHub committed 2026-09-07 15:54:27 +08:00
1 parent 3c1d3c94ac
commit 12296aeb4d
1 file changed
+17 -2
+17 -2
View File
@@ -325,9 +325,14 @@ pub fn mask_url(url: &str) -> String {
None => format!("{}://{}", parsed.scheme(), host),
}
} else {
// URL 解析失败,返回部分内容
// URL 解析失败,返回部分内容。截断点回退到最近的字符边界,
// 避免在多字节 UTF-8 字符中间切割导致 panic。
if url.len() > 20 {
format!("{}...", &url[..20])
let cut = (0..=20)
.rev()
.find(|&i| url.is_char_boundary(i))
.unwrap_or(0);
format!("{}...", &url[..cut])
} else {
url.to_string()
}
@@ -366,6 +371,16 @@ mod tests {
);
}
#[test]
fn test_mask_url_does_not_panic_on_multibyte_boundary() {
// 一个无法被 Url::parse 解析、且在字节 20 处正好切在多字节字符中间的字符串。
// 回归 https://github.com/farion1231/cc-switch 的 mask_url 越界 panic。
let bad = "这是一个无效的代理地址不能解析";
assert!(bad.len() > 20 && !bad.is_char_boundary(20));
let masked = mask_url(bad);
assert!(masked.ends_with("..."));
}
#[test]
fn test_build_client_direct() {
let result = build_client(None);