michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "TestCommon.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsICookieService.h" michael@0: #include "nsICookieManager.h" michael@0: #include "nsICookieManager2.h" michael@0: #include "nsICookie2.h" michael@0: #include michael@0: #include "plstr.h" michael@0: #include "prprf.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsStringAPI.h" michael@0: #include "nsIPrefBranch.h" michael@0: #include "nsIPrefService.h" michael@0: michael@0: static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID); michael@0: static NS_DEFINE_CID(kPrefServiceCID, NS_PREFSERVICE_CID); michael@0: michael@0: // various pref strings michael@0: static const char kCookiesPermissions[] = "network.cookie.cookieBehavior"; michael@0: static const char kCookiesLifetimeEnabled[] = "network.cookie.lifetime.enabled"; michael@0: static const char kCookiesLifetimeDays[] = "network.cookie.lifetime.days"; michael@0: static const char kCookiesLifetimeCurrentSession[] = "network.cookie.lifetime.behavior"; michael@0: static const char kCookiesAskPermission[] = "network.cookie.warnAboutCookies"; michael@0: static const char kCookiesMaxPerHost[] = "network.cookie.maxPerHost"; michael@0: michael@0: static char *sBuffer; michael@0: michael@0: nsresult michael@0: SetACookie(nsICookieService *aCookieService, const char *aSpec1, const char *aSpec2, const char* aCookieString, const char *aServerTime) michael@0: { michael@0: nsCOMPtr uri1, uri2; michael@0: NS_NewURI(getter_AddRefs(uri1), aSpec1); michael@0: if (aSpec2) michael@0: NS_NewURI(getter_AddRefs(uri2), aSpec2); michael@0: michael@0: sBuffer = PR_sprintf_append(sBuffer, " for host \"%s\": SET ", aSpec1); michael@0: nsresult rv = aCookieService->SetCookieStringFromHttp(uri1, uri2, nullptr, (char *)aCookieString, aServerTime, nullptr); michael@0: // the following code is useless. the cookieservice blindly returns NS_OK michael@0: // from SetCookieString. we have to call GetCookie to see if the cookie was michael@0: // set correctly... michael@0: if (NS_FAILED(rv)) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "nothing\n"); michael@0: } else { michael@0: sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", aCookieString); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: nsresult michael@0: SetACookieNoHttp(nsICookieService *aCookieService, const char *aSpec, const char* aCookieString) michael@0: { michael@0: nsCOMPtr uri; michael@0: NS_NewURI(getter_AddRefs(uri), aSpec); michael@0: michael@0: sBuffer = PR_sprintf_append(sBuffer, " for host \"%s\": SET ", aSpec); michael@0: nsresult rv = aCookieService->SetCookieString(uri, nullptr, (char *)aCookieString, nullptr); michael@0: // the following code is useless. the cookieservice blindly returns NS_OK michael@0: // from SetCookieString. we have to call GetCookie to see if the cookie was michael@0: // set correctly... michael@0: if (NS_FAILED(rv)) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "nothing\n"); michael@0: } else { michael@0: sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", aCookieString); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: // returns true if cookie(s) for the given host were found; else false. michael@0: // the cookie string is returned via aCookie. michael@0: bool michael@0: GetACookie(nsICookieService *aCookieService, const char *aSpec1, const char *aSpec2, char **aCookie) michael@0: { michael@0: nsCOMPtr uri1, uri2; michael@0: NS_NewURI(getter_AddRefs(uri1), aSpec1); michael@0: if (aSpec2) michael@0: NS_NewURI(getter_AddRefs(uri2), aSpec2); michael@0: michael@0: sBuffer = PR_sprintf_append(sBuffer, " \"%s\": GOT ", aSpec1); michael@0: nsresult rv = aCookieService->GetCookieStringFromHttp(uri1, uri2, nullptr, aCookie); michael@0: if (NS_FAILED(rv)) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "XXX GetCookieString() failed!\n"); michael@0: } michael@0: if (!*aCookie) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "nothing\n"); michael@0: } else { michael@0: sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", *aCookie); michael@0: } michael@0: return *aCookie != nullptr; michael@0: } michael@0: michael@0: // returns true if cookie(s) for the given host were found; else false. michael@0: // the cookie string is returned via aCookie. michael@0: bool michael@0: GetACookieNoHttp(nsICookieService *aCookieService, const char *aSpec, char **aCookie) michael@0: { michael@0: nsCOMPtr uri; michael@0: NS_NewURI(getter_AddRefs(uri), aSpec); michael@0: michael@0: sBuffer = PR_sprintf_append(sBuffer, " \"%s\": GOT ", aSpec); michael@0: nsresult rv = aCookieService->GetCookieString(uri, nullptr, aCookie); michael@0: if (NS_FAILED(rv)) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "XXX GetCookieString() failed!\n"); michael@0: } michael@0: if (!*aCookie) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "nothing\n"); michael@0: } else { michael@0: sBuffer = PR_sprintf_append(sBuffer, "\"%s\"\n", *aCookie); michael@0: } michael@0: return *aCookie != nullptr; michael@0: } michael@0: michael@0: // some #defines for comparison rules michael@0: #define MUST_BE_NULL 0 michael@0: #define MUST_EQUAL 1 michael@0: #define MUST_CONTAIN 2 michael@0: #define MUST_NOT_CONTAIN 3 michael@0: #define MUST_NOT_EQUAL 4 michael@0: michael@0: // a simple helper function to improve readability: michael@0: // takes one of the #defined rules above, and performs the appropriate test. michael@0: // true means the test passed; false means the test failed. michael@0: static inline bool michael@0: CheckResult(const char *aLhs, uint32_t aRule, const char *aRhs = nullptr) michael@0: { michael@0: switch (aRule) { michael@0: case MUST_BE_NULL: michael@0: return !aLhs || !*aLhs; michael@0: michael@0: case MUST_EQUAL: michael@0: return !PL_strcmp(aLhs, aRhs); michael@0: michael@0: case MUST_NOT_EQUAL: michael@0: return PL_strcmp(aLhs, aRhs); michael@0: michael@0: case MUST_CONTAIN: michael@0: return PL_strstr(aLhs, aRhs) != nullptr; michael@0: michael@0: case MUST_NOT_CONTAIN: michael@0: return PL_strstr(aLhs, aRhs) == nullptr; michael@0: michael@0: default: michael@0: return false; // failure michael@0: } michael@0: } michael@0: michael@0: // helper function that ensures the first aSize elements of aResult are michael@0: // true (i.e. all tests succeeded). prints the result of the tests (if any michael@0: // tests failed, it prints the zero-based index of each failed test). michael@0: bool michael@0: PrintResult(const bool aResult[], uint32_t aSize) michael@0: { michael@0: bool failed = false; michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** tests "); michael@0: for (uint32_t i = 0; i < aSize; ++i) { michael@0: if (!aResult[i]) { michael@0: failed = true; michael@0: sBuffer = PR_sprintf_append(sBuffer, "%d ", i); michael@0: } michael@0: } michael@0: if (failed) { michael@0: sBuffer = PR_sprintf_append(sBuffer, "FAILED!\a\n"); michael@0: } else { michael@0: sBuffer = PR_sprintf_append(sBuffer, "passed.\n"); michael@0: } michael@0: return !failed; michael@0: } michael@0: michael@0: void michael@0: InitPrefs(nsIPrefBranch *aPrefBranch) michael@0: { michael@0: // init some relevant prefs, so the tests don't go awry. michael@0: // we use the most restrictive set of prefs we can; michael@0: // however, we don't test third party blocking here. michael@0: aPrefBranch->SetIntPref(kCookiesPermissions, 0); // accept all michael@0: aPrefBranch->SetBoolPref(kCookiesLifetimeEnabled, true); michael@0: aPrefBranch->SetIntPref(kCookiesLifetimeCurrentSession, 0); michael@0: aPrefBranch->SetIntPref(kCookiesLifetimeDays, 1); michael@0: aPrefBranch->SetBoolPref(kCookiesAskPermission, false); michael@0: // Set the base domain limit to 50 so we have a known value. michael@0: aPrefBranch->SetIntPref(kCookiesMaxPerHost, 50); michael@0: } michael@0: michael@0: class ScopedXPCOM michael@0: { michael@0: public: michael@0: ScopedXPCOM() : rv(NS_InitXPCOM2(nullptr, nullptr, nullptr)) { } michael@0: ~ScopedXPCOM() michael@0: { michael@0: if (NS_SUCCEEDED(rv)) michael@0: NS_ShutdownXPCOM(nullptr); michael@0: } michael@0: michael@0: nsresult rv; michael@0: }; michael@0: michael@0: int michael@0: main(int32_t argc, char *argv[]) michael@0: { michael@0: if (test_common_init(&argc, &argv) != 0) michael@0: return -1; michael@0: michael@0: bool allTestsPassed = true; michael@0: michael@0: ScopedXPCOM xpcom; michael@0: if (NS_FAILED(xpcom.rv)) michael@0: return -1; michael@0: michael@0: { michael@0: nsresult rv0; michael@0: michael@0: nsCOMPtr cookieService = michael@0: do_GetService(kCookieServiceCID, &rv0); michael@0: if (NS_FAILED(rv0)) return -1; michael@0: michael@0: nsCOMPtr prefBranch = michael@0: do_GetService(kPrefServiceCID, &rv0); michael@0: if (NS_FAILED(rv0)) return -1; michael@0: michael@0: InitPrefs(prefBranch); michael@0: michael@0: bool rv[20]; michael@0: nsCString cookie; michael@0: michael@0: /* The basic idea behind these tests is the following: michael@0: * michael@0: * we set() some cookie, then try to get() it in various ways. we have michael@0: * several possible tests we perform on the cookie string returned from michael@0: * get(): michael@0: * michael@0: * a) check whether the returned string is null (i.e. we got no cookies michael@0: * back). this is used e.g. to ensure a given cookie was deleted michael@0: * correctly, or to ensure a certain cookie wasn't returned to a given michael@0: * host. michael@0: * b) check whether the returned string exactly matches a given string. michael@0: * this is used where we want to make sure our cookie service adheres to michael@0: * some strict spec (e.g. ordering of multiple cookies), or where we michael@0: * just know exactly what the returned string should be. michael@0: * c) check whether the returned string contains/does not contain a given michael@0: * string. this is used where we don't know/don't care about the michael@0: * ordering of multiple cookies - we just want to make sure the cookie michael@0: * string contains them all, in some order. michael@0: * michael@0: * the results of each individual testing operation from CheckResult() is michael@0: * stored in an array of bools, which is then checked against the expected michael@0: * outcomes (all successes), by PrintResult(). the overall result of all michael@0: * tests to date is kept in |allTestsPassed|, for convenient display at the michael@0: * end. michael@0: * michael@0: * Interpreting the output: michael@0: * each setting/getting operation will print output saying exactly what michael@0: * it's doing and the outcome, respectively. this information is only michael@0: * useful for debugging purposes; the actual result of the tests is michael@0: * printed at the end of each block of tests. this will either be "all michael@0: * tests passed" or "tests X Y Z failed", where X, Y, Z are the indexes michael@0: * of rv (i.e. zero-based). at the conclusion of all tests, the overall michael@0: * passed/failed result is printed. michael@0: * michael@0: * NOTE: this testsuite is not yet comprehensive or complete, and is michael@0: * somewhat contrived - still under development, and needs improving! michael@0: */ michael@0: michael@0: // *** basic tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning basic tests...\n"); michael@0: michael@0: // test some basic variations of the domain & path michael@0: SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic", nullptr); michael@0: GetACookie(cookieService, "http://www.basic.com", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic"); michael@0: GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt", nullptr, getter_Copies(cookie)); michael@0: rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic"); michael@0: GetACookie(cookieService, "http://www.basic.com./", nullptr, getter_Copies(cookie)); michael@0: rv[2] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: GetACookie(cookieService, "http://www.basic.com.", nullptr, getter_Copies(cookie)); michael@0: rv[3] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt", nullptr, getter_Copies(cookie)); michael@0: rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: GetACookie(cookieService, "http://www.basic2.com/", nullptr, getter_Copies(cookie)); michael@0: rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://www.basic.com/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: allTestsPassed = PrintResult(rv, 7) && allTestsPassed; michael@0: michael@0: michael@0: // *** domain tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning domain tests...\n"); michael@0: michael@0: // test some variations of the domain & path, for different domains of michael@0: // a domain cookie michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com", nullptr); michael@0: GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); michael@0: GetACookie(cookieService, "http://domain.com.", nullptr, getter_Copies(cookie)); michael@0: rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); michael@0: GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com", nullptr); michael@0: GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); michael@0: GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); michael@0: GetACookie(cookieService, "http://bah.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[8] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.foo.domain.com", nullptr); michael@0: GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=moose.com", nullptr); michael@0: GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[10] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com.", nullptr); michael@0: GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[11] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com", nullptr); michael@0: GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[12] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com.", nullptr); michael@0: GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); michael@0: rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; path=\"/bogus\"", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie)); michael@0: rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=taco"); michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie)); michael@0: rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: allTestsPassed = PrintResult(rv, 16) && allTestsPassed; michael@0: michael@0: michael@0: // *** path tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path tests...\n"); michael@0: michael@0: // test some variations of the domain & path, for different paths of michael@0: // a path cookie michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); michael@0: rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: GetACookie(cookieService, "http://path.net/path/hithere.foo", nullptr, getter_Copies(cookie)); michael@0: rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: GetACookie(cookieService, "http://path.net/path?hithere/foo", nullptr, getter_Copies(cookie)); michael@0: rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: GetACookie(cookieService, "http://path.net/path2", nullptr, getter_Copies(cookie)); michael@0: rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: GetACookie(cookieService, "http://path.net/path2/", nullptr, getter_Copies(cookie)); michael@0: rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); michael@0: rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); michael@0: rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: // note that a site can set a cookie for a path it's not on. michael@0: // this is an intentional deviation from spec (see comments in michael@0: // nsCookieService::CheckPath()), so we test this functionality too michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/", nullptr); michael@0: GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); michael@0: rv[10] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: GetACookie(cookieService, "http://path.net/foo", nullptr, getter_Copies(cookie)); michael@0: rv[11] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); michael@0: SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://path.net/foo/", nullptr, getter_Copies(cookie)); michael@0: rv[12] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: // bug 373228: make sure cookies with paths longer than 1024 bytes, michael@0: // and cookies with paths or names containing tabs, are rejected. michael@0: // the following cookie has a path > 1024 bytes explicitly specified in the cookie michael@0: SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr); michael@0: GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", nullptr, getter_Copies(cookie)); michael@0: rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // the following cookie has a path > 1024 bytes implicitly specified by the uri path michael@0: SetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, "test=path", nullptr); michael@0: GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, getter_Copies(cookie)); michael@0: rv[14] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // the following cookie includes a tab in the path michael@0: SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/foo\tbar/", nullptr); michael@0: GetACookie(cookieService, "http://path.net/foo\tbar/", nullptr, getter_Copies(cookie)); michael@0: rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // the following cookie includes a tab in the name michael@0: SetACookie(cookieService, "http://path.net/", nullptr, "test\ttabs=tab", nullptr); michael@0: GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); michael@0: rv[16] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // the following cookie includes a tab in the value - allowed michael@0: SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest", nullptr); michael@0: GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); michael@0: rv[17] = CheckResult(cookie.get(), MUST_EQUAL, "test=tab\ttest"); michael@0: SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); michael@0: rv[18] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: allTestsPassed = PrintResult(rv, 19) && allTestsPassed; michael@0: michael@0: michael@0: // *** expiry & deletion tests michael@0: // XXX add server time str parsing tests here michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning expiry & deletion tests...\n"); michael@0: michael@0: // test some variations of the expiry time, michael@0: // and test deletion of previously set cookies michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=bad", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[3] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT\"", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-20", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=expiry; max-age=60", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[10] = CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry"); michael@0: rv[11] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry"); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "test=differentvalue; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[12] = CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry"); michael@0: SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=evendifferentvalue; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: SetACookie(cookieService, "http://foo.expireme.org/", nullptr, "test=expiry; domain=.expireme.org; max-age=60", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); michael@0: SetACookie(cookieService, "http://bar.expireme.org/", nullptr, "test=differentvalue; domain=.expireme.org; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); michael@0: rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: allTestsPassed = PrintResult(rv, 16) && allTestsPassed; michael@0: michael@0: michael@0: // *** multiple cookie tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning multiple cookie tests...\n"); michael@0: michael@0: // test the setting of multiple cookies, and test the order of precedence michael@0: // (a later cookie overwriting an earlier one, in the same header string) michael@0: 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); michael@0: GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple"); michael@0: rv[1] = CheckResult(cookie.get(), MUST_CONTAIN, "test=different"); michael@0: rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=same"); michael@0: rv[3] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao"); michael@0: rv[4] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo"); michael@0: rv[5] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated"); michael@0: SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=expiry; domain=.multiple.cookies; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same"); michael@0: SetACookie(cookieService, "http://multiple.cookies/", nullptr, "\n test=different; max-age=0 \n", nullptr); michael@0: GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different"); michael@0: SetACookie(cookieService, "http://multiple.cookies/", nullptr, "newtest=dead; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); michael@0: rv[8] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: allTestsPassed = PrintResult(rv, 9) && allTestsPassed; michael@0: michael@0: michael@0: // *** parser tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning parser tests...\n"); michael@0: michael@0: // test the cookie header parser, under various circumstances. michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=parser"); michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; max-age=6\nfive; max-age=2.63,", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=\"fubar! = foo"); michael@0: rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "five"); michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "test=kill; domain=.parser.test; max-age=0 \n five; max-age=0", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: michael@0: // test the handling of VALUE-only cookies (see bug 169091), michael@0: // i.e. "six" should assume an empty NAME, which allows other VALUE-only michael@0: // cookies to overwrite it michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "six", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "six"); michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "seven", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "seven"); michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, " =eight", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "eight"); michael@0: SetACookie(cookieService, "http://parser.test/", nullptr, "test=six", nullptr); michael@0: GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); michael@0: rv[9] = CheckResult(cookie.get(), MUST_CONTAIN, "test=six"); michael@0: michael@0: allTestsPassed = PrintResult(rv, 10) && allTestsPassed; michael@0: michael@0: michael@0: // *** path ordering tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path ordering tests...\n"); michael@0: michael@0: // test that cookies are returned in path order - longest to shortest. michael@0: // if the header doesn't specify a path, it's taken from the host URI. michael@0: SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test1=path; path=/one/two/three", nullptr); michael@0: 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); michael@0: SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/", nullptr, "test6=path", nullptr); michael@0: SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, "test7=path; path=", nullptr); michael@0: SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test8=path; path=/", nullptr); michael@0: GetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test7=path; test6=path; test3=path; test1=path; test5=path; test4=path; test2=path; test8=path"); michael@0: michael@0: allTestsPassed = PrintResult(rv, 1) && allTestsPassed; michael@0: michael@0: michael@0: // *** httponly tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning httponly tests...\n"); michael@0: michael@0: // Since this cookie is NOT set via http, setting it fails michael@0: SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly"); michael@0: GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // Since this cookie is set via http, it can be retrieved michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); michael@0: GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); michael@0: rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); michael@0: // ... but not by web content michael@0: GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); michael@0: rv[2] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // Non-Http cookies should not replace HttpOnly cookies michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); michael@0: SetACookieNoHttp(cookieService, "http://httponly.test/", "test=not-httponly"); michael@0: GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); michael@0: rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); michael@0: // ... and, if an HttpOnly cookie already exists, should not be set at all michael@0: GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); michael@0: rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // Non-Http cookies should not delete HttpOnly cookies michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); michael@0: SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; max-age=-1"); michael@0: GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); michael@0: rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); michael@0: // ... but HttpOnly cookies should michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly; max-age=-1", nullptr); michael@0: GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); michael@0: // Non-Httponly cookies can replace HttpOnly cookies when set over http michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr); michael@0: GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly"); michael@0: // scripts should not be able to set httponly cookies by replacing an existing non-httponly cookie michael@0: SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr); michael@0: SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly"); michael@0: GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); michael@0: rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly"); michael@0: michael@0: allTestsPassed = PrintResult(rv, 9) && allTestsPassed; michael@0: michael@0: michael@0: // *** nsICookieManager{2} interface tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n"); michael@0: nsCOMPtr cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0); michael@0: if (NS_FAILED(rv0)) return -1; michael@0: nsCOMPtr cookieMgr2 = do_QueryInterface(cookieMgr); michael@0: if (!cookieMgr2) return -1; michael@0: michael@0: // first, ensure a clean slate michael@0: rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll()); michael@0: // add some cookies michael@0: rv[1] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain michael@0: NS_LITERAL_CSTRING("/foo"), // path michael@0: NS_LITERAL_CSTRING("test1"), // name michael@0: NS_LITERAL_CSTRING("yes"), // value michael@0: false, // is secure michael@0: false, // is httponly michael@0: true, // is session michael@0: INT64_MAX)); // expiry time michael@0: rv[2] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain michael@0: NS_LITERAL_CSTRING("/foo"), // path michael@0: NS_LITERAL_CSTRING("test2"), // name michael@0: NS_LITERAL_CSTRING("yes"), // value michael@0: false, // is secure michael@0: true, // is httponly michael@0: true, // is session michael@0: PR_Now() / PR_USEC_PER_SEC + 2)); // expiry time michael@0: rv[3] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"), // domain michael@0: NS_LITERAL_CSTRING("/rabbit"), // path michael@0: NS_LITERAL_CSTRING("test3"), // name michael@0: NS_LITERAL_CSTRING("yes"), // value michael@0: false, // is secure michael@0: false, // is httponly michael@0: true, // is session michael@0: INT64_MAX)); // expiry time michael@0: // confirm using enumerator michael@0: nsCOMPtr enumerator; michael@0: rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))); michael@0: int32_t i = 0; michael@0: bool more; michael@0: nsCOMPtr expiredCookie, newDomainCookie; michael@0: while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) { michael@0: nsCOMPtr cookie; michael@0: if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break; michael@0: ++i; michael@0: michael@0: // keep tabs on the second and third cookies, so we can check them later michael@0: nsCOMPtr cookie2(do_QueryInterface(cookie)); michael@0: if (!cookie2) break; michael@0: nsAutoCString name; michael@0: cookie2->GetName(name); michael@0: if (name == NS_LITERAL_CSTRING("test2")) michael@0: expiredCookie = cookie2; michael@0: else if (name == NS_LITERAL_CSTRING("test3")) michael@0: newDomainCookie = cookie2; michael@0: } michael@0: rv[5] = i == 3; michael@0: // check the httpOnly attribute of the second cookie is honored michael@0: GetACookie(cookieService, "http://cookiemgr.test/foo/", nullptr, getter_Copies(cookie)); michael@0: rv[6] = CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes"); michael@0: GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", getter_Copies(cookie)); michael@0: rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes"); michael@0: // check CountCookiesFromHost() michael@0: uint32_t hostCookies = 0; michael@0: rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) && michael@0: hostCookies == 2; michael@0: // check CookieExists() using the third cookie michael@0: bool found; michael@0: rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && found; michael@0: // remove the cookie, block it, and ensure it can't be added again michael@0: rv[10] = NS_SUCCEEDED(cookieMgr->Remove(NS_LITERAL_CSTRING("new.domain"), // domain michael@0: NS_LITERAL_CSTRING("test3"), // name michael@0: NS_LITERAL_CSTRING("/rabbit"), // path michael@0: true)); // is blocked michael@0: rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found; michael@0: rv[12] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"), // domain michael@0: NS_LITERAL_CSTRING("/rabbit"), // path michael@0: NS_LITERAL_CSTRING("test3"), // name michael@0: NS_LITERAL_CSTRING("yes"), // value michael@0: false, // is secure michael@0: false, // is httponly michael@0: true, // is session michael@0: INT64_MIN)); // expiry time michael@0: rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found; michael@0: // sleep four seconds, to make sure the second cookie has expired michael@0: PR_Sleep(4 * PR_TicksPerSecond()); michael@0: // check that both CountCookiesFromHost() and CookieExists() count the michael@0: // expired cookie michael@0: rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) && michael@0: hostCookies == 2; michael@0: rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExists(expiredCookie, &found)) && found; michael@0: // double-check RemoveAll() using the enumerator michael@0: rv[16] = NS_SUCCEEDED(cookieMgr->RemoveAll()); michael@0: rv[17] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))) && michael@0: NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && michael@0: !more; michael@0: michael@0: allTestsPassed = PrintResult(rv, 18) && allTestsPassed; michael@0: michael@0: michael@0: // *** eviction and creation ordering tests michael@0: sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation ordering tests...\n"); michael@0: michael@0: // test that cookies are michael@0: // a) returned by order of creation time (oldest first, newest last) michael@0: // b) evicted by order of lastAccessed time, if the limit on cookies per host (50) is reached michael@0: nsAutoCString name; michael@0: nsAutoCString expected; michael@0: for (int32_t i = 0; i < 60; ++i) { michael@0: name = NS_LITERAL_CSTRING("test"); michael@0: name.AppendInt(i); michael@0: name += NS_LITERAL_CSTRING("=creation"); michael@0: SetACookie(cookieService, "http://creation.ordering.tests/", nullptr, name.get(), nullptr); michael@0: michael@0: if (i >= 10) { michael@0: expected += name; michael@0: if (i < 59) michael@0: expected += NS_LITERAL_CSTRING("; "); michael@0: } michael@0: } michael@0: GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, getter_Copies(cookie)); michael@0: rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get()); michael@0: michael@0: allTestsPassed = PrintResult(rv, 1) && allTestsPassed; michael@0: michael@0: michael@0: // XXX the following are placeholders: add these tests please! michael@0: // *** "noncompliant cookie" tests michael@0: // *** IP address tests michael@0: // *** speed tests michael@0: michael@0: michael@0: sBuffer = PR_sprintf_append(sBuffer, "\n*** Result: %s!\n\n", allTestsPassed ? "all tests passed" : "TEST(S) FAILED"); michael@0: } michael@0: michael@0: if (!allTestsPassed) { michael@0: // print the entire log michael@0: printf("%s", sBuffer); michael@0: return 1; michael@0: } michael@0: michael@0: PR_smprintf_free(sBuffer); michael@0: sBuffer = nullptr; michael@0: michael@0: return 0; michael@0: }