diff options
author | Darius Jahandarie <djahandarie@gmail.com> | 2018-05-21 14:00:40 -0400 |
---|---|---|
committer | Kartikaya Gupta (kats) <staktrace@users.noreply.github.com> | 2018-05-23 21:57:05 -0400 |
commit | 01cbbc450ec2eae016a0258532aa3438f25c44e1 (patch) | |
tree | c3fff0766cc27b9a49cef11481e55c86c0acf7cc /src/lib.rs | |
parent | d10c28b41ef1b81d03875043ae304f67b3a80549 (diff) |
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.
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 42 |
1 files changed, 26 insertions, 16 deletions
@@ -795,23 +795,17 @@ pub fn parse_mail(raw_data: &[u8]) -> Result<ParsedMail, MailParseError> { 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; } } } @@ -1180,6 +1174,22 @@ mod tests { } #[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( "Content-Type: multipart/related; boundary=\"----=_\"\n".as_bytes(), |