summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qnetworkcookie.cpp13
-rw-r--r--src/network/access/qnetworkcookiejar.cpp20
-rw-r--r--tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp38
3 files changed, 50 insertions, 21 deletions
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index 306195addb..5a75dd55e8 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -466,7 +466,7 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const
}
if (!d->path.isEmpty()) {
result += "; path=";
- result += QUrl::toPercentEncoding(d->path, "/");
+ result += d->path.toUtf8();
}
}
return result;
@@ -954,8 +954,15 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt
}
//if unparsed, ignore the attribute but not the whole cookie (RFC6265 section 5.2.2)
} else if (field.first == "path") {
- QString path = QUrl::fromPercentEncoding(field.second);
- cookie.setPath(path);
+ if (field.second.startsWith('/')) {
+ // ### we should treat cookie paths as an octet sequence internally
+ // However RFC6265 says we should assume UTF-8 for presentation as a string
+ cookie.setPath(QString::fromUtf8(field.second));
+ } else {
+ // if the path doesn't start with '/' then set the default path (RFC6265 section 5.2.4)
+ // and also IETF test case path0030 which has valid and empty path in the same cookie
+ cookie.setPath(QString());
+ }
} else if (field.first == "secure") {
cookie.setSecure(true);
} else if (field.first == "httponly") {
diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp
index 9e5dfe0371..b4cf8ce0bf 100644
--- a/src/network/access/qnetworkcookiejar.cpp
+++ b/src/network/access/qnetworkcookiejar.cpp
@@ -140,11 +140,21 @@ void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList)
static inline bool isParentPath(QString path, QString reference)
{
- if (!path.endsWith(QLatin1Char('/')))
- path += QLatin1Char('/');
- if (!reference.endsWith(QLatin1Char('/')))
- reference += QLatin1Char('/');
- return path.startsWith(reference);
+ if (path.startsWith(reference)) {
+ //The cookie-path and the request-path are identical.
+ if (path.length() == reference.length())
+ return true;
+ //The cookie-path is a prefix of the request-path, and the last
+ //character of the cookie-path is %x2F ("/").
+ if (reference.endsWith('/'))
+ return true;
+ //The cookie-path is a prefix of the request-path, and the first
+ //character of the request-path that is not included in the cookie-
+ //path is a %x2F ("/") character.
+ if (path.at(reference.length()) == '/')
+ return true;
+ }
+ return false;
}
static inline bool isParentDomain(QString domain, QString reference)
diff --git a/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp
index 77afd23289..7896003bb2 100644
--- a/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp
+++ b/tests/auto/network/access/qnetworkcookie/tst_qnetworkcookie.cpp
@@ -235,20 +235,24 @@ void tst_QNetworkCookie::parseSingleCookie_data()
QTest::newRow("path9") << "a=b;path=/foo" << cookie;
// some weird paths:
- cookie.setPath("/with spaces");
+ cookie.setPath("/with%20spaces");
QTest::newRow("path-with-spaces") << "a=b;path=/with%20spaces" << cookie;
QTest::newRow("path-with-spaces2") << "a=b; path=/with%20spaces " << cookie;
- cookie.setPath("\"/with spaces\"");
- QTest::newRow("path-with-spaces3") << "a=b; path=\"/with spaces\"" << cookie;
- QTest::newRow("path-with-spaces4") << "a=b; path = \"/with spaces\" " << cookie;
+ cookie.setPath(QString());
+ QTest::newRow("invalid-path-with-spaces3") << "a=b; path=\"/with spaces\"" << cookie;
+ QTest::newRow("invalid-path-with-spaces4") << "a=b; path = \"/with spaces\" " << cookie;
+ cookie.setPath("/with spaces");
+ QTest::newRow("path-with-spaces5") << "a=b; path=/with spaces" << cookie;
+ QTest::newRow("path-with-spaces6") << "a=b; path = /with spaces " << cookie;
cookie.setPath("/with\"Quotes");
- QTest::newRow("path-with-quotes") << "a=b; path = /with%22Quotes" << cookie;
- cookie.setPath("\"/with\\\"Quotes\"");
- QTest::newRow("path-with-quotes2") << "a=b; path = \"/with\\\"Quotes\"" << cookie;
+ QTest::newRow("path-with-quotes") << "a=b; path = /with\"Quotes" << cookie;
+ cookie.setPath(QString());
+ QTest::newRow("invalid-path-with-quotes2") << "a=b; path = \"/with\\\"Quotes\"" << cookie;
cookie.setPath(QString::fromUtf8("/R\303\251sum\303\251"));
QTest::newRow("path-with-utf8") << QString::fromUtf8("a=b;path=/R\303\251sum\303\251") << cookie;
+ cookie.setPath("/R%C3%A9sum%C3%A9");
QTest::newRow("path-with-utf8-2") << "a=b;path=/R%C3%A9sum%C3%A9" << cookie;
cookie.setPath(QString());
@@ -649,12 +653,21 @@ void tst_QNetworkCookie::parseMultipleCookies_data()
QTest::newRow("invalid-06") << "=b" << list;
QTest::newRow("invalid-07") << ";path=/" << list;
+ // these should be accepted by RFC6265 but ignoring the expires field
// reason: malformed expiration date string
- QTest::newRow("invalid-08") << "a=b;expires=" << list;
- QTest::newRow("invalid-09") << "a=b;expires=foobar" << list;
- QTest::newRow("invalid-10") << "a=b;expires=foobar, abc" << list;
- QTest::newRow("invalid-11") << "a=b;expires=foobar, dd-mmm-yyyy hh:mm:ss GMT; path=/" << list;
- QTest::newRow("invalid-12") << "a=b;expires=foobar, 32-Caz-1999 24:01:60 GMT; path=/" << list;
+ QNetworkCookie datelessCookie;
+ datelessCookie.setName("a");
+ datelessCookie.setValue("b");
+ list << datelessCookie;
+ QTest::newRow("expiration-empty") << "a=b;expires=" << list;
+ QTest::newRow("expiration-invalid-01") << "a=b;expires=foobar" << list;
+ QTest::newRow("expiration-invalid-02") << "a=b;expires=foobar, abc" << list;
+ QTest::newRow("expiration-invalid-03") << "a=b; expires=123" << list; // used to ASSERT
+ datelessCookie.setPath("/");
+ list.clear();
+ list << datelessCookie;
+ QTest::newRow("expiration-invalid-04") << "a=b;expires=foobar, dd-mmm-yyyy hh:mm:ss GMT; path=/" << list;
+ QTest::newRow("expiration-invalid-05") << "a=b;expires=foobar, 32-Caz-1999 24:01:60 GMT; path=/" << list;
// cookies obtained from the network:
QNetworkCookie cookie;
@@ -697,7 +710,6 @@ void tst_QNetworkCookie::parseMultipleCookies_data()
cookie.setDomain("!@#$%^&*();:."); // the ';' is actually problematic, because it is a separator
list = QList<QNetworkCookie>();
QTest::newRow("domain-non-alpha-numeric") << "NonAlphNumDomName=NonAlphNumDomValue; domain=!@#$%^&*()" << list;
- QTest::newRow("expiration-3digit1") << "a=b; expires=123" << list; // used to ASSERT
}
void tst_QNetworkCookie::parseMultipleCookies()