Skip to content

Commit 75425fa

Browse files
truncate docs on char boundary using floor_char_boundary
1 parent 9afaa33 commit 75425fa

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

soroban-sdk-macros/src/doc.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ pub fn docs_from_attrs(attrs: &[Attribute]) -> StringM<DOCS_MAX_LEN> {
2020
_ => None,
2121
})
2222
.map(|s| s.trim().to_string())
23-
.join("\n")
24-
.as_bytes()
25-
.to_vec();
26-
docs.truncate(DOCS_MAX_LEN as usize);
27-
docs.try_into().unwrap()
23+
.join("\n");
24+
// Truncate on a char boundary to avoid splitting multi-byte UTF-8 codepoints.
25+
let max = DOCS_MAX_LEN as usize;
26+
let safe_len = docs.floor_char_boundary(max);
27+
docs.truncate(safe_len);
28+
docs.into_bytes().try_into().unwrap()
2829
}
2930

3031
#[cfg(test)]
@@ -34,10 +35,10 @@ mod test {
3435

3536
#[test]
3637
fn test_truncation_does_not_split_multibyte_utf8() {
37-
// 1023 ASCII bytes followed by 'é' (2 bytes: 0xC3 0xA9) = 1025 bytes.
38-
// Truncation at 1024 keeps the 0xC3 but drops the 0xA9, producing
39-
// invalid UTF-8.
40-
let padding = "a".repeat(1023);
38+
// (DOCS_MAX_LEN - 1) ASCII bytes followed by 'é' (2 bytes: 0xC3
39+
// 0xA9) = DOCS_MAX_LEN + 1 bytes. Truncation at DOCS_MAX_LEN keeps
40+
// the 0xC3 but drops the 0xA9, producing invalid UTF-8.
41+
let padding = "a".repeat(DOCS_MAX_LEN as usize - 1);
4142
let doc_value = format!("{padding}é");
4243
let attr: Attribute = parse_quote!(#[doc = #doc_value]);
4344
let result = docs_from_attrs(&[attr]);

0 commit comments

Comments
 (0)