diff options
author | Shane Kearns <ext-shane.2.kearns@nokia.com> | 2012-06-08 12:01:27 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-06-27 00:46:35 +0200 |
commit | d76bd0d7358b1c061f3c685a9256243eb9f11d7a (patch) | |
tree | d34d12f2662b6dc59c26fab0f520cdb873628f4b /src/network/access | |
parent | 7b61e60676cd7989050d50f6e823e30a5c99cf14 (diff) |
QNetworkCookie: Use RFC6265 rules for parsing Set-Cookie
The ';' separator takes priority even inside a quoted string.
Quotation marks have no special meaning, they are not parsed and
regenerated anymore. This means it is not possible to include
the ';' character inside a cookie value.
Other characters are returned transparently, including [",\]
Task-number: QTBUG-15794
Task-number: QTBUG-26002
Task-number: QTBUG-11641
Change-Id: I4eefef5c6ac7753d5a21c226169e264578521fe9
Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkcookie.cpp | 103 |
1 files changed, 16 insertions, 87 deletions
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 89e6f8a5ae..306195addb 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -379,85 +379,27 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi // (1) token // (2) token = token // (3) token = quoted-string - int i; const int length = text.length(); position = nextNonWhitespace(text, position); - // parse the first part, before the equal sign - for (i = position; i < length; ++i) { - register char c = text.at(i); - if (c == ';' || c == '=') - break; - } - - QByteArray first = text.mid(position, i - position).trimmed(); - position = i; - - if (first.isEmpty()) - return qMakePair(QByteArray(), QByteArray()); - if (i == length || text.at(i) != '=') - // no equal sign, we found format (1) - return qMakePair(first, QByteArray()); - - QByteArray second; - second.reserve(32); // arbitrary but works for most cases - - i = nextNonWhitespace(text, position + 1); - if (i < length && text.at(i) == '"') { - // a quote, we found format (3), where: - // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) - // qdtext = <any TEXT except <">> - // quoted-pair = "\" CHAR + int semiColonPosition = text.indexOf(';', position); + if (semiColonPosition < 0) + semiColonPosition = length; //no ';' means take everything to end of string - // If it is NAME=VALUE, retain the value as is - // refer to http://bugreports.qt-project.org/browse/QTBUG-17746 + int equalsPosition = text.indexOf('=', position); + if (equalsPosition < 0 || equalsPosition > semiColonPosition) { if (isNameValue) - second += '"'; - ++i; - while (i < length) { - register char c = text.at(i); - if (c == '"') { - // end of quoted text - if (isNameValue) - second += '"'; - break; - } else if (c == '\\') { - if (isNameValue) - second += '\\'; - ++i; - if (i >= length) - // broken line - return qMakePair(QByteArray(), QByteArray()); - c = text.at(i); - } - - second += c; - ++i; - } - - for ( ; i < length; ++i) { - register char c = text.at(i); - if (c == ';') - break; - } - position = i; - } else { - // no quote, we found format (2) - position = i; - for ( ; i < length; ++i) { - register char c = text.at(i); - // for name value pairs, we want to parse until reaching the next ';' - // and not break when reaching a space char - if (c == ';' || ((isNameValue && (c == '\n' || c == '\r')) || (!isNameValue && isLWS(c)))) - break; - } - - second = text.mid(position, i - position).trimmed(); - position = i; + return qMakePair(QByteArray(), QByteArray()); //'=' is required for name-value-pair (RFC6265 section 5.2, rule 2) + equalsPosition = semiColonPosition; //no '=' means there is an attribute-name but no attribute-value } - if (second.isNull()) - second.resize(0); // turns into empty-but-not-null + QByteArray first = text.mid(position, equalsPosition - position).trimmed(); + QByteArray second; + int secondLength = semiColonPosition - equalsPosition - 1; + if (secondLength > 0) + second = text.mid(equalsPosition + 1, secondLength).trimmed(); + + position = semiColonPosition; return qMakePair(first, second); } @@ -500,20 +442,7 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const result = d->name; result += '='; - if ((d->value.contains(';') || - d->value.contains('"')) && - (!d->value.startsWith('"') && - !d->value.endsWith('"'))) { - result += '"'; - - QByteArray value = d->value; - value.replace('"', "\\\""); - result += value; - - result += '"'; - } else { - result += d->value; - } + result += d->value; if (form == Full) { // same as above, but encoding everything back @@ -972,7 +901,7 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt // The first part is always the "NAME=VALUE" part QPair<QByteArray,QByteArray> field = nextField(cookieString, position, true); - if (field.first.isEmpty() || field.second.isNull()) + if (field.first.isEmpty()) // parsing error break; cookie.setName(field.first); |