diff --git a/imap-proto/src/parser/core.rs b/imap-proto/src/parser/core.rs index 6d02bce..2e2e4e4 100644 --- a/imap-proto/src/parser/core.rs +++ b/imap-proto/src/parser/core.rs @@ -2,9 +2,9 @@ use nom::{ branch::alt, bytes::streaming::{escaped, tag, tag_no_case, take, take_while, take_while1}, character::streaming::{char, digit1, one_of}, - combinator::{map, map_res}, + combinator::{map, map_res, opt}, multi::{separated_list0, separated_list1}, - sequence::{delimited, tuple}, + sequence::{delimited, preceded, tuple}, IResult, }; @@ -212,7 +212,14 @@ where F: FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>, E: nom::error::ParseError<&'a [u8]>, { - delimited(char('('), separated_list0(char(' '), f), char(')')) + delimited( + char('('), + separated_list0(char(' '), f), + preceded( + opt(char(' ')), // Surgemail sometimes sends a space before the closing bracket. + char(')'), + ), + ) } pub fn opt_opt<'a, F, O, E>(mut f: F) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Option, E> diff --git a/imap-proto/src/parser/rfc3501/mod.rs b/imap-proto/src/parser/rfc3501/mod.rs index 91d1792..bf4eced 100644 --- a/imap-proto/src/parser/rfc3501/mod.rs +++ b/imap-proto/src/parser/rfc3501/mod.rs @@ -93,6 +93,11 @@ fn flag_list(i: &[u8]) -> IResult<&[u8], Vec>> { // * FLAGS (\Answered \Flagged \Deleted \Seen \Draft \*) // // As a workaround, "\*" is allowed here. + // + // Also, surgemail sends an additional space before the closing bracket: + // * FLAGS (\Answered \Flagged \Deleted \Draft \Seen $Forwarded ) + // + // As a workaround, optional spaces before the closing bracket are allowed. parenthesized_list(map(flag_perm, Cow::Borrowed))(i) } @@ -803,4 +808,22 @@ mod tests { Err(_) ); } + + #[test] + fn test_surgemail_select_flags() { + // Tests workaround for surgemail with space before closing bracket + assert_matches!( + super::flag_list(b"(\\Answered \\Flagged \\Deleted \\Draft \\Seen $Forwarded )"), + Ok(([], flags)) => { + assert_eq!(flags, vec![ + "\\Answered", + "\\Flagged", + "\\Deleted", + "\\Draft", + "\\Seen", + "$Forwarded" + ]) + } + ); + } }