From e310741646af346c79bbed92053dc0965c7257b5 Mon Sep 17 00:00:00 2001 From: Michael Nosov Date: Tue, 26 Jun 2018 11:06:24 +0300 Subject: [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 --- src/plugins/messageservices/imap/imapprotocol.cpp | 31 +++++++++++++++++++---- 1 file 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()) { -- cgit v1.2.3