Restore support for symbol names longer than 65535 bytes

The ClickHouse benchmark contains C++ symbol names longer than the u16
limit, causing valid input to panic in Symbol::new. Restore u32 storage
for the cached name length and retain the checked conversion into that
representation.

Change the boundary test to construct a 65536-byte name successfully and
verify that Symbol::name returns all of its bytes. This removes the
restriction introduced by narrowing the length field.
This commit is contained in:
Rui Ueyama committed 2026-09-04 20:58:33 +09:00
1 parent 182785e0c4
commit 4a0485c774
1 file changed
+5 -5
+5 -5
View File
@@ -233,7 +233,7 @@ pub struct Symbol {
// in the owner file. Since the symbol map and symbol array are separate,
// retain a thin pointer rather than a 16-byte slice.
name_ptr: usize,
name_len: u16,
name_len: u32,
/// Serializes the parallel updates made while resolving definitions.
/// The byte also holds the resolution-only `skip_dso` bit; both fit in
@@ -466,7 +466,7 @@ symbol_bits! {
impl Symbol {
#[inline]
pub fn new(name: &'static BStr) -> Symbol {
let name_len = u16::try_from(name.len()).expect("symbol name is longer than 65535 bytes");
let name_len = u32::try_from(name.len()).expect("symbol name is larger than 4 GiB");
Symbol {
name_ptr: name.as_ptr() as usize,
name_len,
@@ -1909,9 +1909,9 @@ mod tests {
}
#[test]
#[should_panic(expected = "symbol name is longer than 65535 bytes")]
fn rejects_too_long_symbol_name() {
fn accepts_long_symbol_name() {
let name = Box::leak(vec![b'x'; u16::MAX as usize + 1].into_boxed_slice());
Symbol::new(BStr::new(name));
let symbol = Symbol::new(BStr::new(name));
assert_eq!(symbol.name(), BStr::new(name));
}
}