Skip to content

Commit 0782c72

Browse files
author
Jayce Fayne
committed
refactor
1 parent 29a7935 commit 0782c72

File tree

1 file changed

+60
-40
lines changed

1 file changed

+60
-40
lines changed

src/lib.rs

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,65 @@ fn strip_trailing_crlf(raw_data: &[u8], ix_start: usize, mut ix: usize) -> usize
942942
ix
943943
}
944944

945+
fn parse_multipart(
946+
raw_data: &[u8],
947+
ix_body: usize,
948+
boundary: String,
949+
in_multipart_digest: bool,
950+
) -> Result<(Vec<ParsedMail<'_>>, usize), MailParseError> {
951+
let mut subparts = Vec::new();
952+
let mut ix_body_end = ix_body;
953+
954+
if let Some(ix_boundary_start) =
955+
find_from_u8_line_prefix(raw_data, ix_body, boundary.as_bytes())
956+
{
957+
ix_body_end = strip_trailing_crlf(raw_data, ix_body, ix_boundary_start);
958+
let mut ix_boundary_end = ix_boundary_start + boundary.len();
959+
while let Some(ix_part_start) =
960+
find_from_u8(raw_data, ix_boundary_end, b"\n").map(|v| v + 1)
961+
{
962+
let ix_part_boundary_start =
963+
find_from_u8_line_prefix(raw_data, ix_part_start, boundary.as_bytes());
964+
let ix_part_end = ix_part_boundary_start
965+
.map(|x| strip_trailing_crlf(raw_data, ix_part_start, x))
966+
// if there is no terminating boundary, assume the part end is the end of the email
967+
.unwrap_or(raw_data.len());
968+
969+
subparts.push(parse_mail_recursive(
970+
&raw_data[ix_part_start..ix_part_end],
971+
in_multipart_digest,
972+
)?);
973+
ix_boundary_end = ix_part_boundary_start
974+
.map(|x| x + boundary.len())
975+
.unwrap_or(raw_data.len());
976+
if ix_boundary_end + 2 > raw_data.len()
977+
|| (raw_data[ix_boundary_end] == b'-' && raw_data[ix_boundary_end + 1] == b'-')
978+
{
979+
break;
980+
}
981+
}
982+
}
983+
Ok((subparts, ix_body_end))
984+
}
985+
986+
fn parse_subparts<'a>(
987+
raw_data: &'a [u8],
988+
ix_body: usize,
989+
ctype: &'_ ParsedContentType,
990+
) -> Result<(Vec<ParsedMail<'a>>, &'a [u8]), MailParseError> {
991+
if raw_data.len() > ix_body
992+
&& ctype.mimetype.starts_with("multipart")
993+
&& let Some(boundary) = ctype.params.get("boundary")
994+
{
995+
let boundary = String::from("--") + boundary;
996+
let in_multipart_digest = ctype.mimetype == "multipart/digest";
997+
let (subparts, ix_body_end) =
998+
parse_multipart(raw_data, ix_body, boundary, in_multipart_digest)?;
999+
return Ok((subparts, &raw_data[ix_body..ix_body_end]));
1000+
}
1001+
Ok((Vec::new(), &raw_data[ix_body..]))
1002+
}
1003+
9451004
fn parse_mail_recursive(
9461005
raw_data: &[u8],
9471006
in_multipart_digest: bool,
@@ -953,46 +1012,7 @@ fn parse_mail_recursive(
9531012
.map(parse_content_type)
9541013
.unwrap_or_else(|| ParsedContentType::default_conditional(in_multipart_digest));
9551014

956-
let mut subparts = Vec::new();
957-
let mut body_bytes = &raw_data[ix_body..];
958-
959-
if ctype.mimetype.starts_with("multipart/")
960-
&& let Some(boundary) = ctype.params.get("boundary")
961-
&& raw_data.len() > ix_body
962-
{
963-
let boundary = String::from("--") + boundary;
964-
let in_multipart_digest = ctype.mimetype == "multipart/digest";
965-
if let Some(ix_boundary_start) =
966-
find_from_u8_line_prefix(raw_data, ix_body, boundary.as_bytes())
967-
{
968-
let ix_body_end = strip_trailing_crlf(raw_data, ix_body, ix_boundary_start);
969-
body_bytes = &raw_data[ix_body..ix_body_end];
970-
let mut ix_boundary_end = ix_boundary_start + boundary.len();
971-
while let Some(ix_part_start) =
972-
find_from_u8(raw_data, ix_boundary_end, b"\n").map(|v| v + 1)
973-
{
974-
let ix_part_boundary_start =
975-
find_from_u8_line_prefix(raw_data, ix_part_start, boundary.as_bytes());
976-
let ix_part_end = ix_part_boundary_start
977-
.map(|x| strip_trailing_crlf(raw_data, ix_part_start, x))
978-
// if there is no terminating boundary, assume the part end is the end of the email
979-
.unwrap_or(raw_data.len());
980-
981-
subparts.push(parse_mail_recursive(
982-
&raw_data[ix_part_start..ix_part_end],
983-
in_multipart_digest,
984-
)?);
985-
ix_boundary_end = ix_part_boundary_start
986-
.map(|x| x + boundary.len())
987-
.unwrap_or(raw_data.len());
988-
if ix_boundary_end + 2 > raw_data.len()
989-
|| (raw_data[ix_boundary_end] == b'-' && raw_data[ix_boundary_end + 1] == b'-')
990-
{
991-
break;
992-
}
993-
}
994-
}
995-
}
1015+
let (subparts, body_bytes) = parse_subparts(raw_data, ix_body, &ctype)?;
9961016

9971017
Ok(ParsedMail {
9981018
raw_bytes: raw_data,

0 commit comments

Comments
 (0)