summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarius Jahandarie <djahandarie@gmail.com>2018-05-21 14:00:40 -0400
committerKartikaya Gupta (kats) <staktrace@users.noreply.github.com>2018-05-23 21:57:05 -0400
commit01cbbc450ec2eae016a0258532aa3438f25c44e1 (patch)
treec3fff0766cc27b9a49cef11481e55c86c0acf7cc
parentd10c28b41ef1b81d03875043ae304f67b3a80549 (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.
-rw-r--r--src/lib.rs42
1 files 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<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(),