summaryrefslogtreecommitdiff
path: root/chromium/net/cookies
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-29 10:46:47 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-02 12:02:10 +0000
commit99677208ff3b216fdfec551fbe548da5520cd6fb (patch)
tree476a4865c10320249360e859d8fdd3e01833b03a /chromium/net/cookies
parentc30a6232df03e1efbd9f3b226777b07e087a1122 (diff)
downloadqtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/cookies')
-rw-r--r--chromium/net/cookies/README.md545
-rw-r--r--chromium/net/cookies/canonical_cookie.cc95
-rw-r--r--chromium/net/cookies/canonical_cookie.h44
-rw-r--r--chromium/net/cookies/canonical_cookie_unittest.cc693
-rw-r--r--chromium/net/cookies/cookie_access_result.cc10
-rw-r--r--chromium/net/cookies/cookie_access_result.h13
-rw-r--r--chromium/net/cookies/cookie_change_dispatcher.cc10
-rw-r--r--chromium/net/cookies/cookie_change_dispatcher.h7
-rw-r--r--chromium/net/cookies/cookie_constants.h3
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.cc5
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.h4
-rw-r--r--chromium/net/cookies/cookie_inclusion_status_unittest.cc28
-rw-r--r--chromium/net/cookies/cookie_monster.cc56
-rw-r--r--chromium/net/cookies/cookie_monster.h8
-rw-r--r--chromium/net/cookies/cookie_monster_change_dispatcher.cc2
-rw-r--r--chromium/net/cookies/cookie_monster_perftest.cc25
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc131
-rw-r--r--chromium/net/cookies/cookie_store.h4
-rw-r--r--chromium/net/cookies/cookie_store_change_unittest.h18
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.cc5
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.h4
-rw-r--r--chromium/net/cookies/cookie_store_unittest.h88
-rw-r--r--chromium/net/cookies/cookie_util.cc48
-rw-r--r--chromium/net/cookies/cookie_util.h26
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc43
25 files changed, 1472 insertions, 443 deletions
diff --git a/chromium/net/cookies/README.md b/chromium/net/cookies/README.md
new file mode 100644
index 00000000000..c4baf8e8158
--- /dev/null
+++ b/chromium/net/cookies/README.md
@@ -0,0 +1,545 @@
+# Cookies
+
+*** aside
+_"In the beginning ~~the Universe was~~ cookies were created. This has
+made a lot of people very angry and has been widely regarded as a bad move."_
+
+_"Sometimes me think, what is friend? And then me say: a friend is someone to
+share last cookie with."_
+***
+
+This directory is concerned with the management of cookies, as specified by
+[RFC 6265bis](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis).
+Cookies are implemented mostly in this directory, but also elsewhere, as
+described [below](#Cookie-implementation-classes).
+
+*** promo
+* Those who wish to work with the implementation of cookies may refer to
+ [Life of a cookie](#Life-of-a-cookie) and
+ [Cookie implementation classes](#Cookie-implementation-classes).
+
+* Those who wish to make use of cookies elsewhere in Chromium may refer to
+ [Main interfaces for finding, setting, deleting, and observing cookies](#Main-interfaces-for-finding_setting_deleting_and-observing-cookies).
+***
+
+[TOC]
+
+## Life of a cookie
+
+This section describes the lifecycle of a typical/simple cookie on most
+platforms, and serves as an overview of some important classes involved in
+managing cookies.
+
+This only covers cookie accesses via
+[HTTP requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies).
+Other APIs for accessing cookies include JavaScript
+([`document.cookie`](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie)
+and [CookieStore API](https://wicg.github.io/cookie-store/)) or Chrome
+extensions
+([`chrome.cookies`](https://developer.chrome.com/extensions/cookies)).
+
+### Cookie is received and parsed
+
+*** note
+**Summary:**
+
+1. An HTTP response containing a `Set-Cookie` header is received.
+2. The `Set-Cookie` header is processed by `URLRequestHttpJob`.
+3. The header contents are parsed into a `CanonicalCookie` and passed to the
+ `CookieStore` for storage.
+***
+
+A cookie starts as a `Set-Cookie` header sent in the server's response to an
+HTTP request:
+
+<pre>
+HTTP/1.1 200 OK
+Date: ...
+Server: ...
+...
+<b>Set-Cookie: chocolate_chip=tasty; Secure; SameSite=Lax; Max-Age=3600</b>
+</pre>
+
+The response passes through the `HttpNetworkTransaction` and
+`HttpCache::Transaction` to the `URLRequestHttpJob`. (See
+[Life of a `URLRequest`](/net/docs/life-of-a-url-request.md#send-request-and-read-the-response-headers)
+for more details.) The `URLRequestHttpJob` then reads any `Set-Cookie` headers
+in the response (there may be multiple) and processes each `Set-Cookie` header
+by calling into `//net/cookies` classes for parsing and storing:
+
+First, the cookie, which has been provided as a string, is parsed into a
+`ParsedCookie`. This struct simply records all the token-value pairs present in
+the `Set-Cookie` header and keeps track of which cookie attribute each
+corresponds to. The first token-value pair is always treated as the cookie's
+name and value.
+
+The `ParsedCookie` is then converted into a `CanonicalCookie`. This is the main
+data type representing cookies. Any cookie consumer that does not deal directly
+with HTTP headers operates on `CanonicalCookie`s. A `CanonicalCookie` has some
+additional guarantees of validity over a `ParsedCookie`, such as sane expiration
+times, valid domain and path attributes, etc. Once a `CanonicalCookie` is
+created, you will almost never see a `ParsedCookie` used for anything else.
+
+If a valid `CanonicalCookie` could not be created (due to some illegal syntax,
+inconsistent attribute values, or other circumstances preventing parsing), then
+we stop here, and `URLRequestHttpJob` moves on to the next `Set-Cookie` header.
+
+The `NetworkDelegate` also gets a chance to block the setting of the cookie,
+based on the user's third-party cookie blocking settings. If it is blocked,
+`URLRequestHttpJob` likewise moves on to the next `Set-Cookie` header.
+
+If this did result in a valid and not-blocked `CanonicalCookie`, it is then
+passed to the `CookieStore` to be stored.
+
+### Cookie is stored
+
+*** note
+**Summary:**
+
+1. The `CookieStore` receives the `CanonicalCookie` and validates some
+ additional criteria before updating its in-memory cache of cookies.
+2. The `CookieStore` may also update its on-disk backing store via the
+ `CookieMonster::PersistentCookieStore` interface.
+3. The result of the cookie storage attempt is reported back to the
+ `URLRequestHttpJob`.
+***
+
+The `CookieStore` lives in the `URLRequestContext` and its main implementation,
+used for most platforms, is `CookieMonster`. (The rest of this section assumes
+that we are using a `CookieMonster`.) It exposes an asynchronous interface for
+storing and retrieving cookies.
+
+When `CookieMonster` receives a `CanonicalCookie` to be set, it queues a task to
+validate and set the cookie. Most of the time this runs immediately, but it may
+be delayed if the network service has just started up, and the contents of the
+`PersistentCookieStore` are still being loaded from disk. It checks some
+criteria against the cookie's source URL and a `CookieOptions` object (which
+contains some other parameters describing the "context" in which the cookie is
+being set, such as whether it's being accessed in a same-site or cross-site
+context).
+
+If everything checks out, the `CookieMonster` proceeds with setting the cookie.
+If an equivalent cookie is present in the store, then it may be deleted.
+Equivalent is defined as sharing a name, domain, and path, based on the
+invariant specified by the RFC that no two such cookies may exist at a given
+time. `CookieMonster` stores its `CanonicalCookie`s in a multimap keyed on the
+registrable domain (eTLD+1) of the cookie's domain attribute.
+
+The cookie may also be persisted to disk by a
+`CookieMonster::PersistentCookieStore` depending on factors like whether the
+cookie is a persistent cookie (has an expiration date), whether session cookies
+should also be persisted (e.g. if the browser is set to restore the previous
+browsing session), and whether the profile should have persistent storage (e.g.
+yes for normal profiles, but not for Incognito profiles). The
+`SQLitePersistentCookieStore` is the main implementation of
+`CookieMonster::PersistentCookieStore`. It stores cookies in a SQLite database
+on disk, at a filepath specified by the user's profile.
+
+After the cookie has been stored (or rejected), the `CookieMonster` calls back
+to the `URLRequestHttpJob` with the outcome of the storage attempt. The
+`URLRequestHttpJob` stashes away the outcomes and stores them in the
+`URLRequest` after all `Set-Cookie` headers in the response are processed, so
+that interested parties (e.g. DevTools) can subsequently be notified of cookie
+activity.
+
+### Cookie is retrieved and sent
+
+*** note
+**Summary:**
+
+1. A network request reaches the net stack and generates a `URLRequestHttpJob`,
+ which queries the `CookieStore` for cookies to include with the request.
+2. The `CookieStore` evaluates each of its candidate cookies for whether it can
+ be included in the request, and reports back to the `URLRequestHttpJob` with
+ included and excluded cookies.
+3. `URLRequestHttpJob` serializes the included cookies into a `Cookie` request
+ header and attaches it to the outgoing request.
+***
+
+Some time later, a (credentialed) request to the same eTLD+1 triggers a cookie
+access in order to retrieve the relevant cookies to include in the outgoing
+`Cookie` request header. The request makes its way to the net stack and causes a
+`URLRequestHttpJob` to be created. (See
+[Life of a `URLRequest`](/net/docs/life-of-a-url-request.md#check-the-cache_request-an-httpstream)
+for more details.) Upon being started, the `URLRequestHttpJob` asks the
+`CookieStore` to retrieve the correct cookies for the URL being requested.
+
+The `CookieMonster` queues a task to retrieve the cookies. Most of the time this
+runs immediately, except if the contents of the `PersistentCookieStore` are
+still being loaded from disk. The `CookieMonster` examines each of the cookies
+it has stored for that URL's registrable domain and decides whether it should be
+included or excluded for that request based on the requested URL and the
+`CookieOptions`, by computing a `CookieInclusionStatus`. Criteria for inclusion
+are described in
+[RFC 6265bis](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis#section-5.5)
+and include: the URL matching the cookie's `Domain` and `Path` attributes, the
+URL being secure if the cookie has the `Secure` attribute, the request context
+(i.e. `CookieOptions`) being same-site if the cookie is subject to `SameSite`
+enforcement, etc. If any of the requirements are not met, a
+`CookieInclusionStatus::ExclusionReason` is recorded.
+
+After the exclusion reasons have been tallied up for each cookie, the cookies
+without any exclusion reasons are deemed suitable for inclusion, and are
+returned to the `URLRequestHttpJob`. The excluded cookies are also returned,
+along with the `CookieInclusionStatus` describing why each cookie was excluded.
+
+The included cookies are serialized into a `Cookie` header string (if the
+`NetworkDelegate` is ok with it, based on the user's third-party cookie blocking
+settings). The `URLRequestHttpJob` attaches this `Cookie` header to the outgoing
+request headers:
+
+<pre>
+GET /me/want/cookie/omnomnomnom HTTP/1.1
+Host: ...
+User-Agent: ...
+<b>Cookie: chocolate_chip=tasty</b>
+...
+</pre>
+
+The included cookies, excluded cookies, and their corresponding
+`CookieInclusionStatus`es are also stored in the `URLRequest` to notify
+consumers of cookie activity notifications.
+
+## Cookie implementation classes
+
+This section lists classes involved in cookie management and access.
+
+The core classes are highlighted.
+
+### In this directory (//net/cookies)
+
+*** note
+* **[`CanonicalCookie`](/net/cookies/canonical_cookie.h)**
+
+ The main data type representing cookies. Basically everything that's not
+ directly dealing with HTTP headers or their equivalents operates on these.
+
+ These are generally obtained via `CanonicalCookie::Create()`, which parses a
+ string (a `Set-Cookie` header) into an intermediate `ParsedCookie`, whose
+ fields it canonicalizes/validates and then copies into a `CanonicalCookie`.
+***
+
+*** note
+* **[`CookieStore`](/net/cookies/cookie_store.h)**
+
+ The main interface for a given platform's cookie handling. Provides
+ asynchronous methods for setting and retrieving cookies.
+
+ Its implementations are responsible for keeping track of all the cookies,
+ finding cookies relevant for given HTTP requests, saving cookies received in
+ HTTP responses, etc., and need to know quite a bit about cookie semantics.
+***
+
+*** note
+* **[`CookieMonster`](/net/cookies/cookie_monster.h)**
+
+ The implementation of `CookieStore` used on most platforms.
+
+ It stores all cookies in a multimap keyed on the eTLD+1 of the cookie's
+ domain. Also manages storage limits by evicting cookies when per-eTLD+1 or
+ global cookie counts are exceeded.
+
+ It can optionally take an implementation of
+ `CookieMonster::PersistentCookieStore` to load and store cookies
+ persisently.
+***
+
+* [`CookieOptions`](/net/cookies/cookie_options.h)
+
+ Contains parameters for a given attempt to access cookies via
+ `CookieStore`, such as whether the access is for an HTTP request (as opposed
+ to a JavaScript API), and the same-site or cross-site context of the request
+ (relevant to enforcement of the `SameSite` cookie attribute).
+
+* [`SiteForCookies`](/net/cookies/site_for_cookies.h)
+
+ Represents which origins should be considered "same-site" for a given
+ context (e.g. frame). This is used to compute the same-site or cross-site
+ context of a cookie access attempt (which is then conveyed to the
+ `CookieStore` via a `CookieOptions`).
+
+ It is generally the eTLD+1 and scheme of the top-level frame. It may also be
+ empty, in which case it represents a context that is cross-site to
+ everything (e.g. a nested iframe whose ancestor frames don't all belong to
+ the same site).
+
+* [`CookieInclusionStatus`](/net/cookies/cookie_inclusion_status.h)
+
+ Records the outcome of a given attempt to access a cookie. Various reasons
+ for cookie exclusion are recorded
+ (`CookieInclusionStatus::ExclusionReason`), as well as informational
+ statuses (`CookieInclusionStatus::WarningReason`) typically used to emit
+ warnings in DevTools.
+
+ May be used as a member of a `CookieAccessResult`, which includes even more
+ metadata about the outcome of a cookie access attempt.
+
+* [`CookieAccessDelegate`](/net/cookies/cookie_access_delegate.h)
+
+ Interface for a `CookieStore` to query information from its embedder that
+ may modify its decisions on cookie inclusion/exclusion. Its main
+ implementation allows `CookieMonster` to access data from the network
+ service layer (e.g. `CookieManager`).
+
+* [`CookieChangeDispatcher`](/net/cookies/cookie_monster_change_dispatcher.h)
+
+ Interface for subscribing to changes in the contents of the `CookieStore`.
+ The main implementation is `CookieMonsterChangeDispatcher`.
+
+### Elsewhere in //net
+
+*** note
+* **[`SQLitePersistentCookieStore`](/net/extras/sqlite/sqlite_persistent_cookie_store.h)**
+
+ Implementation of `CookieMonster::PersistentCookieStore` used on most
+ platforms. Uses a SQLite database to load and store cookies, potentially
+ using an optional delegate to encrypt and decrypt their at-rest versions.
+ This class is refcounted.
+
+ `CookieMonster` loads cookies from here on startup. All other operations
+ attempting to access cookies in the process of being loaded are blocked
+ until loading of those cookies completes. Thus, it fast-tracks loading of
+ cookies for an eTLD+1 with pending requests, to decrease latency for
+ cookie access operations made soon after browser startup (by decreasing the
+ number of cookies whose loading is blocking requests).
+***
+
+*** note
+* **[`URLRequestHttpJob`](/net/url_request/url_request_http_job.h)**
+
+ A `URLRequestJob` implementation that handles HTTP requests; most
+ relevantly, the `Cookie` and `Set-Cookie` HTTP headers. It drives the
+ process for storing cookies and retrieving cookies for HTTP requests.
+
+ Also logs cookie events to the NetLog for each request.
+***
+
+* [`URLRequest`](/net/url_request/url_request.h)
+
+ Mostly relevant for its two members, `maybe_sent_cookies_` and
+ `maybe_stored_cookies_`, which are vectors in which `URLRequestHttpJob`
+ stashes the cookies it considered sending/storing and their
+ `CookieInclusionStatus`es. These then get mojo'ed over to the browser
+ process to notify observers of cookie activity.
+
+### In //services/network
+
+*** note
+* **[`CookieManager`](/services/network/cookie_manager.h)**
+
+ The network service API to cookies. Basically exports a `CookieStore` via
+ mojo IPC.
+
+ Owned by the `NetworkContext`.
+***
+
+*** note
+* **[`RestrictedCookieManager`](/services/network/restricted_cookie_manager.h)**
+
+ Mojo interface for accessing cookies for a specific origin. This can be
+ handed out to untrusted (i.e. renderer) processes, as inputs are assumed to
+ be unsafe.
+
+ It is primarily used for accessing cookies via JavaScript.
+ It provides a synchronous interface for
+ [`document.cookie`](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie),
+ as well as an asynchronous one for the [CookieStore API](https://wicg.github.io/cookie-store/).
+***
+
+* [`CookieSettings`](/services/network/cookie_settings.h)
+
+ Keeps track of the content settings (per-profile
+ [permissions](/components/permissions/README.md) for types of
+ content that a given origin is allowed to use) for cookies, such as the
+ user's third-party cookie blocking settings, origins/domains with
+ third-party cookie blocking exceptions or "legacy" access settings.
+
+ It is not to be confused with `content_settings::CookieSettings`, which
+ manages the browser's version of the cookie content settings, of which
+ `network::ContentSettings` is approximately a copy/mirror. The
+ `ProfileNetworkContextService` populates its contents upon `NetworkContext`
+ construction from the browser-side content settings, and also updates it
+ whenever the browser-side content settings change.
+
+* [`SessionCleanupCookieStore`](/services/network/session_cleanup_cookie_store.h)
+
+ Implements `CookieMonster::PersistentCookieStore`, by wrapping a
+ `SQLitePersistentCookieStore`. Keeps an in-memory map of cookies per eTLD+1
+ to allow deletion of cookies for sites whose cookie content setting is
+ "session-only" from the persistent store when the session ends.
+
+
+### Elsewhere
+
+* [`CookieAccessObserver`](/services/network/public/mojom/cookie_access_observer.mojom)
+ and [`WebContentsObserver`](/content/public/browser/web_contents_observer.h)
+
+ `CookieAccessObserver` is a mojo interface used to observe attempts to
+ access (read or write) cookies. It is implemented by `NavigationHandle` and
+ `RenderFrameHost`.
+
+ The cookie accesses are attributable to a committed document that called
+ `document.cookie` or made a network request (if notified through
+ `RenderFrameHost`), or a not-yet-committed navigation that resulted in a
+ network request (if notified through `NavigationHandle`).
+
+ The `CookieAccessObserver`s forward the notifications to `WebContents`,
+ which then notifies its `WebContentsObserver`s. One such
+ `WebContentsObserver` that cares about this information is
+ `PageSpecificContentSettings`, which displays information about allowed and
+ blocked cookies in UI surfaces (see next item).
+
+* [`CookiesTreeModel`](/chrome/browser/browsing_data/cookies_tree_model.h)
+
+ Stores cookie information for use in settings UI (the Page Info Bubble and
+ various `chrome://settings` pages). Populated with info from
+ `PageSpecificContentSettings`.
+
+* [`CookieJar`](/third_party/blink/renderer/core/loader/cookie_jar.h)
+
+ Implements the `document.cookie` API in the renderer by requesting a
+ `RestrictedCookieManager` from the browser.
+
+* [`CookieStore`](/third_party/blink/renderer/modules/cookie_store/cookie_store.h)
+
+ Implements the JavaScript
+ [CookieStore API](https://wicg.github.io/cookie-store/) in the renderer by
+ requesting a `RestrictedCookieManager` from the browser. (Not to be confused
+ with `net::CookieStore`.)
+
+* [`CookiesAPI`](/chrome/browser/extensions/api/cookies/cookies_api.h)
+
+ Implements the
+ [`chrome.cookies`](https://developer.chrome.com/extensions/cookies) API for
+ Chrome extensions. Gives extensions with the proper permissions essentially
+ unfettered access to the `CookieStore`.
+
+### Platform-specific
+
+* [`CookieStoreIOS` and `CookieStoreIOSPersistent`](/ios/net/cookies)
+
+ iOS-specific `CookieStore` implementations, mainly relying on the iOS native
+ cookie implementation (`NSHTTPCookie`).
+
+* [`android_webview::CookieManager`](/android_webview/browser/cookie_manager.h)
+
+ Manages cookies for Android WebView. It typically wraps a
+ `network::mojom::CookieManager`, but it can also be used before a
+ `NetworkContext` even exists, thanks to Android WebView's
+ [cookie API](https://developer.android.com/reference/kotlin/android/webkit/CookieManager),
+ which means it is sometimes initialized with a bare `net::CookieStore`.
+
+ Also notable for allowing cookies for `file://` scheme URLs (normally they
+ are only allowed for HTTP and websocket schemes and `chrome-extension://`),
+ though this is non-default and deprecated.
+
+## Main interfaces for finding, setting, deleting, and observing cookies
+
+This section summarizes interfaces for interacting with cookies from various
+parts of the codebase.
+
+### From //net or //services/network
+
+*** note
+Use [`net::CookieStore`](/net/cookies/cookie_store.h) to save and retrieve
+[`CanonicalCookie`](/net/cookies/canonical_cookie.h)s.
+***
+
+* `CanonicalCookie`s are the main data type representing cookies. Get one using
+ `CanonicalCookie::Create()`.
+
+* The `CookieStore` can be accessed via its owning `URLRequestContext`, which
+ can be accessed through `NetworkContext`.
+
+* To access cookies, you need a `CookieOptions`. The main things in this object
+ are the `HttpOnly` access permission and the `SameSite` context. The latter
+ can be obtained from [`cookie_util`](/net/cookies/cookie_util.h) functions.
+
+* Retrieve cookies using `GetCookieListWithOptionsAsync()`.
+
+* Save cookies using `SetCanonicalCookieAsync()`.
+
+*** note
+Use `CookieStore` to selectively delete cookies.
+***
+
+* `DeleteCanonicalCookieAsync()` deletes a single cookie.
+
+* `DeleteAllCreatedInTimeRangeAsync()` deletes cookies created in a time range.
+
+* `DeleteAllMatchingInfoAsync()` deletes cookies that match a filter.
+
+*** note
+Use the [`CookieChangeDispatcher`](/net/cookies/cookie_change_dispatcher.h)
+interface to subscribe to changes.
+***
+
+* Use `AddCallbackForCookie()` to observe changes to cookies with a given name
+ that would be sent with a request to a specific URL.
+
+* Use `AddCallbackForUrl()` to observe changes to all cookies that would be sent
+ with a request to a specific URL.
+
+* Use `AddCallbackForAllChanges()` to observe changes to all cookies in the
+ `CookieStore`.
+
+### From the browser process
+
+*** note
+Use [`CookieManager`](/services/network/cookie_manager.h)
+(which basically exports a `net::CookieStore` interface via mojo) to save
+and retrieve [`CanonicalCookie`](/net/cookies/canonical_cookie.h)s.
+***
+
+* The profile's `CookieManager` can be accessed from the browser process through
+ `StoragePartition::GetCookieManagerForBrowserProcess()`.
+
+* You can also get get a `CookieManager` pipe from the `NetworkContext` using
+ `GetCookieManager()`.
+
+* Retrieve cookies using `CookieManager::GetCookieList()`.
+
+* Save cookies using `CookieManager::SetCanonicalCookie()`.
+
+*** note
+Use `CookieManager` to selectively delete cookies.
+***
+
+* If you have a copy of the `CanonicalCookie` to delete (e.g. a cookie
+ previously fetched from the store), use
+ `CookieManager::DeleteCanonicalCookie()`.
+
+* To delete cookies with certain characteristics, construct a
+ [`CookieDeletionFilter`](/services/network/public/mojom/cookie_manager.mojom)
+ and use `CookieManager::DeleteCookies()`.
+
+*** note
+Use `CookieManager`'s change listener interface to subscribe to changes (this
+parallels the `net::CookieChangeDispatcher` interface).
+***
+
+* Add a `CookieChangeListener` registration for a URL (and optionally a cookie
+ name) via `AddCookieChangeListener()`
+
+* Add a `CookieChangeListener` registration for all cookies via
+ `AddGlobalChangeListener()`.
+
+### From untrusted (e.g. renderer) processes
+
+*** note
+Use a
+[`network::mojom::RestrictedCookieManager`](/services/network/public/mojom/restricted_cookie_manager.mojom)
+interface to access cookies for a particular origin.
+***
+
+* Request a `RestrictedCookieManager` interface from the browser. This creates a
+ `RestrictedCookieManager` bound to a `RenderFrameHost`, which can only access
+ cookies on behalf of the corresponding origin.
+
+* Cookies can be read and written asynchronously (`GetAllForUrl()`,
+ `SetCanonicalCookie()`) or synchronously (`SetCookieFromString()`,
+ `GetCookiesString()`).
+
+* [Compromised renderers](/docs/security/compromised-renderers.md#Cookies)
+ shouldn't be able to access cookies of another site, or `HttpOnly` cookies
+ (even from the same site).
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index 68fa41779bb..1c85b9d7daf 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -589,9 +589,18 @@ CookieAccessResult CanonicalCookie::IncludeForRequestURL(
// match the cookie-path.
if (!IsOnPath(url.path()))
status.AddExclusionReason(CookieInclusionStatus::EXCLUDE_NOT_ON_PATH);
+
+ // For LEGACY cookies we should always return the schemeless context,
+ // otherwise let GetContextForCookieInclusion() decide.
+ CookieOptions::SameSiteCookieContext::ContextType cookie_inclusion_context =
+ access_semantics == CookieAccessSemantics::LEGACY
+ ? options.same_site_cookie_context().context()
+ : options.same_site_cookie_context().GetContextForCookieInclusion();
+
// Don't include same-site cookies for cross-site requests.
CookieEffectiveSameSite effective_same_site =
GetEffectiveSameSite(access_semantics);
+ DCHECK(effective_same_site != CookieEffectiveSameSite::UNDEFINED);
// Log the effective SameSite mode that is applied to the cookie on this
// request, if its SameSite was not specified.
if (SameSite() == CookieSameSite::UNSPECIFIED) {
@@ -600,20 +609,19 @@ CookieAccessResult CanonicalCookie::IncludeForRequestURL(
CookieEffectiveSameSite::COUNT);
}
UMA_HISTOGRAM_ENUMERATION(
- "Cookie.RequestSameSiteContext",
- options.same_site_cookie_context().GetContextForCookieInclusion(),
+ "Cookie.RequestSameSiteContext", cookie_inclusion_context,
CookieOptions::SameSiteCookieContext::ContextType::COUNT);
switch (effective_same_site) {
case CookieEffectiveSameSite::STRICT_MODE:
- if (options.same_site_cookie_context().GetContextForCookieInclusion() <
+ if (cookie_inclusion_context <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT) {
status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT);
}
break;
case CookieEffectiveSameSite::LAX_MODE:
- if (options.same_site_cookie_context().GetContextForCookieInclusion() <
+ if (cookie_inclusion_context <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
status.AddExclusionReason(
(SameSite() == CookieSameSite::UNSPECIFIED)
@@ -625,7 +633,7 @@ CookieAccessResult CanonicalCookie::IncludeForRequestURL(
// TODO(crbug.com/990439): Add a browsertest for this behavior.
case CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE:
DCHECK(SameSite() == CookieSameSite::UNSPECIFIED);
- if (options.same_site_cookie_context().GetContextForCookieInclusion() <
+ if (cookie_inclusion_context <
CookieOptions::SameSiteCookieContext::ContextType::
SAME_SITE_LAX_METHOD_UNSAFE) {
// TODO(chlily): Do we need a separate CookieInclusionStatus for this?
@@ -668,25 +676,27 @@ CookieAccessResult CanonicalCookie::IncludeForRequestURL(
}
// TODO(chlily): Log metrics.
- return CookieAccessResult(effective_same_site, status);
+ return CookieAccessResult(effective_same_site, status, access_semantics);
}
-CookieInclusionStatus CanonicalCookie::IsSetPermittedInContext(
+CookieAccessResult CanonicalCookie::IsSetPermittedInContext(
const CookieOptions& options,
CookieAccessSemantics access_semantics) const {
- CookieInclusionStatus status;
- IsSetPermittedInContext(options, access_semantics, &status);
- return status;
+ CookieAccessResult access_result;
+ IsSetPermittedInContext(options, access_semantics, &access_result);
+ return access_result;
}
void CanonicalCookie::IsSetPermittedInContext(
const CookieOptions& options,
CookieAccessSemantics access_semantics,
- CookieInclusionStatus* status) const {
+ CookieAccessResult* access_result) const {
+ access_result->access_semantics = access_semantics;
if (options.exclude_httponly() && IsHttpOnly()) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "HttpOnly cookie not permitted in script context.";
- status->AddExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY);
+ access_result->status.AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_HTTP_ONLY);
}
// If both SameSiteByDefaultCookies and CookiesWithoutSameSiteMustBeSecure
@@ -697,7 +707,7 @@ void CanonicalCookie::IsSetPermittedInContext(
SameSite() == CookieSameSite::NO_RESTRICTION && !IsSecure()) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() rejecting insecure cookie with SameSite=None.";
- status->AddExclusionReason(
+ access_result->status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE);
}
// Log whether a SameSite=None cookie is Secure or not.
@@ -705,37 +715,45 @@ void CanonicalCookie::IsSetPermittedInContext(
UMA_HISTOGRAM_BOOLEAN("Cookie.SameSiteNoneIsSecure", IsSecure());
}
- CookieEffectiveSameSite effective_same_site =
- GetEffectiveSameSite(access_semantics);
- switch (effective_same_site) {
+ // For LEGACY cookies we should always return the schemeless context,
+ // otherwise let GetContextForCookieInclusion() decide.
+ CookieOptions::SameSiteCookieContext::ContextType cookie_inclusion_context =
+ access_semantics == CookieAccessSemantics::LEGACY
+ ? options.same_site_cookie_context().context()
+ : options.same_site_cookie_context().GetContextForCookieInclusion();
+
+ access_result->effective_same_site = GetEffectiveSameSite(access_semantics);
+ DCHECK(access_result->effective_same_site !=
+ CookieEffectiveSameSite::UNDEFINED);
+ switch (access_result->effective_same_site) {
case CookieEffectiveSameSite::STRICT_MODE:
// This intentionally checks for `< SAME_SITE_LAX`, as we allow
// `SameSite=Strict` cookies to be set for top-level navigations that
// qualify for receipt of `SameSite=Lax` cookies.
- if (options.same_site_cookie_context().GetContextForCookieInclusion() <
+ if (cookie_inclusion_context <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "Trying to set a `SameSite=Strict` cookie from a "
"cross-site URL.";
- status->AddExclusionReason(
+ access_result->status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT);
}
break;
case CookieEffectiveSameSite::LAX_MODE:
case CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE:
- if (options.same_site_cookie_context().GetContextForCookieInclusion() <
+ if (cookie_inclusion_context <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
if (SameSite() == CookieSameSite::UNSPECIFIED) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "Cookies with no known SameSite attribute being treated as "
"lax; attempt to set from a cross-site URL denied.";
- status->AddExclusionReason(
+ access_result->status.AddExclusionReason(
CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
} else {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "Trying to set a `SameSite=Lax` cookie from a cross-site URL.";
- status->AddExclusionReason(
+ access_result->status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_LAX);
}
}
@@ -744,14 +762,14 @@ void CanonicalCookie::IsSetPermittedInContext(
break;
}
- ApplySameSiteCookieWarningToStatus(SameSite(), effective_same_site,
- IsSecure(),
- options.same_site_cookie_context(), status,
- true /* is_cookie_being_set */);
+ ApplySameSiteCookieWarningToStatus(
+ SameSite(), access_result->effective_same_site, IsSecure(),
+ options.same_site_cookie_context(), &access_result->status,
+ true /* is_cookie_being_set */);
- if (status->IsInclude()) {
+ if (access_result->status.IsInclude()) {
UMA_HISTOGRAM_ENUMERATION("Cookie.IncludedResponseEffectiveSameSite",
- effective_same_site,
+ access_result->effective_same_site,
CookieEffectiveSameSite::COUNT);
}
@@ -941,25 +959,26 @@ bool CanonicalCookie::IsRecentlyCreated(base::TimeDelta age_threshold) const {
return (base::Time::Now() - creation_date_) <= age_threshold;
}
-CookieAndLineWithStatus::CookieAndLineWithStatus() = default;
+CookieAndLineWithAccessResult::CookieAndLineWithAccessResult() = default;
-CookieAndLineWithStatus::CookieAndLineWithStatus(
+CookieAndLineWithAccessResult::CookieAndLineWithAccessResult(
base::Optional<CanonicalCookie> cookie,
std::string cookie_string,
- CookieInclusionStatus status)
+ CookieAccessResult access_result)
: cookie(std::move(cookie)),
cookie_string(std::move(cookie_string)),
- status(status) {}
-
-CookieAndLineWithStatus::CookieAndLineWithStatus(
- const CookieAndLineWithStatus&) = default;
+ access_result(access_result) {}
-CookieAndLineWithStatus& CookieAndLineWithStatus::operator=(
- const CookieAndLineWithStatus& cookie_and_line_with_status) = default;
+CookieAndLineWithAccessResult::CookieAndLineWithAccessResult(
+ const CookieAndLineWithAccessResult&) = default;
-CookieAndLineWithStatus::CookieAndLineWithStatus(CookieAndLineWithStatus&&) =
+CookieAndLineWithAccessResult& CookieAndLineWithAccessResult::operator=(
+ const CookieAndLineWithAccessResult& cookie_and_line_with_access_result) =
default;
-CookieAndLineWithStatus::~CookieAndLineWithStatus() = default;
+CookieAndLineWithAccessResult::CookieAndLineWithAccessResult(
+ CookieAndLineWithAccessResult&&) = default;
+
+CookieAndLineWithAccessResult::~CookieAndLineWithAccessResult() = default;
} // namespace net
diff --git a/chromium/net/cookies/canonical_cookie.h b/chromium/net/cookies/canonical_cookie.h
index aa538085ac8..4cb63368be1 100644
--- a/chromium/net/cookies/canonical_cookie.h
+++ b/chromium/net/cookies/canonical_cookie.h
@@ -26,13 +26,12 @@ namespace net {
class ParsedCookie;
class CanonicalCookie;
-struct CookieWithStatus;
struct CookieWithAccessResult;
-struct CookieAndLineWithStatus;
+struct CookieAndLineWithAccessResult;
using CookieList = std::vector<CanonicalCookie>;
-using CookieStatusList = std::vector<CookieWithStatus>;
-using CookieAndLineStatusList = std::vector<CookieAndLineWithStatus>;
+using CookieAndLineAccessResultList =
+ std::vector<CookieAndLineWithAccessResult>;
using CookieAccessResultList = std::vector<CookieWithAccessResult>;
class NET_EXPORT CanonicalCookie {
@@ -242,7 +241,7 @@ class NET_EXPORT CanonicalCookie {
// WARNING: this does not cover checking whether secure cookies are set in
// a secure schema, since whether the schema is secure isn't part of
// |options|.
- CookieInclusionStatus IsSetPermittedInContext(
+ CookieAccessResult IsSetPermittedInContext(
const CookieOptions& options,
CookieAccessSemantics access_semantics =
CookieAccessSemantics::UNKNOWN) const;
@@ -250,7 +249,7 @@ class NET_EXPORT CanonicalCookie {
// Overload that updates an existing |status| rather than returning a new one.
void IsSetPermittedInContext(const CookieOptions& options,
CookieAccessSemantics access_semantics,
- CookieInclusionStatus* status) const;
+ CookieAccessResult* access_result) const;
std::string DebugString() const;
@@ -362,34 +361,27 @@ class NET_EXPORT CanonicalCookie {
CookieSourceScheme source_scheme_;
};
-// These enable us to pass along a list of excluded cookie with the reason they
-// were excluded
-struct CookieWithStatus {
- CanonicalCookie cookie;
- CookieInclusionStatus status;
-};
-
// Used to pass excluded cookie information when it's possible that the
// canonical cookie object may not be available.
-struct NET_EXPORT CookieAndLineWithStatus {
- CookieAndLineWithStatus();
- CookieAndLineWithStatus(base::Optional<CanonicalCookie> cookie,
- std::string cookie_string,
- CookieInclusionStatus status);
- CookieAndLineWithStatus(
- const CookieAndLineWithStatus& cookie_and_line_with_status);
+struct NET_EXPORT CookieAndLineWithAccessResult {
+ CookieAndLineWithAccessResult();
+ CookieAndLineWithAccessResult(base::Optional<CanonicalCookie> cookie,
+ std::string cookie_string,
+ CookieAccessResult access_result);
+ CookieAndLineWithAccessResult(
+ const CookieAndLineWithAccessResult& cookie_and_line_with_access_result);
- CookieAndLineWithStatus& operator=(
- const CookieAndLineWithStatus& cookie_and_line_with_status);
+ CookieAndLineWithAccessResult& operator=(
+ const CookieAndLineWithAccessResult& cookie_and_line_with_access_result);
- CookieAndLineWithStatus(
- CookieAndLineWithStatus&& cookie_and_line_with_status);
+ CookieAndLineWithAccessResult(
+ CookieAndLineWithAccessResult&& cookie_and_line_with_access_result);
- ~CookieAndLineWithStatus();
+ ~CookieAndLineWithAccessResult();
base::Optional<CanonicalCookie> cookie;
std::string cookie_string;
- CookieInclusionStatus status;
+ CookieAccessResult access_result;
};
struct CookieWithAccessResult {
diff --git a/chromium/net/cookies/canonical_cookie_unittest.cc b/chromium/net/cookies/canonical_cookie_unittest.cc
index 77465c83b92..04c1b6488f5 100644
--- a/chromium/net/cookies/canonical_cookie_unittest.cc
+++ b/chromium/net/cookies/canonical_cookie_unittest.cc
@@ -758,9 +758,8 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
// Test cases that are the same regardless of feature status or access
- // semantics:
- // TODO(https://crbug.com/1030938): This test will need to consider
- // SchemefulSameSite when it is added to CanonicalCookie.
+ // semantics. For Schemeful Same-Site this means that the context downgrade is
+ // a no-op (such as for NO_RESTRICTION cookies) or that there is no downgrade:
std::vector<IncludeForRequestURLTestCase> common_test_cases = {
// Strict cookies:
{"Common=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
@@ -781,104 +780,86 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
CookieInclusionStatus()},
- // Strict cookies with downgrade:
- {"Common=5;SameSite=Strict", CookieSameSite::STRICT_MODE,
- CookieEffectiveSameSite::STRICT_MODE,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<CookieInclusionStatus::ExclusionReason>(),
- {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
- {"Common=6;SameSite=Strict", CookieSameSite::STRICT_MODE,
- CookieEffectiveSameSite::STRICT_MODE,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<CookieInclusionStatus::ExclusionReason>(),
- {CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
- {"Common=7;SameSite=Strict", CookieSameSite::STRICT_MODE,
- CookieEffectiveSameSite::STRICT_MODE,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::ContextType::CROSS_SITE),
- CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<CookieInclusionStatus::ExclusionReason>(),
- {CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
// Lax cookies:
- {"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=5;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
- {"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=6;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
- {"Common=10;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=7;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
CookieInclusionStatus()},
- {"Common=11;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
CookieInclusionStatus()},
// Lax cookies with downgrade:
- {"Common=12;SameSite=Lax", CookieSameSite::LAX_MODE,
+ {"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::SAME_SITE_LAX),
CookieInclusionStatus()},
- {"Common=13;SameSite=Lax", CookieSameSite::LAX_MODE,
- CookieEffectiveSameSite::LAX_MODE,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<CookieInclusionStatus::ExclusionReason>(),
- {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
- {"Common=14;SameSite=Lax", CookieSameSite::LAX_MODE,
- CookieEffectiveSameSite::LAX_MODE,
- SameSiteCookieContext(
- SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
- SameSiteCookieContext::ContextType::CROSS_SITE),
- CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<CookieInclusionStatus::ExclusionReason>(),
- {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
- {"Common=15;SameSite=Lax", CookieSameSite::LAX_MODE,
- CookieEffectiveSameSite::LAX_MODE,
- SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- SameSiteCookieContext::ContextType::CROSS_SITE),
- CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<CookieInclusionStatus::ExclusionReason>(),
- {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
// None and Secure cookies:
- {"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ {"Common=10;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
CookieInclusionStatus()},
- {"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ {"Common=11;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
CookieInclusionStatus()},
- {"Common=18;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ {"Common=12;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
CookieInclusionStatus()},
- {"Common=19;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ {"Common=13;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CookieInclusionStatus()}};
+ CookieInclusionStatus()},
+ // Because NO_RESTRICTION cookies are always sent, the schemeful context
+ // downgrades shouldn't matter.
+ {"Common=14;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ CookieEffectiveSameSite::NO_RESTRICTION,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ CookieInclusionStatus()},
+ {"Common=15;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ CookieEffectiveSameSite::NO_RESTRICTION,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ CookieInclusionStatus()},
+ {"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ CookieEffectiveSameSite::NO_RESTRICTION,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus()},
+ {"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ CookieEffectiveSameSite::NO_RESTRICTION,
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus()},
+ {"Common=18;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
+ CookieEffectiveSameSite::NO_RESTRICTION,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus()},
+ };
// Test cases where the default is None (either access semantics is LEGACY, or
- // semantics is UNKNOWN and feature is enabled):
+ // semantics is UNKNOWN and SameSiteByDefaultCookies feature is disabled):
std::vector<IncludeForRequestURLTestCase> default_none_test_cases = {
// Unspecified cookies (without SameSite-by-default):
{"DefaultNone=1", CookieSameSite::UNSPECIFIED,
@@ -907,7 +888,8 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
CookieInclusionStatus()}};
// Test cases where the default is Lax (either access semantics is NONLEGACY,
- // or access semantics is UNKNOWN and feature is enabled):
+ // or access semantics is UNKNOWN and SameSiteByDefaultCookies feature is
+ // enabled):
std::vector<IncludeForRequestURLTestCase> default_lax_test_cases = {
// Unspecified recently-created cookies (with SameSite-by-default):
{"DefaultLax=1", CookieSameSite::UNSPECIFIED,
@@ -961,30 +943,173 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
CookieInclusionStatus(), kLongAge},
};
- VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::UNKNOWN,
- common_test_cases);
- VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::UNKNOWN,
- default_lax_test_cases);
- VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::LEGACY,
- common_test_cases);
- VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::LEGACY,
- default_none_test_cases);
- VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::NONLEGACY,
- common_test_cases);
- VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::NONLEGACY,
- default_lax_test_cases);
- VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::UNKNOWN,
- common_test_cases);
- VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::UNKNOWN,
- default_none_test_cases);
- VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::LEGACY,
- common_test_cases);
- VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::LEGACY,
- default_none_test_cases);
- VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::NONLEGACY,
- common_test_cases);
- VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::NONLEGACY,
- default_lax_test_cases);
+ // Test cases that require LEGACY semantics or Schemeful Same-Site to be
+ // disabled.
+ std::vector<IncludeForRequestURLTestCase> schemeful_disabled_test_cases = {
+ {"LEGACY_Schemeful=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
+ {"LEGACY_Schemeful=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
+ {"LEGACY_Schemeful=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
+ {"LEGACY_Schemeful=4;SameSite=Lax", CookieSameSite::LAX_MODE,
+ CookieEffectiveSameSite::LAX_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ {"LEGACY_Schemeful=5;SameSite=Lax", CookieSameSite::LAX_MODE,
+ CookieEffectiveSameSite::LAX_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ {"LEGACY_Schemeful=6;SameSite=Lax", CookieSameSite::LAX_MODE,
+ CookieEffectiveSameSite::LAX_MODE,
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ };
+
+ // Test cases that require NONLEGACY or UNKNOWN semantics with Schemeful
+ // Same-Site enabled
+ std::vector<IncludeForRequestURLTestCase> schemeful_enabled_test_cases = {
+ {"NONLEGACY_Schemeful=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
+ {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
+ {"NONLEGACY_Schemeful=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
+ {CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
+ {"NONLEGACY_Schemeful=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
+ CookieEffectiveSameSite::STRICT_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
+ {CookieInclusionStatus::
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
+ {"NONLEGACY_Schemeful=4;SameSite=Lax", CookieSameSite::LAX_MODE,
+ CookieEffectiveSameSite::LAX_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
+ {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ {"NONLEGACY_Schemeful=5;SameSite=Lax", CookieSameSite::LAX_MODE,
+ CookieEffectiveSameSite::LAX_MODE,
+ SameSiteCookieContext(
+ SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
+ {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ {"NONLEGACY_Schemeful=6;SameSite=Lax", CookieSameSite::LAX_MODE,
+ CookieEffectiveSameSite::LAX_MODE,
+ SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
+ SameSiteCookieContext::ContextType::CROSS_SITE),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
+ {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ };
+
+ auto SchemefulIndependentCases = [&]() {
+ // Run the test cases that are independent of Schemeful Same-Site.
+ VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::UNKNOWN,
+ common_test_cases);
+ VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::UNKNOWN,
+ default_lax_test_cases);
+ VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::LEGACY,
+ common_test_cases);
+ VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::LEGACY,
+ default_none_test_cases);
+ VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::NONLEGACY,
+ common_test_cases);
+ VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::NONLEGACY,
+ default_lax_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::UNKNOWN,
+ common_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::UNKNOWN,
+ default_none_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::LEGACY,
+ common_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::LEGACY,
+ default_none_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::NONLEGACY,
+ common_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::NONLEGACY,
+ default_lax_test_cases);
+ };
+
+ {
+ // Schemeful Same-Site disabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
+
+ SchemefulIndependentCases();
+
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::LEGACY,
+ schemeful_disabled_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::NONLEGACY,
+ schemeful_disabled_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::UNKNOWN,
+ schemeful_disabled_test_cases);
+ }
+ {
+ // Schemeful Same-Site enabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
+
+ SchemefulIndependentCases();
+
+ // With LEGACY access the cases should act as if schemeful is disabled, even
+ // when it's not.
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::LEGACY,
+ schemeful_disabled_test_cases);
+
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::NONLEGACY,
+ schemeful_enabled_test_cases);
+ VerifyIncludeForRequestURLTestCases(false, CookieAccessSemantics::UNKNOWN,
+ schemeful_enabled_test_cases);
+ }
}
// Test that non-SameSite, insecure cookies are excluded if both
@@ -1095,7 +1220,7 @@ TEST(CanonicalCookieTest, MultipleExclusionReasons) {
url, "name=value;HttpOnly;SameSite=Lax", creation_time, server_time);
ASSERT_TRUE(cookie3);
EXPECT_TRUE(cookie3->IsSetPermittedInContext(options)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
}
@@ -1990,15 +2115,15 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CookieOptions context_network;
context_network.set_include_httponly();
- EXPECT_TRUE(
- cookie_scriptable.IsSetPermittedInContext(context_network).IsInclude());
- EXPECT_TRUE(
- cookie_scriptable.IsSetPermittedInContext(context_script).IsInclude());
+ EXPECT_TRUE(cookie_scriptable.IsSetPermittedInContext(context_network)
+ .status.IsInclude());
+ EXPECT_TRUE(cookie_scriptable.IsSetPermittedInContext(context_script)
+ .status.IsInclude());
- EXPECT_TRUE(
- cookie_httponly.IsSetPermittedInContext(context_network).IsInclude());
+ EXPECT_TRUE(cookie_httponly.IsSetPermittedInContext(context_network)
+ .status.IsInclude());
EXPECT_TRUE(cookie_httponly.IsSetPermittedInContext(context_script)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
CookieOptions context_cross_site;
@@ -2037,29 +2162,62 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(cookie_same_site_unrestricted
.IsSetPermittedInContext(context_cross_site)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unrestricted
.IsSetPermittedInContext(context_same_site_lax)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unrestricted
.IsSetPermittedInContext(context_same_site_strict)
- .IsInclude());
-
- CookieInclusionStatus status_strict_to_lax =
- cookie_same_site_unrestricted.IsSetPermittedInContext(
- context_same_site_strict_to_lax);
- EXPECT_TRUE(status_strict_to_lax.IsInclude());
- EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
- CookieInclusionStatus status_strict_to_cross =
- cookie_same_site_unrestricted.IsSetPermittedInContext(
- context_same_site_strict_to_cross);
- EXPECT_TRUE(status_strict_to_cross.IsInclude());
- EXPECT_FALSE(status_strict_to_cross.HasDowngradeWarning());
- CookieInclusionStatus status_lax_to_cross =
- cookie_same_site_unrestricted.IsSetPermittedInContext(
- context_same_site_lax_to_cross);
- EXPECT_TRUE(status_lax_to_cross.IsInclude());
- EXPECT_FALSE(status_lax_to_cross.HasDowngradeWarning());
+ .status.IsInclude());
+
+ {
+ // Schemeful Same-Site disabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
+
+ CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_unrestricted
+ .IsSetPermittedInContext(context_same_site_strict_to_lax)
+ .status;
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_unrestricted
+ .IsSetPermittedInContext(context_same_site_strict_to_cross)
+ .status;
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_FALSE(status_strict_to_cross.HasDowngradeWarning());
+ CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_unrestricted
+ .IsSetPermittedInContext(context_same_site_lax_to_cross)
+ .status;
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_FALSE(status_lax_to_cross.HasDowngradeWarning());
+ }
+ {
+ // Schemeful Same-Site enabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
+
+ CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_unrestricted
+ .IsSetPermittedInContext(context_same_site_strict_to_lax)
+ .status;
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_unrestricted
+ .IsSetPermittedInContext(context_same_site_strict_to_cross)
+ .status;
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_FALSE(status_strict_to_cross.HasDowngradeWarning());
+ CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_unrestricted
+ .IsSetPermittedInContext(context_same_site_lax_to_cross)
+ .status;
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_FALSE(status_lax_to_cross.HasDowngradeWarning());
+ }
}
{
@@ -2069,32 +2227,71 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT);
EXPECT_TRUE(cookie_same_site_lax.IsSetPermittedInContext(context_cross_site)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
EXPECT_TRUE(
cookie_same_site_lax.IsSetPermittedInContext(context_same_site_lax)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(
cookie_same_site_lax.IsSetPermittedInContext(context_same_site_strict)
- .IsInclude());
-
- CookieInclusionStatus status_strict_to_lax =
- cookie_same_site_lax.IsSetPermittedInContext(
- context_same_site_strict_to_lax);
- EXPECT_TRUE(status_strict_to_lax.IsInclude());
- EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
- CookieInclusionStatus status_strict_to_cross =
- cookie_same_site_lax.IsSetPermittedInContext(
- context_same_site_strict_to_cross);
- EXPECT_TRUE(status_strict_to_cross.IsInclude());
- EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
- CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE));
- CookieInclusionStatus status_lax_to_cross =
- cookie_same_site_lax.IsSetPermittedInContext(
- context_same_site_lax_to_cross);
- EXPECT_TRUE(status_lax_to_cross.IsInclude());
- EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
- CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE));
+ .status.IsInclude());
+
+ {
+ // Schemeful Same-Site disabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
+
+ CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_lax
+ .IsSetPermittedInContext(context_same_site_strict_to_lax)
+ .status;
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_lax
+ .IsSetPermittedInContext(context_same_site_strict_to_cross)
+ .status;
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE));
+ CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_lax
+ .IsSetPermittedInContext(context_same_site_lax_to_cross)
+ .status;
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE));
+ }
+ {
+ // Schemeful Same-Site enabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
+
+ CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_lax
+ .IsSetPermittedInContext(context_same_site_strict_to_lax)
+ .status;
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_lax
+ .IsSetPermittedInContext(context_same_site_strict_to_cross)
+ .status;
+ EXPECT_FALSE(status_strict_to_cross.IsInclude());
+ EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE));
+ EXPECT_TRUE(status_strict_to_cross.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_LAX));
+ CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_lax
+ .IsSetPermittedInContext(context_same_site_lax_to_cross)
+ .status;
+ EXPECT_FALSE(status_lax_to_cross.IsInclude());
+ EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE));
+ EXPECT_TRUE(status_strict_to_cross.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_LAX));
+ }
}
{
@@ -2107,32 +2304,96 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
// context really should be accepted.
EXPECT_TRUE(
cookie_same_site_strict.IsSetPermittedInContext(context_cross_site)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT}));
EXPECT_TRUE(
cookie_same_site_strict.IsSetPermittedInContext(context_same_site_lax)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_strict
.IsSetPermittedInContext(context_same_site_strict)
- .IsInclude());
-
- CookieInclusionStatus status_strict_to_lax =
- cookie_same_site_strict.IsSetPermittedInContext(
- context_same_site_strict_to_lax);
- EXPECT_TRUE(status_strict_to_lax.IsInclude());
- EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
- CookieInclusionStatus status_strict_to_cross =
- cookie_same_site_strict.IsSetPermittedInContext(
- context_same_site_strict_to_cross);
- EXPECT_TRUE(status_strict_to_cross.IsInclude());
- EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
- CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE));
- CookieInclusionStatus status_lax_to_cross =
- cookie_same_site_strict.IsSetPermittedInContext(
- context_same_site_lax_to_cross);
- EXPECT_TRUE(status_lax_to_cross.IsInclude());
- EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
- CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ .status.IsInclude());
+
+ {
+ // Schemeful Same-Site disabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
+
+ CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_lax)
+ .status;
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_cross)
+ .status;
+ EXPECT_TRUE(status_strict_to_cross.IsInclude());
+ EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_lax_to_cross)
+ .status;
+ EXPECT_TRUE(status_lax_to_cross.IsInclude());
+ EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ }
+ {
+ // Schemeful Same-Site enabled.
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
+
+ CookieInclusionStatus status_strict_to_lax =
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_lax)
+ .status;
+ EXPECT_TRUE(status_strict_to_lax.IsInclude());
+ EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
+ CookieInclusionStatus status_strict_to_cross =
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_cross)
+ .status;
+ EXPECT_FALSE(status_strict_to_cross.IsInclude());
+ EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ EXPECT_TRUE(status_strict_to_cross.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT));
+ CookieInclusionStatus status_lax_to_cross =
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_lax_to_cross)
+ .status;
+ EXPECT_FALSE(status_lax_to_cross.IsInclude());
+ EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ EXPECT_TRUE(status_strict_to_cross.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT));
+ }
+
+ // Even with Schemeful Same-Site enabled, cookies semantics could change the
+ // inclusion.
+ {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
+
+ EXPECT_FALSE(
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_cross,
+ CookieAccessSemantics::UNKNOWN)
+ .status.IsInclude());
+ EXPECT_FALSE(
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_cross,
+ CookieAccessSemantics::NONLEGACY)
+ .status.IsInclude());
+ // LEGACY semantics should allow cookies which Schemeful Same-Site would
+ // normally block.
+ EXPECT_TRUE(
+ cookie_same_site_strict
+ .IsSetPermittedInContext(context_same_site_strict_to_cross,
+ CookieAccessSemantics::LEGACY)
+ .status.IsInclude());
+ }
}
// Behavior of UNSPECIFIED depends on an experiment and CookieAccessSemantics.
@@ -2148,41 +2409,41 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::UNKNOWN)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
CookieAccessSemantics::UNKNOWN)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::UNKNOWN)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::NONLEGACY)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
CookieAccessSemantics::NONLEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::NONLEGACY)
- .IsInclude());
+ .status.IsInclude());
}
{
@@ -2192,44 +2453,124 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::UNKNOWN)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
CookieAccessSemantics::UNKNOWN)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::UNKNOWN)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::NONLEGACY)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
CookieAccessSemantics::NONLEGACY)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_strict,
CookieAccessSemantics::NONLEGACY)
- .IsInclude());
+ .status.IsInclude());
}
}
+TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
+ GURL url("http://www.example.com/test");
+ base::Time current_time = base::Time::Now();
+ CookieOptions options;
+
+ // Test IsSetPermitted CookieEffectiveSameSite for
+ // CanonicalCookie with CookieSameSite::NO_RESTRICTION.
+ CanonicalCookie cookie_no_restriction(
+ "A", "2", "www.example.com", "/test", current_time, base::Time(),
+ base::Time(), true /*secure*/, false /*httponly*/,
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+
+ EXPECT_EQ(
+ cookie_no_restriction
+ .IsSetPermittedInContext(options, CookieAccessSemantics::UNKNOWN)
+ .effective_same_site,
+ CookieEffectiveSameSite::NO_RESTRICTION);
+
+ // Test IsSetPermitted CookieEffectiveSameSite for
+ // CanonicalCookie with CookieSameSite::LAX_MODE.
+ CanonicalCookie cookie_lax("A", "2", "www.example.com", "/test", current_time,
+ base::Time(), base::Time(), true /*secure*/,
+ false /*httponly*/, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT);
+
+ EXPECT_EQ(
+ cookie_lax
+ .IsSetPermittedInContext(options, CookieAccessSemantics::UNKNOWN)
+ .effective_same_site,
+ CookieEffectiveSameSite::LAX_MODE);
+
+ // Test IsSetPermitted CookieEffectiveSameSite for
+ // CanonicalCookie with CookieSameSite::STRICT_MODE.
+ CanonicalCookie cookie_strict(
+ "A", "2", "www.example.com", "/test", current_time, base::Time(),
+ base::Time(), true /*secure*/, false /*httponly*/,
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
+
+ EXPECT_EQ(
+ cookie_strict
+ .IsSetPermittedInContext(options, CookieAccessSemantics::UNKNOWN)
+ .effective_same_site,
+ CookieEffectiveSameSite::STRICT_MODE);
+
+ // Test IsSetPermitted CookieEffectiveSameSite for
+ // CanonicalCookie with CookieSameSite::UNSPECIFIED.
+ base::Time creation_time = base::Time::Now() - (kLaxAllowUnsafeMaxAge * 4);
+ CanonicalCookie cookie_old_unspecified(
+ "A", "2", "www.example.com", "/test", creation_time, base::Time(),
+ base::Time(), true /*secure*/, false /*httponly*/,
+ CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT);
+ CanonicalCookie cookie_unspecified(
+ "A", "2", "www.example.com", "/test", current_time, base::Time(),
+ base::Time(), true /*secure*/, false /*httponly*/,
+ CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT);
+
+ EXPECT_EQ(
+ cookie_old_unspecified
+ .IsSetPermittedInContext(options, CookieAccessSemantics::UNKNOWN)
+ .effective_same_site,
+ CookieEffectiveSameSite::LAX_MODE);
+
+ EXPECT_EQ(
+ cookie_unspecified
+ .IsSetPermittedInContext(options, CookieAccessSemantics::UNKNOWN)
+ .effective_same_site,
+ CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE);
+
+ EXPECT_EQ(
+ cookie_unspecified
+ .IsSetPermittedInContext(options, CookieAccessSemantics::NONLEGACY)
+ .effective_same_site,
+ CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE);
+
+ EXPECT_EQ(cookie_unspecified
+ .IsSetPermittedInContext(options, CookieAccessSemantics::LEGACY)
+ .effective_same_site,
+ CookieEffectiveSameSite::NO_RESTRICTION);
+}
+
} // namespace net
diff --git a/chromium/net/cookies/cookie_access_result.cc b/chromium/net/cookies/cookie_access_result.cc
index 182dc53f704..d618254360b 100644
--- a/chromium/net/cookies/cookie_access_result.cc
+++ b/chromium/net/cookies/cookie_access_result.cc
@@ -10,8 +10,14 @@ CookieAccessResult::CookieAccessResult() = default;
CookieAccessResult::CookieAccessResult(
CookieEffectiveSameSite effective_same_site,
- CookieInclusionStatus status)
- : effective_same_site(effective_same_site), status(status) {}
+ CookieInclusionStatus status,
+ CookieAccessSemantics access_semantics)
+ : status(status),
+ effective_same_site(effective_same_site),
+ access_semantics(access_semantics) {}
+
+CookieAccessResult::CookieAccessResult(CookieInclusionStatus status)
+ : status(status) {}
CookieAccessResult::CookieAccessResult(const CookieAccessResult&) = default;
diff --git a/chromium/net/cookies/cookie_access_result.h b/chromium/net/cookies/cookie_access_result.h
index a21305bfe11..7e5aa208b6f 100644
--- a/chromium/net/cookies/cookie_access_result.h
+++ b/chromium/net/cookies/cookie_access_result.h
@@ -12,9 +12,15 @@
namespace net {
struct NET_EXPORT CookieAccessResult {
+ // Creating a CookieAccessResult with out any parameters will create a
+ // CookieInclusionStatus that has no exclusion reasons, therefore
+ // indicates inclusion.
CookieAccessResult();
CookieAccessResult(CookieEffectiveSameSite effective_same_site,
- CookieInclusionStatus status);
+ CookieInclusionStatus status,
+ CookieAccessSemantics access_semantics);
+
+ explicit CookieAccessResult(CookieInclusionStatus status);
CookieAccessResult(const CookieAccessResult& cookie_access_result);
@@ -24,9 +30,10 @@ struct NET_EXPORT CookieAccessResult {
~CookieAccessResult();
- CookieEffectiveSameSite effective_same_site =
- CookieEffectiveSameSite::LAX_MODE;
CookieInclusionStatus status;
+ CookieEffectiveSameSite effective_same_site =
+ CookieEffectiveSameSite::UNDEFINED;
+ CookieAccessSemantics access_semantics = CookieAccessSemantics::UNKNOWN;
};
} // namespace net
diff --git a/chromium/net/cookies/cookie_change_dispatcher.cc b/chromium/net/cookies/cookie_change_dispatcher.cc
index 07c6457fc4c..755a4128d19 100644
--- a/chromium/net/cookies/cookie_change_dispatcher.cc
+++ b/chromium/net/cookies/cookie_change_dispatcher.cc
@@ -37,9 +37,15 @@ const char* CookieChangeCauseToString(CookieChangeCause cause) {
CookieChangeInfo::CookieChangeInfo() = default;
CookieChangeInfo::CookieChangeInfo(const CanonicalCookie& cookie,
- CookieAccessSemantics access_semantics,
+ CookieAccessResult access_result,
CookieChangeCause cause)
- : cookie(cookie), access_semantics(access_semantics), cause(cause) {}
+ : cookie(cookie), access_result(access_result), cause(cause) {
+ DCHECK(access_result.status.IsInclude());
+ if (CookieChangeCauseIsDeletion(cause)) {
+ DCHECK_EQ(access_result.effective_same_site,
+ CookieEffectiveSameSite::UNDEFINED);
+ }
+}
CookieChangeInfo::~CookieChangeInfo() = default;
diff --git a/chromium/net/cookies/cookie_change_dispatcher.h b/chromium/net/cookies/cookie_change_dispatcher.h
index c1b7f516249..ffa9a003da7 100644
--- a/chromium/net/cookies/cookie_change_dispatcher.h
+++ b/chromium/net/cookies/cookie_change_dispatcher.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_access_result.h"
class GURL;
@@ -41,15 +42,15 @@ enum class CookieChangeCause {
struct NET_EXPORT CookieChangeInfo {
CookieChangeInfo();
CookieChangeInfo(const CanonicalCookie& cookie,
- CookieAccessSemantics access_semantics,
+ CookieAccessResult access_result,
CookieChangeCause cause);
~CookieChangeInfo();
// The cookie that changed.
CanonicalCookie cookie;
- // The access semantics of the cookie at the time of the change.
- CookieAccessSemantics access_semantics = CookieAccessSemantics::UNKNOWN;
+ // The access result of the cookie at the time of the change.
+ CookieAccessResult access_result;
// The reason for the change.
CookieChangeCause cause = CookieChangeCause::EXPLICIT;
diff --git a/chromium/net/cookies/cookie_constants.h b/chromium/net/cookies/cookie_constants.h
index 732d7d56c70..8397a471a8b 100644
--- a/chromium/net/cookies/cookie_constants.h
+++ b/chromium/net/cookies/cookie_constants.h
@@ -47,6 +47,9 @@ enum class CookieEffectiveSameSite {
LAX_MODE = 1,
STRICT_MODE = 2,
LAX_MODE_ALLOW_UNSAFE = 3,
+ // Undefined is used when no value applies for the object as there is no
+ // valid cookie object to evaluate on.
+ UNDEFINED = 4,
// Keep last, used for histograms.
COUNT
diff --git a/chromium/net/cookies/cookie_inclusion_status.cc b/chromium/net/cookies/cookie_inclusion_status.cc
index 8e13916ba13..240b17cd1b0 100644
--- a/chromium/net/cookies/cookie_inclusion_status.cc
+++ b/chromium/net/cookies/cookie_inclusion_status.cc
@@ -51,6 +51,11 @@ bool CookieInclusionStatus::HasExclusionReason(ExclusionReason reason) const {
return exclusion_reasons_ & GetExclusionBitmask(reason);
}
+bool CookieInclusionStatus::HasOnlyExclusionReason(
+ ExclusionReason reason) const {
+ return exclusion_reasons_ == GetExclusionBitmask(reason);
+}
+
void CookieInclusionStatus::AddExclusionReason(ExclusionReason reason) {
exclusion_reasons_ |= GetExclusionBitmask(reason);
// If the cookie would be excluded for reasons other than the new SameSite
diff --git a/chromium/net/cookies/cookie_inclusion_status.h b/chromium/net/cookies/cookie_inclusion_status.h
index 3f38eddb39b..9e506b55501 100644
--- a/chromium/net/cookies/cookie_inclusion_status.h
+++ b/chromium/net/cookies/cookie_inclusion_status.h
@@ -184,6 +184,10 @@ class NET_EXPORT CookieInclusionStatus {
// Whether the given reason for exclusion is present.
bool HasExclusionReason(ExclusionReason status_type) const;
+ // Whether the given reason for exclusion is present, and is the ONLY reason
+ // for exclusion.
+ bool HasOnlyExclusionReason(ExclusionReason status_type) const;
+
// Add an exclusion reason.
void AddExclusionReason(ExclusionReason status_type);
diff --git a/chromium/net/cookies/cookie_inclusion_status_unittest.cc b/chromium/net/cookies/cookie_inclusion_status_unittest.cc
index bc5c7edaa39..579edb4b8ae 100644
--- a/chromium/net/cookies/cookie_inclusion_status_unittest.cc
+++ b/chromium/net/cookies/cookie_inclusion_status_unittest.cc
@@ -32,17 +32,31 @@ TEST(CookieInclusionStatusTest, IncludeStatus) {
TEST(CookieInclusionStatusTest, ExcludeStatus) {
int num_exclusion_reasons =
static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
+ // Test exactly one exclusion reason and multiple (two) exclusion reasons.
for (int i = 0; i < num_exclusion_reasons; ++i) {
- auto reason = static_cast<CookieInclusionStatus::ExclusionReason>(i);
- CookieInclusionStatus status(reason);
- EXPECT_TRUE(status.IsValid());
- EXPECT_FALSE(status.IsInclude());
- EXPECT_TRUE(status.HasExclusionReason(reason));
+ auto reason1 = static_cast<CookieInclusionStatus::ExclusionReason>(i);
+ CookieInclusionStatus status_one_reason(reason1);
+ EXPECT_TRUE(status_one_reason.IsValid());
+ EXPECT_FALSE(status_one_reason.IsInclude());
+ EXPECT_TRUE(status_one_reason.HasExclusionReason(reason1));
+ EXPECT_TRUE(status_one_reason.HasOnlyExclusionReason(reason1));
+
for (int j = 0; j < num_exclusion_reasons; ++j) {
if (i == j)
continue;
- EXPECT_FALSE(status.HasExclusionReason(
- static_cast<CookieInclusionStatus::ExclusionReason>(j)));
+ auto reason2 = static_cast<CookieInclusionStatus::ExclusionReason>(j);
+
+ EXPECT_FALSE(status_one_reason.HasExclusionReason(reason2));
+ EXPECT_FALSE(status_one_reason.HasOnlyExclusionReason(reason2));
+
+ CookieInclusionStatus status_two_reasons = status_one_reason;
+ status_two_reasons.AddExclusionReason(reason2);
+ EXPECT_TRUE(status_two_reasons.IsValid());
+ EXPECT_FALSE(status_two_reasons.IsInclude());
+ EXPECT_TRUE(status_two_reasons.HasExclusionReason(reason1));
+ EXPECT_TRUE(status_two_reasons.HasExclusionReason(reason2));
+ EXPECT_FALSE(status_two_reasons.HasOnlyExclusionReason(reason1));
+ EXPECT_FALSE(status_two_reasons.HasOnlyExclusionReason(reason2));
}
}
}
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index 477b47a7721..265deed0e52 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -765,8 +765,10 @@ void CookieMonster::StoreLoadedCookies(
for (auto& cookie : cookies) {
CanonicalCookie* cookie_ptr = cookie.get();
- auto inserted = InternalInsertCookie(GetKey(cookie_ptr->Domain()),
- std::move(cookie), false);
+ CookieAccessResult access_result;
+ access_result.access_semantics = CookieAccessSemantics::UNKNOWN;
+ auto inserted = InternalInsertCookie(
+ GetKey(cookie_ptr->Domain()), std::move(cookie), false, access_result);
const Time cookie_access_time(cookie_ptr->LastAccessDate());
if (earliest_access_time_.is_null() ||
cookie_access_time < earliest_access_time_) {
@@ -1115,7 +1117,8 @@ base::Time CookieMonster::EffectiveCreationTimeForMaybePreexistingCookie(
CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
const std::string& key,
std::unique_ptr<CanonicalCookie> cc,
- bool sync_to_store) {
+ bool sync_to_store,
+ const CookieAccessResult& access_result) {
DCHECK(thread_checker_.CalledOnValidThread());
CanonicalCookie* cc_ptr = cc.get();
@@ -1132,19 +1135,16 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
// See InitializeHistograms() for details.
int32_t type_sample =
- !cc_ptr->IsEffectivelySameSiteNone(GetAccessSemanticsForCookie(
- *cc_ptr, false /* legacy_access_granted */))
+ !cc_ptr->IsEffectivelySameSiteNone(access_result.access_semantics)
? 1 << COOKIE_TYPE_SAME_SITE
: 0;
type_sample |= cc_ptr->IsHttpOnly() ? 1 << COOKIE_TYPE_HTTPONLY : 0;
type_sample |= cc_ptr->IsSecure() ? 1 << COOKIE_TYPE_SECURE : 0;
histogram_cookie_type_->Add(type_sample);
+ DCHECK(access_result.status.IsInclude());
change_dispatcher_.DispatchChange(
- CookieChangeInfo(*cc_ptr,
- GetAccessSemanticsForCookie(
- *cc_ptr, false /* legacy_access_granted */),
- CookieChangeCause::INSERTED),
+ CookieChangeInfo(*cc_ptr, access_result, CookieChangeCause::INSERTED),
true);
// If this is the first cookie in |cookies_| with this key, increment the
@@ -1165,17 +1165,18 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
SetCookiesCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- CookieInclusionStatus status;
+ CookieAccessResult access_result;
bool secure_source = source_url.SchemeIsCryptographic();
cc->SetSourceScheme(secure_source ? CookieSourceScheme::kSecure
: CookieSourceScheme::kNonSecure);
if ((cc->IsSecure() && !secure_source)) {
- status.AddExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY);
+ access_result.status.AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SECURE_ONLY);
}
if (!IsCookieableScheme(source_url.scheme())) {
- status.AddExclusionReason(
+ access_result.status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME);
}
@@ -1188,7 +1189,7 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
cookie_util::IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled()
? EffectiveCreationTimeForMaybePreexistingCookie(key, *cc)
: base::Time()),
- &status);
+ &access_result);
base::Time creation_date = cc->CreationDate();
if (creation_date.is_null()) {
@@ -1201,11 +1202,11 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
MaybeDeleteEquivalentCookieAndUpdateStatus(
key, *cc, secure_source, options.exclude_httponly(), already_expired,
- &creation_date_to_inherit, &status);
+ &creation_date_to_inherit, &access_result.status);
- if (status.HasExclusionReason(
+ if (access_result.status.HasExclusionReason(
CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE) ||
- status.HasExclusionReason(
+ access_result.status.HasExclusionReason(
CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY)) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() not clobbering httponly cookie or secure cookie for "
@@ -1215,13 +1216,13 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
// Now that IsSetPermittedInContext() and
// MaybeDeleteEquivalentCookieAndUpdateStatus() have had a chance to set
// cookie warnings/exclusions, record the downgrade metric.
- if (status.ShouldRecordDowngradeMetrics()) {
+ if (access_result.status.ShouldRecordDowngradeMetrics()) {
UMA_HISTOGRAM_ENUMERATION(
"Cookie.SameSiteContextDowngradeResponse",
- status.GetBreakingDowngradeMetricsEnumValue(source_url));
+ access_result.status.GetBreakingDowngradeMetricsEnumValue(source_url));
}
- if (status.IsInclude()) {
+ if (access_result.status.IsInclude()) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() key: " << key << " cc: " << cc->DebugString();
@@ -1255,7 +1256,7 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
MaybeRecordCookieAccessWithOptions(*cc, options, true);
- InternalInsertCookie(key, std::move(cc), true);
+ InternalInsertCookie(key, std::move(cc), true, access_result);
} else {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() not storing already expired cookie.";
@@ -1270,7 +1271,7 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
}
// TODO(chlily): Log metrics.
- MaybeRunCookieCallback(std::move(callback), status);
+ MaybeRunCookieCallback(std::move(callback), access_result);
}
void CookieMonster::SetAllCookies(CookieList list,
@@ -1295,7 +1296,11 @@ void CookieMonster::SetAllCookies(CookieList list,
(cookie.ExpiryDate() - creation_time).InMinutes());
}
- InternalInsertCookie(key, std::make_unique<CanonicalCookie>(cookie), true);
+ CookieAccessResult access_result;
+ access_result.access_semantics = GetAccessSemanticsForCookie(
+ cookie, false /* legacy_semantics_granted */);
+ InternalInsertCookie(key, std::make_unique<CanonicalCookie>(cookie), true,
+ access_result);
GarbageCollect(creation_time, key);
}
@@ -1303,7 +1308,7 @@ void CookieMonster::SetAllCookies(CookieList list,
// shouldn't have a return value. But it should also be deleted (see
// https://codereview.chromium.org/2882063002/#msg64), which would
// solve the return value problem.
- MaybeRunCookieCallback(std::move(callback), CookieInclusionStatus());
+ MaybeRunCookieCallback(std::move(callback), CookieAccessResult());
}
void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc,
@@ -1364,7 +1369,10 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
change_dispatcher_.DispatchChange(
CookieChangeInfo(
*cc,
- GetAccessSemanticsForCookie(*cc, false /* legacy_access_granted */),
+ CookieAccessResult(CookieEffectiveSameSite::UNDEFINED,
+ CookieInclusionStatus(),
+ GetAccessSemanticsForCookie(
+ *cc, false /* legacy_access_granted */)),
mapping.cause),
mapping.notify);
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index 9908e6f8e7e..57ce9d640ac 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -448,9 +448,11 @@ class NET_EXPORT CookieMonster : public CookieStore {
// Inserts |cc| into cookies_. Returns an iterator that points to the inserted
// cookie in cookies_. Guarantee: all iterators to cookies_ remain valid.
- CookieMap::iterator InternalInsertCookie(const std::string& key,
- std::unique_ptr<CanonicalCookie> cc,
- bool sync_to_store);
+ CookieMap::iterator InternalInsertCookie(
+ const std::string& key,
+ std::unique_ptr<CanonicalCookie> cc,
+ bool sync_to_store,
+ const CookieAccessResult& access_result);
// Sets all cookies from |list| after deleting any equivalent cookie.
// For data gathering purposes, this routine is treated as if it is
diff --git a/chromium/net/cookies/cookie_monster_change_dispatcher.cc b/chromium/net/cookies/cookie_monster_change_dispatcher.cc
index 6bd731f47ca..d79fb3a54d6 100644
--- a/chromium/net/cookies/cookie_monster_change_dispatcher.cc
+++ b/chromium/net/cookies/cookie_monster_change_dispatcher.cc
@@ -60,7 +60,7 @@ void CookieMonsterChangeDispatcher::Subscription::DispatchChange(
if (!url_.is_empty() &&
!cookie
.IncludeForRequestURL(url_, CookieOptions::MakeAllInclusive(),
- change.access_semantics)
+ change.access_result.access_semantics)
.status.IsInclude()) {
return;
}
diff --git a/chromium/net/cookies/cookie_monster_perftest.cc b/chromium/net/cookies/cookie_monster_perftest.cc
index 96d16f545a6..10c79a1f191 100644
--- a/chromium/net/cookies/cookie_monster_perftest.cc
+++ b/chromium/net/cookies/cookie_monster_perftest.cc
@@ -28,8 +28,7 @@ namespace net {
namespace {
const int kNumCookies = 20000;
-const char kCookieLine[] = "A = \"b=;\\\"\" ;secure;;;";
-const char kGoogleURL[] = "http://www.foo.com";
+const char kCookieLine[] = "A = \"b=;\\\"\" ;secure;;; samesite=none";
static constexpr char kMetricPrefixParsedCookie[] = "ParsedCookie.";
static constexpr char kMetricPrefixCookieMonster[] = "CookieMonster.";
@@ -105,8 +104,9 @@ class SetCookieCallback : public CookieTestCallback {
}
private:
- void Run(CookieInclusionStatus status) {
- EXPECT_TRUE(status.IsInclude());
+ void Run(CookieAccessResult result) {
+ EXPECT_TRUE(result.status.IsInclude())
+ << "result.status: " << result.status.GetDebugString();
CookieTestCallback::Run();
}
CookieOptions options_;
@@ -178,7 +178,7 @@ TEST_F(CookieMonsterTest, TestAddCookiesOnSingleHost) {
auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
std::vector<std::string> cookies;
for (int i = 0; i < kNumCookies; i++) {
- cookies.push_back(base::StringPrintf("a%03d=b", i));
+ cookies.push_back(base::StringPrintf("a%03d=b; SameSite=None; Secure", i));
}
SetCookieCallback setCookieCallback;
@@ -187,9 +187,10 @@ TEST_F(CookieMonsterTest, TestAddCookiesOnSingleHost) {
auto reporter = SetUpCookieMonsterReporter("single_host");
base::ElapsedTimer add_timer;
+ const GURL kGoogleURL = GURL("https://www.foo.com");
for (std::vector<std::string>::const_iterator it = cookies.begin();
it != cookies.end(); ++it) {
- setCookieCallback.SetCookie(cm.get(), GURL(kGoogleURL), *it);
+ setCookieCallback.SetCookie(cm.get(), kGoogleURL, *it);
}
reporter.AddResult(kMetricAddTimeMs, add_timer.Elapsed().InMillisecondsF());
@@ -198,7 +199,7 @@ TEST_F(CookieMonsterTest, TestAddCookiesOnSingleHost) {
base::ElapsedTimer query_timer;
for (std::vector<std::string>::const_iterator it = cookies.begin();
it != cookies.end(); ++it) {
- getCookieListCallback.GetCookieList(cm.get(), GURL(kGoogleURL));
+ getCookieListCallback.GetCookieList(cm.get(), kGoogleURL);
}
reporter.AddResult(kMetricQueryTimeMs,
query_timer.Elapsed().InMillisecondsF());
@@ -250,7 +251,8 @@ TEST_F(CookieMonsterTest, TestDomainTree) {
auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
GetCookieListCallback getCookieListCallback;
SetCookieCallback setCookieCallback;
- const char domain_cookie_format_tree[] = "a=b; domain=%s";
+ const char domain_cookie_format_tree[] =
+ "a=b; domain=%s; samesite=none; secure";
const std::string domain_base("top.com");
std::vector<std::string> domain_list;
@@ -323,7 +325,8 @@ TEST_F(CookieMonsterTest, TestDomainLine) {
domain_list.push_back("b.a.b.a.top.com");
EXPECT_EQ(4u, domain_list.size());
- const char domain_cookie_format_line[] = "a%03d=b; domain=%s";
+ const char domain_cookie_format_line[] =
+ "a%03d=b; domain=%s; samesite=none; secure";
for (int i = 0; i < 8; i++) {
for (std::vector<std::string>::const_iterator it = domain_list.begin();
it != domain_list.end(); it++) {
@@ -445,8 +448,8 @@ TEST_F(CookieMonsterTest, TestGCTimes) {
test_case.num_cookies, test_case.num_old_cookies, 0, 0,
CookieMonster::kSafeFromGlobalPurgeDays * 2);
- GURL gurl("http://foo.com");
- std::string cookie_line("z=3");
+ GURL gurl("https://foo.com");
+ std::string cookie_line("z=3; samesite=none; secure");
// Trigger the Garbage collection we're allowed.
setCookieCallback.SetCookie(cm.get(), gurl, cookie_line);
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index fc83d6a6211..a4b72d59e64 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -148,10 +148,10 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
bool SetAllCookies(CookieMonster* cm, const CookieList& list) {
DCHECK(cm);
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cm->SetAllCookiesAsync(list, callback.MakeCallback());
callback.WaitUntilDone();
- return callback.result().IsInclude();
+ return callback.result().status.IsInclude();
}
bool SetCookieWithCreationTime(CookieMonster* cm,
@@ -160,13 +160,13 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
base::Time creation_time) {
DCHECK(cm);
DCHECK(!creation_time.is_null());
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cm->SetCanonicalCookieAsync(
CanonicalCookie::Create(url, cookie_line, creation_time,
base::nullopt /* server_time */),
url, CookieOptions::MakeAllInclusive(), callback.MakeCallback());
callback.WaitUntilDone();
- return callback.result().IsInclude();
+ return callback.result().status.IsInclude();
}
uint32_t DeleteAllCreatedInTimeRange(CookieMonster* cm,
@@ -981,7 +981,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
// Generate puts to store w/o needing a proper expiration.
cookie_monster_->SetPersistSessionCookies(true);
- ResultSavingCookieCallback<CookieInclusionStatus> call1;
+ ResultSavingCookieCallback<CookieAccessResult> call1;
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
base::nullopt /* server_time */),
@@ -992,17 +992,17 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
ExecuteLoads(CookieStoreCommand::LOAD_COOKIES_FOR_KEY);
call1.WaitUntilDone();
- EXPECT_TRUE(call1.result().IsInclude());
+ EXPECT_TRUE(call1.result().status.IsInclude());
EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ADD; ", TakeCommandSummary());
- ResultSavingCookieCallback<CookieInclusionStatus> call2;
+ ResultSavingCookieCallback<CookieAccessResult> call2;
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "X=Y", base::Time::Now(),
base::nullopt /* server_time */),
http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
call2.MakeCallback());
ASSERT_TRUE(call2.was_run());
- EXPECT_TRUE(call2.result().IsInclude());
+ EXPECT_TRUE(call2.result().status.IsInclude());
EXPECT_EQ("ADD; ", TakeCommandSummary());
}
@@ -1020,21 +1020,21 @@ TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
false, true, CookieSameSite::NO_RESTRICTION,
COOKIE_PRIORITY_DEFAULT));
- ResultSavingCookieCallback<CookieInclusionStatus> call1;
+ ResultSavingCookieCallback<CookieAccessResult> call1;
cookie_monster_->SetAllCookiesAsync(list, call1.MakeCallback());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(call1.was_run());
ExecuteLoads(CookieStoreCommand::LOAD);
call1.WaitUntilDone();
- EXPECT_TRUE(call1.result().IsInclude());
+ EXPECT_TRUE(call1.result().status.IsInclude());
EXPECT_EQ("LOAD; ADD; ADD; ", TakeCommandSummary());
// 2nd set doesn't need to read from store. It erases the old cookies, though.
- ResultSavingCookieCallback<CookieInclusionStatus> call2;
+ ResultSavingCookieCallback<CookieAccessResult> call2;
cookie_monster_->SetAllCookiesAsync(list, call2.MakeCallback());
ASSERT_TRUE(call2.was_run());
- EXPECT_TRUE(call2.result().IsInclude());
+ EXPECT_TRUE(call2.result().status.IsInclude());
EXPECT_EQ("REMOVE; REMOVE; ADD; ADD; ", TakeCommandSummary());
}
@@ -1232,7 +1232,7 @@ TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
bool get_cookie_list_callback_was_run = false;
GetCookieListCallback get_cookie_list_callback_deferred;
- ResultSavingCookieCallback<CookieInclusionStatus> set_cookies_callback;
+ ResultSavingCookieCallback<CookieAccessResult> set_cookies_callback;
base::RunLoop run_loop;
cookie_monster_->GetCookieListWithOptionsAsync(
http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
@@ -1273,7 +1273,7 @@ TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ADD; ", TakeCommandSummary());
EXPECT_TRUE(get_cookie_list_callback_was_run);
ASSERT_TRUE(set_cookies_callback.was_run());
- EXPECT_TRUE(set_cookies_callback.result().IsInclude());
+ EXPECT_TRUE(set_cookies_callback.result().status.IsInclude());
ASSERT_TRUE(get_cookie_list_callback_deferred.was_run());
EXPECT_THAT(get_cookie_list_callback_deferred.cookies(),
@@ -1487,38 +1487,38 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
base::Optional<base::Time> server_time = base::nullopt;
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_url, "x=1").IsInclude());
- EXPECT_TRUE(SetCanonicalCookieReturnStatus(
+ EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
cm.get(),
CanonicalCookie::Create(http_url, "y=1", now, server_time),
http_url, false /*modify_httponly*/)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), foo_url, "x=1")
.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
- EXPECT_TRUE(SetCanonicalCookieReturnStatus(
+ EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
cm.get(),
CanonicalCookie::Create(foo_url, "y=1", now, server_time),
foo_url, false /*modify_httponly*/)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm_foo.get(), foo_url, "x=1").IsInclude());
- EXPECT_TRUE(SetCanonicalCookieReturnStatus(
+ EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
cm_foo.get(),
CanonicalCookie::Create(foo_url, "y=1", now, server_time),
foo_url, false /*modify_httponly*/)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm_foo.get(), http_url, "x=1")
.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
- EXPECT_TRUE(SetCanonicalCookieReturnStatus(
+ EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
cm_foo.get(),
CanonicalCookie::Create(http_url, "y=1", now, server_time),
http_url, false /*modify_httponly*/)
- .HasExactlyExclusionReasonsForTesting(
+ .status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
}
@@ -2234,7 +2234,7 @@ TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
auto cookie = CanonicalCookie::Create(kUrl, "a=b", base::Time::Now(),
base::nullopt /* server_time */);
- ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
+ ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback());
@@ -2254,7 +2254,7 @@ TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
// The tasks should run in order, and the get should see the cookies.
set_cookie_callback.WaitUntilDone();
- EXPECT_TRUE(set_cookie_callback.result().IsInclude());
+ EXPECT_TRUE(set_cookie_callback.result().status.IsInclude());
get_cookies_callback1.WaitUntilDone();
EXPECT_EQ(1u, get_cookies_callback1.cookies().size());
@@ -2322,7 +2322,7 @@ TEST_F(CookieMonsterTest, WhileLoadingGetAllSetGetAll) {
auto cookie = CanonicalCookie::Create(kUrl, "a=b", base::Time::Now(),
base::nullopt /* server_time */);
- ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
+ ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback());
@@ -2341,7 +2341,7 @@ TEST_F(CookieMonsterTest, WhileLoadingGetAllSetGetAll) {
EXPECT_EQ(0u, get_cookies_callback1.cookies().size());
set_cookie_callback.WaitUntilDone();
- EXPECT_TRUE(set_cookie_callback.result().IsInclude());
+ EXPECT_TRUE(set_cookie_callback.result().status.IsInclude());
get_cookies_callback2.WaitUntilDone();
EXPECT_EQ(1u, get_cookies_callback2.cookies().size());
@@ -2369,7 +2369,7 @@ TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
// Get all cookies task that queues a task to set a cookie when executed.
auto cookie = CanonicalCookie::Create(kUrl, "a=b", base::Time::Now(),
base::nullopt /* server_time */);
- ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
+ ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
cm->GetAllCookiesAsync(base::BindOnce(
&RunClosureOnAllCookiesReceived,
base::BindOnce(&CookieStore::SetCanonicalCookieAsync,
@@ -2394,7 +2394,7 @@ TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
EXPECT_EQ(0u, get_cookies_callback1.cookies().size());
set_cookie_callback.WaitUntilDone();
- EXPECT_TRUE(set_cookie_callback.result().IsInclude());
+ EXPECT_TRUE(set_cookie_callback.result().status.IsInclude());
// A subsequent get cookies call should see the new cookie.
GetAllCookiesCallback get_cookies_callback2;
@@ -2859,10 +2859,10 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
auto preexisting_cookie = CanonicalCookie::Create(
https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now(),
base::nullopt /* server_time */);
- CookieInclusionStatus status = SetCanonicalCookieReturnStatus(
+ CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
true /* can_modify_httponly */);
- ASSERT_TRUE(status.IsInclude());
+ ASSERT_TRUE(access_result.status.IsInclude());
// Set a new cookie with a different name. Should work because cookies with
// different names are not considered equivalent nor "equivalent for secure
@@ -2879,10 +2879,10 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
base::nullopt /* server_time */);
// Allow modifying HttpOnly, so that we don't skip preexisting cookies for
// being HttpOnly.
- status = SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
- http_www_foo_.url(),
- true /* can_modify_httponly */);
- EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ access_result = SetCanonicalCookieReturnAccessResult(
+ cm.get(), std::move(bad_cookie), http_www_foo_.url(),
+ true /* can_modify_httponly */);
+ EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// The preexisting cookie should still be there.
EXPECT_THAT(GetCookiesWithOptions(cm.get(), https_www_foo_.url(),
@@ -2910,10 +2910,10 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
base::nullopt /* server_time */);
// Allow modifying HttpOnly, so that we don't skip preexisting cookies for
// being HttpOnly.
- status = SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
- http_www_foo_.url(),
- true /* can_modify_httponly */);
- EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ access_result = SetCanonicalCookieReturnAccessResult(
+ cm.get(), std::move(bad_cookie), http_www_foo_.url(),
+ true /* can_modify_httponly */);
+ EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// The preexisting cookie should still be there.
EXPECT_THAT(GetCookiesWithOptions(cm.get(), https_www_foo_.url(),
@@ -2938,10 +2938,10 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
bad_cookie = CanonicalCookie::Create(https_www_foo_.url(), "A=E; Secure",
base::Time::Now(),
base::nullopt /* server_time */);
- status = SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
- https_www_foo_.url(),
- false /* can_modify_httponly */);
- EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ access_result = SetCanonicalCookieReturnAccessResult(
+ cm.get(), std::move(bad_cookie), https_www_foo_.url(),
+ false /* can_modify_httponly */);
+ EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
entries = net_log_.GetEntries();
@@ -2962,20 +2962,20 @@ TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) {
auto preexisting_cookie = CanonicalCookie::Create(
https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now(),
base::nullopt /* server_time */);
- CookieInclusionStatus status = SetCanonicalCookieReturnStatus(
+ CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
true /* can_modify_httponly */);
- ASSERT_TRUE(status.IsInclude());
+ ASSERT_TRUE(access_result.status.IsInclude());
// Attempt to set a new cookie with the same name that is not Secure or
// Httponly from an insecure scheme.
auto cookie =
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
base::nullopt /* server_time */);
- status = SetCanonicalCookieReturnStatus(cm.get(), std::move(cookie),
- http_www_foo_.url(),
- false /* can_modify_httponly */);
- EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ access_result = SetCanonicalCookieReturnAccessResult(
+ cm.get(), std::move(cookie), http_www_foo_.url(),
+ false /* can_modify_httponly */);
+ EXPECT_TRUE(access_result.status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE,
CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
@@ -2997,18 +2997,18 @@ TEST_F(CookieMonsterTest, DontDeleteEquivalentCookieIfSetIsRejected) {
auto preexisting_cookie = CanonicalCookie::Create(
http_www_foo_.url(), "cookie=foo", base::Time::Now(),
base::nullopt /* server_time */);
- CookieInclusionStatus status = SetCanonicalCookieReturnStatus(
+ CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
cm.get(), std::move(preexisting_cookie), http_www_foo_.url(),
false /* can_modify_httponly */);
- ASSERT_TRUE(status.IsInclude());
+ ASSERT_TRUE(access_result.status.IsInclude());
auto bad_cookie = CanonicalCookie::Create(
http_www_foo_.url(), "cookie=bar;secure", base::Time::Now(),
base::nullopt /* server_time */);
- CookieInclusionStatus status2 = SetCanonicalCookieReturnStatus(
+ CookieAccessResult access_result2 = SetCanonicalCookieReturnAccessResult(
cm.get(), std::move(bad_cookie), http_www_foo_.url(),
false /* can_modify_httponly */);
- EXPECT_TRUE(status2.HasExactlyExclusionReasonsForTesting(
+ EXPECT_TRUE(access_result2.status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
// Check that the original cookie is still there.
@@ -3613,7 +3613,7 @@ TEST_F(CookieMonsterTest, SetCanonicalCookieDoesNotBlockForLoadAll) {
CookieMonster cm(persistent_store.get(), nullptr);
// Start of a canonical cookie set.
- ResultSavingCookieCallback<CookieInclusionStatus> callback_set;
+ ResultSavingCookieCallback<CookieAccessResult> callback_set;
GURL cookie_url("http://a.com/");
cm.SetCanonicalCookieAsync(
CanonicalCookie::Create(cookie_url, "A=B", base::Time::Now(),
@@ -3699,14 +3699,14 @@ TEST_F(CookieMonsterTest, DeleteCookieWithInheritedTimestamps) {
// Write a cookie created at |t1|.
auto cookie = CanonicalCookie::Create(url, cookie_line, t1, server_time);
- ResultSavingCookieCallback<CookieInclusionStatus> set_callback_1;
+ ResultSavingCookieCallback<CookieAccessResult> set_callback_1;
cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
set_callback_1.MakeCallback());
set_callback_1.WaitUntilDone();
// Overwrite the cookie at |t2|.
cookie = CanonicalCookie::Create(url, cookie_line, t2, server_time);
- ResultSavingCookieCallback<CookieInclusionStatus> set_callback_2;
+ ResultSavingCookieCallback<CookieAccessResult> set_callback_2;
cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
set_callback_2.MakeCallback());
set_callback_2.WaitUntilDone();
@@ -3739,11 +3739,11 @@ TEST_F(CookieMonsterTest, RejectCreatedSameSiteCookieOnSet) {
ASSERT_TRUE(status.IsInclude());
// ... but the environment is checked on set, so this may be rejected then.
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cm.SetCanonicalCookieAsync(std::move(cookie), url, env_cross_site,
callback.MakeCallback());
callback.WaitUntilDone();
- EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
+ EXPECT_TRUE(callback.result().status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
}
@@ -3763,12 +3763,12 @@ TEST_F(CookieMonsterTest, RejectCreatedSecureCookieOnSet) {
ASSERT_TRUE(status.IsInclude());
// Cookie is rejected when attempting to set from a non-secure scheme.
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cm.SetCanonicalCookieAsync(std::move(cookie), http_url,
CookieOptions::MakeAllInclusive(),
callback.MakeCallback());
callback.WaitUntilDone();
- EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
+ EXPECT_TRUE(callback.result().status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
}
@@ -3793,11 +3793,11 @@ TEST_F(CookieMonsterTest, RejectCreatedHttpOnlyCookieOnSet) {
CookieOptions::SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
options_no_httponly.set_exclude_httponly(); // Default, but make it explicit.
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cm.SetCanonicalCookieAsync(std::move(cookie), url, options_no_httponly,
callback.MakeCallback());
callback.WaitUntilDone();
- EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
+ EXPECT_TRUE(callback.result().status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
}
@@ -3910,16 +3910,15 @@ TEST_F(CookieMonsterTest, CookiesWithoutSameSiteMustBeSecure) {
base::nullopt /* server_time */);
// Make a copy so we can delete it after the test.
CanonicalCookie cookie_copy = *cookie;
- CookieInclusionStatus result = SetCanonicalCookieReturnStatus(
+ CookieAccessResult result = SetCanonicalCookieReturnAccessResult(
cm.get(), std::move(cookie), url,
true /* can_modify_httponly (irrelevant) */);
- EXPECT_EQ(test.expected_set_cookie_result, result)
+ EXPECT_EQ(test.expected_set_cookie_result, result.status)
<< "Test case " << i << " failed.";
- if (result.IsInclude()) {
+ if (result.status.IsInclude()) {
auto cookies = GetAllCookiesForURL(cm.get(), url);
ASSERT_EQ(1u, cookies.size());
- EXPECT_EQ(test.expected_effective_samesite,
- cookies[0].GetEffectiveSameSiteForTesting())
+ EXPECT_EQ(test.expected_effective_samesite, result.effective_same_site)
<< "Test case " << i << " failed.";
DeleteCanonicalCookie(cm.get(), cookie_copy);
}
diff --git a/chromium/net/cookies/cookie_store.h b/chromium/net/cookies/cookie_store.h
index 47f2942cd32..5ffbe648343 100644
--- a/chromium/net/cookies/cookie_store.h
+++ b/chromium/net/cookies/cookie_store.h
@@ -19,8 +19,8 @@
#include "net/base/net_export.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_delegate.h"
+#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_deletion_info.h"
-#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_options.h"
class GURL;
@@ -55,7 +55,7 @@ class NET_EXPORT CookieStore {
const CookieList& cookies,
const std::vector<CookieAccessSemantics>& access_semantics_list)>;
using SetCookiesCallback =
- base::OnceCallback<void(CookieInclusionStatus status)>;
+ base::OnceCallback<void(CookieAccessResult access_result)>;
using DeleteCallback = base::OnceCallback<void(uint32_t num_deleted)>;
using SetCookieableSchemesCallback = base::OnceCallback<void(bool success)>;
diff --git a/chromium/net/cookies/cookie_store_change_unittest.h b/chromium/net/cookies/cookie_store_change_unittest.h
index ba3767fd677..d2259dcfb3e 100644
--- a/chromium/net/cookies/cookie_store_change_unittest.h
+++ b/chromium/net/cookies/cookie_store_change_unittest.h
@@ -691,16 +691,20 @@ TYPED_TEST_P(CookieStoreChangeGlobalTest, ChangeIncludesCookieAccessSemantics) {
EXPECT_EQ("domain1.test", cookie_changes[0].cookie.Domain());
EXPECT_TRUE(this->IsExpectedAccessSemantics(
- CookieAccessSemantics::LEGACY, cookie_changes[0].access_semantics));
+ CookieAccessSemantics::LEGACY,
+ cookie_changes[0].access_result.access_semantics));
EXPECT_EQ("domain2.test", cookie_changes[1].cookie.Domain());
EXPECT_TRUE(this->IsExpectedAccessSemantics(
- CookieAccessSemantics::NONLEGACY, cookie_changes[1].access_semantics));
+ CookieAccessSemantics::NONLEGACY,
+ cookie_changes[1].access_result.access_semantics));
EXPECT_EQ("domain3.test", cookie_changes[2].cookie.Domain());
EXPECT_TRUE(this->IsExpectedAccessSemantics(
- CookieAccessSemantics::UNKNOWN, cookie_changes[2].access_semantics));
+ CookieAccessSemantics::UNKNOWN,
+ cookie_changes[2].access_result.access_semantics));
EXPECT_EQ("domain4.test", cookie_changes[3].cookie.Domain());
EXPECT_TRUE(this->IsExpectedAccessSemantics(
- CookieAccessSemantics::UNKNOWN, cookie_changes[3].access_semantics));
+ CookieAccessSemantics::UNKNOWN,
+ cookie_changes[3].access_result.access_semantics));
}
TYPED_TEST_P(CookieStoreChangeUrlTest, NoCookie) {
@@ -1715,7 +1719,8 @@ TYPED_TEST_P(CookieStoreChangeUrlTest, ChangeIncludesCookieAccessSemantics) {
EXPECT_EQ("domain1.test", cookie_changes[0].cookie.Domain());
EXPECT_TRUE(this->IsExpectedAccessSemantics(
- CookieAccessSemantics::LEGACY, cookie_changes[0].access_semantics));
+ CookieAccessSemantics::LEGACY,
+ cookie_changes[0].access_result.access_semantics));
}
TYPED_TEST_P(CookieStoreChangeNamedTest, NoCookie) {
@@ -2849,7 +2854,8 @@ TYPED_TEST_P(CookieStoreChangeNamedTest, ChangeIncludesCookieAccessSemantics) {
EXPECT_EQ("domain1.test", cookie_changes[0].cookie.Domain());
EXPECT_EQ("cookie", cookie_changes[0].cookie.Name());
EXPECT_TRUE(this->IsExpectedAccessSemantics(
- CookieAccessSemantics::LEGACY, cookie_changes[0].access_semantics));
+ CookieAccessSemantics::LEGACY,
+ cookie_changes[0].access_result.access_semantics));
}
REGISTER_TYPED_TEST_SUITE_P(CookieStoreChangeGlobalTest,
diff --git a/chromium/net/cookies/cookie_store_test_helpers.cc b/chromium/net/cookies/cookie_store_test_helpers.cc
index aae0c873540..2a541f5cd3d 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.cc
+++ b/chromium/net/cookies/cookie_store_test_helpers.cc
@@ -68,12 +68,13 @@ DelayedCookieMonster::DelayedCookieMonster()
: cookie_monster_(
new CookieMonster(nullptr /* store */, nullptr /* netlog */)),
did_run_(false),
- result_(CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE) {}
+ result_(CookieAccessResult(CookieInclusionStatus(
+ CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE))) {}
DelayedCookieMonster::~DelayedCookieMonster() = default;
void DelayedCookieMonster::SetCookiesInternalCallback(
- CookieInclusionStatus result) {
+ CookieAccessResult result) {
result_ = result;
did_run_ = true;
}
diff --git a/chromium/net/cookies/cookie_store_test_helpers.h b/chromium/net/cookies/cookie_store_test_helpers.h
index 5f9f03d15d4..269fd673b32 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.h
+++ b/chromium/net/cookies/cookie_store_test_helpers.h
@@ -86,7 +86,7 @@ class DelayedCookieMonster : public CookieStore {
private:
// Be called immediately from CookieMonster.
- void SetCookiesInternalCallback(CookieInclusionStatus result);
+ void SetCookiesInternalCallback(CookieAccessResult result);
void GetCookiesWithOptionsInternalCallback(const std::string& cookie);
void GetCookieListWithOptionsInternalCallback(
@@ -106,7 +106,7 @@ class DelayedCookieMonster : public CookieStore {
DelayedCookieMonsterChangeDispatcher change_dispatcher_;
bool did_run_;
- CookieInclusionStatus result_;
+ CookieAccessResult result_;
std::string cookie_;
std::string cookie_line_;
CookieAccessResultList cookie_access_result_list_;
diff --git a/chromium/net/cookies/cookie_store_unittest.h b/chromium/net/cookies/cookie_store_unittest.h
index 026ed96ba11..c2f495bedce 100644
--- a/chromium/net/cookies/cookie_store_unittest.h
+++ b/chromium/net/cookies/cookie_store_unittest.h
@@ -14,9 +14,9 @@
#include "base/bind.h"
#include "base/location.h"
-#include "base/message_loop/message_loop_current.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_tokenizer.h"
+#include "base/task/current_thread.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -127,7 +127,7 @@ class CookieStoreTest : public testing::Test {
http_bar_com_("http://bar.com") {
// This test may be used outside of the net test suite, and thus may not
// have a task environment.
- if (!base::MessageLoopCurrent::Get()) {
+ if (!base::CurrentThread::Get()) {
task_environment_ =
std::make_unique<base::test::SingleThreadTaskEnvironment>();
}
@@ -201,11 +201,11 @@ class CookieStoreTest : public testing::Test {
if (!cookie)
return false;
DCHECK(cs);
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
callback.MakeCallback());
callback.WaitUntilDone();
- return callback.result().IsInclude();
+ return callback.result().status.IsInclude();
}
bool SetCanonicalCookie(CookieStore* cs,
@@ -213,7 +213,7 @@ class CookieStoreTest : public testing::Test {
const GURL& source_url,
bool can_modify_httponly) {
DCHECK(cs);
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
CookieOptions options;
if (can_modify_httponly)
options.set_include_httponly();
@@ -222,7 +222,7 @@ class CookieStoreTest : public testing::Test {
cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
callback.MakeCallback());
callback.WaitUntilDone();
- return callback.result().IsInclude();
+ return callback.result().status.IsInclude();
}
bool SetCookieWithServerTime(CookieStore* cs,
@@ -268,20 +268,20 @@ class CookieStoreTest : public testing::Test {
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
DCHECK(cs);
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
callback.MakeCallback());
callback.WaitUntilDone();
- return callback.result();
+ return callback.result().status;
}
- CookieInclusionStatus SetCanonicalCookieReturnStatus(
+ CookieAccessResult SetCanonicalCookieReturnAccessResult(
CookieStore* cs,
std::unique_ptr<CanonicalCookie> cookie,
const GURL& source_url,
bool can_modify_httponly) {
DCHECK(cs);
- ResultSavingCookieCallback<CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieAccessResult> callback;
CookieOptions options;
if (can_modify_httponly)
options.set_include_httponly();
@@ -562,14 +562,15 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
// A secure source is required for setting secure cookies.
EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(
+ this->SetCanonicalCookieReturnAccessResult(
cs,
std::make_unique<CanonicalCookie>(
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), true)
- .HasExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
// A Secure cookie can be created from an insecure URL, but is rejected upon
// setting.
@@ -579,10 +580,10 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
base::nullopt /* server_time */, &status);
EXPECT_TRUE(cookie->IsSecure());
EXPECT_TRUE(status.IsInclude());
- EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(cs, std::move(cookie),
- this->http_www_foo_.url(), true)
- .HasExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
+ cs, std::move(cookie), this->http_www_foo_.url(), true)
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
// A secure source is also required for overwriting secure cookies. Writing
// a secure cookie then overwriting it from a non-secure source should fail.
@@ -595,28 +596,29 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
this->https_www_foo_.url(), true /* modify_http_only */));
EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(
+ this->SetCanonicalCookieReturnAccessResult(
cs,
std::make_unique<CanonicalCookie>(
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
base::Time(), true /* secure */, false /* httponly */,
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), true /* modify_http_only */)
- .HasExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
if (TypeParam::supports_http_only) {
// Permission to modify http only cookies is required to set an
// httponly cookie.
- EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(
- cs,
- std::make_unique<CanonicalCookie>(
- "G", "H", http_foo_host, "/unique", base::Time(),
- base::Time(), base::Time(), false /* secure */,
- true /* httponly */, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- this->http_www_foo_.url(), false /* modify_http_only */)
- .HasExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
+ EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
+ cs,
+ std::make_unique<CanonicalCookie>(
+ "G", "H", http_foo_host, "/unique", base::Time(),
+ base::Time(), base::Time(), false /* secure */,
+ true /* httponly */, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT),
+ this->http_www_foo_.url(), false /* modify_http_only */)
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
// A HttpOnly cookie can be created, but is rejected
// upon setting if the options do not specify include_httponly.
@@ -626,11 +628,11 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
base::nullopt /* server_time */, &create_status);
EXPECT_TRUE(c->IsHttpOnly());
EXPECT_TRUE(create_status.IsInclude());
- EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(cs, std::move(c),
- this->http_www_foo_.url(),
- false /* can_modify_httponly */)
- .HasExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
+ EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
+ cs, std::move(c), this->http_www_foo_.url(),
+ false /* can_modify_httponly */)
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
// Permission to modify httponly cookies is also required to overwrite
// an httponly cookie.
@@ -642,16 +644,16 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), true /* modify_http_only */));
- EXPECT_TRUE(
- this->SetCanonicalCookieReturnStatus(
- cs,
- std::make_unique<CanonicalCookie>(
- "G", "H", http_foo_host, "/unique", base::Time(),
- base::Time(), base::Time(), false /* secure */,
- true /* httponly */, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
- this->http_www_foo_.url(), false /* modify_http_only */)
- .HasExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
+ EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
+ cs,
+ std::make_unique<CanonicalCookie>(
+ "G", "H", http_foo_host, "/unique", base::Time(),
+ base::Time(), base::Time(), false /* secure */,
+ true /* httponly */, CookieSameSite::LAX_MODE,
+ COOKIE_PRIORITY_DEFAULT),
+ this->http_www_foo_.url(), false /* modify_http_only */)
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
} else {
// Leave store in same state as if the above tests had been run.
EXPECT_TRUE(this->SetCanonicalCookie(
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index 99859d89606..86735d1d510 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -14,6 +14,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/stl_util.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
@@ -331,23 +332,40 @@ base::Time ParseCookieExpirationTime(const std::string& time_string) {
return base::Time();
}
-GURL CookieOriginToURL(const std::string& domain, bool is_https) {
- if (domain.empty())
+GURL CookieDomainAndPathToURL(const std::string& domain,
+ const std::string& path,
+ const std::string& source_scheme) {
+ // Note: domain_no_dot could be empty for e.g. file cookies.
+ std::string domain_no_dot = CookieDomainAsHost(domain);
+ if (domain_no_dot.empty() || source_scheme.empty())
return GURL();
+ return GURL(base::StrCat(
+ {source_scheme, url::kStandardSchemeSeparator, domain_no_dot, path}));
+}
- const std::string scheme = is_https ? url::kHttpsScheme : url::kHttpScheme;
- return GURL(scheme + url::kStandardSchemeSeparator +
- CookieDomainAsHost(domain) + "/");
+GURL CookieDomainAndPathToURL(const std::string& domain,
+ const std::string& path,
+ bool is_https) {
+ return CookieDomainAndPathToURL(
+ domain, path,
+ std::string(is_https ? url::kHttpsScheme : url::kHttpScheme));
+}
+
+GURL CookieDomainAndPathToURL(const std::string& domain,
+ const std::string& path,
+ CookieSourceScheme source_scheme) {
+ return CookieDomainAndPathToURL(domain, path,
+ source_scheme == CookieSourceScheme::kSecure);
+}
+
+GURL CookieOriginToURL(const std::string& domain, bool is_https) {
+ return CookieDomainAndPathToURL(domain, "/", is_https);
}
GURL SimulatedCookieSource(const CanonicalCookie& cookie,
const std::string& source_scheme) {
- // Note: cookie.DomainWithoutDot() could be empty for e.g. file cookies.
- if (cookie.DomainWithoutDot().empty() || source_scheme.empty())
- return GURL();
-
- return GURL(source_scheme + url::kStandardSchemeSeparator +
- cookie.DomainWithoutDot() + cookie.Path());
+ return CookieDomainAndPathToURL(cookie.Domain(), cookie.Path(),
+ source_scheme);
}
bool IsDomainMatch(const std::string& domain, const std::string& host) {
@@ -657,12 +675,12 @@ bool DoesCreationTimeGrantLegacySemantics(base::Time creation_date) {
return (base::Time::Now() - creation_date) < recency_threshold;
}
-base::OnceCallback<void(CookieInclusionStatus)>
-AdaptCookieInclusionStatusToBool(base::OnceCallback<void(bool)> callback) {
+base::OnceCallback<void(CookieAccessResult)> AdaptCookieAccessResultToBool(
+ base::OnceCallback<void(bool)> callback) {
return base::BindOnce(
[](base::OnceCallback<void(bool)> inner_callback,
- const CookieInclusionStatus status) {
- bool success = status.IsInclude();
+ const CookieAccessResult access_result) {
+ bool success = access_result.status.IsInclude();
std::move(inner_callback).Run(success);
},
std::move(callback));
diff --git a/chromium/net/cookies/cookie_util.h b/chromium/net/cookies/cookie_util.h
index be3cd3f458d..b2b7992d03b 100644
--- a/chromium/net/cookies/cookie_util.h
+++ b/chromium/net/cookies/cookie_util.h
@@ -13,7 +13,7 @@
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/cookies/canonical_cookie.h"
-#include "net/cookies/cookie_inclusion_status.h"
+#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/site_for_cookies.h"
#include "url/origin.h"
@@ -81,6 +81,22 @@ NET_EXPORT std::string CookieDomainAsHost(const std::string& cookie_domain);
// Time::Max(), respectively.
NET_EXPORT base::Time ParseCookieExpirationTime(const std::string& time_string);
+// Get a cookie's URL from it's domain, path, and source scheme.
+// The first field can be the combined domain-and-host-only-flag (e.g. the
+// string returned by CanonicalCookie::Domain()) as opposed to the domain
+// attribute per RFC6265bis. The GURL is constructed after stripping off any
+// leading dot.
+// Note: the GURL returned by this method is not guaranteed to be valid.
+NET_EXPORT GURL CookieDomainAndPathToURL(const std::string& domain,
+ const std::string& path,
+ const std::string& source_scheme);
+NET_EXPORT GURL CookieDomainAndPathToURL(const std::string& domain,
+ const std::string& path,
+ bool is_https);
+NET_EXPORT GURL CookieDomainAndPathToURL(const std::string& domain,
+ const std::string& path,
+ CookieSourceScheme source_scheme);
+
// Convenience for converting a cookie origin (domain and https pair) to a URL.
NET_EXPORT GURL CookieOriginToURL(const std::string& domain, bool is_https);
@@ -230,14 +246,14 @@ bool DoesLastHttpSameSiteAccessGrantLegacySemantics(
// the feature param, and the creation time of the cookie.
bool DoesCreationTimeGrantLegacySemantics(base::Time creation_date);
-// Takes a callback accepting a CookieInclusionStatus and returns a callback
+// Takes a callback accepting a CookieAccessResult and returns a callback
// that accepts a bool, setting the bool to true if the CookieInclusionStatus
-// was set to "include", else sending false.
+// in CookieAccessResult was set to "include", else sending false.
//
// Can be used with SetCanonicalCookie when you don't need to know why a cookie
// was blocked, only whether it was blocked.
-NET_EXPORT base::OnceCallback<void(CookieInclusionStatus)>
-AdaptCookieInclusionStatusToBool(base::OnceCallback<void(bool)> callback);
+NET_EXPORT base::OnceCallback<void(CookieAccessResult)>
+AdaptCookieAccessResultToBool(base::OnceCallback<void(bool)> callback);
// Turn a CookieAccessResultList into a CookieList by stripping out access
// results (for callers who only care about cookies).
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index 14f8edf50f7..8093a6f440e 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -225,6 +225,36 @@ TEST(CookieUtilTest, TestRequestCookieParsing) {
}
}
+TEST(CookieUtilTest, CookieDomainAndPathToURL) {
+ struct {
+ std::string domain;
+ std::string path;
+ bool is_https;
+ std::string expected_url;
+ } kTests[]{
+ {"a.com", "/", true, "https://a.com/"},
+ {"a.com", "/", false, "http://a.com/"},
+ {".a.com", "/", true, "https://a.com/"},
+ {".a.com", "/", false, "http://a.com/"},
+ {"b.a.com", "/", true, "https://b.a.com/"},
+ {"b.a.com", "/", false, "http://b.a.com/"},
+ {"a.com", "/example/path", true, "https://a.com/example/path"},
+ {".a.com", "/example/path", false, "http://a.com/example/path"},
+ {"b.a.com", "/example/path", true, "https://b.a.com/example/path"},
+ {".b.a.com", "/example/path", false, "http://b.a.com/example/path"},
+ };
+
+ for (auto& test : kTests) {
+ GURL url1 = cookie_util::CookieDomainAndPathToURL(test.domain, test.path,
+ test.is_https);
+ GURL url2 = cookie_util::CookieDomainAndPathToURL(
+ test.domain, test.path, std::string(test.is_https ? "https" : "http"));
+ // Test both overloads for equality.
+ EXPECT_EQ(url1, url2);
+ EXPECT_EQ(url1, GURL(test.expected_url));
+ }
+}
+
TEST(CookieUtilTest, SimulatedCookieSource) {
GURL secure_url("https://b.a.com");
GURL insecure_url("http://b.a.com");
@@ -1211,16 +1241,17 @@ TEST(CookieUtilTest, TestComputeSameSiteContextForSubresource) {
false /* force_ignore_site_for_cookies */));
}
-TEST(CookieUtilTest, AdaptCookieInclusionStatusToBool) {
+TEST(CookieUtilTest, AdaptCookieAccessResultToBool) {
bool result_out = true;
base::OnceCallback<void(bool)> callback = base::BindLambdaForTesting(
[&result_out](bool result) { result_out = result; });
- base::OnceCallback<void(CookieInclusionStatus)> adapted_callback =
- cookie_util::AdaptCookieInclusionStatusToBool(std::move(callback));
+ base::OnceCallback<void(CookieAccessResult)> adapted_callback =
+ cookie_util::AdaptCookieAccessResultToBool(std::move(callback));
std::move(adapted_callback)
- .Run(CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
+ .Run(CookieAccessResult(
+ CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR)));
EXPECT_FALSE(result_out);
@@ -1229,9 +1260,9 @@ TEST(CookieUtilTest, AdaptCookieInclusionStatusToBool) {
[&result_out](bool result) { result_out = result; });
adapted_callback =
- cookie_util::AdaptCookieInclusionStatusToBool(std::move(callback));
+ cookie_util::AdaptCookieAccessResultToBool(std::move(callback));
- std::move(adapted_callback).Run(CookieInclusionStatus());
+ std::move(adapted_callback).Run(CookieAccessResult());
EXPECT_TRUE(result_out);
}