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