diff --git a/Cargo.lock b/Cargo.lock index f0dc2c4..9939410 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,9 +168,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "imap-codec" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "204c4816456f1a732d55bb42d90bac69538588dcdf3ef8c9a90b5ca02397021a" +checksum = "f584310addd1fb8fe288e4f07c279fec9264ac1ea68b018241ae4dcd4fb28557" dependencies = [ "abnf-core", "base64", @@ -196,9 +196,9 @@ dependencies = [ [[package]] name = "imap-types" -version = "2.0.0-alpha.3" +version = "2.0.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20a1a5a918696bcc51132d4b96f9dd872517e70fcb7a7b8082f0edcd83a84eeb" +checksum = "d601d81f11962a649acc2d535ad7311770e30364b4a978a762de291829c9ef53" dependencies = [ "arbitrary", "base64", @@ -539,18 +539,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index ae4c9af..c436d9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ ext_metadata = ["imap-codec/ext_metadata"] [dependencies] bytes = { version = "1.7.1", optional = true } -imap-codec = { version = "2.0.0-alpha.4", features = ["quirk_crlf_relaxed"] } +imap-codec = { version = "2.0.0-alpha.5", features = ["quirk_crlf_relaxed"] } thiserror = "1.0.63" tokio = { version = "1.40.0", optional = true, features = ["io-util", "macros", "net"] } tokio-rustls = { version = "0.26.0", optional = true, default-features = false } diff --git a/src/receive.rs b/src/receive.rs index a936dea..e14a906 100644 --- a/src/receive.rs +++ b/src/receive.rs @@ -16,7 +16,6 @@ pub struct ReceiveState { crlf_relaxed: bool, fragmentizer: Fragmentizer, message_has_invalid_line_ending: bool, - message_is_poisoned: bool, } impl ReceiveState { @@ -30,7 +29,6 @@ impl ReceiveState { crlf_relaxed, fragmentizer, message_has_invalid_line_ending: false, - message_is_poisoned: false, } } @@ -55,7 +53,7 @@ impl ReceiveState { /// To achieve this the fragments of the current message will be parsed until the end of the /// message. Then the message will be discarded without being decoded. pub fn poison_message(&mut self) { - self.message_is_poisoned = true; + self.fragmentizer.poison_message(); } /// Tries to decode the tag of the current message before it was received completely. @@ -82,6 +80,7 @@ impl ReceiveState { }) => { // Check for line ending compatibility if !self.crlf_relaxed && ending == LineEnding::Lf { + self.fragmentizer.poison_message(); self.message_has_invalid_line_ending = true; } @@ -91,43 +90,42 @@ impl ReceiveState { return Ok(ReceiveEvent::LiteralAnnouncement { mode, length }); } None => { - // The message is now complete - let result = if self.message_has_invalid_line_ending { - let discarded_bytes = - Secret::new(self.fragmentizer.message_bytes().into()); - Err(Interrupt::Error(ReceiveError::ExpectedCrlfGotLf { - discarded_bytes, - })) - } else if self.message_is_poisoned { - let discarded_bytes = - Secret::new(self.fragmentizer.message_bytes().into()); - Err(Interrupt::Error(ReceiveError::MessageIsPoisoned { - discarded_bytes, - })) - } else { - // Decode the complete message - match self.fragmentizer.decode_message(codec) { - Ok(message) => { - Ok(ReceiveEvent::DecodingSuccess(message.into_static())) - } - Err(DecodeMessageError::DecodingFailure(_)) => { - let discarded_bytes = - Secret::new(self.fragmentizer.message_bytes().into()); - Err(Interrupt::Error(ReceiveError::DecodingFailure { - discarded_bytes, - })) - } - Err(DecodeMessageError::DecodingRemainder { .. }) => { - let discarded_bytes = - Secret::new(self.fragmentizer.message_bytes().into()); - Err(Interrupt::Error(ReceiveError::DecodingFailure { + // The message is now complete and can be decoded + let result = match self.fragmentizer.decode_message(codec) { + Ok(message) => { + Ok(ReceiveEvent::DecodingSuccess(message.into_static())) + } + Err(DecodeMessageError::DecodingFailure(_)) => { + let discarded_bytes = + Secret::new(self.fragmentizer.message_bytes().into()); + Err(Interrupt::Error(ReceiveError::DecodingFailure { + discarded_bytes, + })) + } + Err(DecodeMessageError::DecodingRemainder { .. }) => { + let discarded_bytes = + Secret::new(self.fragmentizer.message_bytes().into()); + Err(Interrupt::Error(ReceiveError::DecodingFailure { + discarded_bytes, + })) + } + Err(DecodeMessageError::MessageTooLong { .. }) => { + let discarded_bytes = + Secret::new(self.fragmentizer.message_bytes().into()); + Err(Interrupt::Error(ReceiveError::MessageTooLong { + discarded_bytes, + })) + } + Err(DecodeMessageError::MessagePoisoned { .. }) => { + let discarded_bytes = + Secret::new(self.fragmentizer.message_bytes().into()); + + if self.message_has_invalid_line_ending { + Err(Interrupt::Error(ReceiveError::ExpectedCrlfGotLf { discarded_bytes, })) - } - Err(DecodeMessageError::MessageTooLong { .. }) => { - let discarded_bytes = - Secret::new(self.fragmentizer.message_bytes().into()); - Err(Interrupt::Error(ReceiveError::MessageTooLong { + } else { + Err(Interrupt::Error(ReceiveError::MessageIsPoisoned { discarded_bytes, })) } @@ -135,7 +133,6 @@ impl ReceiveState { }; self.message_has_invalid_line_ending = false; - self.message_is_poisoned = false; return result; } }