diff --git a/src/generator/ical.rs b/src/generator/ical.rs index 0c5288e..eab3fb8 100644 --- a/src/generator/ical.rs +++ b/src/generator/ical.rs @@ -19,13 +19,14 @@ fn get_value(value: &Option) -> String { } pub(crate) fn split_line>(str: T) -> String { - let mut str = str.into(); - let mut x = 75; - while x < str.len() { - str.insert_str(x, "\r\n "); - x += 77; - } - str + let str = str.into(); + let mut chars = str.chars(); + let mut first = true; + let sub_string = (0..) + .map(|_| chars.by_ref().take(if first { first = false; 75 } else { 74 }).collect::()) + .take_while(|s| !s.is_empty()) + .collect::>(); + sub_string.join("\r\n ") } // @@ -85,6 +86,17 @@ mod should { assert_eq!(text, split_line(text.replace("\r\n ", ""))); } + #[test] + fn split_long_line_multibyte() { + // the following text includes multibyte characters (UTF-8) at strategic places to ensure + // split_line would panic if not multibyte aware + let text = "DESCRIPTION:ABCDEFGHIJ\\n\\nKLMNOPQRSTUVWXYZ123456789üABCDEFGHIJKLMNOPQRS\\n\\n\r\n \ + TUVWXYZ123456ä7890ABCDEFGHIJKLM\\n\\nNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOP\r\n \ + QRSTUVWXöYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWX\\n\\nYZ1234567890abcdefghiÜjkl\r\n \ + m\\nnopqrstuvwx"; + assert_eq!(text, split_line(text.replace("\r\n ", ""))); + } + #[test] fn protect_chars_in_params() { assert_eq!(