Skip to content

Commit 84ebbfe

Browse files
HeroSizyclaude
andcommitted
fix(gmail): handle escaped quotes in mailbox list splitting
split_mailbox_list toggled quote state on every `"` without accounting for backslash-escaped quotes (`\"`), causing display names like `"Doe \"JD, Sr\""` to split incorrectly at interior commas. Track `prev_backslash` so `\"` inside quoted strings is treated as a literal quote character rather than a delimiter toggle. Double backslashes (`\\`) are handled correctly as well. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c491d5c commit 84ebbfe

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

src/helpers/gmail/reply.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,15 @@ fn split_mailbox_list(header: &str) -> Vec<&str> {
216216
let mut result = Vec::new();
217217
let mut in_quotes = false;
218218
let mut start = 0;
219+
let mut prev_backslash = false;
219220

220221
for (i, ch) in header.char_indices() {
221222
match ch {
222-
'"' => in_quotes = !in_quotes,
223+
'\\' if in_quotes => {
224+
prev_backslash = !prev_backslash;
225+
continue;
226+
}
227+
'"' if !prev_backslash => in_quotes = !in_quotes,
223228
',' if !in_quotes => {
224229
let token = header[start..i].trim();
225230
if !token.is_empty() {
@@ -229,6 +234,7 @@ fn split_mailbox_list(header: &str) -> Vec<&str> {
229234
}
230235
_ => {}
231236
}
237+
prev_backslash = false;
232238
}
233239

234240
let token = header[start..].trim();
@@ -835,6 +841,30 @@ mod tests {
835841
assert!(addrs.is_empty());
836842
}
837843

844+
#[test]
845+
fn test_split_mailbox_list_escaped_quotes() {
846+
let addrs =
847+
split_mailbox_list(r#""Doe \"JD, Sr\"" <john@example.com>, alice@example.com"#);
848+
assert_eq!(
849+
addrs,
850+
vec![
851+
r#""Doe \"JD, Sr\"" <john@example.com>"#,
852+
"alice@example.com"
853+
]
854+
);
855+
}
856+
857+
#[test]
858+
fn test_split_mailbox_list_double_backslash() {
859+
// \\\\" inside quotes means an escaped backslash followed by a closing quote
860+
let addrs =
861+
split_mailbox_list(r#""Trail\\" <t@example.com>, b@example.com"#);
862+
assert_eq!(
863+
addrs,
864+
vec![r#""Trail\\" <t@example.com>"#, "b@example.com"]
865+
);
866+
}
867+
838868
#[test]
839869
fn test_reply_all_with_quoted_comma_display_name() {
840870
let original = OriginalMessage {

0 commit comments

Comments
 (0)