commit eb52be5f19ef981bd14302cbab273b5e78f2f72f
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Mon Sep 9 18:47:32 2019 +0200

    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 commit 6f2160f1 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.

 TODO              |  2 --
 src/drv_imap.c    | 38 ++++++++++++++++++++++++++++----------
 src/drv_maildir.c |  5 +++++
 3 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/TODO b/TODO
index aa9ef54..66c9489 100644
--- a/TODO
+++ b/TODO
@@ -37,8 +37,6 @@ Patterns.
   function being missing so far
 - this is needed for move detection, which would work only within one Channel
 
-normalize INBOX capitalization received from IMAP, to avoid anomalies.
-
 add regexp-based mailbox path rewriting to the drivers. user would provide
 expressions for both directions. every transformation would be immediately
 verified with the inverse transform. PathDelimiter and Flatten would become
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 1a41581..1b5c959 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -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 );
 }
 
+// Use this to check whether a full path refers to the actual IMAP INBOX.
 static int
 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 ))
                return 0;
@@ -1256,16 +1268,22 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list, 
char *cmd ATTR_UNUSED )
        }
        arg = list->val;
        argl = list->len;
-       if ((l = strlen( ctx->prefix ))) {
-               if (starts_with( arg, argl, ctx->prefix, l )) {
-                       arg += l;
-                       argl -= l;
-                       if (is_inbox( ctx, arg, argl )) {
-                               if (!arg[5])
-                                       warn( "IMAP warning: ignoring INBOX in 
%s\n", ctx->prefix );
-                               goto skip;
-                       }
-               } else if (!is_inbox( ctx, arg, argl )) {
+       if (is_inbox( ctx, arg, argl )) {
+               // 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;
+               argl -= l;
+               // 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 (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 );
                        goto skip;
                }
        }
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 958dde8..c9b3c42 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -352,6 +352,7 @@ maildir_list_maildirpp( maildir_store_t *ctx, int flags, 
const char *inbox )
                } else {
                        if (!(flags & (LIST_PATH | LIST_PATH_MAYBE)))
                                continue;
+                       // Explained in maildir_list_recurse().
                        if (starts_with( ent, -1, "INBOX", 5 ) && (!ent[5] || 
ent[5] == '.')) {
                                if (!warned) {
                                        warned = 1;
@@ -437,6 +438,10 @@ maildir_list_recurse( maildir_store_t *ctx, int isBox, int 
flags,
                                                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 )) {
                                path[pathLen] = 0;
                                warn( "Maildir warning: ignoring INBOX in 
%s\n", path );


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to