summaryrefslogtreecommitdiffstats
path: root/src/network/access/qnetworkcookie.cpp
diff options
context:
space:
mode:
authorShane Kearns <ext-shane.2.kearns@nokia.com>2012-06-08 12:01:27 +0100
committerQt by Nokia <qt-info@nokia.com>2012-06-27 00:46:35 +0200
commitd76bd0d7358b1c061f3c685a9256243eb9f11d7a (patch)
treed34d12f2662b6dc59c26fab0f520cdb873628f4b /src/network/access/qnetworkcookie.cpp
parent7b61e60676cd7989050d50f6e823e30a5c99cf14 (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/qnetworkcookie.cpp')
-rw-r--r--src/network/access/qnetworkcookie.cpp103
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);