Ticket #28 (closed defect: fixed)

Opened 9 months ago

Last modified 4 months ago

Mailbox names with escaped chars them aren't returned correctly

Reported by: menno Owned by: menno
Priority: critical Milestone: 0.6
Version: Keywords:
Cc:

Description

'Test "folder"' is returned by list_folders() as 'Test \'

Escaping needs to be handled correctly.

Change History

  Changed 9 months ago by menno

This problem doesn't occur with all IMAP servers. Gmail uses backslash escaping so the problem occurs there. Dovecot returns folders with double quotes in a literal which doesn't trip IMAPClient up.

Example Gmail response:

* LIST (\HasNoChildren) "/" "Test \"folder\""

The new response parser should handle this cleanly. It should be possible to use a temporary fix in the mean time.

follow-up: ↓ 3   Changed 9 months ago by menno

  • milestone changed from 0.6 to 0.5.2

in reply to: ↑ 2   Changed 8 months ago by eichin

Replying to menno:

Possible workaround (with debugging still in)...

  1. use a named backref qqq in re_folder, so that we can use a greedy match on the foldername regardless of whether or not it has quotes (ie. if and only if there's a start quote, match an end one)
  2. use a named ref for the folder name itself
  3. clean up the extra quoting (in list_folders, though list_sub_folders needs both 2 and 3 as well)

With these changes, all of my gmail foldernames round-trip from list_folders back to select_folder, except for [Gmail] itself; I haven't tested this against any other implementation. extract_folder_from_line probably needs to be a common function called by list_folders and list_sub_folders anyway, instead of a shared regexp.

diff -r 5ac3ccadb5fc imapclient/imapclient.py
--- a/imapclient/imapclient.py	Fri Dec 18 17:17:30 2009 +0000
+++ b/imapclient/imapclient.py	Sun Dec 27 01:50:30 2009 -0500
@@ -63,7 +63,7 @@
     ReadOnlyError = imaplib.IMAP4.readonly
 
     re_sep = re.compile('^\(\("[^"]*" "([^"]+)"\)\)')
-    re_folder = re.compile('\([^)]*\) "[^"]+" "?([^"]+)"?')
+    re_folder = re.compile(r'\([^)]*\) "[^"]+" (?P<qqq>"?)(?P<folder>.+)(?P=qqq)')
     re_status = re.compile(r'^\s*"?(?P<folder>[^"]+)"?\s+'
                            r'\((?P<status_items>.*)\)$')
 
@@ -169,7 +169,10 @@
             else:
                 match = self.re_folder.match(line)
                 if match:
-                    folder_text = match.group(1)
+                    folder_text = match.group("folder")
+                    print "matched folder", repr(folder_text), "in", repr(line)
+                    folder_text = folder_text.replace('\\"', '"')
+                    print "  fixed folder", repr(folder_text)
             if folder_text is not None:
                 folders.append(self._decode_folder_name(folder_text))
         return folders

  Changed 8 months ago by menno

  • status changed from new to closed
  • resolution set to fixed

Fixed in r91 thru r95

follow-up: ↓ 8   Changed 6 months ago by eichin

  • status changed from closed to reopened
  • resolution fixed deleted

Working with trunk (r139), it looks like it again does the wrong thing with a gmail folder name that begins with quotes (as opposed to merely containing them); a folder named

"Make" Magazine (ORA)

becomes

Make" Magazine (ORA

Turning off this bit of re-unquoting from r103 fixes my case, but I don't know if it impacts non-gmail IMAP servers...

diff -r be5626eee037 imapclient/response_parser.py
--- a/imapclient/response_parser.py Wed Mar 17 02:10:37 2010 +0000
+++ b/imapclient/response_parser.py Wed Mar 17 02:13:56 2010 -0400
@@ -207,8 +207,8 @@

raise ParseError?('Expecting literal of size %d, got %d' % (

literal_len, len(literal_text)))

return literal_text

- elif token.startswith('"'):
- return token[1:-1]
+ #elif token.startswith('"'):
+ # return token[1:-1]

elif token.isdigit():

return int(token)

else:

  Changed 6 months ago by menno

  • milestone changed from 0.5.2 to 0.6

Thanks, I'll try and get this sorted before the 0.6 release goes out.

  Changed 4 months ago by menno

  • owner set to menno
  • status changed from reopened to accepted

in reply to: ↑ 5   Changed 4 months ago by menno

  • status changed from accepted to closed
  • resolution set to fixed

Fixed in r142.
Thanks

Note: See TracTickets for help on using tickets.