mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
fix(bedrock): use floor_char_boundary to avoid UTF-8 slice panic in header preview
header_value_preview in eventstream_to_sse.rs used a raw byte-slice (&s[..64]) to truncate long header strings for log output. If byte index 64 landed inside a multi-byte codepoint (e.g. 63 ASCII chars followed by é or an emoji), Rust panics at runtime. Replace with floor_char_boundary(64) which returns the largest valid char boundary ≤ 64 without scanning the whole string. Two regression tests added: - truncates_at_char_boundary: 63 ASCII + é → must not panic, must end with … - exact_boundary_not_truncated: 64-byte ASCII string is returned unchanged Fixes #415
This commit is contained in:
parent
cd89a8297a
commit
82468e4e99
1 changed files with 21 additions and 1 deletions
|
|
@ -238,7 +238,8 @@ pub fn header_value_preview(v: &HeaderValue) -> String {
|
|||
if s.len() <= 64 {
|
||||
s.clone()
|
||||
} else {
|
||||
format!("{}…", &s[..64])
|
||||
let end = s.floor_char_boundary(64);
|
||||
format!("{}…", &s[..end])
|
||||
}
|
||||
}
|
||||
HeaderValue::Bytes(b) => format!("[{} bytes]", b.len()),
|
||||
|
|
@ -394,4 +395,23 @@ mod tests {
|
|||
.starts_with("[3 bytes")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn header_value_preview_truncates_at_char_boundary() {
|
||||
// 63 ASCII bytes + a 2-byte UTF-8 char (é = U+00E9) puts a char
|
||||
// boundary at byte 63 but NOT at byte 64 — the old `&s[..64]`
|
||||
// would panic here. floor_char_boundary(64) must return 63.
|
||||
let s = "x".repeat(63) + "éfoo";
|
||||
assert!(s.len() > 64);
|
||||
let preview = header_value_preview(&HeaderValue::String(s));
|
||||
assert!(preview.ends_with('…'), "expected ellipsis suffix: {preview:?}");
|
||||
assert!(!preview.contains('é'), "must not include the split codepoint");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn header_value_preview_exact_boundary_not_truncated() {
|
||||
// A string whose UTF-8 length is exactly 64 must not be truncated.
|
||||
let s = "x".repeat(64);
|
||||
assert_eq!(header_value_preview(&HeaderValue::String(s.clone())), s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue