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