Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions resources/eml/malformed/019.crlf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
{
"html_body": [
1
],
"text_body": [
1
],
"attachments": [
2
],
"parts": [
{
"headers": [
{
"name": "content_type",
"value": {
"ContentType": {
"c_type": "multipart",
"c_subtype": "mixed",
"attributes": [
{
"name": "boundary",
"value": "89"
}
]
}
},
"offset_field": 0,
"offset_start": 13,
"offset_end": 46
}
],
"is_encoding_problem": false,
"body": {
"Multipart": [
1,
2
]
},
"offset_header": 0,
"offset_body": 48,
"offset_end": 135
},
{
"headers": [
{
"name": "content_type",
"value": {
"ContentType": {
"c_type": "text",
"c_subtype": "plain",
"attributes": null
}
},
"offset_field": 54,
"offset_start": 67,
"offset_end": 80
}
],
"is_encoding_problem": false,
"body": {
"Text": ""
},
"offset_header": 54,
"offset_body": 82,
"offset_end": 82
},
{
"headers": [
{
"name": "content_type",
"value": {
"ContentType": {
"c_type": "message",
"c_subtype": "rfc822",
"attributes": null
}
},
"offset_field": 88,
"offset_start": 101,
"offset_end": 118
}
],
"is_encoding_problem": false,
"body": {
"Message": {
"html_body": [],
"text_body": [],
"attachments": [],
"parts": [
{
"headers": [
{
"name": {
"other": "--89--"
},
"value": "Empty",
"offset_field": 129,
"offset_start": 135,
"offset_end": 135
}
],
"is_encoding_problem": true,
"body": {
"Binary": [
105,
110,
118,
97,
108,
105,
100,
13,
10,
45,
45,
56,
57,
45,
45
]
},
"offset_header": 120,
"offset_body": 0,
"offset_end": 0
}
]
}
},
"offset_header": 88,
"offset_body": 120,
"offset_end": 135
}
]
}
10 changes: 10 additions & 0 deletions resources/eml/malformed/019.eml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Content-Type: multipart/mixed; boundary="89"

--89
Content-Type: text/plain

--89
Content-Type: message/rfc822

invalid
--89--
134 changes: 134 additions & 0 deletions resources/eml/malformed/019.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
{
"html_body": [
1
],
"text_body": [
1
],
"attachments": [
2
],
"parts": [
{
"headers": [
{
"name": "content_type",
"value": {
"ContentType": {
"c_type": "multipart",
"c_subtype": "mixed",
"attributes": [
{
"name": "boundary",
"value": "89"
}
]
}
},
"offset_field": 0,
"offset_start": 13,
"offset_end": 45
}
],
"is_encoding_problem": false,
"body": {
"Multipart": [
1,
2
]
},
"offset_header": 0,
"offset_body": 46,
"offset_end": 126
},
{
"headers": [
{
"name": "content_type",
"value": {
"ContentType": {
"c_type": "text",
"c_subtype": "plain",
"attributes": null
}
},
"offset_field": 51,
"offset_start": 64,
"offset_end": 76
}
],
"is_encoding_problem": false,
"body": {
"Text": ""
},
"offset_header": 51,
"offset_body": 77,
"offset_end": 77
},
{
"headers": [
{
"name": "content_type",
"value": {
"ContentType": {
"c_type": "message",
"c_subtype": "rfc822",
"attributes": null
}
},
"offset_field": 82,
"offset_start": 95,
"offset_end": 111
}
],
"is_encoding_problem": false,
"body": {
"Message": {
"html_body": [],
"text_body": [],
"attachments": [],
"parts": [
{
"headers": [
{
"name": {
"other": "--89--"
},
"value": "Empty",
"offset_field": 120,
"offset_start": 126,
"offset_end": 126
}
],
"is_encoding_problem": true,
"body": {
"Binary": [
105,
110,
118,
97,
108,
105,
100,
10,
45,
45,
56,
57,
45,
45
]
},
"offset_header": 112,
"offset_body": 0,
"offset_end": 0
}
]
}
},
"offset_header": 82,
"offset_body": 112,
"offset_end": 126
}
]
}
2 changes: 1 addition & 1 deletion src/decoders/encoded_word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ mod tests {
//println!("Decoded '{}'", string);
assert_eq!(result, expected_result);
}
_ => panic!("Failed to decode '{}'", input),
_ => panic!("Failed to decode '{input}'"),
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/parsers/fields/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ mod tests {
.parse_raw()
.unwrap_text(),
expected,
"Failed for '{:?}'",
input
"Failed for '{input:?}'",
);
}
}
Expand Down
23 changes: 21 additions & 2 deletions src/parsers/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,11 +490,29 @@ impl MessageParser {
}

// Corrupted MIME message, try to recover whatever is possible.
let mut last_message = true;
while let Some((prev_state, prev_message)) = state_stack.pop() {
if let Some(mut prev_message) = prev_message {
message.raw_message = raw_message.into(); //raw_message[state.offset_header..stream.offset()].as_ref().into();

if let Some(part) = prev_message.parts.get_mut(state.part_id as usize) {
// complete message as best we can if no parts yet assigned
if message.parts.is_empty() {
let bytes = &message.raw_message[state.offset_header..];
message.parts.push(MessagePart {
headers: std::mem::take(&mut part_headers),
encoding: Encoding::None,
is_encoding_problem: true,
body: if last_message {
PartType::Binary(bytes.to_owned().into())
} else {
PartType::Text("".into())
},
offset_header: state.offset_header as u32,
offset_body: state.offset_body as u32,
offset_end: state.offset_end as u32,
});
}
part.body = PartType::Message(message);
part.offset_end = stream.offset() as u32;
} else {
Expand All @@ -509,12 +527,13 @@ impl MessageParser {
debug_assert!(false, "This should not have happened.");
}
state = prev_state;
last_message = false;
}

message.raw_message = raw_message.into();

if !message.is_empty() {
message.parts[0].offset_end = message.raw_message.len() as u32;
if let Some(part) = message.parts.first_mut() {
part.offset_end = message.raw_message.len() as u32;
Some(message)
} else if !part_headers.is_empty() {
// Message without a body
Expand Down