Skip to content

Commit 91f4b2b

Browse files
committed
Cookie Store API: add branch for empty string path
https://bugs.webkit.org/show_bug.cgi?id=297268 Reviewed by NOBODY (OOPS!). Implement whatwg/cookiestore#283 with tests upstreamed at web-platform-tests/wpt#54264
1 parent 85e4462 commit 91f4b2b

File tree

9 files changed

+78
-39
lines changed

9 files changed

+78
-39
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
PASS CookieListItem - cookieStore.set with empty string path defaults to current URL
3+
PASS CookieListItem - cookieStore.set with empty string path defaults to current URL with __host- prefix
4+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!-- This file is required for WebKit test infrastructure to run the templated test -->
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// META: title=Cookie Store API: set()'s path option
2+
// META: script=/resources/testdriver.js
3+
// META: script=/resources/testdriver-vendor.js
4+
5+
promise_test(async testCase => {
6+
const currentUrl = new URL(self.location.href);
7+
const currentPath = currentUrl.pathname;
8+
const currentDirectory = currentPath.substr(0, currentPath.lastIndexOf('/'));
9+
10+
await cookieStore.set({ name: 'cookie-name', value: 'cookie-value', path: '' });
11+
testCase.add_cleanup(async () => {
12+
await cookieStore.delete({ name: 'cookie-name', path: currentDirectory });
13+
});
14+
15+
const internalCookie = await test_driver.get_named_cookie('cookie-name');
16+
assert_equals(internalCookie.path, currentDirectory);
17+
}, 'CookieListItem - cookieStore.set with empty string path defaults to current URL');
18+
19+
promise_test(async testCase => {
20+
const currentUrl = new URL(self.location.href);
21+
const currentPath = currentUrl.pathname;
22+
return promise_rejects_js(testCase, TypeError, cookieStore.set({ name: '__host-cookie-name', value: 'cookie-value', path: '' }));
23+
}, 'CookieListItem - cookieStore.set with empty string path defaults to current URL with __host- prefix');

LayoutTests/imported/w3c/web-platform-tests/cookiestore/w3c-import.log

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ List of files:
5353
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_set_domain_parsing.sub.https.html
5454
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_set_domain_parsing.tentative.sub.https.html
5555
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_set_limit.https.any.js
56+
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_set_path.https.window.js
5657
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_special_names.https.any.js
5758
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_subscribe_arguments.https.any.js
5859
/LayoutTests/imported/w3c/web-platform-tests/cookiestore/cookieStore_subscriptions_empty.https.window.js

Source/WebCore/Modules/cookie-store/CookieStore.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -464,18 +464,13 @@ void CookieStore::set(CookieInit&& options, Ref<DeferredPromise>&& promise)
464464
return;
465465
}
466466

467-
if (cookie.name.startsWithIgnoringASCIICase("__Host-"_s)) {
468-
if (!options.domain.isNull()) {
469-
promise->reject(Exception { ExceptionCode::TypeError, "If the cookie name begins with \"__Host-\", the domain must not be specified."_s });
470-
return;
471-
}
472-
473-
if (!options.path.isNull() && options.path != "/"_s) {
474-
promise->reject(Exception { ExceptionCode::TypeError, "If the cookie name begins with \"__Host-\", the path must either not be specified or be \"/\"."_s });
475-
return;
476-
}
467+
// FIXME: This should be further down.
468+
if (!options.domain.isNull() && cookie.name.startsWithIgnoringASCIICase("__Host-"_s)) {
469+
promise->reject(Exception { ExceptionCode::TypeError, "If the cookie name begins with \"__Host-\", the domain must not be specified."_s });
470+
return;
477471
}
478472

473+
// FIXME: The specification does not perform this initialization of domain.
479474
cookie.domain = options.domain.isNull() ? domain : options.domain;
480475
if (!cookie.domain.isNull()) {
481476
if (cookie.domain.startsWith('.')) {
@@ -507,17 +502,24 @@ void CookieStore::set(CookieInit&& options, Ref<DeferredPromise>&& promise)
507502
}
508503

509504
cookie.path = WTFMove(options.path);
510-
if (!cookie.path.isNull()) {
511-
if (!cookie.path.startsWith('/')) {
512-
promise->reject(Exception { ExceptionCode::TypeError, "The path must begin with a '/'"_s });
513-
return;
514-
}
505+
ASSERT(!cookie.path.isNull());
506+
if (cookie.path.isEmpty())
507+
cookie.path = CookieUtil::defaultPathForURL(url);
515508

516-
// FIXME: <rdar://85515842> Obtain the encoded length without allocating and encoding.
517-
if (cookie.path.utf8().length() > maximumAttributeValueSize) {
518-
promise->reject(Exception { ExceptionCode::TypeError, makeString("The size of the path must not be greater than "_s, maximumAttributeValueSize, " bytes"_s) });
519-
return;
520-
}
509+
if (!cookie.path.startsWith('/')) {
510+
promise->reject(Exception { ExceptionCode::TypeError, "The path must begin with a '/'"_s });
511+
return;
512+
}
513+
514+
if (cookie.path != "/"_s && cookie.name.startsWithIgnoringASCIICase("__Host-"_s)) {
515+
promise->reject(Exception { ExceptionCode::TypeError, "If the cookie name begins with \"__Host-\", the path must be \"/\" or default to that."_s });
516+
return;
517+
}
518+
519+
// FIXME: <rdar://85515842> Obtain the encoded length without allocating and encoding.
520+
if (cookie.path.utf8().length() > maximumAttributeValueSize) {
521+
promise->reject(Exception { ExceptionCode::TypeError, makeString("The size of the path must not be greater than "_s, maximumAttributeValueSize, " bytes"_s) });
522+
return;
521523
}
522524

523525
if (options.expires) {

Source/WebCore/platform/Cookie.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,13 @@ struct CookieHash {
137137
static const bool safeToCompareToEmptyOrDeleted = false;
138138
};
139139

140-
}
140+
namespace CookieUtil {
141+
142+
WEBCORE_EXPORT String defaultPathForURL(const URL&);
143+
144+
} // namespace CookieUtil
145+
146+
} // namespace WebCore
141147

142148
namespace WTF {
143149
template<typename T> struct DefaultHash;

Source/WebCore/platform/network/Cookie.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ unsigned Cookie::hash() const
4242
return StringHash::hash(name) + StringHash::hash(domain) + StringHash::hash(path) + secure;
4343
}
4444
#endif
45-
45+
46+
namespace CookieUtil {
47+
48+
String defaultPathForURL(const URL& url)
49+
{
50+
// Algorithm to generate the default path is outlined in https://tools.ietf.org/html/rfc6265#section-5.1.4
51+
52+
String path = url.path().toString();
53+
if (path.isEmpty() || !path.startsWith('/'))
54+
return "/"_s;
55+
56+
auto lastSlashPosition = path.reverseFind('/');
57+
if (!lastSlashPosition)
58+
return "/"_s;
59+
60+
return path.left(lastSlashPosition);
61+
}
62+
63+
} // namespace CookieUtil
64+
4665
} // namespace WebCore
4766

Source/WebCore/platform/network/curl/CookieUtil.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,21 +183,6 @@ std::optional<Cookie> parseCookieHeader(const String& cookieLine)
183183
return cookie;
184184
}
185185

186-
String defaultPathForURL(const URL& url)
187-
{
188-
// Algorithm to generate the default path is outlined in https://tools.ietf.org/html/rfc6265#section-5.1.4
189-
190-
String path = url.path().toString();
191-
if (path.isEmpty() || !path.startsWith('/'))
192-
return "/"_s;
193-
194-
auto lastSlashPosition = path.reverseFind('/');
195-
if (!lastSlashPosition)
196-
return "/"_s;
197-
198-
return path.left(lastSlashPosition);
199-
}
200-
201186
} // namespace CookieUtil
202187

203188
} // namespace WebCore

Source/WebCore/platform/network/curl/CookieUtil.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ bool isIPAddress(const String&);
4040

4141
bool domainMatch(const String& cookieDomain, const String& host);
4242

43-
WEBCORE_EXPORT String defaultPathForURL(const URL&);
44-
4543
} // namespace CookieUtil
4644

4745
} // namespace WebCore

0 commit comments

Comments
 (0)