mirror of
https://github.com/stalwartlabs/stalwart.git
synced 2026-03-17 14:34:03 +00:00
IMAP: Check buf size before pushing escape sequences within quoted literals
This commit is contained in:
@@ -26,9 +26,9 @@ If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking c
|
||||
- IMAP: Include `administer` permission in ACL responses.
|
||||
- IMAP: Add owner rights to ACL get responses.
|
||||
- IMAP: Do not auto-train Bayes when moving messages from Junk to Trash.
|
||||
- IMAP/ManageSieve: Increase maximum quoted argument size (fixes #2039).
|
||||
- CalDAV: Limit recurrence expansions in calendar reports.
|
||||
- WebDAV: Do not fix percent encoding on WebDAV FS (closes #2036).
|
||||
- IMAP/ManageSieve: Increase maximum quoted argument size (#2039).
|
||||
- CalDAV: Limit recurrence expansions in calendar reports ([CVE-2025-59045](https://github.com/stalwartlabs/stalwart/security/advisories/GHSA-xv4r-q6gr-6pfg)).
|
||||
- WebDAV: Do not fix percent encoding on WebDAV FS (#2036).
|
||||
|
||||
## [0.13.2] - 2025-07-28
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use super::{ResponseCode, ResponseType};
|
||||
use compact_str::{CompactString, format_compact};
|
||||
use std::fmt::Display;
|
||||
|
||||
use compact_str::{CompactString, format_compact};
|
||||
|
||||
use super::{ResponseCode, ResponseType};
|
||||
const QUOTED_ARG_MAX_LEN: usize = 4096;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Error {
|
||||
@@ -277,7 +277,7 @@ impl<T: CommandParser> Receiver<T> {
|
||||
if !escaped {
|
||||
self.push_argument(true)?;
|
||||
self.state = State::Argument { last_ch: b' ' };
|
||||
} else if self.buf.len() < 4096 {
|
||||
} else if self.buf.len() < QUOTED_ARG_MAX_LEN {
|
||||
self.buf.push(ch);
|
||||
self.state = State::ArgumentQuoted { escaped: false };
|
||||
} else {
|
||||
@@ -286,7 +286,11 @@ impl<T: CommandParser> Receiver<T> {
|
||||
}
|
||||
b'\\' => {
|
||||
if escaped {
|
||||
self.buf.push(ch);
|
||||
if self.buf.len() < QUOTED_ARG_MAX_LEN {
|
||||
self.buf.push(ch);
|
||||
} else {
|
||||
return Err(self.error_reset("Quoted argument too long."));
|
||||
}
|
||||
}
|
||||
self.state = State::ArgumentQuoted { escaped: !escaped };
|
||||
}
|
||||
@@ -294,7 +298,7 @@ impl<T: CommandParser> Receiver<T> {
|
||||
return Err(self.error_reset("Unterminated quoted argument."));
|
||||
}
|
||||
_ => {
|
||||
if self.buf.len() < 4096 {
|
||||
if self.buf.len() < QUOTED_ARG_MAX_LEN {
|
||||
if escaped {
|
||||
self.buf.push(b'\\');
|
||||
}
|
||||
@@ -340,7 +344,6 @@ impl<T: CommandParser> Receiver<T> {
|
||||
self.buf.push(ch);
|
||||
} else {
|
||||
// Digit found after non-sync '+' flag
|
||||
|
||||
return Err(self.error_reset("Invalid literal."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ async fn limits() {
|
||||
// Exceed max line length
|
||||
let mut session = Session::test_with_shutdown(TestSMTP::from_core(core).server, rx);
|
||||
session.data.remote_ip_str = "10.0.0.1".into();
|
||||
let mut buf = vec![b'A'; 2049];
|
||||
let mut buf = vec![b'A'; 4097];
|
||||
session.ingest(&buf).await.unwrap();
|
||||
session.ingest(b"\r\n").await.unwrap();
|
||||
session.response().assert_code("554 5.3.4");
|
||||
|
||||
Reference in New Issue
Block a user