Skip to content

Commit f55a10b

Browse files
committed
Added support for non-compliant keywords that begin with '\'
Fixes issue #1906
1 parent e5f891d commit f55a10b

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

MailKit/Net/Imap/ImapCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ void UpdateProgress (int n)
368368
Progress?.Report (nwritten, totalSize);
369369
}
370370

371-
static bool IsAtom (char c)
371+
internal static bool IsAtom (char c)
372372
{
373373
return c < 128 && !char.IsControl (c) && "(){ %*\\\"]".IndexOf (c) == -1;
374374
}

MailKit/Net/Imap/ImapFolderSearch.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,29 @@ void AddTextArgument (StringBuilder builder, List<object> args, string text, ref
8585
args.Add (buffer);
8686
}
8787

88+
void AddKeywordArgument (StringBuilder builder, List<object> args, string text, ref string charset)
89+
{
90+
// Note: Technically, the IMAP RFC states that keywords are not allowed to start with '\',
91+
// but some non-rfc-compliant IMAP servers do it anyway, so we need to allow it here.
92+
// See https://github.com/jstedfast/MailKit/issues/1906 for details.
93+
int startIndex = text[0] == '\\' ? 1 : 0;
94+
bool isAtom = true;
95+
96+
for (int i = startIndex; i < text.Length; i++) {
97+
if (!ImapCommand.IsAtom (text[i])) {
98+
isAtom = false;
99+
break;
100+
}
101+
}
102+
103+
if (isAtom) {
104+
builder.Append ("%s");
105+
args.Add (text);
106+
} else {
107+
AddTextArgument (builder, args, text, ref charset);
108+
}
109+
}
110+
88111
void BuildQuery (StringBuilder builder, SearchQuery query, List<object> args, bool parens, ref string charset)
89112
{
90113
AnnotationSearchQuery annotation;
@@ -196,7 +219,7 @@ void BuildQuery (StringBuilder builder, SearchQuery query, List<object> args, bo
196219
case SearchTerm.Keyword:
197220
text = (TextSearchQuery) query;
198221
builder.Append ("KEYWORD ");
199-
AddTextArgument (builder, args, text.Text, ref charset);
222+
AddKeywordArgument (builder, args, text.Text, ref charset);
200223
break;
201224
case SearchTerm.LargerThan:
202225
numeric = (NumericSearchQuery) query;
@@ -236,7 +259,7 @@ void BuildQuery (StringBuilder builder, SearchQuery query, List<object> args, bo
236259
case SearchTerm.NotKeyword:
237260
text = (TextSearchQuery) query;
238261
builder.Append ("UNKEYWORD ");
239-
AddTextArgument (builder, args, text.Text, ref charset);
262+
AddKeywordArgument (builder, args, text.Text, ref charset);
240263
break;
241264
case SearchTerm.NotRecent:
242265
builder.Append ("OLD");

0 commit comments

Comments
 (0)