diff options
author | Michael Nosov <Michael.Nosov@harman.com> | 2018-06-26 11:06:24 +0300 |
---|---|---|
committer | Michael Nosov <Michael.Nosov@harman.com> | 2018-07-20 08:44:19 +0000 |
commit | e310741646af346c79bbed92053dc0965c7257b5 (patch) | |
tree | 4868fbb23e8b445e77dc7c7a45bfcf6fbcb3e345 | |
parent | 179fb1ed0cc69a3913cbac234b440dd48e99dc17 (diff) |
[qmf] IMAP: fix when folder name contains quote '"' symbol
Problem description:
Consider the following IMAP response:
* XLIST (\HasNoChildren) "/" "Q/22\"22/3333"
Implementation will parse name between '"' symbols, e.g. only Q/22\
And it will create folder 22\ instead of 22"22 and will not create folder 3333
Fix is to parse folder name between '"' but don't treat '\"' as end of token
After the fix, verify that sub-folder "3333" is created in above scenario
Note: folder 22"22 will still be displayed as 22\"22.
This is separate fix, review number is 233280
Also verify case when folder name consists of only one quote character (")
Change-Id: I9c7434f5dc0b68fdac38202c350ccb02ea6eca46
Reviewed-by: Matthew Vogt <matthew.vogt@qinetic.com.au>
-rw-r--r-- | src/plugins/messageservices/imap/imapprotocol.cpp | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/plugins/messageservices/imap/imapprotocol.cpp b/src/plugins/messageservices/imap/imapprotocol.cpp index 48e625f0..210d9fcb 100644 --- a/src/plugins/messageservices/imap/imapprotocol.cpp +++ b/src/plugins/messageservices/imap/imapprotocol.cpp @@ -155,7 +155,28 @@ static bool parseFlags(const QString& field, MessageFlags& flags) return true; } -static QString token( QString str, QChar c1, QChar c2, int *index ) +static int indexOfWithEscape(const QString &str, QChar c, int from, const QString &ignoreEscape) +{ + int index = from; + int pos = str.indexOf(c, index, Qt::CaseInsensitive); + if (ignoreEscape.isEmpty()) { + return pos; + } + const int ignoreLength = ignoreEscape.length(); + while (pos + 1 >= ignoreLength) { + if (str.mid(pos - ignoreLength + 1, ignoreLength) == ignoreEscape) { + index = pos + 1; + pos = str.indexOf(c, index, Qt::CaseInsensitive); + continue; + } else { + break; + } + } + + return pos; +} + +static QString token( QString str, QChar c1, QChar c2, int *index, const QString &ignoreEscape = QString()) { int start, stop; @@ -163,13 +184,13 @@ static QString token( QString str, QChar c1, QChar c2, int *index ) // caller considers the sequence to be atomic. if (c1 == QMailMessage::CarriageReturn) c1 = QMailMessage::LineFeed; - start = str.indexOf( c1, *index, Qt::CaseInsensitive ); + start = indexOfWithEscape(str, c1, *index, ignoreEscape); if (start == -1) return QString(); if (c2 == QMailMessage::CarriageReturn) c2 = QMailMessage::LineFeed; - stop = str.indexOf( c2, ++start, Qt::CaseInsensitive ); + stop = indexOfWithEscape(str, c2, ++start, ignoreEscape); if (stop == -1) return QString(); @@ -943,9 +964,9 @@ void ListState::untaggedResponse(ImapContext *c, const QString &line) index--; //to point back to previous ' ' so we can find it with next search path = token(str, ' ', '\n', &index).trimmed(); pos = 0; - if (!token(path, '"', '"', &pos).isNull()) { + if (!token(path, '"', '"', &pos, "\\\"").isNull()) { pos = 0; - path = token(path, '"', '"', &pos); + path = token(path, '"', '"', &pos, "\\\""); } if (!path.isEmpty()) { |