From c128b46abd8685fb22cd91a925d3bba35cd746f7 Mon Sep 17 00:00:00 2001 From: Paolo Barbolini Date: Wed, 27 Mar 2024 21:51:14 +0100 Subject: [PATCH] fix(rfc2047): replace broken ccaf5a7b fix with workaround --- src/headers/rfc2047.rs | 21 +++++++++++++++------ src/headers/writer.rs | 19 ++++++------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/headers/rfc2047.rs b/src/headers/rfc2047.rs index 8857aba..37b4afc 100644 --- a/src/headers/rfc2047.rs +++ b/src/headers/rfc2047.rs @@ -28,18 +28,27 @@ const ENCODING_END_SUFFIX: &str = "?="; /// # } /// ``` pub fn encode(mut s: &str, w: &mut EmailWriter<'_>) -> fmt::Result { + let mut wrote = false; + while !s.is_empty() { let remaining_line_len = MAX_LINE_LEN.saturating_sub( ENCODING_START_PREFIX.len() + ENCODING_END_SUFFIX.len() + w.line_len() + "\r\n".len(), ); let unencoded_remaining_line_len = remaining_line_len / 4 * 3; - let word = utils::truncate_to_char_boundary(s, unencoded_remaining_line_len.min(s.len())); - + let mut word = + utils::truncate_to_char_boundary(s, unencoded_remaining_line_len.min(s.len())); if word.is_empty() { - // No space remaining on this line, go to a new one - w.new_line_and_space()?; - continue; + if wrote { + // No space remaining on this line, go to a new one + w.new_line()?; + w.space(); + continue; + } + + // No space remaining, but going to a new line will require us + // to introduce a new space, which will mess up things even more. + word = &s[..s.chars().next().unwrap().len_utf8()]; } // Write the prefix @@ -55,8 +64,8 @@ pub fn encode(mut s: &str, w: &mut EmailWriter<'_>) -> fmt::Result { // Write the suffix w.write_str(ENCODING_END_SUFFIX)?; - // Advance `s` s = &s[word.len()..]; + wrote = true; } Ok(()) diff --git a/src/headers/writer.rs b/src/headers/writer.rs index 1dd4c1b..c099114 100644 --- a/src/headers/writer.rs +++ b/src/headers/writer.rs @@ -53,17 +53,6 @@ impl<'a> EmailWriter<'a> { Ok(()) } - /// Equivalent to calling `new_line()` and `space()` consecutively. - pub(crate) fn new_line_and_space(&mut self) -> fmt::Result { - self.spaces = 0; - self.writer.write_str("\r\n ")?; - self.line_len = 1; - self.optional_breakpoint = false; - self.can_go_to_new_line_now = false; - - Ok(()) - } - #[cfg(not(tarpaulin_include))] #[doc(hidden)] #[deprecated(note = "Renamed to `new_line`", since = "0.1.2")] @@ -76,6 +65,10 @@ impl<'a> EmailWriter<'a> { self.spaces += 1; } + pub(super) fn has_spaces(&self) -> bool { + self.spaces > 0 + } + /// Write a space which won't be printed if the line wraps. /// /// This method shouldn't be called multiple times consecutively, @@ -367,8 +360,8 @@ mod tests { assert_eq!( s, concat!( - "Subject: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA BBBBBBBBBBBBB\r\n", - " =?utf-8?b?c8OpbGVjdGlvbg==?=", + "Subject: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA BBBBBBBBBBBBB =?utf-8?b?cw==?=\r\n", + " =?utf-8?b?w6lsZWN0aW9u?=", ) ); }