Skip to content

Commit

Permalink
v0.9.2
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Nov 27, 2023
1 parent 28a9b67 commit 65533d3
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
mail-parser 0.9.2
================================
- Fixed `quoted_printable_decode` external function (not used by mail-parser directly).
- Fix `Received` header serialization for bincode compatibility.

mail-parser 0.9.1
================================
- Fixed panic when Content-Disposition is empty (#63)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "mail-parser"
description = "Fast and robust e-mail parsing library for Rust"
version = "0.9.1"
version = "0.9.2"
edition = "2021"
authors = [ "Stalwart Labs <[email protected]>"]
license = "Apache-2.0 OR MIT"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Performance and memory safety were two important factors while designing _mail-p
- **High performance Base64 decoding** based on Chromium's decoder ([the fastest non-SIMD decoder](https://github.com/lemire/fastbase64)).
- **Fast parsing** of message header fields, character set names and HTML entities using [perfect hashing](https://en.wikipedia.org/wiki/Perfect_hash_function).
- Written in **100% safe** Rust with no external dependencies.
- Every function in the library has been [fuzzed](#testing-fuzzing--benchmarking) and
thoroughly [tested with MIRI](#testing-fuzzing--benchmarking).
- **Battle-tested** with millions of real-world e-mail messages dating from 1995 until today.
- Every function in the library has been [fuzzed](#testing-fuzzing--benchmarking) and thoroughly [tested with MIRI](#testing-fuzzing--benchmarking).
- **Battle-tested** with millions of real-world e-mail messages dating from 1995 until today.
- Used in production environments worldwide by [Stalwart Mail Server](https://github.com/stalwartlabs/mail-server).

## Usage Example

Expand Down
14 changes: 14 additions & 0 deletions resources/eml/rfc/002.crlf.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,19 @@
"Name": "mailhost.whitehouse.gov"
},
"from_ip": "192.168.51.200",
"from_iprev": null,
"by": {
"Name": "heartbeat.whitehouse.gov"
},
"for_": "[email protected]",
"with": "ESMTP",
"tls_version": null,
"tls_cipher": null,
"id": "SAA22453",
"ident": null,
"helo": null,
"helo_cmd": null,
"via": null,
"date": {
"year": 1998,
"month": 8,
Expand All @@ -223,12 +230,19 @@
"Name": "the_big_box.whitehouse.gov"
},
"from_ip": "192.168.51.50",
"from_iprev": null,
"by": {
"Name": "mailhost.whitehouse.gov"
},
"for_": "[email protected]",
"with": "ESMTP",
"tls_version": null,
"tls_cipher": null,
"id": "RAA20366",
"ident": null,
"helo": null,
"helo_cmd": null,
"via": null,
"date": {
"year": 1998,
"month": 8,
Expand Down
14 changes: 14 additions & 0 deletions resources/eml/rfc/002.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,19 @@
"Name": "mailhost.whitehouse.gov"
},
"from_ip": "192.168.51.200",
"from_iprev": null,
"by": {
"Name": "heartbeat.whitehouse.gov"
},
"for_": "[email protected]",
"with": "ESMTP",
"tls_version": null,
"tls_cipher": null,
"id": "SAA22453\n",
"ident": null,
"helo": null,
"helo_cmd": null,
"via": null,
"date": {
"year": 1998,
"month": 8,
Expand All @@ -223,12 +230,19 @@
"Name": "the_big_box.whitehouse.gov"
},
"from_ip": "192.168.51.50",
"from_iprev": null,
"by": {
"Name": "mailhost.whitehouse.gov"
},
"for_": "[email protected]",
"with": "ESMTP",
"tls_version": null,
"tls_cipher": null,
"id": "RAA20366\n",
"ident": null,
"helo": null,
"helo_cmd": null,
"via": null,
"date": {
"year": 1998,
"month": 8,
Expand Down
8 changes: 8 additions & 0 deletions resources/eml/thirdparty/011.crlf.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,18 @@
"IpAddr": "10.1.1.1"
},
"from_ip": "10.1.1.1",
"from_iprev": null,
"by": {
"Name": "xyz-webserver.abcd-gestion.com"
},
"for_": null,
"with": "ESMTPA",
"tls_version": null,
"tls_cipher": null,
"ident": null,
"helo": null,
"helo_cmd": null,
"via": null,
"date": {
"year": 2022,
"month": 7,
Expand Down
8 changes: 8 additions & 0 deletions resources/eml/thirdparty/011.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,18 @@
"IpAddr": "10.1.1.1"
},
"from_ip": "10.1.1.1",
"from_iprev": null,
"by": {
"Name": "xyz-webserver.abcd-gestion.com"
},
"for_": null,
"with": "ESMTPA",
"tls_version": null,
"tls_cipher": null,
"ident": null,
"helo": null,
"helo_cmd": null,
"via": null,
"date": {
"year": 2022,
"month": 7,
Expand Down
33 changes: 27 additions & 6 deletions src/decoders/quoted_printable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub fn quoted_printable_decode(bytes: &[u8]) -> Option<Vec<u8>> {

let mut state = QuotedPrintableState::None;
let mut hex1 = 0;
let mut ws_count = 0;
let mut crlf = b"\n".as_ref();

for &ch in bytes {
match ch {
Expand All @@ -39,12 +41,23 @@ pub fn quoted_printable_decode(bytes: &[u8]) -> Option<Vec<u8>> {
if QuotedPrintableState::Eq == state {
state = QuotedPrintableState::None;
} else {
buf.push(b'\n');
if ws_count > 0 {
buf.truncate(buf.len() - ws_count);
}
buf.extend_from_slice(crlf);
}
ws_count = 0;
}
b'\r' => {
crlf = b"\r\n".as_ref();
}
b'\r' => (),
_ => match state {
QuotedPrintableState::None => {
if ch.is_ascii_whitespace() {
ws_count += 1;
} else {
ws_count = 0;
}
buf.push(ch);
}
QuotedPrintableState::Eq => {
Expand All @@ -59,7 +72,7 @@ pub fn quoted_printable_decode(bytes: &[u8]) -> Option<Vec<u8>> {

if hex1 != -1 {
state = QuotedPrintableState::Hex1;
} else {
} else if !ch.is_ascii_whitespace() {
return None;
}
}
Expand All @@ -72,6 +85,7 @@ pub fn quoted_printable_decode(bytes: &[u8]) -> Option<Vec<u8>> {
state = QuotedPrintableState::None;
if hex2 != -1 {
buf.push(((hex1 as u8) << 4) | hex2 as u8);
ws_count = 0;
} else {
return None;
}
Expand Down Expand Up @@ -337,14 +351,21 @@ mod tests {
concat!(
"Die Hasen klagten einst uber ihre Lage; \"wir leben\", ",
"sprach ein Redner, \"in steter Furcht vor Menschen und ",
"Tieren, eine Beute der Hunde, der\n"
"Tieren, eine Beute der Hunde, der\r\n"
),
),
(
concat!(
"hello \r\nbar=\r\n\r\nfoo\t=\r\nbar\r\nfoo\t \t= \r\n=62\r\nfoo = ",
"\t\r\nbar\r\nfoo =\r\n=62\r\nfoo \r\nbar=\r\n\r\nfoo_bar\r\n"
),
"hello\r\nbar\r\nfoo\tbar\r\nfoo\t \tb\r\nfoo bar\r\nfoo b\r\nfoo\r\nbar\r\nfoo_bar\r\n",
),
("\n\n", "\n\n"),
] {
assert_eq!(
super::quoted_printable_decode(encoded_str.as_bytes()).unwrap_or_default(),
expected_result.as_bytes(),
String::from_utf8(super::quoted_printable_decode(encoded_str.as_bytes()).unwrap_or_default()).unwrap(),
expected_result,
"Failed for {encoded_str:?}",
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
//! - **High performance Base64 decoding** based on Chromium's decoder ([the fastest non-SIMD decoder](https://github.com/lemire/fastbase64)).
//! - **Fast parsing** of message header fields, character set names and HTML entities using [perfect hashing](https://en.wikipedia.org/wiki/Perfect_hash_function).
//! - Written in **100% safe** Rust with no external dependencies.
//! - Every function in the library has been [fuzzed](#testing-fuzzing--benchmarking) and
//! thoroughly [tested with MIRI](#testing-fuzzing--benchmarking).
//! - Every function in the library has been [fuzzed](#testing-fuzzing--benchmarking) and thoroughly [tested with MIRI](#testing-fuzzing--benchmarking).
//! - **Battle-tested** with millions of real-world e-mail messages dating from 1995 until today.
//! - Used in production environments worldwide by [Stalwart Mail Server](https://github.com/stalwartlabs/mail-server).
//!
//! Jump to the [example](#usage-example).
//!
Expand Down

0 comments on commit 65533d3

Please sign in to comment.