tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestCookie.cpp (57103B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "TestCommon.h"
      7 #include "gtest/gtest.h"
      8 #include "nsContentUtils.h"
      9 #include "nsICookieService.h"
     10 #include "nsICookieManager.h"
     11 #include "nsICookie.h"
     12 #include "plstr.h"
     13 #include "nsNetUtil.h"
     14 #include "nsIChannel.h"
     15 #include "nsIPrincipal.h"
     16 #include "nsIScriptSecurityManager.h"
     17 #include "nsServiceManagerUtils.h"
     18 #include "nsNetCID.h"
     19 #include "nsIPrefBranch.h"
     20 #include "nsIPrefService.h"
     21 #include "mozilla/dom/Document.h"
     22 #include "mozilla/gtest/MozAssertions.h"
     23 #include "mozilla/Preferences.h"
     24 #include "mozilla/net/CookieJarSettings.h"
     25 #include "mozilla/net/CookieValidation.h"
     26 #include "Cookie.h"
     27 #include "CookieParser.h"
     28 #include "nsIURI.h"
     29 #include "nsIConsoleReportCollector.h"
     30 
     31 using namespace mozilla;
     32 using namespace mozilla::net;
     33 
     34 static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
     35 static NS_DEFINE_CID(kPrefServiceCID, NS_PREFSERVICE_CID);
     36 
     37 // various pref strings
     38 static const char kCookiesPermissions[] = "network.cookie.cookieBehavior";
     39 static const char kCookiesMaxPerHost[] = "network.cookie.maxPerHost";
     40 
     41 void SetACookieInternal(nsICookieService* aCookieService, const char* aSpec,
     42                        const nsTArray<const char*>& aCookieStrings,
     43                        bool aAllowed) {
     44  nsCOMPtr<nsIURI> uri;
     45  NS_NewURI(getter_AddRefs(uri), aSpec);
     46 
     47  // We create a dummy channel using the aSpec to simulate same-siteness
     48  nsresult rv0;
     49  nsCOMPtr<nsIScriptSecurityManager> ssm =
     50      do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv0);
     51  ASSERT_NS_SUCCEEDED(rv0);
     52  nsCOMPtr<nsIPrincipal> specPrincipal;
     53  nsCString tmpString(aSpec);
     54  ssm->CreateContentPrincipalFromOrigin(tmpString,
     55                                        getter_AddRefs(specPrincipal));
     56 
     57  nsCOMPtr<nsIChannel> dummyChannel;
     58  NS_NewChannel(getter_AddRefs(dummyChannel), uri, specPrincipal,
     59                nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
     60                nsIContentPolicy::TYPE_OTHER);
     61 
     62  nsCOMPtr<nsICookieJarSettings> cookieJarSettings =
     63      aAllowed
     64          ? CookieJarSettings::Create(CookieJarSettings::eRegular,
     65                                      /* shouldResistFingerprinting */ false)
     66          : CookieJarSettings::GetBlockingAll(
     67                /* shouldResistFingerprinting */ false);
     68  MOZ_RELEASE_ASSERT(cookieJarSettings);
     69 
     70  nsCOMPtr<nsILoadInfo> loadInfo = dummyChannel->LoadInfo();
     71  loadInfo->SetCookieJarSettings(cookieJarSettings);
     72 
     73  for (const char* cookieString : aCookieStrings) {
     74    nsresult rv = aCookieService->SetCookieStringFromHttp(
     75        uri, nsDependentCString(cookieString), dummyChannel);
     76    EXPECT_NS_SUCCEEDED(rv);
     77  }
     78 }
     79 
     80 void SetACookieJarBlocked(nsICookieService* aCookieService, const char* aSpec,
     81                          const char* aCookieString) {
     82  nsTArray<const char*> cookieStrings;
     83  cookieStrings.AppendElement(aCookieString);
     84  SetACookieInternal(aCookieService, aSpec, cookieStrings, false);
     85 }
     86 
     87 void SetACookie(nsICookieService* aCookieService, const char* aSpec,
     88                const char* aCookieString) {
     89  nsTArray<const char*> cookieStrings;
     90  cookieStrings.AppendElement(aCookieString);
     91  SetACookieInternal(aCookieService, aSpec, cookieStrings, true);
     92 }
     93 
     94 void SetACookie(nsICookieService* aCookieService, const char* aSpec,
     95                const nsTArray<const char*>& aCookieStrings) {
     96  SetACookieInternal(aCookieService, aSpec, aCookieStrings, true);
     97 }
     98 
     99 // The cookie string is returned via aCookie.
    100 void GetACookie(nsICookieService* aCookieService, const char* aSpec,
    101                nsACString& aCookie) {
    102  nsCOMPtr<nsIURI> uri;
    103  NS_NewURI(getter_AddRefs(uri), aSpec);
    104 
    105  nsCOMPtr<nsIIOService> service = do_GetIOService();
    106 
    107  nsCOMPtr<nsIChannel> channel;
    108  (void)service->NewChannelFromURI(
    109      uri, nullptr, nsContentUtils::GetSystemPrincipal(),
    110      nsContentUtils::GetSystemPrincipal(), 0, nsIContentPolicy::TYPE_DOCUMENT,
    111      getter_AddRefs(channel));
    112 
    113  (void)aCookieService->GetCookieStringFromHttp(uri, channel, aCookie);
    114 }
    115 
    116 // The cookie string is returned via aCookie.
    117 void GetACookieNoHttp(nsICookieService* aCookieService, const char* aSpec,
    118                      nsACString& aCookie) {
    119  nsCOMPtr<nsIURI> uri;
    120  NS_NewURI(getter_AddRefs(uri), aSpec);
    121 
    122  RefPtr<BasePrincipal> principal =
    123      BasePrincipal::CreateContentPrincipal(uri, OriginAttributes());
    124  MOZ_RELEASE_ASSERT(principal);
    125 
    126  nsCOMPtr<mozilla::dom::Document> document;
    127  nsresult rv =
    128      NS_NewDOMDocument(getter_AddRefs(document),
    129                        u""_ns,   // aNamespaceURI
    130                        u""_ns,   // aQualifiedName
    131                        nullptr,  // aDoctype
    132                        uri, uri, principal,
    133                        mozilla::dom::LoadedAsData::No,  // aLoadedAsData
    134                        nullptr,                         // aEventObject
    135                        DocumentFlavor::HTML);
    136  (void)NS_WARN_IF(NS_FAILED(rv));
    137 
    138  nsAutoString cookie;
    139  ErrorResult err;
    140  document->GetCookie(cookie, err);
    141  EXPECT_TRUE(!err.Failed());
    142 
    143  CopyUTF16toUTF8(cookie, aCookie);
    144 }
    145 
    146 // some #defines for comparison rules
    147 #define MUST_BE_NULL 0
    148 #define MUST_EQUAL 1
    149 #define MUST_CONTAIN 2
    150 #define MUST_NOT_CONTAIN 3
    151 #define MUST_NOT_EQUAL 4
    152 
    153 // a simple helper function to improve readability:
    154 // takes one of the #defined rules above, and performs the appropriate test.
    155 // true means the test passed; false means the test failed.
    156 static inline bool CheckResult(const char* aLhs, uint32_t aRule,
    157                               const char* aRhs = nullptr) {
    158  switch (aRule) {
    159    case MUST_BE_NULL:
    160      return !aLhs || !*aLhs;
    161 
    162    case MUST_EQUAL:
    163      return !PL_strcmp(aLhs, aRhs);
    164 
    165    case MUST_NOT_EQUAL:
    166      return PL_strcmp(aLhs, aRhs);
    167 
    168    case MUST_CONTAIN:
    169      return strstr(aLhs, aRhs) != nullptr;
    170 
    171    case MUST_NOT_CONTAIN:
    172      return strstr(aLhs, aRhs) == nullptr;
    173 
    174    default:
    175      return false;  // failure
    176  }
    177 }
    178 
    179 void InitPrefs(nsIPrefBranch* aPrefBranch) {
    180  // init some relevant prefs, so the tests don't go awry.
    181  // we use the most restrictive set of prefs we can;
    182  // however, we don't test third party blocking here.
    183  aPrefBranch->SetIntPref(kCookiesPermissions, 0);  // accept all
    184  // Set quotaPerHost to maxPerHost, so there is only one cookie
    185  // will be evicted everytime.
    186  aPrefBranch->SetIntPref(kPrefCookieQuotaPerHost, 50);
    187  // Set the base domain limit to 50 so we have a known value.
    188  aPrefBranch->SetIntPref(kCookiesMaxPerHost, 50);
    189 
    190  // SameSite=None by default. We have other tests for lax-by-default.
    191  // XXX: Bug 1617611 - Fix all the tests broken by "cookies SameSite=Lax by
    192  // default"
    193  Preferences::SetBool("network.cookie.sameSite.laxByDefault", false);
    194  Preferences::SetBool("network.cookieJarSettings.unblocked_for_testing", true);
    195  Preferences::SetBool("dom.securecontext.allowlist_onions", false);
    196  Preferences::SetBool("network.cookie.sameSite.schemeful", false);
    197 
    198  // Disable a few security checks for document.cookie
    199  Preferences::SetBool("dom.cookie.testing.enabled", true);
    200 }
    201 
    202 TEST(TestCookie, TestCookieMain)
    203 {
    204  nsresult rv0;
    205 
    206  nsCOMPtr<nsICookieService> cookieService =
    207      do_GetService(kCookieServiceCID, &rv0);
    208  ASSERT_NS_SUCCEEDED(rv0);
    209 
    210  nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(kPrefServiceCID, &rv0);
    211  ASSERT_NS_SUCCEEDED(rv0);
    212 
    213  InitPrefs(prefBranch);
    214 
    215  nsCString cookie;
    216 
    217  /* The basic idea behind these tests is the following:
    218   *
    219   * we set() some cookie, then try to get() it in various ways. we have
    220   * several possible tests we perform on the cookie string returned from
    221   * get():
    222   *
    223   * a) check whether the returned string is null (i.e. we got no cookies
    224   *    back). this is used e.g. to ensure a given cookie was deleted
    225   *    correctly, or to ensure a certain cookie wasn't returned to a given
    226   *    host.
    227   * b) check whether the returned string exactly matches a given string.
    228   *    this is used where we want to make sure our cookie service adheres to
    229   *    some strict spec (e.g. ordering of multiple cookies), or where we
    230   *    just know exactly what the returned string should be.
    231   * c) check whether the returned string contains/does not contain a given
    232   *    string. this is used where we don't know/don't care about the
    233   *    ordering of multiple cookies - we just want to make sure the cookie
    234   *    string contains them all, in some order.
    235   *
    236   * NOTE: this testsuite is not yet comprehensive or complete, and is
    237   * somewhat contrived - still under development, and needs improving!
    238   */
    239 
    240  // test some basic variations of the domain & path
    241  SetACookie(cookieService, "http://www.basic.com", "test=basic");
    242  GetACookie(cookieService, "http://www.basic.com", cookie);
    243  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=basic"));
    244  GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt",
    245             cookie);
    246  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=basic"));
    247  GetACookie(cookieService, "http://www.basic.com./", cookie);
    248  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    249  GetACookie(cookieService, "http://www.basic.com.", cookie);
    250  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    251  GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt",
    252             cookie);
    253  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    254  GetACookie(cookieService, "http://www.basic2.com/", cookie);
    255  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    256  SetACookie(cookieService, "http://www.basic.com", "test=basic; max-age=-1");
    257  GetACookie(cookieService, "http://www.basic.com/", cookie);
    258  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    259 
    260  // *** domain tests
    261 
    262  // test some variations of the domain & path, for different domains of
    263  // a domain cookie
    264  SetACookie(cookieService, "http://www.domain.com",
    265             "test=domain; domain=domain.com; sameSite=lax");
    266  GetACookie(cookieService, "http://domain.com", cookie);
    267  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=domain"));
    268  GetACookie(cookieService, "http://domain.com.", cookie);
    269  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    270  GetACookie(cookieService, "http://www.domain.com", cookie);
    271  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=domain"));
    272  GetACookie(cookieService, "http://foo.domain.com", cookie);
    273  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=domain"));
    274  SetACookie(cookieService, "http://www.domain.com",
    275             "test=domain; domain=domain.com; max-age=-1");
    276  GetACookie(cookieService, "http://domain.com", cookie);
    277  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    278 
    279  SetACookie(cookieService, "http://www.domain.com",
    280             "test=domain; domain=.domain.com");
    281  GetACookie(cookieService, "http://domain.com", cookie);
    282  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=domain"));
    283  GetACookie(cookieService, "http://www.domain.com", cookie);
    284  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=domain"));
    285  GetACookie(cookieService, "http://bah.domain.com", cookie);
    286  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=domain"));
    287  SetACookie(cookieService, "http://www.domain.com",
    288             "test=domain; domain=.domain.com; max-age=-1");
    289  GetACookie(cookieService, "http://domain.com", cookie);
    290  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    291 
    292  SetACookie(cookieService, "http://www.domain.com",
    293             "test=domain; domain=.foo.domain.com");
    294  GetACookie(cookieService, "http://foo.domain.com", cookie);
    295  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    296 
    297  SetACookie(cookieService, "http://www.domain.com",
    298             "test=domain; domain=moose.com");
    299  GetACookie(cookieService, "http://foo.domain.com", cookie);
    300  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    301 
    302  SetACookie(cookieService, "http://www.domain.com",
    303             "test=domain; domain=domain.com.");
    304  GetACookie(cookieService, "http://foo.domain.com", cookie);
    305  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    306 
    307  SetACookie(cookieService, "http://www.domain.com",
    308             "test=domain; domain=..domain.com");
    309  GetACookie(cookieService, "http://foo.domain.com", cookie);
    310  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    311 
    312  SetACookie(cookieService, "http://www.domain.com",
    313             "test=domain; domain=..domain.com.");
    314  GetACookie(cookieService, "http://foo.domain.com", cookie);
    315  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    316 
    317  SetACookie(cookieService, "http://path.net/path/file",
    318             R"(test=taco; path="/bogus")");
    319  GetACookie(cookieService, "http://path.net/path/file", cookie);
    320  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=taco"));
    321  SetACookie(cookieService, "http://path.net/path/file",
    322             "test=taco; max-age=-1");
    323  GetACookie(cookieService, "http://path.net/path/file", cookie);
    324  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    325 
    326  // *** path tests
    327 
    328  // test some variations of the domain & path, for different paths of
    329  // a path cookie
    330  SetACookie(cookieService, "http://path.net/path/file",
    331             "test=path; path=/path");
    332  GetACookie(cookieService, "http://path.net/path", cookie);
    333  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    334  GetACookie(cookieService, "http://path.net/path/", cookie);
    335  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    336  GetACookie(cookieService, "http://path.net/path/hithere.foo", cookie);
    337  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    338  GetACookie(cookieService, "http://path.net/path?hithere/foo", cookie);
    339  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    340  GetACookie(cookieService, "http://path.net/path2", cookie);
    341  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    342  GetACookie(cookieService, "http://path.net/path2/", cookie);
    343  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    344  SetACookie(cookieService, "http://path.net/path/file",
    345             "test=path; path=/path; max-age=-1");
    346  GetACookie(cookieService, "http://path.net/path/", cookie);
    347  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    348 
    349  SetACookie(cookieService, "http://path.net/path/file",
    350             "test=path; path=/path/");
    351  GetACookie(cookieService, "http://path.net/path", cookie);
    352  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    353  GetACookie(cookieService, "http://path.net/path/", cookie);
    354  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    355  SetACookie(cookieService, "http://path.net/path/file",
    356             "test=path; path=/path/; max-age=-1");
    357  GetACookie(cookieService, "http://path.net/path/", cookie);
    358  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    359 
    360  // note that a site can set a cookie for a path it's not on.
    361  // this is an intentional deviation from spec (see comments in
    362  // CookieService::CheckPath()), so we test this functionality too
    363  SetACookie(cookieService, "http://path.net/path/file",
    364             "test=path; path=/foo/");
    365  GetACookie(cookieService, "http://path.net/path", cookie);
    366  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    367  GetACookie(cookieService, "http://path.net/foo", cookie);
    368  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    369  SetACookie(cookieService, "http://path.net/path/file",
    370             "test=path; path=/foo/; max-age=-1");
    371  GetACookie(cookieService, "http://path.net/foo/", cookie);
    372  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    373 
    374  // attributes with size > 1024 are ignored.
    375  SetACookie(
    376      cookieService, "http://path.net/",
    377      "test=path; "
    378      "path=/"
    379      "123456789012345678901234567890123456789012345678901234567890123456789012"
    380      "345678901234567890123456789012345678901234567890123456789012345678901234"
    381      "567890123456789012345678901234567890123456789012345678901234567890123456"
    382      "789012345678901234567890123456789012345678901234567890123456789012345678"
    383      "901234567890123456789012345678901234567890123456789012345678901234567890"
    384      "123456789012345678901234567890123456789012345678901234567890123456789012"
    385      "345678901234567890123456789012345678901234567890123456789012345678901234"
    386      "567890123456789012345678901234567890123456789012345678901234567890123456"
    387      "789012345678901234567890123456789012345678901234567890123456789012345678"
    388      "901234567890123456789012345678901234567890123456789012345678901234567890"
    389      "123456789012345678901234567890123456789012345678901234567890123456789012"
    390      "345678901234567890123456789012345678901234567890123456789012345678901234"
    391      "567890123456789012345678901234567890123456789012345678901234567890123456"
    392      "789012345678901234567890123456789012345678901234567890123456789012345678"
    393      "9012345678901234567890/");
    394  GetACookie(
    395      cookieService,
    396      "http://path.net/"
    397      "123456789012345678901234567890123456789012345678901234567890123456789012"
    398      "345678901234567890123456789012345678901234567890123456789012345678901234"
    399      "567890123456789012345678901234567890123456789012345678901234567890123456"
    400      "789012345678901234567890123456789012345678901234567890123456789012345678"
    401      "901234567890123456789012345678901234567890123456789012345678901234567890"
    402      "123456789012345678901234567890123456789012345678901234567890123456789012"
    403      "345678901234567890123456789012345678901234567890123456789012345678901234"
    404      "567890123456789012345678901234567890123456789012345678901234567890123456"
    405      "789012345678901234567890123456789012345678901234567890123456789012345678"
    406      "901234567890123456789012345678901234567890123456789012345678901234567890"
    407      "123456789012345678901234567890123456789012345678901234567890123456789012"
    408      "345678901234567890123456789012345678901234567890123456789012345678901234"
    409      "567890123456789012345678901234567890123456789012345678901234567890123456"
    410      "789012345678901234567890123456789012345678901234567890123456789012345678"
    411      "9012345678901234567890",
    412      cookie);
    413  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    414  GetACookie(cookieService, "http://path.net/", cookie);
    415  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=path"));
    416  // the following cookie has a path > 1024 bytes implicitly specified by the
    417  // uri path
    418  SetACookie(
    419      cookieService,
    420      "http://longpath.net/"
    421      "123456789012345678901234567890123456789012345678901234567890123456789012"
    422      "345678901234567890123456789012345678901234567890123456789012345678901234"
    423      "567890123456789012345678901234567890123456789012345678901234567890123456"
    424      "789012345678901234567890123456789012345678901234567890123456789012345678"
    425      "901234567890123456789012345678901234567890123456789012345678901234567890"
    426      "123456789012345678901234567890123456789012345678901234567890123456789012"
    427      "345678901234567890123456789012345678901234567890123456789012345678901234"
    428      "567890123456789012345678901234567890123456789012345678901234567890123456"
    429      "789012345678901234567890123456789012345678901234567890123456789012345678"
    430      "901234567890123456789012345678901234567890123456789012345678901234567890"
    431      "123456789012345678901234567890123456789012345678901234567890123456789012"
    432      "345678901234567890123456789012345678901234567890123456789012345678901234"
    433      "567890123456789012345678901234567890123456789012345678901234567890123456"
    434      "789012345678901234567890123456789012345678901234567890123456789012345678"
    435      "9012345678901234567890/",
    436      "test=path");
    437  GetACookie(
    438      cookieService,
    439      "http://longpath.net/"
    440      "123456789012345678901234567890123456789012345678901234567890123456789012"
    441      "345678901234567890123456789012345678901234567890123456789012345678901234"
    442      "567890123456789012345678901234567890123456789012345678901234567890123456"
    443      "789012345678901234567890123456789012345678901234567890123456789012345678"
    444      "901234567890123456789012345678901234567890123456789012345678901234567890"
    445      "123456789012345678901234567890123456789012345678901234567890123456789012"
    446      "345678901234567890123456789012345678901234567890123456789012345678901234"
    447      "567890123456789012345678901234567890123456789012345678901234567890123456"
    448      "789012345678901234567890123456789012345678901234567890123456789012345678"
    449      "901234567890123456789012345678901234567890123456789012345678901234567890"
    450      "123456789012345678901234567890123456789012345678901234567890123456789012"
    451      "345678901234567890123456789012345678901234567890123456789012345678901234"
    452      "567890123456789012345678901234567890123456789012345678901234567890123456"
    453      "789012345678901234567890123456789012345678901234567890123456789012345678"
    454      "9012345678901234567890/",
    455      cookie);
    456  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    457  // the following cookie includes a tab in the path
    458  SetACookie(cookieService, "http://pathwithtab.net/",
    459             "test=path; path=/foo\tbar/");
    460  GetACookie(cookieService, "http://pathwithtab.net/foo\tbar/", cookie);
    461  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    462  // the following cookie includes a tab in the name
    463  SetACookie(cookieService, "http://pathwithtab.net/", "test\ttabs=tab");
    464  GetACookie(cookieService, "http://pathwithtab.net/", cookie);
    465  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test\ttabs=tab"));
    466  // the following cookie includes a tab in the value - allowed
    467  SetACookie(cookieService, "http://pathwithtab.net/", "test=tab\ttest");
    468  GetACookie(cookieService, "http://pathwithtab.net/", cookie);
    469  EXPECT_TRUE(
    470      CheckResult(cookie.get(), MUST_EQUAL, "test\ttabs=tab; test=tab\ttest"));
    471  SetACookie(cookieService, "http://pathwithtab.net/",
    472             "test=tab\ttest; max-age=-1");
    473  GetACookie(cookieService, "http://pathwithtab.net/", cookie);
    474  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test\ttabs=tab"));
    475 
    476  // *** expiry & deletion tests
    477  // XXX add server time str parsing tests here
    478 
    479  // test some variations of the expiry time,
    480  // and test deletion of previously set cookies
    481  SetACookie(cookieService, "http://expireme.org/", "test=expiry; max-age=-1");
    482  GetACookie(cookieService, "http://expireme.org/", cookie);
    483  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    484  SetACookie(cookieService, "http://expireme.org/", "test=expiry; max-age=0");
    485  GetACookie(cookieService, "http://expireme.org/", cookie);
    486  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    487  SetACookie(cookieService, "http://expireme.org/", "test=expiry; expires=bad");
    488  GetACookie(cookieService, "http://expireme.org/", cookie);
    489  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"));
    490  SetACookie(cookieService, "http://expireme.org/",
    491             "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT");
    492  GetACookie(cookieService, "http://expireme.org/", cookie);
    493  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    494  SetACookie(cookieService, "http://expireme.org/",
    495             R"(test=expiry; expires="Thu, 10 Apr 1980 16:33:12 GMT)");
    496  GetACookie(cookieService, "http://expireme.org/", cookie);
    497  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    498  SetACookie(cookieService, "http://expireme.org/",
    499             R"(test=expiry; expires="Thu, 10 Apr 1980 16:33:12 GMT")");
    500  GetACookie(cookieService, "http://expireme.org/", cookie);
    501  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    502 
    503  SetACookie(cookieService, "http://expireme.org/", "test=expiry; max-age=60");
    504  GetACookie(cookieService, "http://expireme.org/", cookie);
    505  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"));
    506  SetACookie(cookieService, "http://expireme.org/", "test=expiry; max-age=-20");
    507  GetACookie(cookieService, "http://expireme.org/", cookie);
    508  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    509  SetACookie(cookieService, "http://expireme.org/", "test=expiry; max-age=60");
    510  GetACookie(cookieService, "http://expireme.org/", cookie);
    511  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"));
    512  SetACookie(cookieService, "http://expireme.org/",
    513             "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT");
    514  GetACookie(cookieService, "http://expireme.org/", cookie);
    515  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    516  SetACookie(cookieService, "http://expireme.org/", "test=expiry; max-age=60");
    517  SetACookie(cookieService, "http://expireme.org/",
    518             "newtest=expiry; max-age=60");
    519  GetACookie(cookieService, "http://expireme.org/", cookie);
    520  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry"));
    521  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry"));
    522  SetACookie(cookieService, "http://expireme.org/",
    523             "test=differentvalue; max-age=0");
    524  GetACookie(cookieService, "http://expireme.org/", cookie);
    525  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry"));
    526  SetACookie(cookieService, "http://expireme.org/",
    527             "newtest=evendifferentvalue; max-age=0");
    528  GetACookie(cookieService, "http://expireme.org/", cookie);
    529  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    530 
    531  SetACookie(cookieService, "http://foo.expireme.org/",
    532             "test=expiry; domain=.expireme.org; max-age=60");
    533  GetACookie(cookieService, "http://expireme.org/", cookie);
    534  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"));
    535  SetACookie(cookieService, "http://bar.expireme.org/",
    536             "test=differentvalue; domain=.expireme.org; max-age=0");
    537  GetACookie(cookieService, "http://expireme.org/", cookie);
    538  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    539 
    540  nsAutoCString ServerTime;
    541  nsAutoCString CookieString;
    542 
    543  // *** multiple cookie tests
    544 
    545  // test the setting of multiple cookies, and test the order of precedence
    546  // (a later cookie overwriting an earlier one, in the same header string)
    547  SetACookie(cookieService, "http://multiple.cookies/",
    548             nsTArray<const char*>{
    549                 "test=multiple; domain=.multiple.cookies ", " test=different ",
    550                 " test=same; domain=.multiple.cookies ", "newtest=ciao ",
    551                 "newtest=foo; max-age=-6 ", " newtest=reincarnated"});
    552  GetACookie(cookieService, "http://multiple.cookies/", cookie);
    553  EXPECT_TRUE(CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple"));
    554  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test=different"));
    555  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test=same"));
    556  EXPECT_TRUE(CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao"));
    557  EXPECT_TRUE(CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo"));
    558  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated"));
    559  SetACookie(cookieService, "http://multiple.cookies/",
    560             "test=expiry; domain=.multiple.cookies; max-age=0");
    561  GetACookie(cookieService, "http://multiple.cookies/", cookie);
    562  EXPECT_TRUE(CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same"));
    563  SetACookie(cookieService, "http://multiple.cookies/",
    564             nsTArray<const char*>{"", " test=different; max-age=0 ", ""});
    565  GetACookie(cookieService, "http://multiple.cookies/", cookie);
    566  EXPECT_TRUE(CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different"));
    567  SetACookie(cookieService, "http://multiple.cookies/",
    568             "newtest=dead; max-age=0");
    569  GetACookie(cookieService, "http://multiple.cookies/", cookie);
    570  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    571 
    572  // *** parser tests
    573 
    574  // test the cookie header parser, under various circumstances.
    575  SetACookie(cookieService, "http://parser.test/",
    576             "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; "
    577             "abracadabra! max-age=20;=;;");
    578  GetACookie(cookieService, "http://parser.test/", cookie);
    579  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=parser"));
    580  SetACookie(cookieService, "http://parser.test/",
    581             "test=parser; domain=.parser.test; max-age=0");
    582  GetACookie(cookieService, "http://parser.test/", cookie);
    583  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    584  SetACookie(cookieService, "http://parser.test/",
    585             nsTArray<const char*>{
    586                 "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; "
    587                 "max-age=6",
    588                 "five; max-age=2.63,"});
    589  GetACookie(cookieService, "http://parser.test/", cookie);
    590  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, R"(test="fubar! = foo)"));
    591  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "five"));
    592  SetACookie(cookieService, "http://parser.test/",
    593             nsTArray<const char*>{"test=kill; domain=.parser.test; max-age=0 ",
    594                                   " five; max-age=0"});
    595  GetACookie(cookieService, "http://parser.test/", cookie);
    596  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    597 
    598  // test the handling of VALUE-only cookies (see bug 169091),
    599  // i.e. "six" should assume an empty NAME, which allows other VALUE-only
    600  // cookies to overwrite it
    601  SetACookie(cookieService, "http://parser.test/", "six");
    602  GetACookie(cookieService, "http://parser.test/", cookie);
    603  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "six"));
    604  SetACookie(cookieService, "http://parser.test/", "seven");
    605  GetACookie(cookieService, "http://parser.test/", cookie);
    606  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "seven"));
    607  SetACookie(cookieService, "http://parser.test/", " =eight");
    608  GetACookie(cookieService, "http://parser.test/", cookie);
    609  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "eight"));
    610  SetACookie(cookieService, "http://parser.test/", "test=six");
    611  GetACookie(cookieService, "http://parser.test/", cookie);
    612  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test=six"));
    613 
    614  // *** path ordering tests
    615 
    616  // test that cookies are returned in path order - longest to shortest.
    617  // if the header doesn't specify a path, it's taken from the host URI.
    618  SetACookie(cookieService, "http://multi.path.tests/",
    619             "test1=path; path=/one/two/three");
    620  SetACookie(cookieService, "http://multi.path.tests/",
    621             nsTArray<const char*>{"test2=path; path=/one ",
    622                                   " test3=path; path=/one/two/three/four ",
    623                                   " test4=path; path=/one/two ",
    624                                   " test5=path; path=/one/two/"});
    625  SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/",
    626             "test6=path");
    627  SetACookie(cookieService,
    628             "http://multi.path.tests/one/two/three/four/five/six/",
    629             "test7=path; path=");
    630  SetACookie(cookieService, "http://multi.path.tests/", "test8=path; path=/");
    631  GetACookie(cookieService,
    632             "http://multi.path.tests/one/two/three/four/five/six/", cookie);
    633  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL,
    634                          "test7=path; test6=path; test3=path; test1=path; "
    635                          "test5=path; test4=path; test2=path; test8=path"));
    636 
    637  // *** Cookie prefix tests
    638 
    639  // prefixed cookies can't be set from insecure HTTP
    640  SetACookie(cookieService, "http://prefixed.test/", "__Secure-test1=test");
    641  SetACookie(cookieService, "http://prefixed.test/",
    642             "__Secure-test2=test; secure");
    643  SetACookie(cookieService, "http://prefixed.test/", "__Host-test1=test");
    644  SetACookie(cookieService, "http://prefixed.test/",
    645             "__Host-test2=test; secure");
    646  GetACookie(cookieService, "http://prefixed.test/", cookie);
    647  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    648 
    649  // prefixed cookies won't be set without the secure flag
    650  SetACookie(cookieService, "https://prefixed.test/", "__Secure-test=test");
    651  SetACookie(cookieService, "https://prefixed.test/", "__Host-test=test");
    652  GetACookie(cookieService, "https://prefixed.test/", cookie);
    653  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    654 
    655  // prefixed cookies can be set when done correctly
    656  SetACookie(cookieService, "https://prefixed.test/",
    657             "__Secure-test=test; secure");
    658  SetACookie(cookieService, "https://prefixed.test/",
    659             "__Host-test=test; secure");
    660  GetACookie(cookieService, "https://prefixed.test/", cookie);
    661  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "__Secure-test=test"));
    662  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "__Host-test=test"));
    663 
    664  // but when set must not be returned to the host insecurely
    665  GetACookie(cookieService, "http://prefixed.test/", cookie);
    666  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    667 
    668  // Host-prefixed cookies cannot specify a domain
    669  SetACookie(cookieService, "https://host.prefixed.test/",
    670             "__Host-a=test; secure; domain=prefixed.test");
    671  SetACookie(cookieService, "https://host.prefixed.test/",
    672             "__Host-b=test; secure; domain=.prefixed.test");
    673  SetACookie(cookieService, "https://host.prefixed.test/",
    674             "__Host-c=test; secure; domain=host.prefixed.test");
    675  SetACookie(cookieService, "https://host.prefixed.test/",
    676             "__Host-d=test; secure; domain=.host.prefixed.test");
    677  GetACookie(cookieService, "https://host.prefixed.test/", cookie);
    678  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    679 
    680  // Host-prefixed cookies can only have a path of "/"
    681  SetACookie(cookieService, "https://host.prefixed.test/some/path",
    682             "__Host-e=test; secure");
    683  SetACookie(cookieService, "https://host.prefixed.test/some/path",
    684             "__Host-f=test; secure; path=/");
    685  SetACookie(cookieService, "https://host.prefixed.test/some/path",
    686             "__Host-g=test; secure; path=/some");
    687  GetACookie(cookieService, "https://host.prefixed.test/", cookie);
    688  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "__Host-f=test"));
    689 
    690  // *** leave-secure-alone tests
    691 
    692  // testing items 0 & 1 for 3.1 of spec Deprecate modification of ’secure’
    693  // cookies from non-secure origins
    694  SetACookie(cookieService, "http://www.security.test/",
    695             "test=non-security; secure");
    696  GetACookieNoHttp(cookieService, "https://www.security.test/", cookie);
    697  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    698  SetACookie(cookieService, "https://www.security.test/path/",
    699             "test=security; secure; path=/path/");
    700  GetACookieNoHttp(cookieService, "https://www.security.test/path/", cookie);
    701  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=security"));
    702  // testing items 2 & 3 & 4 for 3.2 of spec Deprecate modification of ’secure’
    703  // cookies from non-secure origins
    704  // Secure site can modify cookie value
    705  SetACookie(cookieService, "https://www.security.test/path/",
    706             "test=security2; secure; path=/path/");
    707  GetACookieNoHttp(cookieService, "https://www.security.test/path/", cookie);
    708  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=security2"));
    709  // If new cookie contains same name, same host and partially matching path
    710  // with an existing security cookie on non-security site, it can't modify an
    711  // existing security cookie.
    712  SetACookie(cookieService, "http://www.security.test/path/foo/",
    713             "test=non-security; path=/path/foo");
    714  GetACookieNoHttp(cookieService, "https://www.security.test/path/foo/",
    715                   cookie);
    716  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=security2"));
    717  // Non-secure cookie can set by same name, same host and non-matching path.
    718  SetACookie(cookieService, "http://www.security.test/bar/",
    719             "test=non-security; path=/bar");
    720  GetACookieNoHttp(cookieService, "http://www.security.test/bar/", cookie);
    721  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=non-security"));
    722  // Modify value and downgrade secure level.
    723  SetACookie(
    724      cookieService, "https://www.security.test/",
    725      "test_modify_cookie=security-cookie; secure; domain=.security.test");
    726  GetACookieNoHttp(cookieService, "https://www.security.test/", cookie);
    727  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL,
    728                          "test_modify_cookie=security-cookie"));
    729  SetACookie(cookieService, "https://www.security.test/",
    730             "test_modify_cookie=non-security-cookie; domain=.security.test");
    731  GetACookieNoHttp(cookieService, "https://www.security.test/", cookie);
    732  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL,
    733                          "test_modify_cookie=non-security-cookie"));
    734 
    735  // Test the non-security cookie can set when domain or path not same to secure
    736  // cookie of same name.
    737  SetACookie(cookieService, "https://www.security.test/", "test=security3");
    738  GetACookieNoHttp(cookieService, "http://www.security.test/", cookie);
    739  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test=security3"));
    740  SetACookie(cookieService, "http://www.security.test/",
    741             "test=non-security2; domain=security.test");
    742  GetACookieNoHttp(cookieService, "http://www.security.test/", cookie);
    743  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test=non-security2"));
    744 
    745  // *** nsICookieManager interface tests
    746  nsCOMPtr<nsICookieManager> cookieMgr =
    747      do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0);
    748  ASSERT_NS_SUCCEEDED(rv0);
    749 
    750  const nsCOMPtr<nsICookieManager>& cookieMgr2 = cookieMgr;
    751  ASSERT_TRUE(cookieMgr2);
    752 
    753  nsCOMPtr<nsIURI> uri;
    754  NS_NewURI(getter_AddRefs(uri), "https://cookie.test"_ns);
    755 
    756  mozilla::OriginAttributes attrs;
    757 
    758  // first, ensure a clean slate
    759  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
    760 
    761  nsCOMPtr<nsICookieValidation> cv;
    762 
    763  // add some cookies
    764  EXPECT_TRUE(NS_SUCCEEDED(cookieMgr2->AddNative(uri,
    765                                                 "cookiemgr.test"_ns,  // domain
    766                                                 "/foo"_ns,            // path
    767                                                 "test1"_ns,           // name
    768                                                 "yes"_ns,             // value
    769                                                 false,      // is secure
    770                                                 false,      // is httponly
    771                                                 true,       // is session
    772                                                 INT64_MAX,  // expiry time
    773                                                 &attrs,     // originAttributes
    774                                                 nsICookie::SAMESITE_LAX,
    775                                                 nsICookie::SCHEME_HTTP,
    776                                                 false,    // is partitioned
    777                                                 true,     // from http
    778                                                 nullptr,  // operation ID
    779                                                 getter_AddRefs(cv))));
    780  EXPECT_TRUE(!!cv);
    781  EXPECT_EQ(CookieValidation::Cast(cv)->Result(), nsICookieValidation::eOK);
    782 
    783  EXPECT_TRUE(NS_SUCCEEDED(
    784      cookieMgr2->AddNative(uri,
    785                            "cookiemgr.test"_ns,                 // domain
    786                            "/foo"_ns,                           // path
    787                            "test2"_ns,                          // name
    788                            "yes"_ns,                            // value
    789                            false,                               // is secure
    790                            true,                                // is httponly
    791                            true,                                // is session
    792                            PR_Now() / PR_USEC_PER_MSEC + 2000,  // expiry time
    793                            &attrs,  // originAttributes
    794                            nsICookie::SAMESITE_LAX, nsICookie::SCHEME_HTTP,
    795                            false,    // is partitioned
    796                            true,     // from http
    797                            nullptr,  // operation ID
    798                            getter_AddRefs(cv))));
    799  EXPECT_TRUE(!!cv);
    800  EXPECT_EQ(CookieValidation::Cast(cv)->Result(), nsICookieValidation::eOK);
    801 
    802  EXPECT_TRUE(NS_SUCCEEDED(cookieMgr2->AddNative(uri,
    803                                                 "new.domain"_ns,  // domain
    804                                                 "/rabbit"_ns,     // path
    805                                                 "test3"_ns,       // name
    806                                                 "yes"_ns,         // value
    807                                                 false,            // is secure
    808                                                 false,      // is httponly
    809                                                 true,       // is session
    810                                                 INT64_MAX,  // expiry time
    811                                                 &attrs,     // originAttributes
    812                                                 nsICookie::SAMESITE_LAX,
    813                                                 nsICookie::SCHEME_HTTP,
    814                                                 false,    // is partitioned
    815                                                 true,     // from http
    816                                                 nullptr,  // operation ID
    817                                                 getter_AddRefs(cv))));
    818  EXPECT_TRUE(!!cv);
    819  EXPECT_EQ(CookieValidation::Cast(cv)->Result(), nsICookieValidation::eOK);
    820 
    821  // confirm using enumerator
    822  nsTArray<RefPtr<nsICookie>> cookies;
    823  EXPECT_NS_SUCCEEDED(cookieMgr->GetCookies(cookies));
    824  nsCOMPtr<nsICookie> expiredCookie, newDomainCookie;
    825  for (const auto& cookie : cookies) {
    826    nsAutoCString name;
    827    cookie->GetName(name);
    828    if (name.EqualsLiteral("test2")) {
    829      expiredCookie = cookie;
    830    } else if (name.EqualsLiteral("test3")) {
    831      newDomainCookie = cookie;
    832    }
    833  }
    834  EXPECT_EQ(cookies.Length(), 3ul);
    835  // check the httpOnly attribute of the second cookie is honored
    836  GetACookie(cookieService, "http://cookiemgr.test/foo/", cookie);
    837  EXPECT_TRUE(CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes"));
    838  GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", cookie);
    839  EXPECT_TRUE(CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes"));
    840  // check CountCookiesFromHost()
    841  uint32_t hostCookies = 0;
    842  EXPECT_TRUE(NS_SUCCEEDED(
    843      cookieMgr2->CountCookiesFromHost("cookiemgr.test"_ns, &hostCookies)));
    844  EXPECT_EQ(hostCookies, 2u);
    845  // check CookieExistsNative() using the third cookie
    846  bool found;
    847  EXPECT_TRUE(NS_SUCCEEDED(cookieMgr2->CookieExistsNative(
    848      "new.domain"_ns, "/rabbit"_ns, "test3"_ns, &attrs, &found)));
    849  EXPECT_TRUE(found);
    850 
    851  // sleep four seconds, to make sure the second cookie has expired
    852  PR_Sleep(4 * PR_TicksPerSecond());
    853  // check that both CountCookiesFromHost() and CookieExistsNative() count the
    854  // expired cookie
    855  EXPECT_TRUE(NS_SUCCEEDED(
    856      cookieMgr2->CountCookiesFromHost("cookiemgr.test"_ns, &hostCookies)));
    857  EXPECT_EQ(hostCookies, 2u);
    858  EXPECT_TRUE(NS_SUCCEEDED(cookieMgr2->CookieExistsNative(
    859      "cookiemgr.test"_ns, "/foo"_ns, "test2"_ns, &attrs, &found)));
    860  EXPECT_TRUE(found);
    861  // double-check RemoveAll() using the enumerator
    862  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
    863  cookies.SetLength(0);
    864  EXPECT_TRUE(NS_SUCCEEDED(cookieMgr->GetCookies(cookies)) &&
    865              cookies.IsEmpty());
    866 
    867  // *** eviction and creation ordering tests
    868 
    869  // test that cookies are
    870  // a) returned by order of creation time (oldest first, newest last)
    871  // b) evicted by order of lastAccessed time, if the limit on cookies per host
    872  // (50) is reached
    873  nsAutoCString name;
    874  nsAutoCString expected;
    875  for (int32_t i = 0; i < 60; ++i) {
    876    name = "test"_ns;
    877    name.AppendInt(i);
    878    name += "=creation"_ns;
    879    SetACookie(cookieService, "http://creation.ordering.tests/", name.get());
    880 
    881    if (i >= 10) {
    882      expected += name;
    883      if (i < 59) expected += "; "_ns;
    884    }
    885  }
    886  GetACookie(cookieService, "http://creation.ordering.tests/", cookie);
    887  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, expected.get()));
    888 
    889  cookieMgr->RemoveAll();
    890 
    891  for (int32_t i = 0; i < 60; ++i) {
    892    name = "test"_ns;
    893    name.AppendInt(i);
    894    name += "=delete_non_security"_ns;
    895 
    896    // Create 50 cookies that include the secure flag.
    897    if (i < 50) {
    898      name += "; secure"_ns;
    899      SetACookie(cookieService, "https://creation.ordering.tests/", name.get());
    900    } else {
    901      // non-security cookies will be removed beside the latest cookie that be
    902      // created.
    903      SetACookie(cookieService, "http://creation.ordering.tests/", name.get());
    904    }
    905  }
    906  GetACookie(cookieService, "http://creation.ordering.tests/", cookie);
    907 
    908  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    909 
    910  // *** SameSite attribute - parsing and cookie storage tests
    911  // Clear the cookies
    912  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
    913 
    914  // None of these cookies will be set because using
    915  // CookieJarSettings::GetBlockingAll().
    916  SetACookieJarBlocked(cookieService, "http://samesite.test", "unset=yes");
    917  SetACookieJarBlocked(cookieService, "http://samesite.test",
    918                       "unspecified=yes; samesite");
    919  SetACookieJarBlocked(cookieService, "http://samesite.test",
    920                       "empty=yes; samesite=");
    921  SetACookieJarBlocked(cookieService, "http://samesite.test",
    922                       "bogus=yes; samesite=bogus");
    923  SetACookieJarBlocked(cookieService, "http://samesite.test",
    924                       "strict=yes; samesite=strict");
    925  SetACookieJarBlocked(cookieService, "http://samesite.test",
    926                       "lax=yes; samesite=lax");
    927 
    928  cookies.SetLength(0);
    929  EXPECT_NS_SUCCEEDED(cookieMgr->GetCookies(cookies));
    930 
    931  EXPECT_TRUE(cookies.IsEmpty());
    932 
    933  // Set cookies with various incantations of the samesite attribute:
    934  // No same site attribute present
    935  SetACookie(cookieService, "http://samesite.test", "unset=yes");
    936  // samesite attribute present but with no value
    937  SetACookie(cookieService, "http://samesite.test",
    938             "unspecified=yes; samesite");
    939  // samesite attribute present but with an empty value
    940  SetACookie(cookieService, "http://samesite.test", "empty=yes; samesite=");
    941  // samesite attribute present but with an invalid value
    942  SetACookie(cookieService, "http://samesite.test",
    943             "bogus=yes; samesite=bogus");
    944  // samesite=strict
    945  SetACookie(cookieService, "http://samesite.test",
    946             "strict=yes; samesite=strict");
    947  // samesite=lax
    948  SetACookie(cookieService, "http://samesite.test", "lax=yes; samesite=lax");
    949 
    950  cookies.SetLength(0);
    951  EXPECT_NS_SUCCEEDED(cookieMgr->GetCookies(cookies));
    952 
    953  // check the cookies for the required samesite value
    954  for (const auto& cookie : cookies) {
    955    nsAutoCString name;
    956    cookie->GetName(name);
    957    int32_t sameSiteAttr;
    958    cookie->GetSameSite(&sameSiteAttr);
    959    if (name.EqualsLiteral("unset")) {
    960      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_UNSET);
    961    } else if (name.EqualsLiteral("unspecified")) {
    962      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_UNSET);
    963    } else if (name.EqualsLiteral("empty")) {
    964      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_UNSET);
    965    } else if (name.EqualsLiteral("bogus")) {
    966      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_UNSET);
    967    } else if (name.EqualsLiteral("none")) {
    968      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_NONE);
    969    } else if (name.EqualsLiteral("strict")) {
    970      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_STRICT);
    971    } else if (name.EqualsLiteral("lax")) {
    972      EXPECT_TRUE(sameSiteAttr == nsICookie::SAMESITE_LAX);
    973    }
    974  }
    975 
    976  EXPECT_TRUE(cookies.Length() == 6);
    977 
    978  // *** SameSite attribute
    979  // Clear the cookies
    980  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
    981 
    982  // please note that the flag aForeign is always set to true using this test
    983  // setup because no nsIChannel is passed to SetCookieString(). therefore we
    984  // can only test that no cookies are sent for cross origin requests using
    985  // same-site cookies.
    986  SetACookie(cookieService, "http://www.samesite.com",
    987             "test=sameSiteStrictVal; samesite=strict");
    988  GetACookie(cookieService, "http://www.notsamesite.com", cookie);
    989  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    990 
    991  SetACookie(cookieService, "http://www.samesite.test",
    992             "test=sameSiteLaxVal; samesite=lax");
    993  GetACookie(cookieService, "http://www.notsamesite.com", cookie);
    994  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
    995 
    996  static const char* secureURIs[] = {
    997      "http://localhost", "http://localhost:1234", "http://127.0.0.1",
    998      "http://127.0.0.2", "http://127.1.0.1",      "http://[::1]",
    999      // TODO bug 1220810 "http://xyzzy.localhost"
   1000  };
   1001 
   1002  uint32_t numSecureURIs = sizeof(secureURIs) / sizeof(const char*);
   1003  for (uint32_t i = 0; i < numSecureURIs; ++i) {
   1004    SetACookie(cookieService, secureURIs[i], "test=basic; secure");
   1005    GetACookie(cookieService, secureURIs[i], cookie);
   1006    EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=basic"));
   1007    SetACookie(cookieService, secureURIs[i], "test=basic1");
   1008    GetACookie(cookieService, secureURIs[i], cookie);
   1009    EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=basic1"));
   1010  }
   1011 
   1012  // XXX the following are placeholders: add these tests please!
   1013  // *** "noncompliant cookie" tests
   1014  // *** IP address tests
   1015  // *** speed tests
   1016 }
   1017 
   1018 TEST(TestCookie, InvalidCharsInNameAndValue)
   1019 {
   1020  nsresult rv;
   1021 
   1022  nsCOMPtr<nsICookieManager> cookieMgr =
   1023      do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv);
   1024  ASSERT_NS_SUCCEEDED(rv);
   1025 
   1026  nsCOMPtr<nsIURI> uri;
   1027  NS_NewURI(getter_AddRefs(uri), "https://cookie.test"_ns);
   1028 
   1029  mozilla::OriginAttributes attrs;
   1030 
   1031  // Test some invalid chars
   1032 #define TEST_INVALID_CHARS(name, value, error)                                 \
   1033  {                                                                            \
   1034    nsCOMPtr<nsICookieValidation> cv;                                          \
   1035    EXPECT_EQ(                                                                 \
   1036        cookieMgr->AddNative(uri, "cookiemgr.test"_ns, "/foo"_ns, name, value, \
   1037                             false, false, true, INT64_MAX, &attrs,            \
   1038                             nsICookie::SAMESITE_LAX, nsICookie::SCHEME_HTTP,  \
   1039                             false, true, nullptr, getter_AddRefs(cv)),        \
   1040        NS_ERROR_ILLEGAL_VALUE);                                               \
   1041    EXPECT_TRUE(!!cv);                                                         \
   1042    EXPECT_EQ(CookieValidation::Cast(cv)->Result(), error);                    \
   1043  }
   1044 
   1045  TEST_INVALID_CHARS(" test invalid name"_ns, "test valid value"_ns,
   1046                     nsICookieValidation::eRejectedInvalidCharName)
   1047  TEST_INVALID_CHARS("test invalid name "_ns, "test valid value"_ns,
   1048                     nsICookieValidation::eRejectedInvalidCharName)
   1049  TEST_INVALID_CHARS("test valid name"_ns, " test invalid value"_ns,
   1050                     nsICookieValidation::eRejectedInvalidCharValue)
   1051  TEST_INVALID_CHARS("test valid name"_ns, "test invalid value "_ns,
   1052                     nsICookieValidation::eRejectedInvalidCharValue)
   1053 
   1054 #undef TEST_INVALID_CHARS
   1055 }
   1056 
   1057 TEST(TestCookie, OnionSite)
   1058 {
   1059  Preferences::SetBool("dom.securecontext.allowlist_onions", true);
   1060  Preferences::SetBool("network.cookie.sameSite.laxByDefault", false);
   1061 
   1062  nsresult rv;
   1063  nsCString cookie;
   1064 
   1065  nsCOMPtr<nsICookieService> cookieService =
   1066      do_GetService(kCookieServiceCID, &rv);
   1067  ASSERT_NS_SUCCEEDED(rv);
   1068 
   1069  // .onion secure cookie tests
   1070  SetACookie(cookieService, "http://123456789abcdef.onion/",
   1071             "test=onion-security; secure");
   1072  GetACookieNoHttp(cookieService, "https://123456789abcdef.onion/", cookie);
   1073  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=onion-security"));
   1074  SetACookie(cookieService, "http://123456789abcdef.onion/",
   1075             "test=onion-security2; secure");
   1076  GetACookieNoHttp(cookieService, "http://123456789abcdef.onion/", cookie);
   1077  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=onion-security2"));
   1078  SetACookie(cookieService, "https://123456789abcdef.onion/",
   1079             "test=onion-security3; secure");
   1080  GetACookieNoHttp(cookieService, "http://123456789abcdef.onion/", cookie);
   1081  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=onion-security3"));
   1082  SetACookie(cookieService, "http://123456789abcdef.onion/",
   1083             "test=onion-security4");
   1084  GetACookieNoHttp(cookieService, "http://123456789abcdef.onion/", cookie);
   1085  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "test=onion-security4"));
   1086 }
   1087 
   1088 TEST(TestCookie, HiddenPrefix)
   1089 {
   1090  nsresult rv;
   1091  nsCString cookie;
   1092 
   1093  nsCOMPtr<nsICookieService> cookieService =
   1094      do_GetService(kCookieServiceCID, &rv);
   1095  ASSERT_NS_SUCCEEDED(rv);
   1096 
   1097  SetACookie(cookieService, "http://hiddenprefix.test/", "=__Host-test=a");
   1098  GetACookie(cookieService, "http://hiddenprefix.test/", cookie);
   1099  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
   1100 
   1101  SetACookie(cookieService, "http://hiddenprefix.test/", "=__Secure-test=a");
   1102  GetACookie(cookieService, "http://hiddenprefix.test/", cookie);
   1103  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
   1104 
   1105  SetACookie(cookieService, "http://hiddenprefix.test/", "=__Host-check");
   1106  GetACookie(cookieService, "http://hiddenprefix.test/", cookie);
   1107  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
   1108 
   1109  SetACookie(cookieService, "http://hiddenprefix.test/", "=__Secure-check");
   1110  GetACookie(cookieService, "http://hiddenprefix.test/", cookie);
   1111  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
   1112 }
   1113 
   1114 TEST(TestCookie, BlockUnicode)
   1115 {
   1116  Preferences::SetBool("network.cookie.blockUnicode", true);
   1117 
   1118  nsresult rv;
   1119  nsCString cookie;
   1120 
   1121  nsCOMPtr<nsICookieService> cookieService =
   1122      do_GetService(kCookieServiceCID, &rv);
   1123  ASSERT_NS_SUCCEEDED(rv);
   1124 
   1125  SetACookie(cookieService, "http://unicode.com/", "name=🍪");
   1126  GetACookie(cookieService, "http://unicode.com/", cookie);
   1127  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
   1128 
   1129  SetACookie(cookieService, "http://unicode.com/", "🍪=value");
   1130  GetACookie(cookieService, "http://unicode.com/", cookie);
   1131  EXPECT_TRUE(CheckResult(cookie.get(), MUST_BE_NULL));
   1132 
   1133  Preferences::SetBool("network.cookie.blockUnicode", false);
   1134 
   1135  SetACookie(cookieService, "http://unicode.com/", "name=🍪");
   1136  GetACookie(cookieService, "http://unicode.com/", cookie);
   1137  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "name=🍪"));
   1138 
   1139  nsCOMPtr<nsICookieManager> cookieMgr =
   1140      do_GetService(NS_COOKIEMANAGER_CONTRACTID);
   1141  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
   1142 
   1143  SetACookie(cookieService, "http://unicode.com/", "🍪=value");
   1144  GetACookie(cookieService, "http://unicode.com/", cookie);
   1145  EXPECT_TRUE(CheckResult(cookie.get(), MUST_EQUAL, "🍪=value"));
   1146 
   1147  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
   1148  Preferences::ClearUser("network.cookie.blockUnicode");
   1149 }
   1150 
   1151 TEST(TestCookie, MaxAgeParser)
   1152 {
   1153  nsCOMPtr<nsIURI> uri;
   1154  NS_NewURI(getter_AddRefs(uri), "https://maxage.net");
   1155 
   1156  nsCOMPtr<nsIIOService> service = do_GetIOService();
   1157 
   1158  nsCOMPtr<nsIChannel> channel;
   1159  (void)service->NewChannelFromURI(
   1160      uri, nullptr, nsContentUtils::GetSystemPrincipal(),
   1161      nsContentUtils::GetSystemPrincipal(), 0, nsIContentPolicy::TYPE_DOCUMENT,
   1162      getter_AddRefs(channel));
   1163 
   1164  nsCOMPtr<nsIConsoleReportCollector> crc = do_QueryInterface(channel);
   1165 
   1166  CookieParser cp(crc, uri);
   1167 
   1168  int64_t value;
   1169  EXPECT_FALSE(cp.ParseMaxAgeAttribute(""_ns, &value));
   1170 
   1171  EXPECT_TRUE(cp.ParseMaxAgeAttribute("0"_ns, &value));
   1172  EXPECT_EQ(value, 0);
   1173 
   1174  EXPECT_TRUE(cp.ParseMaxAgeAttribute("1"_ns, &value));
   1175  EXPECT_EQ(value, 1);
   1176 
   1177  EXPECT_TRUE(cp.ParseMaxAgeAttribute("1234"_ns, &value));
   1178  EXPECT_EQ(value, 1234);
   1179 
   1180  EXPECT_TRUE(cp.ParseMaxAgeAttribute("00000000000000001234"_ns, &value));
   1181  EXPECT_EQ(value, 1234);
   1182 
   1183  EXPECT_TRUE(cp.ParseMaxAgeAttribute("-1234"_ns, &value));
   1184  EXPECT_EQ(value, INT64_MIN);
   1185 
   1186  {
   1187    nsCString str;
   1188    for (int i = 0; i < 1024; ++i) {
   1189      str.Append("9");
   1190    }
   1191    EXPECT_TRUE(cp.ParseMaxAgeAttribute(str, &value));
   1192    EXPECT_EQ(value, INT64_MAX);
   1193  }
   1194 
   1195  EXPECT_FALSE(cp.ParseMaxAgeAttribute("1234a"_ns, &value));
   1196  EXPECT_FALSE(cp.ParseMaxAgeAttribute("12a34"_ns, &value));
   1197  EXPECT_FALSE(cp.ParseMaxAgeAttribute("12🌊34"_ns, &value));
   1198 
   1199  nsresult rv;
   1200  nsCOMPtr<nsICookieManager> cookieMgr =
   1201      do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv);
   1202  ASSERT_NS_SUCCEEDED(rv);
   1203 
   1204  EXPECT_NS_SUCCEEDED(cookieMgr->RemoveAll());
   1205 
   1206  nsCOMPtr<nsICookieService> cookieService =
   1207      do_GetService(kCookieServiceCID, &rv);
   1208  ASSERT_NS_SUCCEEDED(rv);
   1209 
   1210  SetACookie(cookieService, "http://maxage.net/", "a=1; max-age=1234");
   1211 
   1212  nsCString cookieStr;
   1213  GetACookie(cookieService, "http://maxage.net/", cookieStr);
   1214  EXPECT_TRUE(CheckResult(cookieStr.get(), MUST_EQUAL, "a=1"));
   1215 
   1216  nsTArray<RefPtr<nsICookie>> cookies;
   1217  EXPECT_NS_SUCCEEDED(cookieMgr->GetCookies(cookies));
   1218  EXPECT_EQ(cookies.Length(), (uint64_t)1);
   1219 
   1220  Cookie* cookie = static_cast<Cookie*>(cookies[0].get());
   1221  EXPECT_FALSE(cookie->IsSession());
   1222 
   1223  SetACookie(cookieService, "http://maxage.net/", "a=1; max-age=-1");
   1224  GetACookie(cookieService, "http://maxage.net/", cookieStr);
   1225  EXPECT_TRUE(CheckResult(cookieStr.get(), MUST_EQUAL, ""));
   1226 }