handle case-insensitivity of IMAP's INBOX
this is relevant only when listing an IMAP Store's contents, as that's the only place where we aren't imposing the spelling ourselves. we need to be careful not to treat our own canonical (prefix-stripped and always slash-delimited) box names like that; codify that in comments. this reveals that commit6f2160f1
may be deemed to have been incorrect - the TODO item was ambiguous, and could quite possibly have meant this fix. unsurprisingly,380ccdd4
re-introduced it with more explicit wording.
This commit is contained in:
parent
94022a6752
commit
04fc586e75
2
TODO
2
TODO
|
@ -37,8 +37,6 @@ Patterns.
|
||||||
function being missing so far
|
function being missing so far
|
||||||
- this is needed for move detection, which would work only within one Channel
|
- this is needed for move detection, which would work only within one Channel
|
||||||
|
|
||||||
normalize INBOX capitalization received from IMAP, to avoid anomalies.
|
|
||||||
|
|
||||||
kill the concept of an INBOX, it is a relic from single-channel operation.
|
kill the concept of an INBOX, it is a relic from single-channel operation.
|
||||||
if somebody needs it, he can have two stores with different Paths. the path
|
if somebody needs it, he can have two stores with different Paths. the path
|
||||||
can name a single (in-)box (curr. broken with maildir). an empty box name
|
can name a single (in-)box (curr. broken with maildir). an empty box name
|
||||||
|
|
|
@ -1232,8 +1232,20 @@ parse_list_rsp_p1( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
||||||
return parse_list( ctx, cmd, parse_list_rsp_p2 );
|
return parse_list( ctx, cmd, parse_list_rsp_p2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use this to check whether a full path refers to the actual IMAP INBOX.
|
||||||
static int
|
static int
|
||||||
is_inbox( imap_store_t *ctx, const char *arg, int argl )
|
is_inbox( imap_store_t *ctx, const char *arg, int argl )
|
||||||
|
{
|
||||||
|
if (!starts_with_upper( arg, argl, "INBOX", 5 ))
|
||||||
|
return 0;
|
||||||
|
if (arg[5] && arg[5] != ctx->delimiter[0])
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use this to check whether a path fragment collides with the canonical INBOX.
|
||||||
|
static int
|
||||||
|
is_INBOX( imap_store_t *ctx, const char *arg, int argl )
|
||||||
{
|
{
|
||||||
if (!starts_with( arg, argl, "INBOX", 5 ))
|
if (!starts_with( arg, argl, "INBOX", 5 ))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1256,18 +1268,24 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, char *cmd ATTR_UNUSED )
|
||||||
}
|
}
|
||||||
arg = list->val;
|
arg = list->val;
|
||||||
argl = list->len;
|
argl = list->len;
|
||||||
if ((l = strlen( ctx->prefix ))) {
|
if (is_inbox( ctx, arg, argl )) {
|
||||||
if (starts_with( arg, argl, ctx->prefix, l )) {
|
// The server might be weird and have a non-uppercase INBOX. It
|
||||||
|
// may legitimately do so, but we need the canonical spelling.
|
||||||
|
memcpy( arg, "INBOX", 5 );
|
||||||
|
} else if ((l = strlen( ctx->prefix ))) {
|
||||||
|
if (!starts_with( arg, argl, ctx->prefix, l ))
|
||||||
|
goto skip;
|
||||||
arg += l;
|
arg += l;
|
||||||
argl -= l;
|
argl -= l;
|
||||||
if (is_inbox( ctx, arg, argl )) {
|
// A folder named "INBOX" would be indistinguishable from the
|
||||||
if (!arg[5])
|
// actual INBOX after prefix stripping, so drop it. This applies
|
||||||
|
// only to the fully uppercased spelling, as our canonical box
|
||||||
|
// names are case-sensitive (unlike IMAP's INBOX).
|
||||||
|
if (is_INBOX( ctx, arg, argl )) {
|
||||||
|
if (!arg[5]) // No need to complain about subfolders as well.
|
||||||
warn( "IMAP warning: ignoring INBOX in %s\n", ctx->prefix );
|
warn( "IMAP warning: ignoring INBOX in %s\n", ctx->prefix );
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
} else if (!is_inbox( ctx, arg, argl )) {
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */
|
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
|
@ -352,6 +352,7 @@ maildir_list_maildirpp( maildir_store_t *ctx, int flags, const char *inbox )
|
||||||
} else {
|
} else {
|
||||||
if (!(flags & (LIST_PATH | LIST_PATH_MAYBE)))
|
if (!(flags & (LIST_PATH | LIST_PATH_MAYBE)))
|
||||||
continue;
|
continue;
|
||||||
|
// Explained in maildir_list_recurse().
|
||||||
if (starts_with( ent, -1, "INBOX", 5 ) && (!ent[5] || ent[5] == '.')) {
|
if (starts_with( ent, -1, "INBOX", 5 ) && (!ent[5] || ent[5] == '.')) {
|
||||||
if (!warned) {
|
if (!warned) {
|
||||||
warned = 1;
|
warned = 1;
|
||||||
|
@ -437,6 +438,10 @@ maildir_list_recurse( maildir_store_t *ctx, int isBox, int flags,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// A folder named "INBOX" would be indistinguishable from the
|
||||||
|
// actual INBOX after prefix stripping, so drop it. This applies
|
||||||
|
// only to the fully uppercased spelling, as our canonical box
|
||||||
|
// names are case-sensitive (unlike IMAP's INBOX).
|
||||||
if (!nameLen && equals( ent, -1, "INBOX", 5 )) {
|
if (!nameLen && equals( ent, -1, "INBOX", 5 )) {
|
||||||
path[pathLen] = 0;
|
path[pathLen] = 0;
|
||||||
warn( "Maildir warning: ignoring INBOX in %s\n", path );
|
warn( "Maildir warning: ignoring INBOX in %s\n", path );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user