Skip to content

Commit cd74c9e

Browse files
committed
chars_in_multibyte: use multibyte_length, debug-assert on invalid
Mirror GNU multibyte_chars_in_text (character.c:519): each step uses multibyte_length(allow_8bit=true). A 0-length result triggers emacs_abort in GNU; we debug_assert and fall back to a 1-byte advance in release builds so a malformed buffer does not crash production.
1 parent 001c084 commit cd74c9e

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

neovm-core/src/emacs_core/emacs_char.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,11 +1053,25 @@ pub fn blankp(cat: i64) -> bool {
10531053
// ---------------------------------------------------------------------------
10541054

10551055
/// Count the number of characters in a multibyte byte sequence.
1056+
///
1057+
/// Mirrors GNU `multibyte_chars_in_text` (character.c:519). Each step uses
1058+
/// `multibyte_length(allow_8bit=true)` and a 0-length result triggers
1059+
/// `emacs_abort` in GNU. We assert in debug builds and fall back to a 1-byte
1060+
/// advance in release builds so a malformed buffer does not crash production.
10561061
pub fn chars_in_multibyte(bytes: &[u8]) -> usize {
10571062
let mut count = 0usize;
10581063
let mut pos = 0usize;
10591064
while pos < bytes.len() {
1060-
let (_, len) = string_char(&bytes[pos..]);
1065+
let len = match multibyte_length(&bytes[pos..], true) {
1066+
Some(n) if n > 0 => n,
1067+
_ => {
1068+
debug_assert!(
1069+
false,
1070+
"chars_in_multibyte: invalid multibyte sequence at offset {pos}"
1071+
);
1072+
1
1073+
}
1074+
};
10611075
pos += len;
10621076
count += 1;
10631077
}

0 commit comments

Comments
 (0)