From 01cbbc450ec2eae016a0258532aa3438f25c44e1 Mon Sep 17 00:00:00 2001 From: Darius Jahandarie Date: Mon, 21 May 2018 14:00:40 -0400 Subject: parse_mail: Handle missing terminating boundaries in multipart emails. Instead of erroring when there is no terminating boundary, assume the end of the part is the end of the email. --- src/lib.rs | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9a0e476..f8e2d5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -795,23 +795,17 @@ pub fn parse_mail(raw_data: &[u8]) -> Result { while let Some(ix_part_start) = find_from_u8(raw_data, ix_boundary_end, b"\n").map(|v| v + 1) { - if let Some(ix_part_end) = - find_from_u8(raw_data, ix_part_start, boundary.as_bytes()) + // if there is no terminating boundary, assume the part end is the end of the email + let ix_part_end = find_from_u8(raw_data, ix_part_start, boundary.as_bytes()).unwrap_or(raw_data.len()); + + result.subparts.push(try!(parse_mail( + &raw_data[ix_part_start..ix_part_end], + ))); + ix_boundary_end = ix_part_end + boundary.len(); + if ix_boundary_end + 2 > raw_data.len() || + (raw_data[ix_boundary_end] == b'-' && raw_data[ix_boundary_end + 1] == b'-') { - result.subparts.push(try!(parse_mail( - &raw_data[ix_part_start..ix_part_end], - ))); - ix_boundary_end = ix_part_end + boundary.len(); - if ix_boundary_end + 2 <= raw_data.len() && raw_data[ix_boundary_end] == b'-' && - raw_data[ix_boundary_end + 1] == b'-' - { - break; - } - } else { - return Err(MailParseError::Generic( - "Unable to terminating boundary of \ - multipart message", - )); + break; } } } @@ -1179,6 +1173,22 @@ mod tests { assert_eq!(mail.get_body().unwrap(), "hello world"); } + #[test] + fn test_missing_terminating_boundary() { + let mail = parse_mail( + concat!( + "Content-Type: multipart/alternative; boundary=myboundary\r\n\r\n", + "--myboundary\r\n", + "Content-Type: text/plain\r\n\r\n", + "part0\r\n", + "--myboundary\r\n", + "Content-Type: text/html\r\n\r\n", + "part1\r\n").as_bytes(), + ).unwrap(); + assert_eq!(mail.subparts[0].get_body().unwrap(), "part0\r\n"); + assert_eq!(mail.subparts[1].get_body().unwrap(), "part1\r\n"); + } + #[test] fn test_missing_body() { let parsed = parse_mail( -- cgit v1.2.3