xref: /aosp_15_r20/external/cronet/net/cookies/cookie_store_unittest.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_COOKIES_COOKIE_STORE_UNITTEST_H_
6 #define NET_COOKIES_COOKIE_STORE_UNITTEST_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <optional>
12 #include <set>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
17 #include "base/functional/bind.h"
18 #include "base/strings/string_tokenizer.h"
19 #include "base/task/current_thread.h"
20 #include "base/task/single_thread_task_runner.h"
21 #include "base/test/task_environment.h"
22 #include "base/threading/thread.h"
23 #include "base/time/time.h"
24 #include "build/build_config.h"
25 #include "net/cookies/canonical_cookie.h"
26 #include "net/cookies/cookie_store.h"
27 #include "net/cookies/cookie_store_test_callbacks.h"
28 #include "net/cookies/cookie_store_test_helpers.h"
29 #include "net/cookies/test_cookie_access_delegate.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "url/gurl.h"
32 
33 #if BUILDFLAG(IS_IOS)
34 #include "base/ios/ios_util.h"
35 #endif
36 
37 // This file declares unittest templates that can be used to test common
38 // behavior of any CookieStore implementation.
39 // See cookie_monster_unittest.cc for an example of an implementation.
40 
41 namespace net {
42 
43 using base::Thread;
44 using TimeRange = CookieDeletionInfo::TimeRange;
45 
46 const int kTimeout = 1000;
47 
48 const char kValidCookieLine[] = "A=B; path=/";
49 
50 // The CookieStoreTestTraits must have the following members:
51 // struct CookieStoreTestTraits {
52 //   // Factory function. Will be called at most once per test.
53 //   static std::unique_ptr<CookieStore> Create();
54 //
55 //   // Drains the run loop(s) used to deliver cookie change notifications.
56 //   static void DeliverChangeNotifications();
57 //
58 //   // The cookie store supports cookies with the exclude_httponly() option.
59 //   static const bool supports_http_only;
60 //
61 //   // The cookie store is able to make the difference between the ".com"
62 //   // and the "com" domains.
63 //   static const bool supports_non_dotted_domains;
64 //
65 //   // The cookie store does not fold domains with trailing dots (so "com." and
66 //   "com" are different domains).
67 //   static const bool preserves_trailing_dots;
68 //
69 //   // The cookie store rejects cookies for invalid schemes such as ftp.
70 //   static const bool filters_schemes;
71 //
72 //   // The cookie store has a bug happening when a path is a substring of
73 //   // another.
74 //   static const bool has_path_prefix_bug;
75 //
76 //   // The cookie store forbids setting a cookie with an empty name.
77 //   static const bool forbids_setting_empty_name;
78 //
79 //   // The cookie store supports global tracking of cookie changes (i.e.
80 //   // calls to CookieStore::AddCallbackForAllChanges()).
81 //   static const bool supports_global_cookie_tracking;
82 //
83 //   // The cookie store supports tracking of cookie changes for an URL (i.e.
84 //   // calls to CookieStore::AddCallbackForUrl()).
85 //   static const bool supports_url_cookie_tracking;
86 //
87 //   // The cookie store supports tracking of named cookie changes (i.e.
88 //   // calls to CookieStore::AddCallbackForCookie()).
89 //   static const bool supports_named_cookie_tracking;
90 //
91 //   // The cookie store supports more than one callback per cookie change type.
92 //   static const bool supports_multiple_tracking_callbacks;
93 //
94 //   // The cookie store correctly distinguishes between OVERWRITE and EXPLICIT
95 //   // (deletion) change causes.
96 //   static const bool has_exact_change_cause;
97 //
98 //   // The cookie store is guaranteed to deliver cookie changes in the order
99 //   // in which calls were issued. This only applies to changes coming from
100 //   // _different_ calls. If a call results in a cookie overwrite, the deletion
101 //   // change must still be issued before the insertion change.
102 //   static const bool has_exact_change_ordering;
103 //
104 //   // Time to wait between two cookie insertions to ensure that cookies have
105 //   // different creation times.
106 //   static const int creation_time_granularity_in_ms;
107 //
108 //   // The cookie store supports setting a CookieAccessDelegate and using it to
109 //   // get the access semantics for each cookie via
110 //   // CookieStore::GetAllCookiesWithAccessSemanticsAsync().
111 //   // If this is not supported, all access semantics will show up as UNKNOWN.
112 //   static const bool supports_cookie_access_semantics;
113 // };
114 
115 template <class CookieStoreTestTraits>
116 class CookieStoreTest : public testing::Test {
117  protected:
CookieStoreTest()118   CookieStoreTest()
119       : http_www_foo_("http://www.foo.com"),
120         http_bar_foo_("http://bar.foo.com"),
121         http_www_bar_("http://www.bar.com"),
122         https_www_foo_("https://www.foo.com"),
123         ftp_foo_("ftp://ftp.foo.com/"),
124         ws_www_foo_("ws://www.foo.com"),
125         wss_www_foo_("wss://www.foo.com"),
126         www_foo_foo_("http://www.foo.com/foo"),
127         www_foo_bar_("http://www.foo.com/bar"),
128         http_baz_com_("http://baz.com"),
129         http_bar_com_("http://bar.com"),
130         https_www_bar_("https://www.bar.com") {
131     // This test may be used outside of the net test suite, and thus may not
132     // have a task environment.
133     if (!base::CurrentThread::Get()) {
134       task_environment_ =
135           std::make_unique<base::test::SingleThreadTaskEnvironment>();
136     }
137   }
138 
139   // Helper methods for the asynchronous Cookie Store API that call the
140   // asynchronous method and then pump the loop until the callback is invoked,
141   // finally returning the value.
142   // TODO(chlily): Consolidate some of these.
143 
144   std::string GetCookies(
145       CookieStore* cs,
146       const GURL& url,
147       const CookiePartitionKeyCollection& cookie_partition_key_collection =
148           CookiePartitionKeyCollection()) {
149     DCHECK(cs);
150     CookieOptions options;
151     if (!CookieStoreTestTraits::supports_http_only)
152       options.set_include_httponly();
153     options.set_same_site_cookie_context(
154         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
155     return GetCookiesWithOptions(cs, url, options,
156                                  cookie_partition_key_collection);
157   }
158 
159   std::string GetCookiesWithOptions(
160       CookieStore* cs,
161       const GURL& url,
162       const CookieOptions& options,
163       const CookiePartitionKeyCollection& cookie_partition_key_collection =
164           CookiePartitionKeyCollection()) {
165     return CanonicalCookie::BuildCookieLine(GetCookieListWithOptions(
166         cs, url, options, cookie_partition_key_collection));
167   }
168 
169   CookieList GetCookieListWithOptions(
170       CookieStore* cs,
171       const GURL& url,
172       const CookieOptions& options,
173       const CookiePartitionKeyCollection& cookie_partition_key_collection =
174           CookiePartitionKeyCollection()) {
175     DCHECK(cs);
176     GetCookieListCallback callback;
177     cs->GetCookieListWithOptionsAsync(
178         url, options, cookie_partition_key_collection, callback.MakeCallback());
179     callback.WaitUntilDone();
180     return callback.cookies();
181   }
182 
183   // This does not update the access time on the cookies.
184   CookieList GetAllCookiesForURL(
185       CookieStore* cs,
186       const GURL& url,
187       const CookiePartitionKeyCollection& cookie_partition_key_collection =
188           CookiePartitionKeyCollection()) {
189     return GetCookieListWithOptions(cs, url, CookieOptions::MakeAllInclusive(),
190                                     cookie_partition_key_collection);
191   }
192 
193   // This does not update the access time on the cookies.
GetExcludedCookiesForURL(CookieStore * cs,const GURL & url,const CookiePartitionKeyCollection & cookie_partition_key_collection)194   CookieAccessResultList GetExcludedCookiesForURL(
195       CookieStore* cs,
196       const GURL& url,
197       const CookiePartitionKeyCollection& cookie_partition_key_collection) {
198     DCHECK(cs);
199     GetCookieListCallback callback;
200     CookieOptions options = CookieOptions::MakeAllInclusive();
201     options.set_return_excluded_cookies();
202     cs->GetCookieListWithOptionsAsync(
203         url, options, cookie_partition_key_collection, callback.MakeCallback());
204     callback.WaitUntilDone();
205     return callback.excluded_cookies();
206   }
207 
GetAllCookies(CookieStore * cs)208   CookieList GetAllCookies(CookieStore* cs) {
209     DCHECK(cs);
210     GetAllCookiesCallback callback;
211     cs->GetAllCookiesAsync(callback.MakeCallback());
212     callback.WaitUntilDone();
213     return callback.cookies();
214   }
215 
216   bool CreateAndSetCookie(
217       CookieStore* cs,
218       const GURL& url,
219       const std::string& cookie_line,
220       const CookieOptions& options,
221       std::optional<base::Time> server_time = std::nullopt,
222       std::optional<base::Time> system_time = std::nullopt,
223       std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt,
224       CookieSourceType source_type = CookieSourceType::kUnknown) {
225     // Ensure a different Creation date to guarantee sort order for testing
226     static base::Time last = base::Time::Min();
227     last = base::Time::Now() == last ? last + base::Microseconds(1)
228                                      : base::Time::Now();
229 
230     auto cookie = CanonicalCookie::Create(
231         url, cookie_line, system_time.value_or(last), server_time,
232         cookie_partition_key,
233         /*block_truncated=*/true, source_type, /*status=*/nullptr);
234 
235     if (!cookie)
236       return false;
237     DCHECK(cs);
238     ResultSavingCookieCallback<CookieAccessResult> callback;
239     cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
240                                 callback.MakeCallback());
241     callback.WaitUntilDone();
242     return callback.result().status.IsInclude();
243   }
244 
SetCanonicalCookie(CookieStore * cs,std::unique_ptr<CanonicalCookie> cookie,const GURL & source_url,bool can_modify_httponly)245   bool SetCanonicalCookie(CookieStore* cs,
246                           std::unique_ptr<CanonicalCookie> cookie,
247                           const GURL& source_url,
248                           bool can_modify_httponly) {
249     DCHECK(cs);
250     ResultSavingCookieCallback<CookieAccessResult> callback;
251     CookieOptions options;
252     if (can_modify_httponly)
253       options.set_include_httponly();
254     options.set_same_site_cookie_context(
255         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
256     cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
257                                 callback.MakeCallback());
258     callback.WaitUntilDone();
259     return callback.result().status.IsInclude();
260   }
261 
SetCookieWithSystemTime(CookieStore * cs,const GURL & url,const std::string & cookie_line,const base::Time & system_time)262   bool SetCookieWithSystemTime(CookieStore* cs,
263                                const GURL& url,
264                                const std::string& cookie_line,
265                                const base::Time& system_time) {
266     CookieOptions options;
267     if (!CookieStoreTestTraits::supports_http_only)
268       options.set_include_httponly();
269     options.set_same_site_cookie_context(
270         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
271     return CreateAndSetCookie(cs, url, cookie_line, options, std::nullopt,
272                               std::make_optional(system_time));
273   }
274 
SetCookieWithServerTime(CookieStore * cs,const GURL & url,const std::string & cookie_line,const base::Time & server_time)275   bool SetCookieWithServerTime(CookieStore* cs,
276                                const GURL& url,
277                                const std::string& cookie_line,
278                                const base::Time& server_time) {
279     CookieOptions options;
280     if (!CookieStoreTestTraits::supports_http_only)
281       options.set_include_httponly();
282     options.set_same_site_cookie_context(
283         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
284     return CreateAndSetCookie(cs, url, cookie_line, options,
285                               std::make_optional(server_time));
286   }
287 
288   bool SetCookie(
289       CookieStore* cs,
290       const GURL& url,
291       const std::string& cookie_line,
292       std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt,
293       CookieSourceType source_type = CookieSourceType::kUnknown) {
294     CookieOptions options;
295     if (!CookieStoreTestTraits::supports_http_only)
296       options.set_include_httponly();
297     options.set_same_site_cookie_context(
298         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
299     return CreateAndSetCookie(cs, url, cookie_line, options, std::nullopt,
300                               std::nullopt, cookie_partition_key, source_type);
301   }
302 
CreateAndSetCookieReturnStatus(CookieStore * cs,const GURL & url,const std::string & cookie_line)303   CookieInclusionStatus CreateAndSetCookieReturnStatus(
304       CookieStore* cs,
305       const GURL& url,
306       const std::string& cookie_line) {
307     CookieInclusionStatus create_status;
308     auto cookie = CanonicalCookie::Create(
309         url, cookie_line, base::Time::Now(), /*server_time=*/std::nullopt,
310         /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
311         CookieSourceType::kUnknown, &create_status);
312     if (!cookie)
313       return create_status;
314 
315     CookieOptions options;
316     if (!CookieStoreTestTraits::supports_http_only)
317       options.set_include_httponly();
318     // Allow setting SameSite cookies.
319     options.set_same_site_cookie_context(
320         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
321 
322     DCHECK(cs);
323     ResultSavingCookieCallback<CookieAccessResult> callback;
324     cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
325                                 callback.MakeCallback());
326     callback.WaitUntilDone();
327     return callback.result().status;
328   }
329 
SetCanonicalCookieReturnAccessResult(CookieStore * cs,std::unique_ptr<CanonicalCookie> cookie,const GURL & source_url,bool can_modify_httponly)330   CookieAccessResult SetCanonicalCookieReturnAccessResult(
331       CookieStore* cs,
332       std::unique_ptr<CanonicalCookie> cookie,
333       const GURL& source_url,
334       bool can_modify_httponly) {
335     DCHECK(cs);
336     ResultSavingCookieCallback<CookieAccessResult> callback;
337     CookieOptions options;
338     if (can_modify_httponly)
339       options.set_include_httponly();
340     options.set_same_site_cookie_context(
341         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
342     cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
343                                 callback.MakeCallback());
344     callback.WaitUntilDone();
345     return callback.result();
346   }
347 
DeleteCanonicalCookie(CookieStore * cs,const CanonicalCookie & cookie)348   uint32_t DeleteCanonicalCookie(CookieStore* cs,
349                                  const CanonicalCookie& cookie) {
350     DCHECK(cs);
351     ResultSavingCookieCallback<uint32_t> callback;
352     cs->DeleteCanonicalCookieAsync(cookie, callback.MakeCallback());
353     callback.WaitUntilDone();
354     return callback.result();
355   }
356 
DeleteCreatedInTimeRange(CookieStore * cs,const TimeRange & creation_range)357   uint32_t DeleteCreatedInTimeRange(CookieStore* cs,
358                                     const TimeRange& creation_range) {
359     DCHECK(cs);
360     ResultSavingCookieCallback<uint32_t> callback;
361     cs->DeleteAllCreatedInTimeRangeAsync(creation_range,
362                                          callback.MakeCallback());
363     callback.WaitUntilDone();
364     return callback.result();
365   }
366 
DeleteAllCreatedInTimeRange(CookieStore * cs,CookieDeletionInfo delete_info)367   uint32_t DeleteAllCreatedInTimeRange(CookieStore* cs,
368                                        CookieDeletionInfo delete_info) {
369     DCHECK(cs);
370     ResultSavingCookieCallback<uint32_t> callback;
371     cs->DeleteAllMatchingInfoAsync(std::move(delete_info),
372                                    callback.MakeCallback());
373     callback.WaitUntilDone();
374     return callback.result();
375   }
376 
DeleteSessionCookies(CookieStore * cs)377   uint32_t DeleteSessionCookies(CookieStore* cs) {
378     DCHECK(cs);
379     ResultSavingCookieCallback<uint32_t> callback;
380     cs->DeleteSessionCookiesAsync(callback.MakeCallback());
381     callback.WaitUntilDone();
382     return callback.result();
383   }
384 
DeleteAll(CookieStore * cs)385   uint32_t DeleteAll(CookieStore* cs) {
386     DCHECK(cs);
387     ResultSavingCookieCallback<uint32_t> callback;
388     cs->DeleteAllAsync(callback.MakeCallback());
389     callback.WaitUntilDone();
390     return callback.result();
391   }
392 
FindAndDeleteCookie(CookieStore * cs,const std::string & domain,const std::string & name)393   bool FindAndDeleteCookie(CookieStore* cs,
394                            const std::string& domain,
395                            const std::string& name) {
396     for (auto& cookie : this->GetAllCookies(cs)) {
397       if (cookie.Domain() == domain && cookie.Name() == name)
398         return this->DeleteCanonicalCookie(cs, cookie);
399     }
400 
401     return false;
402   }
403 
404   // Returns the CookieStore for the test - each test only uses one CookieStore.
GetCookieStore()405   CookieStore* GetCookieStore() {
406     if (!cookie_store_)
407       cookie_store_ = CookieStoreTestTraits::Create();
408     return cookie_store_.get();
409   }
410 
411   // Resets CookieStore.
ResetCookieStore()412   void ResetCookieStore() { cookie_store_.reset(); }
413 
414   // Compares two cookie lines.
MatchCookieLines(const std::string & line1,const std::string & line2)415   void MatchCookieLines(const std::string& line1, const std::string& line2) {
416     EXPECT_EQ(TokenizeCookieLine(line1), TokenizeCookieLine(line2));
417   }
418 
419   // Check the cookie line by polling until equality or a timeout is reached.
MatchCookieLineWithTimeout(CookieStore * cs,const GURL & url,const std::string & line)420   void MatchCookieLineWithTimeout(CookieStore* cs,
421                                   const GURL& url,
422                                   const std::string& line) {
423     std::string cookies = GetCookies(cs, url);
424     bool matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
425     base::Time polling_end_date =
426         base::Time::Now() +
427         base::Milliseconds(
428             CookieStoreTestTraits::creation_time_granularity_in_ms);
429 
430     while (!matched && base::Time::Now() <= polling_end_date) {
431       base::PlatformThread::Sleep(base::Milliseconds(10));
432       cookies = GetCookies(cs, url);
433       matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
434     }
435 
436     EXPECT_TRUE(matched) << "\"" << cookies << "\" does not match \"" << line
437                          << "\"";
438   }
439 
440   const CookieURLHelper http_www_foo_;
441   const CookieURLHelper http_bar_foo_;
442   const CookieURLHelper http_www_bar_;
443   const CookieURLHelper https_www_foo_;
444   const CookieURLHelper ftp_foo_;
445   const CookieURLHelper ws_www_foo_;
446   const CookieURLHelper wss_www_foo_;
447   const CookieURLHelper www_foo_foo_;
448   const CookieURLHelper www_foo_bar_;
449   const CookieURLHelper http_baz_com_;
450   const CookieURLHelper http_bar_com_;
451   const CookieURLHelper https_www_bar_;
452 
453   std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_;
454 
455  private:
456   // Returns a set of strings of type "name=value". Fails in case of duplicate.
TokenizeCookieLine(const std::string & line)457   std::set<std::string> TokenizeCookieLine(const std::string& line) {
458     std::set<std::string> tokens;
459     base::StringTokenizer tokenizer(line, " ;");
460     while (tokenizer.GetNext())
461       EXPECT_TRUE(tokens.insert(tokenizer.token()).second);
462     return tokens;
463   }
464 
465   std::unique_ptr<CookieStore> cookie_store_;
466 };
467 TYPED_TEST_SUITE_P(CookieStoreTest);
468 
TYPED_TEST_P(CookieStoreTest,FilterTest)469 TYPED_TEST_P(CookieStoreTest, FilterTest) {
470   CookieStore* cs = this->GetCookieStore();
471 
472   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
473   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
474   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
475 
476   std::unique_ptr<CanonicalCookie> cc(CanonicalCookie::CreateSanitizedCookie(
477       this->www_foo_foo_.url(), "A", "B", std::string(), "/foo", one_hour_ago,
478       one_hour_from_now, base::Time(), false, false,
479       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, std::nullopt,
480       /*status=*/nullptr));
481   ASSERT_TRUE(cc);
482   EXPECT_TRUE(this->SetCanonicalCookie(
483       cs, std::move(cc), this->www_foo_foo_.url(), true /*modify_httponly*/));
484 
485   // Note that for the creation time to be set exactly, without modification,
486   // it must be different from the one set by the line above.
487   cc = CanonicalCookie::CreateSanitizedCookie(
488       this->www_foo_bar_.url(), "C", "D", this->www_foo_bar_.domain(), "/bar",
489       two_hours_ago, base::Time(), one_hour_ago, false, true,
490       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, std::nullopt,
491       /*status=*/nullptr);
492   ASSERT_TRUE(cc);
493   EXPECT_TRUE(this->SetCanonicalCookie(
494       cs, std::move(cc), this->www_foo_bar_.url(), true /*modify_httponly*/));
495 
496   // We permit creating a a secure cookie with an HTTP URL (since the
497   // CookieAccessDelegate may permit some sites to be used as such for
498   // development environment purposes), but it can't actually be set in this
499   // test since no such delegate is configured here.
500   cc = CanonicalCookie::CreateSanitizedCookie(
501       this->http_www_foo_.url(), "E", "F", std::string(), std::string(),
502       base::Time(), base::Time(), base::Time(), true, false,
503       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
504       /*status=*/nullptr);
505   ASSERT_TRUE(cc);
506   EXPECT_FALSE(this->SetCanonicalCookie(
507       cs, std::move(cc), this->http_www_foo_.url(), true /*modify_httponly*/));
508 
509   cc = CanonicalCookie::CreateSanitizedCookie(
510       this->https_www_foo_.url(), "E", "F", std::string(), std::string(),
511       base::Time(), base::Time(), base::Time(), true, false,
512       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
513       /*status=*/nullptr);
514   ASSERT_TRUE(cc);
515   EXPECT_TRUE(this->SetCanonicalCookie(
516       cs, std::move(cc), this->https_www_foo_.url(), true /*modify_httponly*/));
517 
518   // Get all the cookies for a given URL, regardless of properties. This 'get()'
519   // operation shouldn't update the access time, as the test checks that the
520   // access time is set properly upon creation. Updating the access time would
521   // make that difficult.
522   CookieList cookies = this->GetAllCookiesForURL(cs, this->www_foo_foo_.url());
523   CookieList::iterator it = cookies.begin();
524 
525   ASSERT_TRUE(it != cookies.end());
526   EXPECT_EQ("A", it->Name());
527   EXPECT_EQ("B", it->Value());
528   EXPECT_EQ(this->www_foo_foo_.host(), it->Domain());
529   EXPECT_EQ("/foo", it->Path());
530   EXPECT_EQ(one_hour_ago, it->CreationDate());
531   EXPECT_TRUE(it->IsPersistent());
532   // Expect expiration date is in the right range.  Some cookie implementations
533   // may not record it with millisecond accuracy.
534   EXPECT_LE((one_hour_from_now - it->ExpiryDate()).magnitude().InSeconds(), 5);
535   // Some CookieStores don't store last access date.
536   if (!it->LastAccessDate().is_null())
537     EXPECT_EQ(one_hour_ago, it->LastAccessDate());
538   EXPECT_FALSE(it->SecureAttribute());
539   EXPECT_FALSE(it->IsHttpOnly());
540 
541   ASSERT_TRUE(++it == cookies.end());
542 
543   // Verify that the cookie was set as 'httponly' by passing in a CookieOptions
544   // that excludes them and getting an empty result.
545   if (TypeParam::supports_http_only) {
546     net::CookieOptions options;
547     options.set_same_site_cookie_context(
548         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
549     cookies =
550         this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(), options);
551     it = cookies.begin();
552     ASSERT_TRUE(it == cookies.end());
553   }
554 
555   // Get the cookie using the wide open |options|:
556   cookies = this->GetAllCookiesForURL(cs, this->www_foo_bar_.url());
557   it = cookies.begin();
558 
559   ASSERT_TRUE(it != cookies.end());
560   EXPECT_EQ("C", it->Name());
561   EXPECT_EQ("D", it->Value());
562   EXPECT_EQ(this->www_foo_bar_.Format(".%D"), it->Domain());
563   EXPECT_EQ("/bar", it->Path());
564   EXPECT_EQ(two_hours_ago, it->CreationDate());
565   EXPECT_FALSE(it->IsPersistent());
566   // Some CookieStores don't store last access date.
567   if (!it->LastAccessDate().is_null())
568     EXPECT_EQ(one_hour_ago, it->LastAccessDate());
569   EXPECT_FALSE(it->SecureAttribute());
570   EXPECT_TRUE(it->IsHttpOnly());
571 
572   EXPECT_TRUE(++it == cookies.end());
573 
574   cookies = this->GetAllCookiesForURL(cs, this->https_www_foo_.url());
575   it = cookies.begin();
576 
577   ASSERT_TRUE(it != cookies.end());
578   EXPECT_EQ("E", it->Name());
579   EXPECT_EQ("F", it->Value());
580   EXPECT_EQ("/", it->Path());
581   EXPECT_EQ(this->https_www_foo_.host(), it->Domain());
582   // Cookie should have its creation time set, and be in a reasonable range.
583   EXPECT_LE((base::Time::Now() - it->CreationDate()).magnitude().InMinutes(),
584             2);
585   EXPECT_FALSE(it->IsPersistent());
586   // Some CookieStores don't store last access date.
587   if (!it->LastAccessDate().is_null())
588     EXPECT_EQ(it->CreationDate(), it->LastAccessDate());
589   EXPECT_TRUE(it->SecureAttribute());
590   EXPECT_FALSE(it->IsHttpOnly());
591 
592   EXPECT_TRUE(++it == cookies.end());
593 }
594 
TYPED_TEST_P(CookieStoreTest,SetCanonicalCookieTest)595 TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
596   CookieStore* cs = this->GetCookieStore();
597 
598   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
599   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
600   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
601 
602   std::string foo_foo_host(this->www_foo_foo_.url().host());
603   std::string foo_bar_domain(this->www_foo_bar_.domain());
604   std::string http_foo_host(this->http_www_foo_.url().host());
605   std::string https_foo_host(this->https_www_foo_.url().host());
606 
607   EXPECT_TRUE(this->SetCanonicalCookie(
608       cs,
609       CanonicalCookie::CreateUnsafeCookieForTesting(
610           "A", "B", foo_foo_host, "/foo", one_hour_ago, one_hour_from_now,
611           base::Time(), base::Time(), false /* secure */, false /* httponly */,
612           CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
613       this->www_foo_foo_.url(), true));
614   EXPECT_TRUE(this->SetCanonicalCookie(
615       cs,
616       CanonicalCookie::CreateUnsafeCookieForTesting(
617           "C", "D", "." + foo_bar_domain, "/bar", two_hours_ago, base::Time(),
618           one_hour_ago, one_hour_ago, false, true, CookieSameSite::LAX_MODE,
619           COOKIE_PRIORITY_DEFAULT),
620       this->www_foo_bar_.url(), true));
621 
622   // A secure source is required for setting secure cookies.
623   EXPECT_TRUE(
624       this->SetCanonicalCookieReturnAccessResult(
625               cs,
626               CanonicalCookie::CreateUnsafeCookieForTesting(
627                   "E", "F", http_foo_host, "/", base::Time(), base::Time(),
628                   base::Time(), base::Time(), true, false,
629                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
630               this->http_www_foo_.url(), true)
631           .status.HasExclusionReason(
632               CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
633 
634   // A Secure cookie can be created from an insecure URL, but is rejected upon
635   // setting.
636   CookieInclusionStatus status;
637   auto cookie = CanonicalCookie::Create(
638       this->http_www_foo_.url(), "foo=1; Secure", base::Time::Now(),
639       /*server_time=*/std::nullopt, /*cookie_partition_key=*/std::nullopt,
640       /*block_truncated=*/true, CookieSourceType::kUnknown, &status);
641   EXPECT_TRUE(cookie->SecureAttribute());
642   EXPECT_TRUE(status.IsInclude());
643   EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
644                       cs, std::move(cookie), this->http_www_foo_.url(), true)
645                   .status.HasExclusionReason(
646                       CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
647 
648   // A secure source is also required for overwriting secure cookies.  Writing
649   // a secure cookie then overwriting it from a non-secure source should fail.
650   EXPECT_TRUE(this->SetCanonicalCookie(
651       cs,
652       CanonicalCookie::CreateUnsafeCookieForTesting(
653           "E", "F", https_foo_host, "/", base::Time(), base::Time(),
654           base::Time(), base::Time(), true /* secure */, false /* httponly */,
655           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
656       this->https_www_foo_.url(), true /* modify_http_only */));
657 
658   EXPECT_TRUE(
659       this->SetCanonicalCookieReturnAccessResult(
660               cs,
661               CanonicalCookie::CreateUnsafeCookieForTesting(
662                   "E", "F", http_foo_host, "/", base::Time(), base::Time(),
663                   base::Time(), base::Time(), true /* secure */,
664                   false /* httponly */, CookieSameSite::NO_RESTRICTION,
665                   COOKIE_PRIORITY_DEFAULT),
666               this->http_www_foo_.url(), true /* modify_http_only */)
667           .status.HasExclusionReason(
668               CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
669 
670   if (TypeParam::supports_http_only) {
671     // Permission to modify http only cookies is required to set an
672     // httponly cookie.
673     EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
674                         cs,
675                         CanonicalCookie::CreateUnsafeCookieForTesting(
676                             "G", "H", http_foo_host, "/unique", base::Time(),
677                             base::Time(), base::Time(), base::Time(),
678                             false /* secure */, true /* httponly */,
679                             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
680                         this->http_www_foo_.url(), false /* modify_http_only */)
681                     .status.HasExclusionReason(
682                         CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
683 
684     // A HttpOnly cookie can be created, but is rejected
685     // upon setting if the options do not specify include_httponly.
686     CookieInclusionStatus create_status;
687     auto c = CanonicalCookie::Create(
688         this->http_www_foo_.url(), "bar=1; HttpOnly", base::Time::Now(),
689         /*server_time=*/std::nullopt,
690         /*cookie_partition_key=*/std::nullopt,
691         /*block_truncated=*/true, CookieSourceType::kUnknown, &create_status);
692     EXPECT_TRUE(c->IsHttpOnly());
693     EXPECT_TRUE(create_status.IsInclude());
694     EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
695                         cs, std::move(c), this->http_www_foo_.url(),
696                         false /* can_modify_httponly */)
697                     .status.HasExclusionReason(
698                         CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
699 
700     // Permission to modify httponly cookies is also required to overwrite
701     // an httponly cookie.
702     EXPECT_TRUE(this->SetCanonicalCookie(
703         cs,
704         CanonicalCookie::CreateUnsafeCookieForTesting(
705             "G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
706             base::Time(), base::Time(), false /* secure */, true /* httponly */,
707             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
708         this->http_www_foo_.url(), true /* modify_http_only */));
709 
710     EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
711                         cs,
712                         CanonicalCookie::CreateUnsafeCookieForTesting(
713                             "G", "H", http_foo_host, "/unique", base::Time(),
714                             base::Time(), base::Time(), base::Time(),
715                             false /* secure */, true /* httponly */,
716                             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
717                         this->http_www_foo_.url(), false /* modify_http_only */)
718                     .status.HasExclusionReason(
719                         CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
720   } else {
721     // Leave store in same state as if the above tests had been run.
722     EXPECT_TRUE(this->SetCanonicalCookie(
723         cs,
724         CanonicalCookie::CreateUnsafeCookieForTesting(
725             "G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
726             base::Time(), base::Time(), false /* secure */, true /* httponly */,
727             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
728         this->http_www_foo_.url(), true /* modify_http_only */));
729   }
730 
731   // Get all the cookies for a given URL, regardless of properties. This 'get()'
732   // operation shouldn't update the access time, as the test checks that the
733   // access time is set properly upon creation. Updating the access time would
734   // make that difficult.
735   CookieList cookies = this->GetAllCookiesForURL(cs, this->www_foo_foo_.url());
736   CookieList::iterator it = cookies.begin();
737 
738   ASSERT_EQ(1u, cookies.size());
739   EXPECT_EQ("A", it->Name());
740   EXPECT_EQ("B", it->Value());
741   EXPECT_EQ(this->www_foo_foo_.host(), it->Domain());
742   EXPECT_EQ("/foo", it->Path());
743   EXPECT_EQ(one_hour_ago, it->CreationDate());
744   EXPECT_TRUE(it->IsPersistent());
745   // Expect expiration date is in the right range.  Some cookie implementations
746   // may not record it with millisecond accuracy.
747   EXPECT_LE((one_hour_from_now - it->ExpiryDate()).magnitude().InSeconds(), 5);
748   // Some CookieStores don't store last access date.
749   if (!it->LastAccessDate().is_null())
750     EXPECT_EQ(one_hour_ago, it->LastAccessDate());
751   EXPECT_FALSE(it->SecureAttribute());
752   EXPECT_FALSE(it->IsHttpOnly());
753 
754   // Get the cookie using the wide open |options|:
755   cookies = this->GetAllCookiesForURL(cs, this->www_foo_bar_.url());
756   ASSERT_EQ(1u, cookies.size());
757   it = cookies.begin();
758 
759   EXPECT_EQ("C", it->Name());
760   EXPECT_EQ("D", it->Value());
761   EXPECT_EQ(this->www_foo_bar_.Format(".%D"), it->Domain());
762   EXPECT_EQ("/bar", it->Path());
763   EXPECT_EQ(two_hours_ago, it->CreationDate());
764   EXPECT_FALSE(it->IsPersistent());
765   // Some CookieStores don't store last access date.
766   if (!it->LastAccessDate().is_null())
767     EXPECT_EQ(one_hour_ago, it->LastAccessDate());
768   EXPECT_FALSE(it->SecureAttribute());
769   EXPECT_TRUE(it->IsHttpOnly());
770 
771   cookies = this->GetAllCookiesForURL(cs, this->https_www_foo_.url());
772   ASSERT_EQ(1u, cookies.size());
773   it = cookies.begin();
774 
775   EXPECT_EQ("E", it->Name());
776   EXPECT_EQ("F", it->Value());
777   EXPECT_EQ("/", it->Path());
778   EXPECT_EQ(this->https_www_foo_.host(), it->Domain());
779   // Cookie should have its creation time set, and be in a reasonable range.
780   EXPECT_LE((base::Time::Now() - it->CreationDate()).magnitude().InMinutes(),
781             2);
782   EXPECT_FALSE(it->IsPersistent());
783   // Some CookieStores don't store last access date.
784   if (!it->LastAccessDate().is_null())
785     EXPECT_EQ(it->CreationDate(), it->LastAccessDate());
786   EXPECT_TRUE(it->SecureAttribute());
787   EXPECT_FALSE(it->IsHttpOnly());
788 }
789 
790 // Test enforcement around setting secure cookies.
TYPED_TEST_P(CookieStoreTest,SecureEnforcement)791 TYPED_TEST_P(CookieStoreTest, SecureEnforcement) {
792   CookieStore* cs = this->GetCookieStore();
793   GURL http_url(this->http_www_foo_.url());
794   std::string http_domain(http_url.host());
795   GURL https_url(this->https_www_foo_.url());
796   std::string https_domain(https_url.host());
797 
798   // Confirm that setting the secure attribute from an insecure source fails,
799   // but the other combinations work.
800   EXPECT_FALSE(this->SetCanonicalCookie(
801       cs,
802       CanonicalCookie::CreateUnsafeCookieForTesting(
803           "A", "B", http_domain, "/", base::Time::Now(), base::Time(),
804           base::Time(), base::Time(), true, false, CookieSameSite::STRICT_MODE,
805           COOKIE_PRIORITY_DEFAULT),
806       http_url, true /*modify_httponly*/));
807   EXPECT_TRUE(this->SetCanonicalCookie(
808       cs,
809       CanonicalCookie::CreateUnsafeCookieForTesting(
810           "A", "B", http_domain, "/", base::Time::Now(), base::Time(),
811           base::Time(), base::Time(), true, false, CookieSameSite::STRICT_MODE,
812           COOKIE_PRIORITY_DEFAULT),
813       https_url, true /*modify_httponly*/));
814   EXPECT_TRUE(this->SetCanonicalCookie(
815       cs,
816       CanonicalCookie::CreateUnsafeCookieForTesting(
817           "A", "B", http_domain, "/", base::Time::Now(), base::Time(),
818           base::Time(), base::Time(), false, false, CookieSameSite::STRICT_MODE,
819           COOKIE_PRIORITY_DEFAULT),
820       https_url, true /*modify_httponly*/));
821   EXPECT_TRUE(this->SetCanonicalCookie(
822       cs,
823       CanonicalCookie::CreateUnsafeCookieForTesting(
824           "A", "B", http_domain, "/", base::Time::Now(), base::Time(),
825           base::Time(), base::Time(), false, false, CookieSameSite::STRICT_MODE,
826           COOKIE_PRIORITY_DEFAULT),
827       http_url, true /*modify_httponly*/));
828 }
829 
830 // Check that Secure cookies can be set from a localhost URL, regardless of
831 // scheme.
TYPED_TEST_P(CookieStoreTest,SecureCookieLocalhost)832 TYPED_TEST_P(CookieStoreTest, SecureCookieLocalhost) {
833   CookieStore* cs = this->GetCookieStore();
834   EXPECT_TRUE(this->CreateAndSetCookie(cs, GURL("https://localhost/path"),
835                                        "A=B;Secure",
836                                        CookieOptions::MakeAllInclusive()));
837   EXPECT_TRUE(this->CreateAndSetCookie(cs, GURL("https://127.0.0.1/path"),
838                                        "A=B;Secure",
839                                        CookieOptions::MakeAllInclusive()));
840   EXPECT_TRUE(this->CreateAndSetCookie(cs, GURL("http://localhost/path"),
841                                        "A=B;Secure",
842                                        CookieOptions::MakeAllInclusive()));
843   EXPECT_TRUE(this->CreateAndSetCookie(cs, GURL("http://127.0.0.1/path"),
844                                        "A=B;Secure",
845                                        CookieOptions::MakeAllInclusive()));
846   EXPECT_TRUE(this->CreateAndSetCookie(cs, GURL("http://[::1]/path"),
847                                        "A=B;Secure",
848                                        CookieOptions::MakeAllInclusive()));
849 }
850 
851 // The iOS networking stack uses the iOS cookie parser, which we do not
852 // control. While it is spec-compliant, that does not match the practical
853 // behavior of most UAs in some cases, which we try to replicate. See
854 // https://crbug.com/638389 for more information.
TYPED_TEST_P(CookieStoreTest,EmptyKeyTest)855 TYPED_TEST_P(CookieStoreTest, EmptyKeyTest) {
856 #if !BUILDFLAG(IS_IOS)
857   CookieStore* cs = this->GetCookieStore();
858 
859   GURL url1("http://foo1.bar.com");
860   EXPECT_TRUE(this->SetCookie(cs, url1, "foo"));
861   EXPECT_EQ("foo", this->GetCookies(cs, url1));
862 
863   // Cookies with neither name nor value (e.g. `Set-Cookie: =`) are ignored.
864   GURL url2("http://foo2.bar.com");
865   EXPECT_TRUE(this->SetCookie(cs, url2, "foo"));
866   EXPECT_FALSE(this->SetCookie(cs, url2, "\t"));
867   EXPECT_EQ("foo", this->GetCookies(cs, url2));
868 
869   GURL url3("http://foo3.bar.com");
870   EXPECT_TRUE(this->SetCookie(cs, url3, "foo"));
871   EXPECT_FALSE(this->SetCookie(cs, url3, "="));
872   EXPECT_EQ("foo", this->GetCookies(cs, url3));
873 
874   GURL url4("http://foo4.bar.com");
875   EXPECT_TRUE(this->SetCookie(cs, url4, "foo"));
876   EXPECT_FALSE(this->SetCookie(cs, url4, ""));
877   EXPECT_EQ("foo", this->GetCookies(cs, url4));
878 
879   GURL url5("http://foo5.bar.com");
880   EXPECT_TRUE(this->SetCookie(cs, url5, "foo"));
881   EXPECT_FALSE(this->SetCookie(cs, url5, "; bar"));
882   EXPECT_EQ("foo", this->GetCookies(cs, url5));
883 
884   GURL url6("http://foo6.bar.com");
885   EXPECT_TRUE(this->SetCookie(cs, url6, "foo"));
886   EXPECT_FALSE(this->SetCookie(cs, url6, " "));
887   EXPECT_EQ("foo", this->GetCookies(cs, url6));
888 #endif
889 }
890 
TYPED_TEST_P(CookieStoreTest,DomainTest)891 TYPED_TEST_P(CookieStoreTest, DomainTest) {
892   CookieStore* cs = this->GetCookieStore();
893   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
894   this->MatchCookieLines("A=B",
895                          this->GetCookies(cs, this->http_www_foo_.url()));
896   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
897                               this->http_www_foo_.Format("C=D; domain=.%D")));
898   this->MatchCookieLines("A=B; C=D",
899                          this->GetCookies(cs, this->http_www_foo_.url()));
900 
901   // Verify that A=B was set as a host cookie rather than a domain
902   // cookie -- should not be accessible from a sub sub-domain.
903   this->MatchCookieLines(
904       "C=D", this->GetCookies(
905                  cs, GURL(this->http_www_foo_.Format("http://foo.www.%D"))));
906 
907   // Test and make sure we find domain cookies on the same domain.
908   EXPECT_TRUE(
909       this->SetCookie(cs, this->http_www_foo_.url(),
910                       this->http_www_foo_.Format("E=F; domain=.www.%D")));
911   this->MatchCookieLines("A=B; C=D; E=F",
912                          this->GetCookies(cs, this->http_www_foo_.url()));
913 
914   // Test setting a domain= that doesn't start w/ a dot, should
915   // treat it as a domain cookie, as if there was a pre-pended dot.
916   EXPECT_TRUE(
917       this->SetCookie(cs, this->http_www_foo_.url(),
918                       this->http_www_foo_.Format("G=H; domain=www.%D")));
919   this->MatchCookieLines("A=B; C=D; E=F; G=H",
920                          this->GetCookies(cs, this->http_www_foo_.url()));
921 
922   // Test domain enforcement, should fail on a sub-domain or something too deep.
923   EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(),
924                                this->http_www_foo_.Format("I=J; domain=.%R")));
925   this->MatchCookieLines(
926       std::string(),
927       this->GetCookies(cs, GURL(this->http_www_foo_.Format("http://a.%R"))));
928   EXPECT_FALSE(
929       this->SetCookie(cs, this->http_www_foo_.url(),
930                       this->http_www_foo_.Format("K=L; domain=.bla.www.%D")));
931   this->MatchCookieLines(
932       "C=D; E=F; G=H",
933       this->GetCookies(cs,
934                        GURL(this->http_www_foo_.Format("http://bla.www.%D"))));
935   this->MatchCookieLines("A=B; C=D; E=F; G=H",
936                          this->GetCookies(cs, this->http_www_foo_.url()));
937 }
938 
939 // FireFox recognizes domains containing trailing periods as valid.
940 // IE and Safari do not. Assert the expected policy here.
TYPED_TEST_P(CookieStoreTest,DomainWithTrailingDotTest)941 TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) {
942   CookieStore* cs = this->GetCookieStore();
943   // These two cases fail because the url, http://www.foo.com, does not match
944   // the domain given in the cookie line (due to the trailing dots), so the
945   // cookie is not created.
946   EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(),
947                                "a=1; domain=.www.foo.com."));
948   EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(),
949                                "b=2; domain=.www.foo.com.."));
950   this->MatchCookieLines(std::string(),
951                          this->GetCookies(cs, this->http_www_foo_.url()));
952 
953   GURL url_with_dot("http://www.foo.com.");
954   GURL url_with_double_dot("http://www.foo.com..");
955 
956   // This succeeds because the urls match.
957   EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "a=1; domain=.www.foo.com."));
958   // This fails because two trailing dots are not allowed, so the cookie is not
959   // created.
960   EXPECT_FALSE(
961       this->SetCookie(cs, url_with_double_dot, "b=2; domain=.www.foo.com.."));
962 
963   if (TypeParam::preserves_trailing_dots) {
964     // If the CookieStore preserves trailing dots, then .www.foo.com is not
965     // considered the same as .www.foo.com.
966     this->MatchCookieLines(std::string(),
967                            this->GetCookies(cs, this->http_www_foo_.url()));
968     this->MatchCookieLines("a=1", this->GetCookies(cs, url_with_dot));
969   } else {
970     // If the CookieStore does not preserve trailing dots, the domains will both
971     // be folded into one.
972     this->MatchCookieLines("a=1",
973                            this->GetCookies(cs, this->http_www_foo_.url()));
974     this->MatchCookieLines("a=1", this->GetCookies(cs, url_with_dot));
975   }
976 }
977 
978 // Test that cookies can bet set on higher level domains.
TYPED_TEST_P(CookieStoreTest,ValidSubdomainTest)979 TYPED_TEST_P(CookieStoreTest, ValidSubdomainTest) {
980   CookieStore* cs = this->GetCookieStore();
981   GURL url_abcd("http://a.b.c.d.com");
982   GURL url_bcd("http://b.c.d.com");
983   GURL url_cd("http://c.d.com");
984   GURL url_d("http://d.com");
985 
986   EXPECT_TRUE(this->SetCookie(cs, url_abcd, "a=1; domain=.a.b.c.d.com"));
987   EXPECT_TRUE(this->SetCookie(cs, url_abcd, "b=2; domain=.b.c.d.com"));
988   EXPECT_TRUE(this->SetCookie(cs, url_abcd, "c=3; domain=.c.d.com"));
989   EXPECT_TRUE(this->SetCookie(cs, url_abcd, "d=4; domain=.d.com"));
990 
991   this->MatchCookieLines("a=1; b=2; c=3; d=4", this->GetCookies(cs, url_abcd));
992   this->MatchCookieLines("b=2; c=3; d=4", this->GetCookies(cs, url_bcd));
993   this->MatchCookieLines("c=3; d=4", this->GetCookies(cs, url_cd));
994   this->MatchCookieLines("d=4", this->GetCookies(cs, url_d));
995 
996   // Check that the same cookie can exist on different sub-domains.
997   EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=bcd; domain=.b.c.d.com"));
998   EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=cd; domain=.c.d.com"));
999   this->MatchCookieLines("b=2; c=3; d=4; X=bcd; X=cd",
1000                          this->GetCookies(cs, url_bcd));
1001   this->MatchCookieLines("c=3; d=4; X=cd", this->GetCookies(cs, url_cd));
1002 }
1003 
1004 // Test that setting a cookie which specifies an invalid domain has
1005 // no side-effect. An invalid domain in this context is one which does
1006 // not match the originating domain.
TYPED_TEST_P(CookieStoreTest,InvalidDomainTest)1007 TYPED_TEST_P(CookieStoreTest, InvalidDomainTest) {
1008   CookieStore* cs = this->GetCookieStore();
1009   GURL url_foobar("http://foo.bar.com");
1010 
1011   // More specific sub-domain than allowed.
1012   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "a=1; domain=.yo.foo.bar.com"));
1013 
1014   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "b=2; domain=.foo.com"));
1015   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "c=3; domain=.bar.foo.com"));
1016 
1017   // Different TLD, but the rest is a substring.
1018   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "d=4; domain=.foo.bar.com.net"));
1019 
1020   // A substring that isn't really a parent domain.
1021   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "e=5; domain=ar.com"));
1022 
1023   // Completely invalid domains:
1024   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "f=6; domain=."));
1025   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "g=7; domain=/"));
1026   EXPECT_FALSE(
1027       this->SetCookie(cs, url_foobar, "h=8; domain=http://foo.bar.com"));
1028   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "i=9; domain=..foo.bar.com"));
1029   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "j=10; domain=..bar.com"));
1030 
1031   // Make sure there isn't something quirky in the domain canonicalization
1032   // that supports full URL semantics.
1033   EXPECT_FALSE(
1034       this->SetCookie(cs, url_foobar, "k=11; domain=.foo.bar.com?blah"));
1035   EXPECT_FALSE(
1036       this->SetCookie(cs, url_foobar, "l=12; domain=.foo.bar.com/blah"));
1037   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "m=13; domain=.foo.bar.com:80"));
1038   EXPECT_FALSE(this->SetCookie(cs, url_foobar, "n=14; domain=.foo.bar.com:"));
1039   EXPECT_FALSE(
1040       this->SetCookie(cs, url_foobar, "o=15; domain=.foo.bar.com#sup"));
1041 
1042   this->MatchCookieLines(std::string(), this->GetCookies(cs, url_foobar));
1043 }
1044 
1045 // Make sure the cookie code hasn't gotten its subdomain string handling
1046 // reversed, missed a suffix check, etc.  It's important here that the two
1047 // hosts below have the same domain + registry.
TYPED_TEST_P(CookieStoreTest,InvalidDomainSameDomainAndRegistry)1048 TYPED_TEST_P(CookieStoreTest, InvalidDomainSameDomainAndRegistry) {
1049   CookieStore* cs = this->GetCookieStore();
1050   GURL url_foocom("http://foo.com.com");
1051   EXPECT_FALSE(this->SetCookie(cs, url_foocom, "a=1; domain=.foo.com.com.com"));
1052   this->MatchCookieLines(std::string(), this->GetCookies(cs, url_foocom));
1053 }
1054 
1055 // Setting the domain without a dot on a parent domain should add a domain
1056 // cookie.
TYPED_TEST_P(CookieStoreTest,DomainWithoutLeadingDotParentDomain)1057 TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotParentDomain) {
1058   CookieStore* cs = this->GetCookieStore();
1059   GURL url_hosted("http://manage.hosted.filefront.com");
1060   GURL url_filefront("http://www.filefront.com");
1061   EXPECT_TRUE(this->SetCookie(cs, url_hosted, "sawAd=1; domain=filefront.com"));
1062   this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_hosted));
1063   this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_filefront));
1064 }
1065 
1066 // Even when the specified domain matches the domain of the URL exactly, treat
1067 // it as setting a domain cookie.
TYPED_TEST_P(CookieStoreTest,DomainWithoutLeadingDotSameDomain)1068 TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotSameDomain) {
1069   CookieStore* cs = this->GetCookieStore();
1070   GURL url("http://www.foo.com");
1071   EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=www.foo.com"));
1072   this->MatchCookieLines("a=1", this->GetCookies(cs, url));
1073   this->MatchCookieLines("a=1",
1074                          this->GetCookies(cs, GURL("http://sub.www.foo.com")));
1075   this->MatchCookieLines(
1076       std::string(), this->GetCookies(cs, GURL("http://something-else.com")));
1077 }
1078 
1079 // Test that the domain specified in cookie string is treated case-insensitive
TYPED_TEST_P(CookieStoreTest,CaseInsensitiveDomainTest)1080 TYPED_TEST_P(CookieStoreTest, CaseInsensitiveDomainTest) {
1081   CookieStore* cs = this->GetCookieStore();
1082   GURL url("http://www.foo.com");
1083   EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=.FOO.COM"));
1084   EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.wWw.fOO.cOM"));
1085   this->MatchCookieLines("a=1; b=2", this->GetCookies(cs, url));
1086 }
1087 
TYPED_TEST_P(CookieStoreTest,TestIpAddress)1088 TYPED_TEST_P(CookieStoreTest, TestIpAddress) {
1089   GURL url_ip("http://1.2.3.4/weee");
1090   CookieStore* cs = this->GetCookieStore();
1091   EXPECT_TRUE(this->SetCookie(cs, url_ip, kValidCookieLine));
1092   this->MatchCookieLines("A=B", this->GetCookies(cs, url_ip));
1093 }
1094 
1095 // IP addresses should not be able to set domain cookies.
TYPED_TEST_P(CookieStoreTest,TestIpAddressNoDomainCookies)1096 TYPED_TEST_P(CookieStoreTest, TestIpAddressNoDomainCookies) {
1097   GURL url_ip("http://1.2.3.4/weee");
1098   CookieStore* cs = this->GetCookieStore();
1099   EXPECT_FALSE(this->SetCookie(cs, url_ip, "c=3; domain=.3.4"));
1100   this->MatchCookieLines(std::string(), this->GetCookies(cs, url_ip));
1101   // It should be allowed to set a cookie if domain= matches the IP address
1102   // by ignoring case and ignoring a leading dot.  This matches IE/Firefox, even
1103   // though it seems a bit wrong.
1104   EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.3"));
1105   this->MatchCookieLines(std::string(), this->GetCookies(cs, url_ip));
1106   EXPECT_TRUE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.4"));
1107   this->MatchCookieLines("b=2", this->GetCookies(cs, url_ip));
1108   EXPECT_TRUE(this->SetCookie(cs, url_ip, "b=2; domain=.1.2.3.4"));
1109   this->MatchCookieLines("b=2", this->GetCookies(cs, url_ip));
1110 
1111 #if !BUILDFLAG(IS_IOS)
1112   // Test a couple of IPv6 addresses
1113   GURL url_ip6("http://[2606:2800:220:1:248:1893:25c8:1946]");
1114   EXPECT_FALSE(this->SetCookie(
1115       cs, url_ip6, "e=1; domain=.2606:2800:220:1:248:1893:25c8:1946"));
1116   this->MatchCookieLines(std::string(), this->GetCookies(cs, url_ip6));
1117   EXPECT_TRUE(this->SetCookie(
1118       cs, url_ip6, "d=1; domain=[2606:2800:220:1:248:1893:25c8:1946]"));
1119   this->MatchCookieLines("d=1", this->GetCookies(cs, url_ip6));
1120 #endif  // !BUILDFLAG(IS_IOS)
1121 }
1122 
1123 // Test a TLD setting cookies on itself.
TYPED_TEST_P(CookieStoreTest,TestTLD)1124 TYPED_TEST_P(CookieStoreTest, TestTLD) {
1125   if (!TypeParam::supports_non_dotted_domains)
1126     return;
1127   CookieStore* cs = this->GetCookieStore();
1128   GURL url("http://com/");
1129 
1130   // Allow setting on "com", (but only as a host cookie).
1131   EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
1132   // Domain is normalized by stripping leading `.` and lowercasing, so this
1133   // still works.
1134   EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.com"));
1135   EXPECT_TRUE(this->SetCookie(cs, url, "c=3; domain=CoM"));
1136   // Exact matches between the domain attribute and the host are treated as
1137   // host cookies, not domain cookies.
1138   EXPECT_TRUE(this->SetCookie(cs, url, "d=4; domain=com"));
1139 
1140   this->MatchCookieLines("a=1; b=2; c=3; d=4", this->GetCookies(cs, url));
1141 
1142   // Make sure they don't show up for a normal .com, they should be host,
1143   // domain, cookies.
1144   this->MatchCookieLines(
1145       std::string(),
1146       this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
1147   this->MatchCookieLines(std::string(),
1148                          this->GetCookies(cs, GURL("http://.com/")));
1149 }
1150 
1151 // http://com. should be treated the same as http://com.
TYPED_TEST_P(CookieStoreTest,TestTLDWithTerminalDot)1152 TYPED_TEST_P(CookieStoreTest, TestTLDWithTerminalDot) {
1153   CookieStore* cs = this->GetCookieStore();
1154   GURL url("http://com./index.html");
1155   EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
1156   EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.com."));
1157   EXPECT_TRUE(this->SetCookie(cs, url, "c=3; domain=CoM."));
1158   this->MatchCookieLines("a=1 b=2 c=3", this->GetCookies(cs, url));
1159   this->MatchCookieLines(
1160       std::string(),
1161       this->GetCookies(cs, GURL("http://hopefully-no-cookies.com./")));
1162 }
1163 
TYPED_TEST_P(CookieStoreTest,TestSubdomainSettingCookiesOnUnknownTLD)1164 TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnUnknownTLD) {
1165   CookieStore* cs = this->GetCookieStore();
1166   GURL url("http://a.b");
1167   EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.b"));
1168   EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=b"));
1169   this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
1170 }
1171 
TYPED_TEST_P(CookieStoreTest,TestSubdomainSettingCookiesOnKnownTLD)1172 TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnKnownTLD) {
1173   CookieStore* cs = this->GetCookieStore();
1174   GURL url("http://foo.com");
1175   EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.com"));
1176   EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=com"));
1177   this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
1178 }
1179 
TYPED_TEST_P(CookieStoreTest,TestSubdomainSettingCookiesOnKnownDottedTLD)1180 TYPED_TEST_P(CookieStoreTest, TestSubdomainSettingCookiesOnKnownDottedTLD) {
1181   CookieStore* cs = this->GetCookieStore();
1182   GURL url("http://foo.co.uk");
1183   EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.co.uk"));
1184   EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.uk"));
1185   this->MatchCookieLines(std::string(), this->GetCookies(cs, url));
1186   this->MatchCookieLines(
1187       std::string(), this->GetCookies(cs, GURL("http://something-else.co.uk")));
1188   this->MatchCookieLines(
1189       std::string(), this->GetCookies(cs, GURL("http://something-else.uk")));
1190 }
1191 
1192 // Intranet URLs should only be able to set host cookies.
TYPED_TEST_P(CookieStoreTest,TestSettingCookiesOnUnknownTLD)1193 TYPED_TEST_P(CookieStoreTest, TestSettingCookiesOnUnknownTLD) {
1194   CookieStore* cs = this->GetCookieStore();
1195   GURL url("http://b");
1196   EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
1197   // Even though this syntax looks like a domain cookie, it is treated as a host
1198   // cookie because `b` is treated as a public suffix.
1199   EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.b"));
1200   this->MatchCookieLines("a=1 b=2", this->GetCookies(cs, url));
1201   // Verify that this is a host cookie and does not affect a subdomain.
1202   GURL subdomain_url("http://a.b");
1203   this->MatchCookieLines("", this->GetCookies(cs, subdomain_url));
1204 }
1205 
1206 // Exact matches between the domain attribute and an intranet host are
1207 // treated as host cookies, not domain cookies.
TYPED_TEST_P(CookieStoreTest,TestSettingCookiesWithHostDomainOnUnknownTLD)1208 TYPED_TEST_P(CookieStoreTest, TestSettingCookiesWithHostDomainOnUnknownTLD) {
1209   if (!TypeParam::supports_non_dotted_domains)
1210     return;
1211   CookieStore* cs = this->GetCookieStore();
1212   GURL url("http://b");
1213   EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=b"));
1214 
1215   this->MatchCookieLines("a=1", this->GetCookies(cs, url));
1216 
1217   // Make sure it doesn't show up for an intranet subdomain, it should be
1218   // a host, not domain, cookie.
1219   this->MatchCookieLines(
1220       std::string(),
1221       this->GetCookies(cs, GURL("http://hopefully-no-cookies.b/")));
1222   this->MatchCookieLines(std::string(),
1223                          this->GetCookies(cs, GURL("http://.b/")));
1224 }
1225 
1226 // Test reading/writing cookies when the domain ends with a period,
1227 // as in "www.foo.com."
TYPED_TEST_P(CookieStoreTest,TestHostEndsWithDot)1228 TYPED_TEST_P(CookieStoreTest, TestHostEndsWithDot) {
1229   CookieStore* cs = this->GetCookieStore();
1230   GURL url("http://www.foo.com");
1231   GURL url_with_dot("http://www.foo.com.");
1232   EXPECT_TRUE(this->SetCookie(cs, url, "a=1"));
1233   this->MatchCookieLines("a=1", this->GetCookies(cs, url));
1234   // This fails because the url does not match the domain, so the cookie cannot
1235   // be created.
1236   EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.www.foo.com."));
1237   this->MatchCookieLines("a=1", this->GetCookies(cs, url));
1238   // This cookie can be created because the url matches the domain, and it can
1239   // be set, but the get-cookie result differs depending on whether the
1240   // CookieStore preserves trailing dots.
1241   EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "b=2; domain=.foo.com."));
1242 
1243   // Do not share cookie space with the dot version of domain.
1244   // Note: this is not what FireFox does, but it _is_ what IE+Safari do.
1245   if (TypeParam::preserves_trailing_dots) {
1246     this->MatchCookieLines("a=1", this->GetCookies(cs, url));
1247     this->MatchCookieLines("b=2", this->GetCookies(cs, url_with_dot));
1248   } else {
1249     this->MatchCookieLines("a=1 b=2", this->GetCookies(cs, url));
1250     this->MatchCookieLines("a=1 b=2", this->GetCookies(cs, url_with_dot));
1251   }
1252 
1253   // Make sure there weren't any side effects.
1254   this->MatchCookieLines(
1255       std::string(),
1256       this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/")));
1257   this->MatchCookieLines(std::string(),
1258                          this->GetCookies(cs, GURL("http://.com/")));
1259 }
1260 
TYPED_TEST_P(CookieStoreTest,InvalidScheme)1261 TYPED_TEST_P(CookieStoreTest, InvalidScheme) {
1262   if (!TypeParam::filters_schemes)
1263     return;
1264 
1265   CookieStore* cs = this->GetCookieStore();
1266   EXPECT_FALSE(this->SetCookie(cs, this->ftp_foo_.url(), kValidCookieLine));
1267 }
1268 
TYPED_TEST_P(CookieStoreTest,InvalidScheme_Read)1269 TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) {
1270   if (!TypeParam::filters_schemes)
1271     return;
1272 
1273   const std::string kValidDomainCookieLine =
1274       this->http_www_foo_.Format("A=B; path=/; domain=%D");
1275 
1276   CookieStore* cs = this->GetCookieStore();
1277   EXPECT_TRUE(
1278       this->SetCookie(cs, this->http_www_foo_.url(), kValidDomainCookieLine));
1279   this->MatchCookieLines(std::string(),
1280                          this->GetCookies(cs, this->ftp_foo_.url()));
1281   EXPECT_EQ(0U,
1282             this->GetCookieListWithOptions(cs, this->ftp_foo_.url(),
1283                                            CookieOptions::MakeAllInclusive())
1284                 .size());
1285 }
1286 
TYPED_TEST_P(CookieStoreTest,PathTest)1287 TYPED_TEST_P(CookieStoreTest, PathTest) {
1288   CookieStore* cs = this->GetCookieStore();
1289   std::string url("http://www.foo.com");
1290   EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=B; path=/wee"));
1291   this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee")));
1292   this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/")));
1293   this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/war")));
1294   this->MatchCookieLines(
1295       "A=B", this->GetCookies(cs, GURL(url + "/wee/war/more/more")));
1296   if (!TypeParam::has_path_prefix_bug)
1297     this->MatchCookieLines(std::string(),
1298                            this->GetCookies(cs, GURL(url + "/weehee")));
1299   this->MatchCookieLines(std::string(), this->GetCookies(cs, GURL(url + "/")));
1300 
1301   // If we add a 0 length path, it should default to /
1302   EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=C; path="));
1303   this->MatchCookieLines("A=B; A=C", this->GetCookies(cs, GURL(url + "/wee")));
1304   this->MatchCookieLines("A=C", this->GetCookies(cs, GURL(url + "/")));
1305 }
1306 
TYPED_TEST_P(CookieStoreTest,EmptyExpires)1307 TYPED_TEST_P(CookieStoreTest, EmptyExpires) {
1308   CookieStore* cs = this->GetCookieStore();
1309   CookieOptions options;
1310   if (!TypeParam::supports_http_only)
1311     options.set_include_httponly();
1312   options.set_same_site_cookie_context(
1313       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
1314   GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
1315   std::string set_cookie_line =
1316       "ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
1317   std::string cookie_line = "ACSTM=20130308043820420042";
1318 
1319   this->CreateAndSetCookie(cs, url, set_cookie_line, options);
1320   this->MatchCookieLines(cookie_line,
1321                          this->GetCookiesWithOptions(cs, url, options));
1322 
1323   std::optional<base::Time> server_time =
1324       std::make_optional(base::Time::Now() - base::Hours(1));
1325   this->CreateAndSetCookie(cs, url, set_cookie_line, options, server_time);
1326   this->MatchCookieLines(cookie_line,
1327                          this->GetCookiesWithOptions(cs, url, options));
1328 
1329   server_time = base::Time::Now() + base::Hours(1);
1330   this->CreateAndSetCookie(cs, url, set_cookie_line, options, server_time);
1331   this->MatchCookieLines(cookie_line,
1332                          this->GetCookiesWithOptions(cs, url, options));
1333 }
1334 
TYPED_TEST_P(CookieStoreTest,HttpOnlyTest)1335 TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) {
1336   if (!TypeParam::supports_http_only)
1337     return;
1338 
1339   CookieStore* cs = this->GetCookieStore();
1340   CookieOptions options;
1341   options.set_include_httponly();
1342   options.set_same_site_cookie_context(
1343       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
1344 
1345   // Create a httponly cookie.
1346   EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
1347                                        "A=B; httponly", options));
1348 
1349   // Check httponly read protection.
1350   this->MatchCookieLines(std::string(),
1351                          this->GetCookies(cs, this->http_www_foo_.url()));
1352   this->MatchCookieLines("A=B", this->GetCookiesWithOptions(
1353                                     cs, this->http_www_foo_.url(), options));
1354 
1355   // Check httponly overwrite protection.
1356   EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
1357   this->MatchCookieLines(std::string(),
1358                          this->GetCookies(cs, this->http_www_foo_.url()));
1359   this->MatchCookieLines("A=B", this->GetCookiesWithOptions(
1360                                     cs, this->http_www_foo_.url(), options));
1361   EXPECT_TRUE(
1362       this->CreateAndSetCookie(cs, this->http_www_foo_.url(), "A=C", options));
1363   this->MatchCookieLines("A=C",
1364                          this->GetCookies(cs, this->http_www_foo_.url()));
1365 
1366   // Check httponly create protection.
1367   EXPECT_FALSE(this->SetCookie(cs, this->http_www_foo_.url(), "B=A; httponly"));
1368   this->MatchCookieLines("A=C", this->GetCookiesWithOptions(
1369                                     cs, this->http_www_foo_.url(), options));
1370   EXPECT_TRUE(this->CreateAndSetCookie(cs, this->http_www_foo_.url(),
1371                                        "B=A; httponly", options));
1372   this->MatchCookieLines(
1373       "A=C; B=A",
1374       this->GetCookiesWithOptions(cs, this->http_www_foo_.url(), options));
1375   this->MatchCookieLines("A=C",
1376                          this->GetCookies(cs, this->http_www_foo_.url()));
1377 }
1378 
TYPED_TEST_P(CookieStoreTest,TestCookieDeletion)1379 TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) {
1380   CookieStore* cs = this->GetCookieStore();
1381 
1382   // Create a session cookie.
1383   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), kValidCookieLine));
1384   this->MatchCookieLines("A=B",
1385                          this->GetCookies(cs, this->http_www_foo_.url()));
1386   // Delete it via Max-Age.
1387   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1388                               std::string(kValidCookieLine) + "; max-age=0"));
1389   this->MatchCookieLineWithTimeout(cs, this->http_www_foo_.url(),
1390                                    std::string());
1391 
1392   // Create a session cookie.
1393   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), kValidCookieLine));
1394   this->MatchCookieLines("A=B",
1395                          this->GetCookies(cs, this->http_www_foo_.url()));
1396   // Delete it via Expires.
1397   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1398                               std::string(kValidCookieLine) +
1399                                   "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
1400   this->MatchCookieLines(std::string(),
1401                          this->GetCookies(cs, this->http_www_foo_.url()));
1402 
1403   // Create a persistent cookie.
1404   EXPECT_TRUE(
1405       this->SetCookie(cs, this->http_www_foo_.url(),
1406                       kValidCookieLine + FutureCookieExpirationString()));
1407 
1408   this->MatchCookieLines("A=B",
1409                          this->GetCookies(cs, this->http_www_foo_.url()));
1410   // Delete it via Max-Age.
1411   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1412                               std::string(kValidCookieLine) + "; max-age=0"));
1413   this->MatchCookieLineWithTimeout(cs, this->http_www_foo_.url(),
1414                                    std::string());
1415 
1416   // Create a persistent cookie.
1417   EXPECT_TRUE(
1418       this->SetCookie(cs, this->http_www_foo_.url(),
1419                       kValidCookieLine + FutureCookieExpirationString()));
1420   this->MatchCookieLines("A=B",
1421                          this->GetCookies(cs, this->http_www_foo_.url()));
1422   // Delete it via Expires.
1423   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1424                               std::string(kValidCookieLine) +
1425                                   "; expires=Mon, 18-Apr-1977 22:50:13 GMT"));
1426   this->MatchCookieLines(std::string(),
1427                          this->GetCookies(cs, this->http_www_foo_.url()));
1428 
1429   // Create a persistent cookie.
1430   EXPECT_TRUE(
1431       this->SetCookie(cs, this->http_www_foo_.url(),
1432                       kValidCookieLine + FutureCookieExpirationString()));
1433   this->MatchCookieLines("A=B",
1434                          this->GetCookies(cs, this->http_www_foo_.url()));
1435   // Check that it is not deleted with significant enough clock skew.
1436   base::Time server_time;
1437   EXPECT_TRUE(
1438       base::Time::FromString("Sun, 17-Apr-1977 22:50:13 GMT", &server_time));
1439   EXPECT_TRUE(this->SetCookieWithServerTime(
1440       cs, this->http_www_foo_.url(),
1441       std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
1442       server_time));
1443   this->MatchCookieLines("A=B",
1444                          this->GetCookies(cs, this->http_www_foo_.url()));
1445 
1446   // Create a persistent cookie.
1447   EXPECT_TRUE(
1448       this->SetCookie(cs, this->http_www_foo_.url(),
1449                       kValidCookieLine + FutureCookieExpirationString()));
1450   this->MatchCookieLines("A=B",
1451                          this->GetCookies(cs, this->http_www_foo_.url()));
1452   // Delete it via Expires, with a unix epoch of 0.
1453   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1454                               std::string(kValidCookieLine) +
1455                                   "; expires=Thu, 1-Jan-1970 00:00:00 GMT"));
1456   this->MatchCookieLines(std::string(),
1457                          this->GetCookies(cs, this->http_www_foo_.url()));
1458 }
1459 
TYPED_TEST_P(CookieStoreTest,TestDeleteAll)1460 TYPED_TEST_P(CookieStoreTest, TestDeleteAll) {
1461   CookieStore* cs = this->GetCookieStore();
1462 
1463   // Set a session cookie.
1464   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), kValidCookieLine));
1465   EXPECT_EQ("A=B", this->GetCookies(cs, this->http_www_foo_.url()));
1466 
1467   // Set a persistent cookie.
1468   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1469                               "C=D" + FutureCookieExpirationString()));
1470 
1471   EXPECT_EQ(2u, this->GetAllCookies(cs).size());
1472 
1473   // Delete both, and make sure it works
1474   EXPECT_EQ(2u, this->DeleteAll(cs));
1475   EXPECT_EQ(0u, this->GetAllCookies(cs).size());
1476 }
1477 
TYPED_TEST_P(CookieStoreTest,TestDeleteAllCreatedInTimeRange)1478 TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedInTimeRange) {
1479   CookieStore* cs = this->GetCookieStore();
1480   const base::Time last_month = base::Time::Now() - base::Days(30);
1481   const base::Time last_minute = base::Time::Now() - base::Minutes(1);
1482   const base::Time next_minute = base::Time::Now() + base::Minutes(1);
1483   const base::Time next_month = base::Time::Now() + base::Days(30);
1484 
1485   // Add a cookie.
1486   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1487   // Check that the cookie is in the store.
1488   this->MatchCookieLines("A=B",
1489                          this->GetCookies(cs, this->http_www_foo_.url()));
1490 
1491   // Remove cookies in empty intervals.
1492   EXPECT_EQ(0u, this->DeleteCreatedInTimeRange(
1493                     cs, TimeRange(last_month, last_minute)));
1494   EXPECT_EQ(0u, this->DeleteCreatedInTimeRange(
1495                     cs, TimeRange(next_minute, next_month)));
1496   // Check that the cookie is still there.
1497   this->MatchCookieLines("A=B",
1498                          this->GetCookies(cs, this->http_www_foo_.url()));
1499 
1500   // Remove the cookie with an interval defined by two dates.
1501   EXPECT_EQ(1u, this->DeleteCreatedInTimeRange(
1502                     cs, TimeRange(last_minute, next_minute)));
1503   // Check that the cookie disappeared.
1504   this->MatchCookieLines(std::string(),
1505                          this->GetCookies(cs, this->http_www_foo_.url()));
1506 
1507   // Add another cookie.
1508   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1509   // Check that the cookie is in the store.
1510   this->MatchCookieLines("C=D",
1511                          this->GetCookies(cs, this->http_www_foo_.url()));
1512 
1513   // Remove the cookie with a null ending time.
1514   EXPECT_EQ(1u, this->DeleteCreatedInTimeRange(
1515                     cs, TimeRange(last_minute, base::Time())));
1516   // Check that the cookie disappeared.
1517   this->MatchCookieLines(std::string(),
1518                          this->GetCookies(cs, this->http_www_foo_.url()));
1519 }
1520 
TYPED_TEST_P(CookieStoreTest,TestDeleteAllWithInfo)1521 TYPED_TEST_P(CookieStoreTest, TestDeleteAllWithInfo) {
1522   CookieStore* cs = this->GetCookieStore();
1523   base::Time now = base::Time::Now();
1524   base::Time last_month = base::Time::Now() - base::Days(30);
1525   base::Time last_minute = base::Time::Now() - base::Minutes(1);
1526 
1527   // These 3 cookies match the time range and host.
1528   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1529   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
1530   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "Y=Z"));
1531   EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "E=B"));
1532 
1533   // Delete cookies.
1534   CookieDeletionInfo delete_info(now, base::Time::Max());
1535   delete_info.value_for_testing = "B";
1536   EXPECT_EQ(2u,  // Deletes A=B, E=B
1537             this->DeleteAllCreatedInTimeRange(cs, std::move(delete_info)));
1538 
1539   // Check that we deleted the right ones.
1540   this->MatchCookieLines("C=D;Y=Z",
1541                          this->GetCookies(cs, this->https_www_foo_.url()));
1542 
1543   // Finally, check that we don't delete cookies when our time range is off.
1544   delete_info = CookieDeletionInfo(last_month, last_minute);
1545   delete_info.value_for_testing = "D";
1546   EXPECT_EQ(0u, this->DeleteAllCreatedInTimeRange(cs, std::move(delete_info)));
1547   this->MatchCookieLines("C=D;Y=Z",
1548                          this->GetCookies(cs, this->https_www_foo_.url()));
1549   // Same thing, but with a good time range.
1550   delete_info = CookieDeletionInfo(now, base::Time::Max());
1551   delete_info.value_for_testing = "D";
1552   EXPECT_EQ(1u, this->DeleteAllCreatedInTimeRange(cs, std::move(delete_info)));
1553   this->MatchCookieLines("Y=Z",
1554                          this->GetCookies(cs, this->https_www_foo_.url()));
1555 }
1556 
TYPED_TEST_P(CookieStoreTest,TestSecure)1557 TYPED_TEST_P(CookieStoreTest, TestSecure) {
1558   CookieStore* cs = this->GetCookieStore();
1559 
1560   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
1561   this->MatchCookieLines("A=B",
1562                          this->GetCookies(cs, this->http_www_foo_.url()));
1563   this->MatchCookieLines("A=B",
1564                          this->GetCookies(cs, this->https_www_foo_.url()));
1565 
1566   EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "A=B; secure"));
1567   // The secure should overwrite the non-secure.
1568   this->MatchCookieLines(std::string(),
1569                          this->GetCookies(cs, this->http_www_foo_.url()));
1570   this->MatchCookieLines("A=B",
1571                          this->GetCookies(cs, this->https_www_foo_.url()));
1572 
1573   EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "D=E; secure"));
1574   this->MatchCookieLines(std::string(),
1575                          this->GetCookies(cs, this->http_www_foo_.url()));
1576   this->MatchCookieLines("A=B; D=E",
1577                          this->GetCookies(cs, this->https_www_foo_.url()));
1578 
1579   EXPECT_TRUE(this->SetCookie(cs, this->https_www_foo_.url(), "A=B"));
1580   // The non-secure should overwrite the secure.
1581   this->MatchCookieLines("A=B",
1582                          this->GetCookies(cs, this->http_www_foo_.url()));
1583   this->MatchCookieLines("D=E; A=B",
1584                          this->GetCookies(cs, this->https_www_foo_.url()));
1585 }
1586 
1587 // Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling.
TYPED_TEST_P(CookieStoreTest,NetUtilCookieTest)1588 TYPED_TEST_P(CookieStoreTest, NetUtilCookieTest) {
1589   const GURL test_url("http://mojo.jojo.foo.com/");
1590 
1591   CookieStore* cs = this->GetCookieStore();
1592 
1593   EXPECT_TRUE(this->SetCookie(cs, test_url, "foo=bar"));
1594   std::string value = this->GetCookies(cs, test_url);
1595   this->MatchCookieLines("foo=bar", value);
1596 
1597   // test that we can retrieve all cookies:
1598   EXPECT_TRUE(this->SetCookie(cs, test_url, "x=1"));
1599   EXPECT_TRUE(this->SetCookie(cs, test_url, "y=2"));
1600 
1601   std::string result = this->GetCookies(cs, test_url);
1602   EXPECT_FALSE(result.empty());
1603   EXPECT_NE(result.find("x=1"), std::string::npos) << result;
1604   EXPECT_NE(result.find("y=2"), std::string::npos) << result;
1605 }
1606 
TYPED_TEST_P(CookieStoreTest,OverwritePersistentCookie)1607 TYPED_TEST_P(CookieStoreTest, OverwritePersistentCookie) {
1608   GURL url_foo("http://www.foo.com/");
1609   GURL url_chromium("http://chromium.org");
1610   CookieStore* cs = this->GetCookieStore();
1611 
1612   // Insert a cookie "a" for path "/path1"
1613   EXPECT_TRUE(this->SetCookie(
1614       cs, url_foo, "a=val1; path=/path1" + FutureCookieExpirationString()));
1615 
1616   // Insert a cookie "b" for path "/path1"
1617   EXPECT_TRUE(this->SetCookie(
1618       cs, url_foo, "b=val1; path=/path1" + FutureCookieExpirationString()));
1619 
1620   // Insert a cookie "b" for path "/path1", that is httponly. This should
1621   // overwrite the non-http-only version.
1622   CookieOptions allow_httponly;
1623   allow_httponly.set_include_httponly();
1624   allow_httponly.set_same_site_cookie_context(
1625       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
1626   EXPECT_TRUE(this->CreateAndSetCookie(
1627       cs, url_foo,
1628       "b=val2; path=/path1; httponly" + FutureCookieExpirationString(),
1629       allow_httponly));
1630 
1631   // Insert a cookie "a" for path "/path1". This should overwrite.
1632   EXPECT_TRUE(this->SetCookie(
1633       cs, url_foo, "a=val33; path=/path1" + FutureCookieExpirationString()));
1634 
1635   // Insert a cookie "a" for path "/path2". This should NOT overwrite
1636   // cookie "a", since the path is different.
1637   EXPECT_TRUE(this->SetCookie(
1638       cs, url_foo, "a=val9; path=/path2" + FutureCookieExpirationString()));
1639 
1640   // Insert a cookie "a" for path "/path1", but this time for "chromium.org".
1641   // Although the name and path match, the hostnames do not, so shouldn't
1642   // overwrite.
1643   EXPECT_TRUE(
1644       this->SetCookie(cs, url_chromium,
1645                       "a=val99; path=/path1" + FutureCookieExpirationString()));
1646 
1647   if (TypeParam::supports_http_only) {
1648     this->MatchCookieLines(
1649         "a=val33", this->GetCookies(cs, GURL("http://www.foo.com/path1")));
1650   } else {
1651     this->MatchCookieLines(
1652         "a=val33; b=val2",
1653         this->GetCookies(cs, GURL("http://www.foo.com/path1")));
1654   }
1655   this->MatchCookieLines(
1656       "a=val9", this->GetCookies(cs, GURL("http://www.foo.com/path2")));
1657   this->MatchCookieLines(
1658       "a=val99", this->GetCookies(cs, GURL("http://chromium.org/path1")));
1659 }
1660 
1661 // Note that accepting an empty name is contrary to spec; see
1662 // https://tools.ietf.org/html/rfc6265#section-4.1.1.  However, we do it
1663 // for web compatibility; see http://inikulin.github.io/cookie-compat/
1664 // (specifically the "foo" and "=a" tests).  This test is present in Chromium
1665 // so that a flag is raised if this behavior is changed.
1666 // On IOS we use the system cookie store which has Safari's behavior, so
1667 // the test is skipped.
TYPED_TEST_P(CookieStoreTest,EmptyName)1668 TYPED_TEST_P(CookieStoreTest, EmptyName) {
1669   if (TypeParam::forbids_setting_empty_name)
1670     return;
1671 
1672   GURL url_foo("http://www.foo.com/");
1673   CookieStore* cs = this->GetCookieStore();
1674 
1675   CookieOptions options;
1676   if (!TypeParam::supports_http_only)
1677     options.set_include_httponly();
1678   options.set_same_site_cookie_context(
1679       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
1680 
1681   EXPECT_TRUE(this->CreateAndSetCookie(cs, url_foo, "a", options));
1682   CookieList list = this->GetAllCookiesForURL(cs, url_foo);
1683   EXPECT_EQ(1u, list.size());
1684   EXPECT_EQ("", list[0].Name());
1685   EXPECT_EQ("a", list[0].Value());
1686   EXPECT_EQ(1u, this->DeleteAll(cs));
1687 
1688   EXPECT_TRUE(this->CreateAndSetCookie(cs, url_foo, "=b", options));
1689   list = this->GetAllCookiesForURL(cs, url_foo);
1690   EXPECT_EQ(1u, list.size());
1691   EXPECT_EQ("", list[0].Name());
1692   EXPECT_EQ("b", list[0].Value());
1693   EXPECT_EQ(1u, this->DeleteAll(cs));
1694 }
1695 
TYPED_TEST_P(CookieStoreTest,CookieOrdering)1696 TYPED_TEST_P(CookieStoreTest, CookieOrdering) {
1697   // Put a random set of cookies into a store and make sure they're returned in
1698   // the right order.
1699   // Cookies should be sorted by path length and creation time, as per RFC6265.
1700   CookieStore* cs = this->GetCookieStore();
1701   EXPECT_TRUE(
1702       this->SetCookie(cs, GURL("http://d.c.b.a.foo.com/aa/x.html"), "c=1"));
1703   EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.foo.com/aa/bb/cc/x.html"),
1704                               "d=1; domain=b.a.foo.com"));
1705   base::PlatformThread::Sleep(
1706       base::Milliseconds(TypeParam::creation_time_granularity_in_ms));
1707   EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.foo.com/aa/bb/cc/x.html"),
1708                               "a=4; domain=b.a.foo.com"));
1709   base::PlatformThread::Sleep(
1710       base::Milliseconds(TypeParam::creation_time_granularity_in_ms));
1711   EXPECT_TRUE(this->SetCookie(cs, GURL("http://c.b.a.foo.com/aa/bb/cc/x.html"),
1712                               "e=1; domain=c.b.a.foo.com"));
1713   EXPECT_TRUE(
1714       this->SetCookie(cs, GURL("http://d.c.b.a.foo.com/aa/bb/x.html"), "b=1"));
1715   EXPECT_TRUE(this->SetCookie(cs, GURL("http://news.bbc.co.uk/midpath/x.html"),
1716                               "g=10"));
1717   EXPECT_EQ("d=1; a=4; e=1; b=1; c=1",
1718             this->GetCookies(cs, GURL("http://d.c.b.a.foo.com/aa/bb/cc/dd")));
1719 
1720   CookieOptions options;
1721   options.set_same_site_cookie_context(
1722       net::CookieOptions::SameSiteCookieContext::MakeInclusive());
1723 
1724   CookieList cookies = this->GetCookieListWithOptions(
1725       cs, GURL("http://d.c.b.a.foo.com/aa/bb/cc/dd"), options);
1726   CookieList::const_iterator it = cookies.begin();
1727 
1728   ASSERT_TRUE(it != cookies.end());
1729   EXPECT_EQ("d", it->Name());
1730 
1731   ASSERT_TRUE(++it != cookies.end());
1732   EXPECT_EQ("a", it->Name());
1733 
1734   ASSERT_TRUE(++it != cookies.end());
1735   EXPECT_EQ("e", it->Name());
1736 
1737   ASSERT_TRUE(++it != cookies.end());
1738   EXPECT_EQ("b", it->Name());
1739 
1740   ASSERT_TRUE(++it != cookies.end());
1741   EXPECT_EQ("c", it->Name());
1742 
1743   EXPECT_TRUE(++it == cookies.end());
1744 }
1745 
1746 // Check that GetAllCookiesAsync returns cookies from multiple domains, in the
1747 // correct order.
TYPED_TEST_P(CookieStoreTest,GetAllCookiesAsync)1748 TYPED_TEST_P(CookieStoreTest, GetAllCookiesAsync) {
1749   CookieStore* cs = this->GetCookieStore();
1750 
1751   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/a"));
1752   EXPECT_TRUE(this->SetCookie(cs, this->http_baz_com_.url(), "C=D;/"));
1753   EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "E=F; path=/bar"));
1754 
1755   // Check cookies for url.
1756   CookieList cookies = this->GetAllCookies(cs);
1757   CookieList::const_iterator it = cookies.begin();
1758 
1759   ASSERT_TRUE(it != cookies.end());
1760   EXPECT_EQ(this->http_bar_com_.host(), it->Domain());
1761   EXPECT_EQ("/bar", it->Path());
1762   EXPECT_EQ("E", it->Name());
1763   EXPECT_EQ("F", it->Value());
1764 
1765   ASSERT_TRUE(++it != cookies.end());
1766   EXPECT_EQ(this->http_www_foo_.host(), it->Domain());
1767   EXPECT_EQ("/a", it->Path());
1768   EXPECT_EQ("A", it->Name());
1769   EXPECT_EQ("B", it->Value());
1770 
1771   ASSERT_TRUE(++it != cookies.end());
1772   EXPECT_EQ(this->http_baz_com_.host(), it->Domain());
1773   EXPECT_EQ("/", it->Path());
1774   EXPECT_EQ("C", it->Name());
1775   EXPECT_EQ("D", it->Value());
1776 
1777   ASSERT_TRUE(++it == cookies.end());
1778 }
1779 
TYPED_TEST_P(CookieStoreTest,GetAllCookiesWithAccessSemanticsAsync)1780 TYPED_TEST_P(CookieStoreTest, GetAllCookiesWithAccessSemanticsAsync) {
1781   CookieStore* cs = this->GetCookieStore();
1782   auto access_delegate = std::make_unique<TestCookieAccessDelegate>();
1783   TestCookieAccessDelegate* test_delegate = access_delegate.get();
1784   // if !supports_cookie_access_semantics, the delegate will be stored but will
1785   // not be used.
1786   cs->SetCookieAccessDelegate(std::move(access_delegate));
1787 
1788   test_delegate->SetExpectationForCookieDomain("domain1.test",
1789                                                CookieAccessSemantics::LEGACY);
1790   test_delegate->SetExpectationForCookieDomain(
1791       "domain2.test", CookieAccessSemantics::NONLEGACY);
1792   test_delegate->SetExpectationForCookieDomain("domain3.test",
1793                                                CookieAccessSemantics::UNKNOWN);
1794 
1795   this->CreateAndSetCookie(cs, GURL("http://domain1.test"), "cookie=1",
1796                            CookieOptions::MakeAllInclusive());
1797   this->CreateAndSetCookie(cs, GURL("http://domain2.test"), "cookie=1",
1798                            CookieOptions::MakeAllInclusive());
1799   this->CreateAndSetCookie(cs, GURL("http://domain3.test"), "cookie=1",
1800                            CookieOptions::MakeAllInclusive());
1801   this->CreateAndSetCookie(cs, GURL("http://domain4.test"), "cookie=1",
1802                            CookieOptions::MakeAllInclusive());
1803 
1804   GetAllCookiesWithAccessSemanticsCallback callback;
1805   cs->GetAllCookiesWithAccessSemanticsAsync(callback.MakeCallback());
1806   callback.WaitUntilDone();
1807   EXPECT_TRUE(callback.was_run());
1808 
1809   EXPECT_EQ(callback.cookies().size(), callback.access_semantics_list().size());
1810   EXPECT_EQ(4u, callback.access_semantics_list().size());
1811   EXPECT_EQ("domain1.test", callback.cookies()[0].Domain());
1812   EXPECT_EQ("domain2.test", callback.cookies()[1].Domain());
1813   EXPECT_EQ("domain3.test", callback.cookies()[2].Domain());
1814   EXPECT_EQ("domain4.test", callback.cookies()[3].Domain());
1815 
1816   if (!TypeParam::supports_cookie_access_semantics) {
1817     for (CookieAccessSemantics semantics : callback.access_semantics_list()) {
1818       EXPECT_EQ(CookieAccessSemantics::UNKNOWN, semantics);
1819     }
1820   } else {
1821     EXPECT_EQ(CookieAccessSemantics::LEGACY,
1822               callback.access_semantics_list()[0]);
1823     EXPECT_EQ(CookieAccessSemantics::NONLEGACY,
1824               callback.access_semantics_list()[1]);
1825     EXPECT_EQ(CookieAccessSemantics::UNKNOWN,
1826               callback.access_semantics_list()[2]);
1827     EXPECT_EQ(CookieAccessSemantics::UNKNOWN,
1828               callback.access_semantics_list()[3]);
1829   }
1830 }
1831 
TYPED_TEST_P(CookieStoreTest,DeleteCanonicalCookieAsync)1832 TYPED_TEST_P(CookieStoreTest, DeleteCanonicalCookieAsync) {
1833   CookieStore* cs = this->GetCookieStore();
1834 
1835   // Set two cookies with the same name, and make sure both are set.
1836   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B;Path=/foo"));
1837   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C;Path=/bar"));
1838   EXPECT_EQ(2u, this->GetAllCookies(cs).size());
1839   EXPECT_EQ("A=B", this->GetCookies(cs, this->www_foo_foo_.url()));
1840   EXPECT_EQ("A=C", this->GetCookies(cs, this->www_foo_bar_.url()));
1841 
1842   // Delete the "/foo" cookie, and make sure only it was deleted.
1843   CookieList cookies = this->GetCookieListWithOptions(
1844       cs, this->www_foo_foo_.url(), CookieOptions::MakeAllInclusive());
1845   ASSERT_EQ(1u, cookies.size());
1846   EXPECT_EQ(1u, this->DeleteCanonicalCookie(cs, cookies[0]));
1847   EXPECT_EQ(1u, this->GetAllCookies(cs).size());
1848   EXPECT_EQ("", this->GetCookies(cs, this->www_foo_foo_.url()));
1849   EXPECT_EQ("A=C", this->GetCookies(cs, this->www_foo_bar_.url()));
1850 
1851   // Deleting the "/foo" cookie again should fail.
1852   EXPECT_EQ(0u, this->DeleteCanonicalCookie(cs, cookies[0]));
1853 
1854   // Try to delete the "/bar" cookie after overwriting it with a new cookie.
1855   cookies = this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(),
1856                                            CookieOptions::MakeAllInclusive());
1857   ASSERT_EQ(1u, cookies.size());
1858   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=D;Path=/bar"));
1859   EXPECT_EQ(0u, this->DeleteCanonicalCookie(cs, cookies[0]));
1860   EXPECT_EQ(1u, this->GetAllCookies(cs).size());
1861   EXPECT_EQ("A=D", this->GetCookies(cs, this->www_foo_bar_.url()));
1862 
1863   // Delete the new "/bar" cookie.
1864   cookies = this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(),
1865                                            CookieOptions::MakeAllInclusive());
1866   ASSERT_EQ(1u, cookies.size());
1867   EXPECT_EQ(1u, this->DeleteCanonicalCookie(cs, cookies[0]));
1868   EXPECT_EQ(0u, this->GetAllCookies(cs).size());
1869   EXPECT_EQ("", this->GetCookies(cs, this->www_foo_bar_.url()));
1870 }
1871 
TYPED_TEST_P(CookieStoreTest,DeleteSessionCookie)1872 TYPED_TEST_P(CookieStoreTest, DeleteSessionCookie) {
1873   CookieStore* cs = this->GetCookieStore();
1874   // Create a session cookie and a persistent cookie.
1875   EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
1876                               std::string(kValidCookieLine)));
1877   EXPECT_TRUE(this->SetCookie(
1878       cs, this->http_www_foo_.url(),
1879       this->http_www_foo_.Format("C=D; path=/; domain=%D" +
1880                                  FutureCookieExpirationString())));
1881   this->MatchCookieLines("A=B; C=D",
1882                          this->GetCookies(cs, this->http_www_foo_.url()));
1883   // Delete the session cookie.
1884   this->DeleteSessionCookies(cs);
1885   // Check that the session cookie has been deleted but not the persistent one.
1886   EXPECT_EQ("C=D", this->GetCookies(cs, this->http_www_foo_.url()));
1887 }
1888 
1889 REGISTER_TYPED_TEST_SUITE_P(CookieStoreTest,
1890                             FilterTest,
1891                             SetCanonicalCookieTest,
1892                             SecureEnforcement,
1893                             SecureCookieLocalhost,
1894                             EmptyKeyTest,
1895                             DomainTest,
1896                             DomainWithTrailingDotTest,
1897                             ValidSubdomainTest,
1898                             InvalidDomainTest,
1899                             InvalidDomainSameDomainAndRegistry,
1900                             DomainWithoutLeadingDotParentDomain,
1901                             DomainWithoutLeadingDotSameDomain,
1902                             CaseInsensitiveDomainTest,
1903                             TestIpAddress,
1904                             TestIpAddressNoDomainCookies,
1905                             TestTLD,
1906                             TestTLDWithTerminalDot,
1907                             TestSubdomainSettingCookiesOnUnknownTLD,
1908                             TestSubdomainSettingCookiesOnKnownTLD,
1909                             TestSubdomainSettingCookiesOnKnownDottedTLD,
1910                             TestSettingCookiesOnUnknownTLD,
1911                             TestSettingCookiesWithHostDomainOnUnknownTLD,
1912                             TestHostEndsWithDot,
1913                             InvalidScheme,
1914                             InvalidScheme_Read,
1915                             PathTest,
1916                             EmptyExpires,
1917                             HttpOnlyTest,
1918                             TestCookieDeletion,
1919                             TestDeleteAll,
1920                             TestDeleteAllCreatedInTimeRange,
1921                             TestDeleteAllWithInfo,
1922                             TestSecure,
1923                             NetUtilCookieTest,
1924                             OverwritePersistentCookie,
1925                             EmptyName,
1926                             CookieOrdering,
1927                             GetAllCookiesAsync,
1928                             GetAllCookiesWithAccessSemanticsAsync,
1929                             DeleteCanonicalCookieAsync,
1930                             DeleteSessionCookie);
1931 
1932 }  // namespace net
1933 
1934 #endif  // NET_COOKIES_COOKIE_STORE_UNITTEST_H_
1935