Hyphens in folder names break LIST

Matthew Hodgson matthew at mxtelecom.com
Tue May 20 12:44:54 EDT 2008


Hi all,

If I create a hierarchy of folders such as:

test
test.SPAM
test-foo

and try to list the folder hierarchy with something like:

11 LIST "" "test%"

I get broken output, where test is listed twice - the second time with a 
\Noselect flag:

* LIST (\HasNoChildren) "." "test"
* LIST (\HasNoChildren) "." "test-foo"
* LIST (\Noselect \HasChildren) "." "test"

This breaks being able to subscribe to the test folder on MUAs such as 
Thunderbird.

The bug appears to be in imapd.c:mstringdata(), which assumes that 
children immediately follow their parent folder in the list of pattern 
matches with which mstringdata is invoked.  In the above scenario, 
mstringdata is invoked with test, test-foo, then test.SPAM, as hyphen 
comes before dot in ASCII.  As a result, the partial match suppression 
logic fails, not recognising test.SPAM as a child folder, and the bogus 
LIST line is generated.

A viable workaround seems to be to simplify the partial match 
suppression logic such that only the stems of the partial match and 
previous match are compared - and so the "test" of "test.SPAM" matches 
against the "test" of "test-foo", despite "test-foo" not actually being 
the parent of the folder in question.

That said, I'm not 100% comfortable with the intended behaviour here, 
though, so I may well be missing something significant.  Is 
name[matchlen] != '\0' not good enough to detect a partial match that 
should be suppressed, or does that break for more complicated patterns?

My current workaround is:

--- imapd.c.orig        2008-05-20 17:38:03.000000000 +0100
+++ imapd.c     2008-05-20 17:38:48.000000000 +0100
@@ -9305,10 +9305,11 @@
         return;
      }

-    /* Suppress any output of a partial match */
+    /* Suppress any output of a partial match.
+     * Do we even need to compare stems with lastname to see this is a 
partial match?
+     */
      if ((name[matchlen]
-        && strncmp(lastname, name, matchlen) == 0
-        && (lastname[matchlen] == '\0' || lastname[matchlen] == '.'))) {
+        && strncmp(lastname, name, matchlen) == 0)) {
         return;
      }


thanks,

M.

-- 
Matthew Hodgson <matthew at mxtelecom.com>
Media & Systems Project Manager
Tel: +44 (0) 845 666 7778
http://www.mxtelecom.com


More information about the Info-cyrus mailing list