TestCookie.cpp 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  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. #include "TestCommon.h"
  6. #include "TestHarness.h"
  7. #include "nsIServiceManager.h"
  8. #include "nsICookieService.h"
  9. #include "nsICookieManager.h"
  10. #include "nsICookieManager2.h"
  11. #include "nsICookie2.h"
  12. #include <stdio.h>
  13. #include "plstr.h"
  14. #include "prprf.h"
  15. #include "nsNetUtil.h"
  16. #include "nsISimpleEnumerator.h"
  17. #include "nsServiceManagerUtils.h"
  18. #include "nsNetCID.h"
  19. #include "nsStringAPI.h"
  20. #include "nsIPrefBranch.h"
  21. #include "nsIPrefService.h"
  22. static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
  23. static NS_DEFINE_CID(kPrefServiceCID, NS_PREFSERVICE_CID);
  24. // various pref strings
  25. static const char kCookiesPermissions[] = "network.cookie.cookieBehavior";
  26. static const char kCookiesLifetimeEnabled[] = "network.cookie.lifetime.enabled";
  27. static const char kCookiesLifetimeDays[] = "network.cookie.lifetime.days";
  28. static const char kCookiesLifetimeCurrentSession[] = "network.cookie.lifetime.behavior";
  29. static const char kCookiesMaxPerHost[] = "network.cookie.maxPerHost";
  30. static const char kCookieLeaveSecurityAlone[] = "network.cookie.leave-secure-alone";
  31. static char *sBuffer;
  32. #define OFFSET_ONE_WEEK int64_t(604800) * PR_USEC_PER_SEC
  33. #define OFFSET_ONE_DAY int64_t(86400) * PR_USEC_PER_SEC
  34. //Set server time or expiry time
  35. void
  36. SetTime(PRTime offsetTime,nsAutoCString& serverString,nsAutoCString& cookieString,bool expiry)
  37. {
  38. char timeStringPreset[40];
  39. PRTime CurrentTime = PR_Now();
  40. PRTime SetCookieTime = CurrentTime + offsetTime;
  41. PRTime SetExpiryTime;
  42. if (expiry) {
  43. SetExpiryTime = SetCookieTime - OFFSET_ONE_DAY;
  44. } else {
  45. SetExpiryTime = SetCookieTime + OFFSET_ONE_DAY;
  46. }
  47. // Set server time string
  48. PRExplodedTime explodedTime;
  49. PR_ExplodeTime(SetCookieTime , PR_GMTParameters, &explodedTime);
  50. PR_FormatTimeUSEnglish(timeStringPreset, 40, "%c GMT", &explodedTime);
  51. serverString.Assign(timeStringPreset);
  52. // Set cookie string
  53. PR_ExplodeTime(SetExpiryTime , PR_GMTParameters, &explodedTime);
  54. PR_FormatTimeUSEnglish(timeStringPreset, 40, "%c GMT", &explodedTime);
  55. cookieString.Replace(0, strlen("test=expiry; expires=") + strlen(timeStringPreset) + 1, "test=expiry; expires=");
  56. cookieString.Append(timeStringPreset);
  57. }
  58. nsresult
  59. SetACookie(nsICookieService *aCookieService, const char *aSpec1, const char *aSpec2, const char* aCookieString, const char *aServerTime)
  60. {
  61. nsCOMPtr<nsIURI> uri1, uri2;
  62. NS_NewURI(getter_AddRefs(uri1), aSpec1);
  63. if (aSpec2)
  64. NS_NewURI(getter_AddRefs(uri2), aSpec2);
  65. sBuffer = PR_sprintf_append(sBuffer, R"( for host "%s": SET )", aSpec1);
  66. nsresult rv = aCookieService->SetCookieStringFromHttp(uri1, uri2, nullptr, (char *)aCookieString, aServerTime, nullptr);
  67. // the following code is useless. the cookieservice blindly returns NS_OK
  68. // from SetCookieString. we have to call GetCookie to see if the cookie was
  69. // set correctly...
  70. if (NS_FAILED(rv)) {
  71. sBuffer = PR_sprintf_append(sBuffer, "nothing\n");
  72. } else {
  73. sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", aCookieString);
  74. }
  75. return rv;
  76. }
  77. nsresult
  78. SetACookieNoHttp(nsICookieService *aCookieService, const char *aSpec, const char* aCookieString)
  79. {
  80. nsCOMPtr<nsIURI> uri;
  81. NS_NewURI(getter_AddRefs(uri), aSpec);
  82. sBuffer = PR_sprintf_append(sBuffer, R"( for host "%s": SET )", aSpec);
  83. nsresult rv = aCookieService->SetCookieString(uri, nullptr, (char *)aCookieString, nullptr);
  84. // the following code is useless. the cookieservice blindly returns NS_OK
  85. // from SetCookieString. we have to call GetCookie to see if the cookie was
  86. // set correctly...
  87. if (NS_FAILED(rv)) {
  88. sBuffer = PR_sprintf_append(sBuffer, "nothing\n");
  89. } else {
  90. sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", aCookieString);
  91. }
  92. return rv;
  93. }
  94. // returns true if cookie(s) for the given host were found; else false.
  95. // the cookie string is returned via aCookie.
  96. bool
  97. GetACookie(nsICookieService *aCookieService, const char *aSpec1, const char *aSpec2, char **aCookie)
  98. {
  99. nsCOMPtr<nsIURI> uri1, uri2;
  100. NS_NewURI(getter_AddRefs(uri1), aSpec1);
  101. if (aSpec2)
  102. NS_NewURI(getter_AddRefs(uri2), aSpec2);
  103. sBuffer = PR_sprintf_append(sBuffer, R"( "%s": GOT )", aSpec1);
  104. nsresult rv = aCookieService->GetCookieStringFromHttp(uri1, uri2, nullptr, aCookie);
  105. if (NS_FAILED(rv)) {
  106. sBuffer = PR_sprintf_append(sBuffer, "XXX GetCookieString() failed!\n");
  107. }
  108. if (!*aCookie) {
  109. sBuffer = PR_sprintf_append(sBuffer, "nothing\n");
  110. } else {
  111. sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", *aCookie);
  112. }
  113. return *aCookie != nullptr;
  114. }
  115. // returns true if cookie(s) for the given host were found; else false.
  116. // the cookie string is returned via aCookie.
  117. bool
  118. GetACookieNoHttp(nsICookieService *aCookieService, const char *aSpec, char **aCookie)
  119. {
  120. nsCOMPtr<nsIURI> uri;
  121. NS_NewURI(getter_AddRefs(uri), aSpec);
  122. sBuffer = PR_sprintf_append(sBuffer, R"( "%s": GOT )", aSpec);
  123. nsresult rv = aCookieService->GetCookieString(uri, nullptr, aCookie);
  124. if (NS_FAILED(rv)) {
  125. sBuffer = PR_sprintf_append(sBuffer, "XXX GetCookieString() failed!\n");
  126. }
  127. if (!*aCookie) {
  128. sBuffer = PR_sprintf_append(sBuffer, "nothing\n");
  129. } else {
  130. sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", *aCookie);
  131. }
  132. return *aCookie != nullptr;
  133. }
  134. // some #defines for comparison rules
  135. #define MUST_BE_NULL 0
  136. #define MUST_EQUAL 1
  137. #define MUST_CONTAIN 2
  138. #define MUST_NOT_CONTAIN 3
  139. #define MUST_NOT_EQUAL 4
  140. // a simple helper function to improve readability:
  141. // takes one of the #defined rules above, and performs the appropriate test.
  142. // true means the test passed; false means the test failed.
  143. static inline bool
  144. CheckResult(const char *aLhs, uint32_t aRule, const char *aRhs = nullptr)
  145. {
  146. switch (aRule) {
  147. case MUST_BE_NULL:
  148. return !aLhs || !*aLhs;
  149. case MUST_EQUAL:
  150. return !PL_strcmp(aLhs, aRhs);
  151. case MUST_NOT_EQUAL:
  152. return PL_strcmp(aLhs, aRhs);
  153. case MUST_CONTAIN:
  154. return PL_strstr(aLhs, aRhs) != nullptr;
  155. case MUST_NOT_CONTAIN:
  156. return PL_strstr(aLhs, aRhs) == nullptr;
  157. default:
  158. return false; // failure
  159. }
  160. }
  161. // helper function that ensures the first aSize elements of aResult are
  162. // true (i.e. all tests succeeded). prints the result of the tests (if any
  163. // tests failed, it prints the zero-based index of each failed test).
  164. bool
  165. PrintResult(const bool aResult[], uint32_t aSize)
  166. {
  167. bool failed = false;
  168. sBuffer = PR_sprintf_append(sBuffer, "*** tests ");
  169. for (uint32_t i = 0; i < aSize; ++i) {
  170. if (!aResult[i]) {
  171. failed = true;
  172. sBuffer = PR_sprintf_append(sBuffer, "%d ", i);
  173. }
  174. }
  175. if (failed) {
  176. sBuffer = PR_sprintf_append(sBuffer, "FAILED!\a\n");
  177. } else {
  178. sBuffer = PR_sprintf_append(sBuffer, "passed.\n");
  179. }
  180. return !failed;
  181. }
  182. void
  183. InitPrefs(nsIPrefBranch *aPrefBranch)
  184. {
  185. // init some relevant prefs, so the tests don't go awry.
  186. // we use the most restrictive set of prefs we can;
  187. // however, we don't test third party blocking here.
  188. aPrefBranch->SetIntPref(kCookiesPermissions, 0); // accept all
  189. aPrefBranch->SetBoolPref(kCookiesLifetimeEnabled, true);
  190. aPrefBranch->SetIntPref(kCookiesLifetimeCurrentSession, 0);
  191. aPrefBranch->SetIntPref(kCookiesLifetimeDays, 1);
  192. aPrefBranch->SetBoolPref(kCookieLeaveSecurityAlone, true);
  193. // Set the base domain limit to 50 so we have a known value.
  194. aPrefBranch->SetIntPref(kCookiesMaxPerHost, 50);
  195. }
  196. int
  197. main(int32_t argc, char *argv[])
  198. {
  199. if (test_common_init(&argc, &argv) != 0)
  200. return -1;
  201. bool allTestsPassed = true;
  202. ScopedXPCOM xpcom("TestCookie");
  203. {
  204. nsresult rv0;
  205. nsCOMPtr<nsICookieService> cookieService =
  206. do_GetService(kCookieServiceCID, &rv0);
  207. if (NS_FAILED(rv0)) return -1;
  208. nsCOMPtr<nsIPrefBranch> prefBranch =
  209. do_GetService(kPrefServiceCID, &rv0);
  210. if (NS_FAILED(rv0)) return -1;
  211. InitPrefs(prefBranch);
  212. bool rv[20];
  213. nsCString cookie;
  214. /* The basic idea behind these tests is the following:
  215. *
  216. * we set() some cookie, then try to get() it in various ways. we have
  217. * several possible tests we perform on the cookie string returned from
  218. * get():
  219. *
  220. * a) check whether the returned string is null (i.e. we got no cookies
  221. * back). this is used e.g. to ensure a given cookie was deleted
  222. * correctly, or to ensure a certain cookie wasn't returned to a given
  223. * host.
  224. * b) check whether the returned string exactly matches a given string.
  225. * this is used where we want to make sure our cookie service adheres to
  226. * some strict spec (e.g. ordering of multiple cookies), or where we
  227. * just know exactly what the returned string should be.
  228. * c) check whether the returned string contains/does not contain a given
  229. * string. this is used where we don't know/don't care about the
  230. * ordering of multiple cookies - we just want to make sure the cookie
  231. * string contains them all, in some order.
  232. *
  233. * the results of each individual testing operation from CheckResult() is
  234. * stored in an array of bools, which is then checked against the expected
  235. * outcomes (all successes), by PrintResult(). the overall result of all
  236. * tests to date is kept in |allTestsPassed|, for convenient display at the
  237. * end.
  238. *
  239. * Interpreting the output:
  240. * each setting/getting operation will print output saying exactly what
  241. * it's doing and the outcome, respectively. this information is only
  242. * useful for debugging purposes; the actual result of the tests is
  243. * printed at the end of each block of tests. this will either be "all
  244. * tests passed" or "tests X Y Z failed", where X, Y, Z are the indexes
  245. * of rv (i.e. zero-based). at the conclusion of all tests, the overall
  246. * passed/failed result is printed.
  247. *
  248. * NOTE: this testsuite is not yet comprehensive or complete, and is
  249. * somewhat contrived - still under development, and needs improving!
  250. */
  251. // *** basic tests
  252. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning basic tests...\n");
  253. // test some basic variations of the domain & path
  254. SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic", nullptr);
  255. GetACookie(cookieService, "http://www.basic.com", nullptr, getter_Copies(cookie));
  256. rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic");
  257. GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt", nullptr, getter_Copies(cookie));
  258. rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic");
  259. GetACookie(cookieService, "http://www.basic.com./", nullptr, getter_Copies(cookie));
  260. rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
  261. GetACookie(cookieService, "http://www.basic.com.", nullptr, getter_Copies(cookie));
  262. rv[3] = CheckResult(cookie.get(), MUST_BE_NULL);
  263. GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt", nullptr, getter_Copies(cookie));
  264. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  265. GetACookie(cookieService, "http://www.basic2.com/", nullptr, getter_Copies(cookie));
  266. rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
  267. SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic; max-age=-1", nullptr);
  268. GetACookie(cookieService, "http://www.basic.com/", nullptr, getter_Copies(cookie));
  269. rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);
  270. allTestsPassed = PrintResult(rv, 7) && allTestsPassed;
  271. // *** domain tests
  272. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning domain tests...\n");
  273. // test some variations of the domain & path, for different domains of
  274. // a domain cookie
  275. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com", nullptr);
  276. GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
  277. rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
  278. GetACookie(cookieService, "http://domain.com.", nullptr, getter_Copies(cookie));
  279. rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
  280. GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie));
  281. rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
  282. GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
  283. rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
  284. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com; max-age=-1", nullptr);
  285. GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
  286. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  287. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com", nullptr);
  288. GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
  289. rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
  290. GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie));
  291. rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
  292. GetACookie(cookieService, "http://bah.domain.com", nullptr, getter_Copies(cookie));
  293. rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
  294. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com; max-age=-1", nullptr);
  295. GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie));
  296. rv[8] = CheckResult(cookie.get(), MUST_BE_NULL);
  297. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.foo.domain.com", nullptr);
  298. GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
  299. rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);
  300. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=moose.com", nullptr);
  301. GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
  302. rv[10] = CheckResult(cookie.get(), MUST_BE_NULL);
  303. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com.", nullptr);
  304. GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
  305. rv[11] = CheckResult(cookie.get(), MUST_BE_NULL);
  306. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com", nullptr);
  307. GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
  308. rv[12] = CheckResult(cookie.get(), MUST_BE_NULL);
  309. SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com.", nullptr);
  310. GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie));
  311. rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);
  312. SetACookie(cookieService, "http://path.net/path/file", nullptr, R"(test=taco; path="/bogus")", nullptr);
  313. GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie));
  314. rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=taco");
  315. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; max-age=-1", nullptr);
  316. GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie));
  317. rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);
  318. allTestsPassed = PrintResult(rv, 16) && allTestsPassed;
  319. // *** path tests
  320. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path tests...\n");
  321. // test some variations of the domain & path, for different paths of
  322. // a path cookie
  323. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path", nullptr);
  324. GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie));
  325. rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  326. GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
  327. rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  328. GetACookie(cookieService, "http://path.net/path/hithere.foo", nullptr, getter_Copies(cookie));
  329. rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  330. GetACookie(cookieService, "http://path.net/path?hithere/foo", nullptr, getter_Copies(cookie));
  331. rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  332. GetACookie(cookieService, "http://path.net/path2", nullptr, getter_Copies(cookie));
  333. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  334. GetACookie(cookieService, "http://path.net/path2/", nullptr, getter_Copies(cookie));
  335. rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
  336. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path; max-age=-1", nullptr);
  337. GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
  338. rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);
  339. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/", nullptr);
  340. GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie));
  341. rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  342. GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
  343. rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  344. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/; max-age=-1", nullptr);
  345. GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie));
  346. rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);
  347. // note that a site can set a cookie for a path it's not on.
  348. // this is an intentional deviation from spec (see comments in
  349. // nsCookieService::CheckPath()), so we test this functionality too
  350. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/", nullptr);
  351. GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie));
  352. rv[10] = CheckResult(cookie.get(), MUST_BE_NULL);
  353. GetACookie(cookieService, "http://path.net/foo", nullptr, getter_Copies(cookie));
  354. rv[11] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
  355. SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/; max-age=-1", nullptr);
  356. GetACookie(cookieService, "http://path.net/foo/", nullptr, getter_Copies(cookie));
  357. rv[12] = CheckResult(cookie.get(), MUST_BE_NULL);
  358. // bug 373228: make sure cookies with paths longer than 1024 bytes,
  359. // and cookies with paths or names containing tabs, are rejected.
  360. // the following cookie has a path > 1024 bytes explicitly specified in the cookie
  361. SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr);
  362. GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", nullptr, getter_Copies(cookie));
  363. rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);
  364. // the following cookie has a path > 1024 bytes implicitly specified by the uri path
  365. SetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, "test=path", nullptr);
  366. GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, getter_Copies(cookie));
  367. rv[14] = CheckResult(cookie.get(), MUST_BE_NULL);
  368. // the following cookie includes a tab in the path
  369. SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/foo\tbar/", nullptr);
  370. GetACookie(cookieService, "http://path.net/foo\tbar/", nullptr, getter_Copies(cookie));
  371. rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);
  372. // the following cookie includes a tab in the name
  373. SetACookie(cookieService, "http://path.net/", nullptr, "test\ttabs=tab", nullptr);
  374. GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie));
  375. rv[16] = CheckResult(cookie.get(), MUST_BE_NULL);
  376. // the following cookie includes a tab in the value - allowed
  377. SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest", nullptr);
  378. GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie));
  379. rv[17] = CheckResult(cookie.get(), MUST_EQUAL, "test=tab\ttest");
  380. SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest; max-age=-1", nullptr);
  381. GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie));
  382. rv[18] = CheckResult(cookie.get(), MUST_BE_NULL);
  383. allTestsPassed = PrintResult(rv, 19) && allTestsPassed;
  384. // *** expiry & deletion tests
  385. // XXX add server time str parsing tests here
  386. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning expiry & deletion tests...\n");
  387. // test some variations of the expiry time,
  388. // and test deletion of previously set cookies
  389. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-1", nullptr);
  390. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  391. rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
  392. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=0", nullptr);
  393. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  394. rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
  395. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=bad", nullptr);
  396. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  397. rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
  398. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr);
  399. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  400. rv[3] = CheckResult(cookie.get(), MUST_BE_NULL);
  401. SetACookie(cookieService, "http://expireme.org/", nullptr, R"(test=expiry; expires="Thu, 10 Apr 1980 16:33:12 GMT)", nullptr);
  402. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  403. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  404. SetACookie(cookieService, "http://expireme.org/", nullptr, R"(test=expiry; expires="Thu, 10 Apr 1980 16:33:12 GMT")", nullptr);
  405. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  406. rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
  407. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr);
  408. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  409. rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
  410. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-20", nullptr);
  411. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  412. rv[7] = CheckResult(cookie.get(), MUST_BE_NULL);
  413. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr);
  414. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  415. rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
  416. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr);
  417. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  418. rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);
  419. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr);
  420. SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=expiry; max-age=60", nullptr);
  421. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  422. rv[10] = CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry");
  423. rv[11] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry");
  424. SetACookie(cookieService, "http://expireme.org/", nullptr, "test=differentvalue; max-age=0", nullptr);
  425. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  426. rv[12] = CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry");
  427. SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=evendifferentvalue; max-age=0", nullptr);
  428. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  429. rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);
  430. SetACookie(cookieService, "http://foo.expireme.org/", nullptr, "test=expiry; domain=.expireme.org; max-age=60", nullptr);
  431. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  432. rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
  433. SetACookie(cookieService, "http://bar.expireme.org/", nullptr, "test=differentvalue; domain=.expireme.org; max-age=0", nullptr);
  434. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  435. rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);
  436. nsAutoCString ServerTime;
  437. nsAutoCString CookieString;
  438. SetTime(-OFFSET_ONE_WEEK, ServerTime, CookieString, true);
  439. SetACookie(cookieService, "http://expireme.org/", nullptr, CookieString.get(), ServerTime.get());
  440. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  441. rv[16] = CheckResult(cookie.get(), MUST_BE_NULL);
  442. // Set server time earlier than client time for one year + one day, and expirty time earlier than server time for one day.
  443. SetTime(-(OFFSET_ONE_DAY + OFFSET_ONE_WEEK), ServerTime, CookieString, false);
  444. SetACookie(cookieService, "http://expireme.org/", nullptr, CookieString.get(), ServerTime.get());
  445. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  446. rv[17] = CheckResult(cookie.get(), MUST_BE_NULL);
  447. // Set server time later than client time for one year, and expiry time later than server time for one day.
  448. SetTime(OFFSET_ONE_WEEK, ServerTime, CookieString, false);
  449. SetACookie(cookieService, "http://expireme.org/", nullptr, CookieString.get(), ServerTime.get());
  450. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  451. rv[18] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
  452. // Set server time later than client time for one year + one day, and expiry time earlier than server time for one day.
  453. SetTime((OFFSET_ONE_DAY + OFFSET_ONE_WEEK), ServerTime, CookieString, true);
  454. SetACookie(cookieService, "http://expireme.org/", nullptr, CookieString.get(), ServerTime.get());
  455. GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie));
  456. rv[19] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
  457. allTestsPassed = PrintResult(rv, 20) && allTestsPassed;
  458. // *** multiple cookie tests
  459. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning multiple cookie tests...\n");
  460. // test the setting of multiple cookies, and test the order of precedence
  461. // (a later cookie overwriting an earlier one, in the same header string)
  462. SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=multiple; domain=.multiple.cookies \n test=different \n test=same; domain=.multiple.cookies \n newtest=ciao \n newtest=foo; max-age=-6 \n newtest=reincarnated", nullptr);
  463. GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
  464. rv[0] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple");
  465. rv[1] = CheckResult(cookie.get(), MUST_CONTAIN, "test=different");
  466. rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=same");
  467. rv[3] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao");
  468. rv[4] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo");
  469. rv[5] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated");
  470. SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=expiry; domain=.multiple.cookies; max-age=0", nullptr);
  471. GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
  472. rv[6] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same");
  473. SetACookie(cookieService, "http://multiple.cookies/", nullptr, "\n test=different; max-age=0 \n", nullptr);
  474. GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
  475. rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different");
  476. SetACookie(cookieService, "http://multiple.cookies/", nullptr, "newtest=dead; max-age=0", nullptr);
  477. GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie));
  478. rv[8] = CheckResult(cookie.get(), MUST_BE_NULL);
  479. allTestsPassed = PrintResult(rv, 9) && allTestsPassed;
  480. // *** parser tests
  481. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning parser tests...\n");
  482. // test the cookie header parser, under various circumstances.
  483. SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;", nullptr);
  484. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  485. rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=parser");
  486. SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; max-age=0", nullptr);
  487. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  488. rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
  489. SetACookie(cookieService, "http://parser.test/", nullptr, "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; max-age=6\nfive; max-age=2.63,", nullptr);
  490. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  491. rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, R"(test="fubar! = foo)");
  492. rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "five");
  493. SetACookie(cookieService, "http://parser.test/", nullptr, "test=kill; domain=.parser.test; max-age=0 \n five; max-age=0", nullptr);
  494. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  495. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  496. // test the handling of VALUE-only cookies (see bug 169091),
  497. // i.e. "six" should assume an empty NAME, which allows other VALUE-only
  498. // cookies to overwrite it
  499. SetACookie(cookieService, "http://parser.test/", nullptr, "six", nullptr);
  500. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  501. rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "six");
  502. SetACookie(cookieService, "http://parser.test/", nullptr, "seven", nullptr);
  503. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  504. rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "seven");
  505. SetACookie(cookieService, "http://parser.test/", nullptr, " =eight", nullptr);
  506. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  507. rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "eight");
  508. SetACookie(cookieService, "http://parser.test/", nullptr, "test=six", nullptr);
  509. GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie));
  510. rv[9] = CheckResult(cookie.get(), MUST_CONTAIN, "test=six");
  511. allTestsPassed = PrintResult(rv, 10) && allTestsPassed;
  512. // *** path ordering tests
  513. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path ordering tests...\n");
  514. // test that cookies are returned in path order - longest to shortest.
  515. // if the header doesn't specify a path, it's taken from the host URI.
  516. SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test1=path; path=/one/two/three", nullptr);
  517. SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test2=path; path=/one \n test3=path; path=/one/two/three/four \n test4=path; path=/one/two \n test5=path; path=/one/two/", nullptr);
  518. SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/", nullptr, "test6=path", nullptr);
  519. SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, "test7=path; path=", nullptr);
  520. SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test8=path; path=/", nullptr);
  521. GetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, getter_Copies(cookie));
  522. rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test7=path; test6=path; test3=path; test1=path; test5=path; test4=path; test2=path; test8=path");
  523. allTestsPassed = PrintResult(rv, 1) && allTestsPassed;
  524. // *** httponly tests
  525. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning httponly tests...\n");
  526. // Since this cookie is NOT set via http, setting it fails
  527. SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly");
  528. GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
  529. rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
  530. // Since this cookie is set via http, it can be retrieved
  531. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
  532. GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
  533. rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
  534. // ... but not by web content
  535. GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
  536. rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
  537. // Non-Http cookies should not replace HttpOnly cookies
  538. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
  539. SetACookieNoHttp(cookieService, "http://httponly.test/", "test=not-httponly");
  540. GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
  541. rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
  542. // ... and, if an HttpOnly cookie already exists, should not be set at all
  543. GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
  544. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  545. // Non-Http cookies should not delete HttpOnly cookies
  546. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
  547. SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; max-age=-1");
  548. GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
  549. rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
  550. // ... but HttpOnly cookies should
  551. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly; max-age=-1", nullptr);
  552. GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie));
  553. rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);
  554. // Non-Httponly cookies can replace HttpOnly cookies when set over http
  555. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr);
  556. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr);
  557. GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
  558. rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly");
  559. // scripts should not be able to set httponly cookies by replacing an existing non-httponly cookie
  560. SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr);
  561. SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly");
  562. GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
  563. rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly");
  564. allTestsPassed = PrintResult(rv, 9) && allTestsPassed;
  565. // *** Cookie prefix tests
  566. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning cookie prefix tests...\n");
  567. // prefixed cookies can't be set from insecure HTTP
  568. SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Secure-test1=test", nullptr);
  569. SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Secure-test2=test; secure", nullptr);
  570. SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Host-test1=test", nullptr);
  571. SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Host-test2=test; secure", nullptr);
  572. GetACookie(cookieService, "http://prefixed.test/", nullptr, getter_Copies(cookie));
  573. rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
  574. // prefixed cookies won't be set without the secure flag
  575. SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Secure-test=test", nullptr);
  576. SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Host-test=test", nullptr);
  577. GetACookie(cookieService, "https://prefixed.test/", nullptr, getter_Copies(cookie));
  578. rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
  579. // prefixed cookies can be set when done correctly
  580. SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Secure-test=test; secure", nullptr);
  581. SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Host-test=test; secure", nullptr);
  582. GetACookie(cookieService, "https://prefixed.test/", nullptr, getter_Copies(cookie));
  583. rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "__Secure-test=test");
  584. rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "__Host-test=test");
  585. // but when set must not be returned to the host insecurely
  586. GetACookie(cookieService, "http://prefixed.test/", nullptr, getter_Copies(cookie));
  587. rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
  588. // Host-prefixed cookies cannot specify a domain
  589. SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-a=test; secure; domain=prefixed.test", nullptr);
  590. SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-b=test; secure; domain=.prefixed.test", nullptr);
  591. SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-c=test; secure; domain=host.prefixed.test", nullptr);
  592. SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-d=test; secure; domain=.host.prefixed.test", nullptr);
  593. GetACookie(cookieService, "https://host.prefixed.test/", nullptr, getter_Copies(cookie));
  594. rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
  595. // Host-prefixed cookies can only have a path of "/"
  596. SetACookie(cookieService, "https://host.prefixed.test/some/path", nullptr, "__Host-e=test; secure", nullptr);
  597. SetACookie(cookieService, "https://host.prefixed.test/some/path", nullptr, "__Host-f=test; secure; path=/", nullptr);
  598. SetACookie(cookieService, "https://host.prefixed.test/some/path", nullptr, "__Host-g=test; secure; path=/some", nullptr);
  599. GetACookie(cookieService, "https://host.prefixed.test/", nullptr, getter_Copies(cookie));
  600. rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "__Host-f=test");
  601. allTestsPassed = PrintResult(rv, 7) && allTestsPassed;
  602. // *** leave-secure-alone tests
  603. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning leave-secure-alone tests...\n");
  604. // testing items 0 & 1 for 3.1 of spec Deprecate modification of ’secure’
  605. // cookies from non-secure origins
  606. SetACookie(cookieService, "http://www.security.test/", nullptr, "test=non-security; secure", nullptr);
  607. GetACookieNoHttp(cookieService, "https://www.security.test/", getter_Copies(cookie));
  608. rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
  609. SetACookie(cookieService, "https://www.security.test/path/", nullptr, "test=security; secure; path=/path/", nullptr);
  610. GetACookieNoHttp(cookieService, "https://www.security.test/path/", getter_Copies(cookie));
  611. rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=security");
  612. // testing items 2 & 3 & 4 for 3.2 of spec Deprecate modification of ’secure’
  613. // cookies from non-secure origins
  614. // Secure site can modify cookie value
  615. SetACookie(cookieService, "https://www.security.test/path/", nullptr, "test=security2; secure; path=/path/", nullptr);
  616. GetACookieNoHttp(cookieService, "https://www.security.test/path/", getter_Copies(cookie));
  617. rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=security2");
  618. // If new cookie contains same name, same host and partially matching path with
  619. // an existing security cookie on non-security site, it can't modify an existing
  620. // security cookie.
  621. SetACookie(cookieService, "http://www.security.test/path/foo/", nullptr, "test=non-security; path=/path/foo", nullptr);
  622. GetACookieNoHttp(cookieService, "https://www.security.test/path/foo/", getter_Copies(cookie));
  623. rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=security2");
  624. // Non-secure cookie can set by same name, same host and non-matching path.
  625. SetACookie(cookieService, "http://www.security.test/bar/", nullptr, "test=non-security; path=/bar", nullptr);
  626. GetACookieNoHttp(cookieService, "http://www.security.test/bar/", getter_Copies(cookie));
  627. rv[4] = CheckResult(cookie.get(), MUST_EQUAL, "test=non-security");
  628. // Modify value and downgrade secure level.
  629. SetACookie(cookieService, "https://www.security.test/", nullptr, "test_modify_cookie=security-cookie; secure; domain=.security.test", nullptr);
  630. GetACookieNoHttp(cookieService, "https://www.security.test/", getter_Copies(cookie));
  631. rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test_modify_cookie=security-cookie");
  632. SetACookie(cookieService, "https://www.security.test/", nullptr, "test_modify_cookie=non-security-cookie; domain=.security.test", nullptr);
  633. GetACookieNoHttp(cookieService, "https://www.security.test/", getter_Copies(cookie));
  634. rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test_modify_cookie=non-security-cookie");
  635. // Test the non-security cookie can set when domain or path not same to secure cookie of same name.
  636. SetACookie(cookieService, "https://www.security.test/", nullptr, "test=security3", nullptr);
  637. GetACookieNoHttp(cookieService, "http://www.security.test/", getter_Copies(cookie));
  638. rv[7] = CheckResult(cookie.get(), MUST_CONTAIN, "test=security3");
  639. SetACookie(cookieService, "http://www.security.test/", nullptr, "test=non-security2; domain=security.test", nullptr);
  640. GetACookieNoHttp(cookieService, "http://www.security.test/", getter_Copies(cookie));
  641. rv[8] = CheckResult(cookie.get(), MUST_CONTAIN, "test=non-security2");
  642. allTestsPassed = PrintResult(rv, 9) && allTestsPassed;
  643. // *** nsICookieManager{2} interface tests
  644. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n");
  645. nsCOMPtr<nsICookieManager> cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0);
  646. if (NS_FAILED(rv0)) return -1;
  647. nsCOMPtr<nsICookieManager2> cookieMgr2 = do_QueryInterface(cookieMgr);
  648. if (!cookieMgr2) return -1;
  649. mozilla::NeckoOriginAttributes attrs;
  650. // first, ensure a clean slate
  651. rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll());
  652. // add some cookies
  653. rv[1] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
  654. NS_LITERAL_CSTRING("/foo"), // path
  655. NS_LITERAL_CSTRING("test1"), // name
  656. NS_LITERAL_CSTRING("yes"), // value
  657. false, // is secure
  658. false, // is httponly
  659. true, // is session
  660. INT64_MAX, // expiry time
  661. &attrs)); // originAttributes
  662. rv[2] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
  663. NS_LITERAL_CSTRING("/foo"), // path
  664. NS_LITERAL_CSTRING("test2"), // name
  665. NS_LITERAL_CSTRING("yes"), // value
  666. false, // is secure
  667. true, // is httponly
  668. true, // is session
  669. PR_Now() / PR_USEC_PER_SEC + 2, // expiry time
  670. &attrs)); // originAttributes
  671. rv[3] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("new.domain"), // domain
  672. NS_LITERAL_CSTRING("/rabbit"), // path
  673. NS_LITERAL_CSTRING("test3"), // name
  674. NS_LITERAL_CSTRING("yes"), // value
  675. false, // is secure
  676. false, // is httponly
  677. true, // is session
  678. INT64_MAX, // expiry time
  679. &attrs)); // originAttributes
  680. // confirm using enumerator
  681. nsCOMPtr<nsISimpleEnumerator> enumerator;
  682. rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator)));
  683. int32_t i = 0;
  684. bool more;
  685. nsCOMPtr<nsICookie2> expiredCookie, newDomainCookie;
  686. while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
  687. nsCOMPtr<nsISupports> cookie;
  688. if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break;
  689. ++i;
  690. // keep tabs on the second and third cookies, so we can check them later
  691. nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie));
  692. if (!cookie2) break;
  693. nsAutoCString name;
  694. cookie2->GetName(name);
  695. if (name.EqualsLiteral("test2"))
  696. expiredCookie = cookie2;
  697. else if (name.EqualsLiteral("test3"))
  698. newDomainCookie = cookie2;
  699. }
  700. rv[5] = i == 3;
  701. // check the httpOnly attribute of the second cookie is honored
  702. GetACookie(cookieService, "http://cookiemgr.test/foo/", nullptr, getter_Copies(cookie));
  703. rv[6] = CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes");
  704. GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", getter_Copies(cookie));
  705. rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes");
  706. // check CountCookiesFromHost()
  707. uint32_t hostCookies = 0;
  708. rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
  709. hostCookies == 2;
  710. // check CookieExistsNative() using the third cookie
  711. bool found;
  712. rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExistsNative(newDomainCookie, &attrs, &found)) && found;
  713. // remove the cookie, block it, and ensure it can't be added again
  714. rv[10] = NS_SUCCEEDED(cookieMgr->RemoveNative(NS_LITERAL_CSTRING("new.domain"), // domain
  715. NS_LITERAL_CSTRING("test3"), // name
  716. NS_LITERAL_CSTRING("/rabbit"), // path
  717. true, // is blocked
  718. &attrs)); // originAttributes
  719. rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExistsNative(newDomainCookie, &attrs, &found)) && !found;
  720. rv[12] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("new.domain"), // domain
  721. NS_LITERAL_CSTRING("/rabbit"), // path
  722. NS_LITERAL_CSTRING("test3"), // name
  723. NS_LITERAL_CSTRING("yes"), // value
  724. false, // is secure
  725. false, // is httponly
  726. true, // is session
  727. INT64_MIN, // expiry time
  728. &attrs)); // originAttributes
  729. rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExistsNative(newDomainCookie, &attrs, &found)) && !found;
  730. // sleep four seconds, to make sure the second cookie has expired
  731. PR_Sleep(4 * PR_TicksPerSecond());
  732. // check that both CountCookiesFromHost() and CookieExistsNative() count the
  733. // expired cookie
  734. rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
  735. hostCookies == 2;
  736. rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExistsNative(expiredCookie, &attrs, &found)) && found;
  737. // double-check RemoveAll() using the enumerator
  738. rv[16] = NS_SUCCEEDED(cookieMgr->RemoveAll());
  739. rv[17] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))) &&
  740. NS_SUCCEEDED(enumerator->HasMoreElements(&more)) &&
  741. !more;
  742. allTestsPassed = PrintResult(rv, 18) && allTestsPassed;
  743. // *** eviction and creation ordering tests
  744. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation ordering tests...\n");
  745. // test that cookies are
  746. // a) returned by order of creation time (oldest first, newest last)
  747. // b) evicted by order of lastAccessed time, if the limit on cookies per host (50) is reached
  748. nsAutoCString name;
  749. nsAutoCString expected;
  750. for (int32_t i = 0; i < 60; ++i) {
  751. name = NS_LITERAL_CSTRING("test");
  752. name.AppendInt(i);
  753. name += NS_LITERAL_CSTRING("=creation");
  754. SetACookie(cookieService, "http://creation.ordering.tests/", nullptr, name.get(), nullptr);
  755. if (i >= 10) {
  756. expected += name;
  757. if (i < 59)
  758. expected += NS_LITERAL_CSTRING("; ");
  759. }
  760. }
  761. GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, getter_Copies(cookie));
  762. rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get());
  763. allTestsPassed = PrintResult(rv, 1) && allTestsPassed;
  764. // *** eviction and creation ordering tests after enable network.cookie.leave-secure-alone
  765. sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation tests after enable nework.cookie.leave-secure-alone...\n");
  766. // reset cookie
  767. cookieMgr->RemoveAll();
  768. for (int32_t i = 0; i < 60; ++i) {
  769. name = NS_LITERAL_CSTRING("test");
  770. name.AppendInt(i);
  771. name += NS_LITERAL_CSTRING("=delete_non_security");
  772. // Create 50 cookies that include the secure flag.
  773. if (i < 50) {
  774. name += NS_LITERAL_CSTRING("; secure");
  775. SetACookie(cookieService, "https://creation.ordering.tests/", nullptr, name.get(), nullptr);
  776. } else {
  777. // non-security cookies will be removed beside the latest cookie that be created.
  778. SetACookie(cookieService, "http://creation.ordering.tests/", nullptr, name.get(), nullptr);
  779. }
  780. }
  781. GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, getter_Copies(cookie));
  782. rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
  783. allTestsPassed = PrintResult(rv, 1) && allTestsPassed;
  784. // XXX the following are placeholders: add these tests please!
  785. // *** "noncompliant cookie" tests
  786. // *** IP address tests
  787. // *** speed tests
  788. sBuffer = PR_sprintf_append(sBuffer, "\n*** Result: %s!\n\n", allTestsPassed ? "all tests passed" : "TEST(S) FAILED");
  789. }
  790. if (!allTestsPassed) {
  791. // print the entire log
  792. printf("%s", sBuffer);
  793. return 1;
  794. }
  795. PR_smprintf_free(sBuffer);
  796. sBuffer = nullptr;
  797. return 0;
  798. }
  799. // Stubs to make this test happy
  800. mozilla::dom::OriginAttributesDictionary::OriginAttributesDictionary()
  801. : mAppId(0),
  802. mInIsolatedMozBrowser(false),
  803. mPrivateBrowsingId(0),
  804. mUserContextId(0)
  805. {}