Don't create invalid maildir names with lower case maildir flags
If someone had a custom :2,a flag, adding a new flag would lead to the invalid maildir filename ...a:2,... due to regex deficiencies not coping with this. Fix this so we alway produce valid maildir names. Note that custom flags are still problematic: as the syncing to the remote IMAP server will fail, the next sync will assume that they have been removed from the remote IMAP side and they will be removed from the local Maildir then. We will need to think about how to handle this. At least, with this patch we won't lose standard flags and won't produce invalid maildir names. Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
parent
64f5e557bc
commit
d5666ce91d
@ -64,13 +64,13 @@ class MaildirFolder(BaseFolder):
|
|||||||
self.root = root
|
self.root = root
|
||||||
self.sep = sep
|
self.sep = sep
|
||||||
self.messagelist = None
|
self.messagelist = None
|
||||||
|
# check if we should use a different infosep to support Win file systems
|
||||||
self.wincompatible = self.config.getdefaultboolean(
|
self.wincompatible = self.config.getdefaultboolean(
|
||||||
"Account "+self.accountname, "maildir-windows-compatible", False)
|
"Account "+self.accountname, "maildir-windows-compatible", False)
|
||||||
|
|
||||||
self.infosep = '!' if self.wincompatible else ':'
|
self.infosep = '!' if self.wincompatible else ':'
|
||||||
"""infosep is the separator between maildir name and flag appendix"""
|
"""infosep is the separator between maildir name and flag appendix"""
|
||||||
self.flagmatchre = re.compile(self.infosep + '2,([A-Z]+)')
|
self.flagmatchre = re.compile('(%s2,)(\w*)' % self.infosep)
|
||||||
#self.ui is set in BaseFolder.init()
|
#self.ui is set in BaseFolder.init()
|
||||||
# Cache the full folder path, as we use getfullname() very often
|
# Cache the full folder path, as we use getfullname() very often
|
||||||
self._fullname = os.path.join(self.getroot(), self.getname())
|
self._fullname = os.path.join(self.getroot(), self.getname())
|
||||||
@ -162,7 +162,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
#identify flags in the path name
|
#identify flags in the path name
|
||||||
flagmatch = self.flagmatchre.search(messagename)
|
flagmatch = self.flagmatchre.search(messagename)
|
||||||
if flagmatch:
|
if flagmatch:
|
||||||
flags = set(flagmatch.group(1))
|
flags = set(flagmatch.group(2))
|
||||||
else:
|
else:
|
||||||
flags = set()
|
flags = set()
|
||||||
# 'filename' is 'dirannex/filename', e.g. cur/123,U=1,FMD5=1:2,S
|
# 'filename' is 'dirannex/filename', e.g. cur/123,U=1,FMD5=1:2,S
|
||||||
@ -185,7 +185,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
def cachemessagelist(self):
|
def cachemessagelist(self):
|
||||||
if self.messagelist is None:
|
if self.messagelist is None:
|
||||||
self.messagelist = self._scanfolder()
|
self.messagelist = self._scanfolder()
|
||||||
|
|
||||||
def getmessagelist(self):
|
def getmessagelist(self):
|
||||||
return self.messagelist
|
return self.messagelist
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
self.savemessageflags(uid, flags)
|
self.savemessageflags(uid, flags)
|
||||||
self.ui.debug('maildir', 'savemessage: returning uid %d' % uid)
|
self.ui.debug('maildir', 'savemessage: returning uid %d' % uid)
|
||||||
return uid
|
return uid
|
||||||
|
|
||||||
def getmessageflags(self, uid):
|
def getmessageflags(self, uid):
|
||||||
return self.messagelist[uid]['flags']
|
return self.messagelist[uid]['flags']
|
||||||
|
|
||||||
@ -274,15 +274,14 @@ class MaildirFolder(BaseFolder):
|
|||||||
else:
|
else:
|
||||||
dir_prefix = 'new'
|
dir_prefix = 'new'
|
||||||
|
|
||||||
infostr = self.infosep
|
# Strip off existing infostring (preserving small letter flags, that
|
||||||
infomatch = re.search('(' + self.infosep + '.*)$', newname)
|
# dovecot uses)
|
||||||
if infomatch: # If the info string is present..
|
infomatch = self.flagmatchre.search(newname)
|
||||||
infostr = infomatch.group(1)
|
if infomatch:
|
||||||
newname = newname.split(self.infosep)[0] # Strip off the info string.
|
newname = newname[:-len(infomatch.group())] #strip off
|
||||||
infostr = re.sub('2,[A-Z]*', '', infostr)
|
infostr = '%s2,%s' % (self.infosep, ''.join(sorted(flags)))
|
||||||
infostr += '2,' + ''.join(sorted(flags))
|
|
||||||
newname += infostr
|
newname += infostr
|
||||||
|
|
||||||
newfilename = os.path.join(dir_prefix, newname)
|
newfilename = os.path.join(dir_prefix, newname)
|
||||||
if (newfilename != oldfilename):
|
if (newfilename != oldfilename):
|
||||||
try:
|
try:
|
||||||
@ -292,7 +291,7 @@ class MaildirFolder(BaseFolder):
|
|||||||
raise OfflineImapError("Can't rename file '%s' to '%s': %s" % (
|
raise OfflineImapError("Can't rename file '%s' to '%s': %s" % (
|
||||||
oldfilename, newfilename, e[1]),
|
oldfilename, newfilename, e[1]),
|
||||||
OfflineImapError.ERROR.FOLDER)
|
OfflineImapError.ERROR.FOLDER)
|
||||||
|
|
||||||
self.messagelist[uid]['flags'] = flags
|
self.messagelist[uid]['flags'] = flags
|
||||||
self.messagelist[uid]['filename'] = newfilename
|
self.messagelist[uid]['filename'] = newfilename
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user