fix: wrap base64-encoded parts to 76 characters

This is an RFC 2045 requirement for base64-encoded MIME parts.
Previously referenced RFC 5322 requirement
is a general Internet Message Format requirement
and is more generous.
This commit is contained in:
link2xt
2023-09-24 15:38:42 +00:00
parent aa78e82fed
commit f290fe0871

View File

@@ -1363,15 +1363,16 @@ impl<'a> MimeFactory<'a> {
} }
} }
/// Returns base64-encoded buffer `buf` split into 78-bytes long /// Returns base64-encoded buffer `buf` split into 76-bytes long
/// chunks separated by CRLF. /// chunks separated by CRLF.
/// ///
/// This line length limit is an /// [RFC2045 specification of base64 Content-Transfer-Encoding](https://datatracker.ietf.org/doc/html/rfc2045#section-6.8)
/// [RFC5322 requirement](https://tools.ietf.org/html/rfc5322#section-2.1.1). /// says that "The encoded output stream must be represented in lines of no more than 76 characters each."
/// Longer lines trigger `BASE64_LENGTH_78_79` rule of SpamAssassin.
pub(crate) fn wrapped_base64_encode(buf: &[u8]) -> String { pub(crate) fn wrapped_base64_encode(buf: &[u8]) -> String {
let base64 = base64::engine::general_purpose::STANDARD.encode(buf); let base64 = base64::engine::general_purpose::STANDARD.encode(buf);
let mut chars = base64.chars(); let mut chars = base64.chars();
std::iter::repeat_with(|| chars.by_ref().take(78).collect::<String>()) std::iter::repeat_with(|| chars.by_ref().take(76).collect::<String>())
.take_while(|s| !s.is_empty()) .take_while(|s| !s.is_empty())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\r\n") .join("\r\n")
@@ -1611,8 +1612,8 @@ mod tests {
fn test_wrapped_base64_encode() { fn test_wrapped_base64_encode() {
let input = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; let input = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
let output = let output =
"QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU\r\n\ "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB\r\n\
FBQUFBQUFBQQ=="; QUFBQUFBQUFBQQ==";
assert_eq!(wrapped_base64_encode(input), output); assert_eq!(wrapped_base64_encode(input), output);
} }