Make folders containing quotes work
imaputil.imapsplit did not cope with strings that contained encoded quotation marks, e.g. a folder name '"Make" Magazine' would fail and crash OfflineImap. Make it work by adapting the regex that we use to extract the first quote to also work with encoded \" quotes. (We do no sanity checks that there is an even number of such marks within a string though) This commit makes such folders work. This was reported and analyzed by Mark Eichin. Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de> Conflicts: Changelog.draft.rst
This commit is contained in:
parent
bf31accb78
commit
eb04036da5
@ -16,6 +16,9 @@ New Features
|
|||||||
* Beginning of a test suite. So far there is only one test. Configure
|
* Beginning of a test suite. So far there is only one test. Configure
|
||||||
test/credentials.conf and invoke with "python setup.py test"
|
test/credentials.conf and invoke with "python setup.py test"
|
||||||
|
|
||||||
|
* Make folders containing quotes work rather than crashing
|
||||||
|
(reported by Mark Eichin)
|
||||||
|
|
||||||
Changes
|
Changes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -25,7 +25,12 @@ try: # python 2.6 has set() built in
|
|||||||
except NameError:
|
except NameError:
|
||||||
from sets import Set as set
|
from sets import Set as set
|
||||||
|
|
||||||
quotere = re.compile('^("(?:[^"]|\\\\")*")')
|
# find the first quote in a string
|
||||||
|
quotere = re.compile(
|
||||||
|
r"""(?P<quote>"(?:\\"|[^"])*") # Quote, possibly containing encoded
|
||||||
|
# quotation mark
|
||||||
|
\s*(?P<rest>.*)$ # Whitespace & remainder of string""",
|
||||||
|
re.VERBOSE)
|
||||||
|
|
||||||
def debug(*args):
|
def debug(*args):
|
||||||
msg = []
|
msg = []
|
||||||
@ -71,7 +76,7 @@ def options2hash(list):
|
|||||||
|
|
||||||
def flags2hash(flags):
|
def flags2hash(flags):
|
||||||
"""Converts IMAP response string from eg IMAP4.fetch() to a hash.
|
"""Converts IMAP response string from eg IMAP4.fetch() to a hash.
|
||||||
|
|
||||||
E.g. '(FLAGS (\\Seen Old) UID 4807)' leads to
|
E.g. '(FLAGS (\\Seen Old) UID 4807)' leads to
|
||||||
{'FLAGS': '(\\Seen Old)', 'UID': '4807'}"""
|
{'FLAGS': '(\\Seen Old)', 'UID': '4807'}"""
|
||||||
return options2hash(flagsplit(flags))
|
return options2hash(flagsplit(flags))
|
||||||
@ -124,10 +129,11 @@ def imapsplit(imapstring):
|
|||||||
retval.extend(imapsplit(arg))
|
retval.extend(imapsplit(arg))
|
||||||
debug("imapsplit() non-string: returning %s" % str(retval))
|
debug("imapsplit() non-string: returning %s" % str(retval))
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
workstr = imapstring.strip()
|
workstr = imapstring.strip()
|
||||||
retval = []
|
retval = []
|
||||||
while len(workstr):
|
while len(workstr):
|
||||||
|
# handle parenthized fragments (...()...)
|
||||||
if workstr[0] == '(':
|
if workstr[0] == '(':
|
||||||
rparenc = 1 # count of right parenthesis to match
|
rparenc = 1 # count of right parenthesis to match
|
||||||
rpareni = 1 # position to examine
|
rpareni = 1 # position to examine
|
||||||
@ -141,9 +147,10 @@ def imapsplit(imapstring):
|
|||||||
workstr = workstr[rpareni:].lstrip()
|
workstr = workstr[rpareni:].lstrip()
|
||||||
retval.append(parenlist)
|
retval.append(parenlist)
|
||||||
elif workstr[0] == '"':
|
elif workstr[0] == '"':
|
||||||
quotelist = quotere.search(workstr).group(1)
|
# quoted fragments '"...\"..."'
|
||||||
workstr = workstr[len(quotelist):].lstrip()
|
m = quotere.match(workstr)
|
||||||
retval.append(quotelist)
|
retval.append(m.group('quote'))
|
||||||
|
workstr = m.group('rest')
|
||||||
else:
|
else:
|
||||||
splits = string.split(workstr, maxsplit = 1)
|
splits = string.split(workstr, maxsplit = 1)
|
||||||
splitslen = len(splits)
|
splitslen = len(splits)
|
||||||
@ -161,8 +168,9 @@ def imapsplit(imapstring):
|
|||||||
elif splitslen == 0:
|
elif splitslen == 0:
|
||||||
# There was not even an unquoted word.
|
# There was not even an unquoted word.
|
||||||
break
|
break
|
||||||
|
getglobalui().warn("%s->%s" % (imapstring, retval))
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
flagmap = [('\\Seen', 'S'),
|
flagmap = [('\\Seen', 'S'),
|
||||||
('\\Answered', 'R'),
|
('\\Answered', 'R'),
|
||||||
('\\Flagged', 'F'),
|
('\\Flagged', 'F'),
|
||||||
|
Loading…
Reference in New Issue
Block a user