• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <set>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
16 #include "base/functional/bind.h"
17 #include "base/strings/string_tokenizer.h"
18 #include "base/task/current_thread.h"
19 #include "base/task/single_thread_task_runner.h"
20 #include "base/test/task_environment.h"
21 #include "base/threading/thread.h"
22 #include "base/time/time.h"
23 #include "build/build_config.h"
24 #include "net/cookies/canonical_cookie.h"
25 #include "net/cookies/cookie_store.h"
26 #include "net/cookies/cookie_store_test_callbacks.h"
27 #include "net/cookies/cookie_store_test_helpers.h"
28 #include "net/cookies/test_cookie_access_delegate.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "third_party/abseil-cpp/absl/types/optional.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       absl::optional<base::Time> server_time = absl::nullopt,
222       absl::optional<base::Time> system_time = absl::nullopt,
223       absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt) {
224     // Ensure a different Creation date to guarantee sort order for testing
225     static base::Time last = base::Time::Min();
226     last = base::Time::Now() == last ? last + base::Microseconds(1)
227                                      : base::Time::Now();
228 
229     auto cookie =
230         CanonicalCookie::Create(url, cookie_line, system_time.value_or(last),
231                                 server_time, cookie_partition_key);
232 
233     if (!cookie)
234       return false;
235     DCHECK(cs);
236     ResultSavingCookieCallback<CookieAccessResult> callback;
237     cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
238                                 callback.MakeCallback());
239     callback.WaitUntilDone();
240     return callback.result().status.IsInclude();
241   }
242 
SetCanonicalCookie(CookieStore * cs,std::unique_ptr<CanonicalCookie> cookie,const GURL & source_url,bool can_modify_httponly)243   bool SetCanonicalCookie(CookieStore* cs,
244                           std::unique_ptr<CanonicalCookie> cookie,
245                           const GURL& source_url,
246                           bool can_modify_httponly) {
247     DCHECK(cs);
248     ResultSavingCookieCallback<CookieAccessResult> callback;
249     CookieOptions options;
250     if (can_modify_httponly)
251       options.set_include_httponly();
252     options.set_same_site_cookie_context(
253         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
254     cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
255                                 callback.MakeCallback());
256     callback.WaitUntilDone();
257     return callback.result().status.IsInclude();
258   }
259 
SetCookieWithSystemTime(CookieStore * cs,const GURL & url,const std::string & cookie_line,const base::Time & system_time)260   bool SetCookieWithSystemTime(CookieStore* cs,
261                                const GURL& url,
262                                const std::string& cookie_line,
263                                const base::Time& system_time) {
264     CookieOptions options;
265     if (!CookieStoreTestTraits::supports_http_only)
266       options.set_include_httponly();
267     options.set_same_site_cookie_context(
268         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
269     return CreateAndSetCookie(cs, url, cookie_line, options, absl::nullopt,
270                               absl::make_optional(system_time));
271   }
272 
SetCookieWithServerTime(CookieStore * cs,const GURL & url,const std::string & cookie_line,const base::Time & server_time)273   bool SetCookieWithServerTime(CookieStore* cs,
274                                const GURL& url,
275                                const std::string& cookie_line,
276                                const base::Time& server_time) {
277     CookieOptions options;
278     if (!CookieStoreTestTraits::supports_http_only)
279       options.set_include_httponly();
280     options.set_same_site_cookie_context(
281         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
282     return CreateAndSetCookie(cs, url, cookie_line, options,
283                               absl::make_optional(server_time));
284   }
285 
286   bool SetCookie(
287       CookieStore* cs,
288       const GURL& url,
289       const std::string& cookie_line,
290       absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt) {
291     CookieOptions options;
292     if (!CookieStoreTestTraits::supports_http_only)
293       options.set_include_httponly();
294     options.set_same_site_cookie_context(
295         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
296     return CreateAndSetCookie(cs, url, cookie_line, options, absl::nullopt,
297                               absl::nullopt, cookie_partition_key);
298   }
299 
CreateAndSetCookieReturnStatus(CookieStore * cs,const GURL & url,const std::string & cookie_line)300   CookieInclusionStatus CreateAndSetCookieReturnStatus(
301       CookieStore* cs,
302       const GURL& url,
303       const std::string& cookie_line) {
304     CookieInclusionStatus create_status;
305     auto cookie = CanonicalCookie::Create(
306         url, cookie_line, base::Time::Now(), absl::nullopt /* server_time */,
307         absl::nullopt /* cookie_partition_key */, &create_status);
308     if (!cookie)
309       return create_status;
310 
311     CookieOptions options;
312     if (!CookieStoreTestTraits::supports_http_only)
313       options.set_include_httponly();
314     // Allow setting SameSite cookies.
315     options.set_same_site_cookie_context(
316         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
317 
318     DCHECK(cs);
319     ResultSavingCookieCallback<CookieAccessResult> callback;
320     cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
321                                 callback.MakeCallback());
322     callback.WaitUntilDone();
323     return callback.result().status;
324   }
325 
SetCanonicalCookieReturnAccessResult(CookieStore * cs,std::unique_ptr<CanonicalCookie> cookie,const GURL & source_url,bool can_modify_httponly)326   CookieAccessResult SetCanonicalCookieReturnAccessResult(
327       CookieStore* cs,
328       std::unique_ptr<CanonicalCookie> cookie,
329       const GURL& source_url,
330       bool can_modify_httponly) {
331     DCHECK(cs);
332     ResultSavingCookieCallback<CookieAccessResult> callback;
333     CookieOptions options;
334     if (can_modify_httponly)
335       options.set_include_httponly();
336     options.set_same_site_cookie_context(
337         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
338     cs->SetCanonicalCookieAsync(std::move(cookie), source_url, options,
339                                 callback.MakeCallback());
340     callback.WaitUntilDone();
341     return callback.result();
342   }
343 
DeleteCanonicalCookie(CookieStore * cs,const CanonicalCookie & cookie)344   uint32_t DeleteCanonicalCookie(CookieStore* cs,
345                                  const CanonicalCookie& cookie) {
346     DCHECK(cs);
347     ResultSavingCookieCallback<uint32_t> callback;
348     cs->DeleteCanonicalCookieAsync(cookie, callback.MakeCallback());
349     callback.WaitUntilDone();
350     return callback.result();
351   }
352 
DeleteCreatedInTimeRange(CookieStore * cs,const TimeRange & creation_range)353   uint32_t DeleteCreatedInTimeRange(CookieStore* cs,
354                                     const TimeRange& creation_range) {
355     DCHECK(cs);
356     ResultSavingCookieCallback<uint32_t> callback;
357     cs->DeleteAllCreatedInTimeRangeAsync(creation_range,
358                                          callback.MakeCallback());
359     callback.WaitUntilDone();
360     return callback.result();
361   }
362 
DeleteAllCreatedInTimeRange(CookieStore * cs,CookieDeletionInfo delete_info)363   uint32_t DeleteAllCreatedInTimeRange(CookieStore* cs,
364                                        CookieDeletionInfo delete_info) {
365     DCHECK(cs);
366     ResultSavingCookieCallback<uint32_t> callback;
367     cs->DeleteAllMatchingInfoAsync(std::move(delete_info),
368                                    callback.MakeCallback());
369     callback.WaitUntilDone();
370     return callback.result();
371   }
372 
DeleteSessionCookies(CookieStore * cs)373   uint32_t DeleteSessionCookies(CookieStore* cs) {
374     DCHECK(cs);
375     ResultSavingCookieCallback<uint32_t> callback;
376     cs->DeleteSessionCookiesAsync(callback.MakeCallback());
377     callback.WaitUntilDone();
378     return callback.result();
379   }
380 
DeleteAll(CookieStore * cs)381   uint32_t DeleteAll(CookieStore* cs) {
382     DCHECK(cs);
383     ResultSavingCookieCallback<uint32_t> callback;
384     cs->DeleteAllAsync(callback.MakeCallback());
385     callback.WaitUntilDone();
386     return callback.result();
387   }
388 
FindAndDeleteCookie(CookieStore * cs,const std::string & domain,const std::string & name)389   bool FindAndDeleteCookie(CookieStore* cs,
390                            const std::string& domain,
391                            const std::string& name) {
392     for (auto& cookie : this->GetAllCookies(cs)) {
393       if (cookie.Domain() == domain && cookie.Name() == name)
394         return this->DeleteCanonicalCookie(cs, cookie);
395     }
396 
397     return false;
398   }
399 
400   // Returns the CookieStore for the test - each test only uses one CookieStore.
GetCookieStore()401   CookieStore* GetCookieStore() {
402     if (!cookie_store_)
403       cookie_store_ = CookieStoreTestTraits::Create();
404     return cookie_store_.get();
405   }
406 
407   // Resets CookieStore.
ResetCookieStore()408   void ResetCookieStore() { cookie_store_.reset(); }
409 
410   // Compares two cookie lines.
MatchCookieLines(const std::string & line1,const std::string & line2)411   void MatchCookieLines(const std::string& line1, const std::string& line2) {
412     EXPECT_EQ(TokenizeCookieLine(line1), TokenizeCookieLine(line2));
413   }
414 
415   // Check the cookie line by polling until equality or a timeout is reached.
MatchCookieLineWithTimeout(CookieStore * cs,const GURL & url,const std::string & line)416   void MatchCookieLineWithTimeout(CookieStore* cs,
417                                   const GURL& url,
418                                   const std::string& line) {
419     std::string cookies = GetCookies(cs, url);
420     bool matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
421     base::Time polling_end_date =
422         base::Time::Now() +
423         base::Milliseconds(
424             CookieStoreTestTraits::creation_time_granularity_in_ms);
425 
426     while (!matched && base::Time::Now() <= polling_end_date) {
427       base::PlatformThread::Sleep(base::Milliseconds(10));
428       cookies = GetCookies(cs, url);
429       matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies));
430     }
431 
432     EXPECT_TRUE(matched) << "\"" << cookies << "\" does not match \"" << line
433                          << "\"";
434   }
435 
436   const CookieURLHelper http_www_foo_;
437   const CookieURLHelper http_bar_foo_;
438   const CookieURLHelper http_www_bar_;
439   const CookieURLHelper https_www_foo_;
440   const CookieURLHelper ftp_foo_;
441   const CookieURLHelper ws_www_foo_;
442   const CookieURLHelper wss_www_foo_;
443   const CookieURLHelper www_foo_foo_;
444   const CookieURLHelper www_foo_bar_;
445   const CookieURLHelper http_baz_com_;
446   const CookieURLHelper http_bar_com_;
447   const CookieURLHelper https_www_bar_;
448 
449   std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_;
450 
451  private:
452   // Returns a set of strings of type "name=value". Fails in case of duplicate.
TokenizeCookieLine(const std::string & line)453   std::set<std::string> TokenizeCookieLine(const std::string& line) {
454     std::set<std::string> tokens;
455     base::StringTokenizer tokenizer(line, " ;");
456     while (tokenizer.GetNext())
457       EXPECT_TRUE(tokens.insert(tokenizer.token()).second);
458     return tokens;
459   }
460 
461   std::unique_ptr<CookieStore> cookie_store_;
462 };
463 TYPED_TEST_SUITE_P(CookieStoreTest);
464 
TYPED_TEST_P(CookieStoreTest,FilterTest)465 TYPED_TEST_P(CookieStoreTest, FilterTest) {
466   CookieStore* cs = this->GetCookieStore();
467 
468   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
469   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
470   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
471 
472   std::unique_ptr<CanonicalCookie> cc(CanonicalCookie::CreateSanitizedCookie(
473       this->www_foo_foo_.url(), "A", "B", std::string(), "/foo", one_hour_ago,
474       one_hour_from_now, base::Time(), false, false,
475       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false,
476       absl::nullopt));
477   ASSERT_TRUE(cc);
478   EXPECT_TRUE(this->SetCanonicalCookie(
479       cs, std::move(cc), this->www_foo_foo_.url(), true /*modify_httponly*/));
480 
481   // Note that for the creation time to be set exactly, without modification,
482   // it must be different from the one set by the line above.
483   cc = CanonicalCookie::CreateSanitizedCookie(
484       this->www_foo_bar_.url(), "C", "D", this->www_foo_bar_.domain(), "/bar",
485       two_hours_ago, base::Time(), one_hour_ago, false, true,
486       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false,
487       absl::nullopt);
488   ASSERT_TRUE(cc);
489   EXPECT_TRUE(this->SetCanonicalCookie(
490       cs, std::move(cc), this->www_foo_bar_.url(), true /*modify_httponly*/));
491 
492   // We permit creating a a secure cookie with an HTTP URL (since the
493   // CookieAccessDelegate may permit some sites to be used as such for
494   // development environment purposes), but it can't actually be set in this
495   // test since no such delegate is configured here.
496   cc = CanonicalCookie::CreateSanitizedCookie(
497       this->http_www_foo_.url(), "E", "F", std::string(), std::string(),
498       base::Time(), base::Time(), base::Time(), true, false,
499       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false,
500       absl::nullopt);
501   ASSERT_TRUE(cc);
502   EXPECT_FALSE(this->SetCanonicalCookie(
503       cs, std::move(cc), this->http_www_foo_.url(), true /*modify_httponly*/));
504 
505   cc = CanonicalCookie::CreateSanitizedCookie(
506       this->https_www_foo_.url(), "E", "F", std::string(), std::string(),
507       base::Time(), base::Time(), base::Time(), true, false,
508       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false,
509       absl::nullopt);
510   ASSERT_TRUE(cc);
511   EXPECT_TRUE(this->SetCanonicalCookie(
512       cs, std::move(cc), this->https_www_foo_.url(), true /*modify_httponly*/));
513 
514   // Get all the cookies for a given URL, regardless of properties. This 'get()'
515   // operation shouldn't update the access time, as the test checks that the
516   // access time is set properly upon creation. Updating the access time would
517   // make that difficult.
518   CookieList cookies = this->GetAllCookiesForURL(cs, this->www_foo_foo_.url());
519   CookieList::iterator it = cookies.begin();
520 
521   ASSERT_TRUE(it != cookies.end());
522   EXPECT_EQ("A", it->Name());
523   EXPECT_EQ("B", it->Value());
524   EXPECT_EQ(this->www_foo_foo_.host(), it->Domain());
525   EXPECT_EQ("/foo", it->Path());
526   EXPECT_EQ(one_hour_ago, it->CreationDate());
527   EXPECT_TRUE(it->IsPersistent());
528   // Expect expiration date is in the right range.  Some cookie implementations
529   // may not record it with millisecond accuracy.
530   EXPECT_LE((one_hour_from_now - it->ExpiryDate()).magnitude().InSeconds(), 5);
531   // Some CookieStores don't store last access date.
532   if (!it->LastAccessDate().is_null())
533     EXPECT_EQ(one_hour_ago, it->LastAccessDate());
534   EXPECT_FALSE(it->IsSecure());
535   EXPECT_FALSE(it->IsHttpOnly());
536 
537   ASSERT_TRUE(++it == cookies.end());
538 
539   // Verify that the cookie was set as 'httponly' by passing in a CookieOptions
540   // that excludes them and getting an empty result.
541   if (TypeParam::supports_http_only) {
542     net::CookieOptions options;
543     options.set_same_site_cookie_context(
544         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
545     cookies =
546         this->GetCookieListWithOptions(cs, this->www_foo_bar_.url(), options);
547     it = cookies.begin();
548     ASSERT_TRUE(it == cookies.end());
549   }
550 
551   // Get the cookie using the wide open |options|:
552   cookies = this->GetAllCookiesForURL(cs, this->www_foo_bar_.url());
553   it = cookies.begin();
554 
555   ASSERT_TRUE(it != cookies.end());
556   EXPECT_EQ("C", it->Name());
557   EXPECT_EQ("D", it->Value());
558   EXPECT_EQ(this->www_foo_bar_.Format(".%D"), it->Domain());
559   EXPECT_EQ("/bar", it->Path());
560   EXPECT_EQ(two_hours_ago, it->CreationDate());
561   EXPECT_FALSE(it->IsPersistent());
562   // Some CookieStores don't store last access date.
563   if (!it->LastAccessDate().is_null())
564     EXPECT_EQ(one_hour_ago, it->LastAccessDate());
565   EXPECT_FALSE(it->IsSecure());
566   EXPECT_TRUE(it->IsHttpOnly());
567 
568   EXPECT_TRUE(++it == cookies.end());
569 
570   cookies = this->GetAllCookiesForURL(cs, this->https_www_foo_.url());
571   it = cookies.begin();
572 
573   ASSERT_TRUE(it != cookies.end());
574   EXPECT_EQ("E", it->Name());
575   EXPECT_EQ("F", it->Value());
576   EXPECT_EQ("/", it->Path());
577   EXPECT_EQ(this->https_www_foo_.host(), it->Domain());
578   // Cookie should have its creation time set, and be in a reasonable range.
579   EXPECT_LE((base::Time::Now() - it->CreationDate()).magnitude().InMinutes(),
580             2);
581   EXPECT_FALSE(it->IsPersistent());
582   // Some CookieStores don't store last access date.
583   if (!it->LastAccessDate().is_null())
584     EXPECT_EQ(it->CreationDate(), it->LastAccessDate());
585   EXPECT_TRUE(it->IsSecure());
586   EXPECT_FALSE(it->IsHttpOnly());
587 
588   EXPECT_TRUE(++it == cookies.end());
589 }
590 
TYPED_TEST_P(CookieStoreTest,SetCanonicalCookieTest)591 TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
592   CookieStore* cs = this->GetCookieStore();
593 
594   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
595   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
596   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
597 
598   std::string foo_foo_host(this->www_foo_foo_.url().host());
599   std::string foo_bar_domain(this->www_foo_bar_.domain());
600   std::string http_foo_host(this->http_www_foo_.url().host());
601   std::string https_foo_host(this->https_www_foo_.url().host());
602 
603   EXPECT_TRUE(this->SetCanonicalCookie(
604       cs,
605       CanonicalCookie::CreateUnsafeCookieForTesting(
606           "A", "B", foo_foo_host, "/foo", one_hour_ago, one_hour_from_now,
607           base::Time(), base::Time(), false /* secure */, false /* httponly */,
608           CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false),
609       this->www_foo_foo_.url(), true));
610   EXPECT_TRUE(this->SetCanonicalCookie(
611       cs,
612       CanonicalCookie::CreateUnsafeCookieForTesting(
613           "C", "D", "." + foo_bar_domain, "/bar", two_hours_ago, base::Time(),
614           one_hour_ago, one_hour_ago, false, true, CookieSameSite::LAX_MODE,
615           COOKIE_PRIORITY_DEFAULT, false),
616       this->www_foo_bar_.url(), true));
617 
618   // A secure source is required for setting secure cookies.
619   EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
620                       cs,
621                       CanonicalCookie::CreateUnsafeCookieForTesting(
622                           "E", "F", http_foo_host, "/", base::Time(),
623                           base::Time(), base::Time(), base::Time(), true, false,
624                           CookieSameSite::NO_RESTRICTION,
625                           COOKIE_PRIORITY_DEFAULT, false),
626                       this->http_www_foo_.url(), true)
627                   .status.HasExclusionReason(
628                       CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
629 
630   // A Secure cookie can be created from an insecure URL, but is rejected upon
631   // setting.
632   CookieInclusionStatus status;
633   auto cookie = CanonicalCookie::Create(
634       this->http_www_foo_.url(), "foo=1; Secure", base::Time::Now(),
635       absl::nullopt /* server_time */, absl::nullopt /* cookie_partition_key */,
636       &status);
637   EXPECT_TRUE(cookie->IsSecure());
638   EXPECT_TRUE(status.IsInclude());
639   EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
640                       cs, std::move(cookie), this->http_www_foo_.url(), true)
641                   .status.HasExclusionReason(
642                       CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
643 
644   // A secure source is also required for overwriting secure cookies.  Writing
645   // a secure cookie then overwriting it from a non-secure source should fail.
646   EXPECT_TRUE(this->SetCanonicalCookie(
647       cs,
648       CanonicalCookie::CreateUnsafeCookieForTesting(
649           "E", "F", https_foo_host, "/", base::Time(), base::Time(),
650           base::Time(), base::Time(), true /* secure */, false /* httponly */,
651           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
652           false /* same_party */),
653       this->https_www_foo_.url(), true /* modify_http_only */));
654 
655   EXPECT_TRUE(
656       this->SetCanonicalCookieReturnAccessResult(
657               cs,
658               CanonicalCookie::CreateUnsafeCookieForTesting(
659                   "E", "F", http_foo_host, "/", base::Time(), base::Time(),
660                   base::Time(), base::Time(), true /* secure */,
661                   false /* httponly */, CookieSameSite::NO_RESTRICTION,
662                   COOKIE_PRIORITY_DEFAULT, false /* same_party */),
663               this->http_www_foo_.url(), true /* modify_http_only */)
664           .status.HasExclusionReason(
665               CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
666 
667   if (TypeParam::supports_http_only) {
668     // Permission to modify http only cookies is required to set an
669     // httponly cookie.
670     EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
671                         cs,
672                         CanonicalCookie::CreateUnsafeCookieForTesting(
673                             "G", "H", http_foo_host, "/unique", base::Time(),
674                             base::Time(), base::Time(), base::Time(),
675                             false /* secure */, true /* httponly */,
676                             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
677                             false /* same_party */),
678                         this->http_www_foo_.url(), false /* modify_http_only */)
679                     .status.HasExclusionReason(
680                         CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
681 
682     // A HttpOnly cookie can be created, but is rejected
683     // upon setting if the options do not specify include_httponly.
684     CookieInclusionStatus create_status;
685     auto c = CanonicalCookie::Create(
686         this->http_www_foo_.url(), "bar=1; HttpOnly", base::Time::Now(),
687         absl::nullopt /* server_time */,
688         absl::nullopt /* cookie_partition_key */, &create_status);
689     EXPECT_TRUE(c->IsHttpOnly());
690     EXPECT_TRUE(create_status.IsInclude());
691     EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
692                         cs, std::move(c), this->http_www_foo_.url(),
693                         false /* can_modify_httponly */)
694                     .status.HasExclusionReason(
695                         CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
696 
697     // Permission to modify httponly cookies is also required to overwrite
698     // an httponly cookie.
699     EXPECT_TRUE(this->SetCanonicalCookie(
700         cs,
701         CanonicalCookie::CreateUnsafeCookieForTesting(
702             "G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
703             base::Time(), base::Time(), false /* secure */, true /* httponly */,
704             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
705             false /* same_party */),
706         this->http_www_foo_.url(), true /* modify_http_only */));
707 
708     EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
709                         cs,
710                         CanonicalCookie::CreateUnsafeCookieForTesting(
711                             "G", "H", http_foo_host, "/unique", base::Time(),
712                             base::Time(), base::Time(), base::Time(),
713                             false /* secure */, true /* httponly */,
714                             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
715                             false /* same_party */),
716                         this->http_www_foo_.url(), false /* modify_http_only */)
717                     .status.HasExclusionReason(
718                         CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
719   } else {
720     // Leave store in same state as if the above tests had been run.
721     EXPECT_TRUE(this->SetCanonicalCookie(
722         cs,
723         CanonicalCookie::CreateUnsafeCookieForTesting(
724             "G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
725             base::Time(), base::Time(), false /* secure */, true /* httponly */,
726             CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
727             false /* same_party */),
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->IsSecure());
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->IsSecure());
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->IsSecure());
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, false /* same_party */),
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, false /* same_party */),
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, false /* same_party */),
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, false /* same_party */),
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   absl::optional<base::Time> server_time =
1324       absl::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