зеркало из https://github.com/mozilla/gecko-dev.git
Bug 536650 - Cookie values not saved for pages loaded from file://; part 2: deal with empty hosts in the
cookieservice . r=sdwilsh, sr=bz
This commit is contained in:
Родитель
ac5ec695ab
Коммит
d55818f5b3
|
@ -2,6 +2,8 @@ const Cc = Components.classes;
|
|||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function do_check_throws(f, result, stack)
|
||||
{
|
||||
if (!stack)
|
||||
|
@ -20,14 +22,69 @@ function do_check_throws(f, result, stack)
|
|||
function run_test() {
|
||||
var cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
var expiry = (Date.now() + 1000) * 1000;
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
// test that an empty host results in a no-op
|
||||
var uri = ios.newURI("http://baz.com/", null, null);
|
||||
var emptyuri = ios.newURI("http:///", null, null);
|
||||
var doturi = ios.newURI("http://./", null, null);
|
||||
// test that variants of 'baz.com' get normalized appropriately, but that
|
||||
// malformed hosts are rejected
|
||||
cm.add("baz.com", "/", "foo", "bar", false, false, true, expiry);
|
||||
do_check_eq(cm.countCookiesFromHost("baz.com"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost("BAZ.com"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost(".baz.com"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost("baz.com."), 1);
|
||||
do_check_eq(cm.countCookiesFromHost(".baz.com."), 1);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost("baz.com..");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost("baz..com");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost("..baz.com");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
cm.remove("BAZ.com.", "foo", "/", false);
|
||||
do_check_eq(cm.countCookiesFromHost("baz.com"), 0);
|
||||
|
||||
// test that domain cookies are illegal for IP addresses, aliases such as
|
||||
// 'localhost', and eTLD's such as 'co.uk'
|
||||
cm.add("192.168.0.1", "/", "foo", "bar", false, false, true, expiry);
|
||||
do_check_eq(cm.countCookiesFromHost("192.168.0.1"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost("192.168.0.1."), 1);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".192.168.0.1");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".192.168.0.1.");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
cm.add("localhost", "/", "foo", "bar", false, false, true, expiry);
|
||||
do_check_eq(cm.countCookiesFromHost("localhost"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost("localhost."), 1);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".localhost");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".localhost.");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
cm.add("co.uk", "/", "foo", "bar", false, false, true, expiry);
|
||||
do_check_eq(cm.countCookiesFromHost("co.uk"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost("co.uk."), 1);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".co.uk");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".co.uk.");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
// test that setting an empty or '.' http:// host results in a no-op
|
||||
var uri = NetUtil.newURI("http://baz.com/");
|
||||
var emptyuri = NetUtil.newURI("http:///");
|
||||
var doturi = NetUtil.newURI("http://./");
|
||||
do_check_eq(uri.asciiHost, "baz.com");
|
||||
do_check_eq(emptyuri.asciiHost, "");
|
||||
do_check_eq(doturi.asciiHost, ".");
|
||||
cs.setCookieString(emptyuri, null, "foo2=bar", null);
|
||||
|
@ -41,42 +98,98 @@ function run_test() {
|
|||
do_check_eq(cs.getCookieString(emptyuri, null), null);
|
||||
do_check_eq(cs.getCookieString(doturi, null), null);
|
||||
|
||||
// test that an empty host to add() or remove() throws
|
||||
var expiry = (Date.now() + 1000) * 1000;
|
||||
do_check_throws(function() {
|
||||
cm.add("", "/", "foo2", "bar", false, false, true, expiry);
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
do_check_throws(function() {
|
||||
cm.add(".", "/", "foo3", "bar", false, false, true, expiry);
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
cm.add("test.com", "/", "foo", "bar", false, false, true, expiry);
|
||||
do_check_eq(getCookieCount(), 2);
|
||||
|
||||
do_check_throws(function() {
|
||||
cm.remove("", "foo2", "/", false);
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_eq(getCookieCount(), 2);
|
||||
do_check_throws(function() {
|
||||
cm.remove(".", "foo3", "/", false);
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_eq(getCookieCount(), 2);
|
||||
cm.remove("test.com", "foo", "/", false);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
|
||||
do_check_eq(cm.countCookiesFromHost("baz.com"), 1);
|
||||
do_check_eq(cm.countCookiesFromHost(""), 0);
|
||||
do_check_eq(cm.countCookiesFromHost("."), 0);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost("..");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
var e = cm.getCookiesFromHost("baz.com");
|
||||
var e = cm.getCookiesFromHost("");
|
||||
do_check_false(e.hasMoreElements());
|
||||
do_check_throws(function() {
|
||||
cm.getCookiesFromHost(".");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.getCookiesFromHost("..");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
e = cm.getCookiesFromHost("baz.com");
|
||||
do_check_true(e.hasMoreElements());
|
||||
do_check_eq(e.getNext().QueryInterface(Ci.nsICookie2).name, "foo");
|
||||
do_check_false(e.hasMoreElements());
|
||||
e = cm.getCookiesFromHost("");
|
||||
do_check_false(e.hasMoreElements());
|
||||
e = cm.getCookiesFromHost(".");
|
||||
do_check_throws(function() {
|
||||
cm.getCookiesFromHost(".");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_throws(function() {
|
||||
cm.getCookiesFromHost("..");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
// test that an empty file:// host works
|
||||
emptyuri = NetUtil.newURI("file:///");
|
||||
do_check_eq(emptyuri.asciiHost, "");
|
||||
do_check_eq(NetUtil.newURI("file://./").asciiHost, "");
|
||||
do_check_eq(NetUtil.newURI("file://foo.bar/").asciiHost, "");
|
||||
cs.setCookieString(emptyuri, null, "foo2=bar", null);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
cs.setCookieString(emptyuri, null, "foo3=bar; domain=", null);
|
||||
do_check_eq(getCookieCount(), 2);
|
||||
cs.setCookieString(emptyuri, null, "foo4=bar; domain=.", null);
|
||||
do_check_eq(getCookieCount(), 3);
|
||||
cs.setCookieString(emptyuri, null, "foo5=bar; domain=bar.com", null);
|
||||
do_check_eq(getCookieCount(), 3);
|
||||
|
||||
do_check_eq(cs.getCookieString(emptyuri, null), "foo2=bar; foo3=bar; foo4=bar");
|
||||
|
||||
do_check_eq(cm.countCookiesFromHost("baz.com"), 0);
|
||||
do_check_eq(cm.countCookiesFromHost(""), 3);
|
||||
do_check_throws(function() {
|
||||
cm.countCookiesFromHost(".");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
e = cm.getCookiesFromHost("baz.com");
|
||||
do_check_false(e.hasMoreElements());
|
||||
e = cm.getCookiesFromHost("");
|
||||
do_check_true(e.hasMoreElements());
|
||||
e.getNext();
|
||||
do_check_true(e.hasMoreElements());
|
||||
e.getNext();
|
||||
do_check_true(e.hasMoreElements());
|
||||
e.getNext();
|
||||
do_check_false(e.hasMoreElements());
|
||||
do_check_throws(function() {
|
||||
cm.getCookiesFromHost(".");
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
// test that an empty host to add() or remove() works,
|
||||
// but a host of '.' doesn't
|
||||
cm.add("", "/", "foo2", "bar", false, false, true, expiry);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
do_check_throws(function() {
|
||||
cm.add(".", "/", "foo3", "bar", false, false, true, expiry);
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
|
||||
cm.remove("", "foo2", "/", false);
|
||||
do_check_eq(getCookieCount(), 0);
|
||||
do_check_throws(function() {
|
||||
cm.remove(".", "foo3", "/", false);
|
||||
}, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// test that the 'domain' attribute accepts a leading dot for IP addresses,
|
||||
// aliases such as 'localhost', eTLD's such as 'co.uk', and the empty host;
|
||||
// but that the resulting cookie is for the exact host only.
|
||||
testDomainCookie("http://192.168.0.1/", "192.168.0.1");
|
||||
testDomainCookie("http://localhost/", "localhost");
|
||||
testDomainCookie("http://co.uk/", "co.uk");
|
||||
testDomainCookie("file:///", "");
|
||||
|
||||
cm.removeAll();
|
||||
}
|
||||
|
@ -93,3 +206,23 @@ function getCookieCount() {
|
|||
return count;
|
||||
}
|
||||
|
||||
function testDomainCookie(uriString, domain) {
|
||||
var cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
var uri = NetUtil.newURI(uriString);
|
||||
cs.setCookieString(uri, null, "foo=bar; domain=" + domain, null);
|
||||
var e = cm.getCookiesFromHost(domain);
|
||||
do_check_true(e.hasMoreElements());
|
||||
do_check_eq(e.getNext().QueryInterface(Ci.nsICookie2).host, domain);
|
||||
cm.removeAll();
|
||||
|
||||
cs.setCookieString(uri, null, "foo=bar; domain=." + domain, null);
|
||||
e = cm.getCookiesFromHost(domain);
|
||||
do_check_true(e.hasMoreElements());
|
||||
do_check_eq(e.getNext().QueryInterface(Ci.nsICookie2).host, domain);
|
||||
cm.removeAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,13 +62,22 @@ interface nsICookieManager : nsISupports
|
|||
readonly attribute nsISimpleEnumerator enumerator;
|
||||
|
||||
/**
|
||||
* Called to remove an individual cookie from the cookie list
|
||||
* Called to remove an individual cookie from the cookie list, specified
|
||||
* by host, name, and path. If the cookie cannot be found, no exception
|
||||
* is thrown. Typically, the arguments to this method will be obtained
|
||||
* directly from the desired nsICookie object.
|
||||
*
|
||||
* @param aDomain The host or domain for which the cookie was set
|
||||
* @param aHost The host or domain for which the cookie was set. @see
|
||||
* nsICookieManager2::add for a description of acceptable host
|
||||
* strings. If the target cookie is a domain cookie, a leading
|
||||
* dot must be present.
|
||||
* @param aName The name specified in the cookie
|
||||
* @param aPath The path for which the cookie was set
|
||||
* @param aBlocked Indicates if cookies from this host should be permanently blocked
|
||||
*
|
||||
*/
|
||||
void remove(in AUTF8String aDomain, in ACString aName, in AUTF8String aPath, in boolean aBlocked);
|
||||
void remove(in AUTF8String aHost,
|
||||
in ACString aName,
|
||||
in AUTF8String aPath,
|
||||
in boolean aBlocked);
|
||||
};
|
||||
|
|
|
@ -44,17 +44,22 @@ interface nsIFile;
|
|||
* Additions to the frozen nsICookieManager
|
||||
*/
|
||||
|
||||
[scriptable, uuid(d1e9e50f-b78b-4e3b-a474-f3cbca59b013)]
|
||||
[scriptable, uuid(94628d1d-8b31-4baa-b474-9c872c440f90)]
|
||||
interface nsICookieManager2 : nsICookieManager
|
||||
{
|
||||
/**
|
||||
* Add a cookie. nsICookieService is the normal way to do this. This
|
||||
* method is something of a backdoor.
|
||||
*
|
||||
* @param aDomain
|
||||
* @param aHost
|
||||
* the host or domain for which the cookie is set. presence of a
|
||||
* leading dot indicates a domain cookie; otherwise, the cookie
|
||||
* is treated as a non-domain cookie. see RFC2109.
|
||||
* is treated as a non-domain cookie (see RFC2109). The host string
|
||||
* will be normalized to ASCII or ACE; any trailing dot will be
|
||||
* stripped. To be a domain cookie, the host must have at least two
|
||||
* subdomain parts (e.g. '.foo.com', not '.com'), otherwise an
|
||||
* exception will be thrown. An empty string is acceptable
|
||||
* (e.g. file:// URI's).
|
||||
* @param aPath
|
||||
* path within the domain for which the cookie is valid
|
||||
* @param aName
|
||||
|
@ -74,7 +79,7 @@ interface nsICookieManager2 : nsICookieManager
|
|||
* 1970 UTC. note that expiry time will also be honored for session cookies;
|
||||
* in this way, the more restrictive of the two will take effect.
|
||||
*/
|
||||
void add(in AUTF8String aDomain,
|
||||
void add(in AUTF8String aHost,
|
||||
in AUTF8String aPath,
|
||||
in ACString aName,
|
||||
in ACString aValue,
|
||||
|
@ -101,13 +106,13 @@ interface nsICookieManager2 : nsICookieManager
|
|||
* counted.
|
||||
*
|
||||
* @param aHost
|
||||
* the host string to begin from, e.g. "google.com". this should consist
|
||||
* of only the host portion of a URI, and should not contain a leading
|
||||
* dot, a port, etc.
|
||||
* the host string to search for, e.g. "google.com". this should consist
|
||||
* of only the host portion of a URI. see @add for a description of
|
||||
* acceptable host strings.
|
||||
*
|
||||
* @return the number of cookies found.
|
||||
*/
|
||||
unsigned long countCookiesFromHost(in ACString aHost);
|
||||
unsigned long countCookiesFromHost(in AUTF8String aHost);
|
||||
|
||||
/**
|
||||
* Returns an enumerator of cookies that exist within the base domain of
|
||||
|
@ -116,15 +121,15 @@ interface nsICookieManager2 : nsICookieManager
|
|||
* subdomains would be returned.
|
||||
*
|
||||
* @param aHost
|
||||
* the host string to begin from, e.g. "google.com". this should consist
|
||||
* of only the host portion of a URI, and should not contain a leading
|
||||
* dot, a port, etc.
|
||||
* the host string to search for, e.g. "google.com". this should consist
|
||||
* of only the host portion of a URI. see @add for a description of
|
||||
* acceptable host strings.
|
||||
*
|
||||
* @return an nsISimpleEnumerator of nsICookie2 objects.
|
||||
*
|
||||
* @see countCookiesFromHost
|
||||
*/
|
||||
nsISimpleEnumerator getCookiesFromHost(in ACString aHost);
|
||||
nsISimpleEnumerator getCookiesFromHost(in AUTF8String aHost);
|
||||
|
||||
/**
|
||||
* Import an old-style cookie file. Imported cookies will be added to the
|
||||
|
|
|
@ -89,6 +89,9 @@ interface nsICookieService : nsISupports
|
|||
*
|
||||
* @param aURI
|
||||
* the URI of the document for which cookies are being queried.
|
||||
* file:// URI's (i.e. with an empty host) are allowed, but any other
|
||||
* scheme must have a non-empty host. A trailing dot in the host
|
||||
* is acceptable, and will be stripped.
|
||||
* @param aChannel
|
||||
* the channel used to load the document. this parameter should not
|
||||
* be null, otherwise the cookies will not be returned if third-party
|
||||
|
@ -108,6 +111,9 @@ interface nsICookieService : nsISupports
|
|||
*
|
||||
* @param aURI
|
||||
* the URI of the document for which cookies are being queried.
|
||||
* file:// URI's (i.e. with an empty host) are allowed, but any other
|
||||
* scheme must have a non-empty host. A trailing dot in the host
|
||||
* is acceptable, and will be stripped.
|
||||
* @param aFirstURI
|
||||
* the URI that the user originally typed in or clicked on to initiate
|
||||
* the load of the document referenced by aURI.
|
||||
|
@ -127,6 +133,9 @@ interface nsICookieService : nsISupports
|
|||
*
|
||||
* @param aURI
|
||||
* the URI of the document for which cookies are being set.
|
||||
* file:// URI's (i.e. with an empty host) are allowed, but any other
|
||||
* scheme must have a non-empty host. A trailing dot in the host
|
||||
* is acceptable, and will be stripped.
|
||||
* @param aPrompt
|
||||
* the prompt to use for all user-level cookie notifications.
|
||||
* @param aCookie
|
||||
|
@ -151,6 +160,9 @@ interface nsICookieService : nsISupports
|
|||
*
|
||||
* @param aURI
|
||||
* the URI of the document for which cookies are being set.
|
||||
* file:// URI's (i.e. with an empty host) are allowed, but any other
|
||||
* scheme must have a non-empty host. A trailing dot in the host
|
||||
* is acceptable, and will be stripped.
|
||||
* @param aFirstURI
|
||||
* the URI that the user originally typed in or clicked on to initiate
|
||||
* the load of the document referenced by aURI.
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIIDNService.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
@ -405,6 +406,9 @@ nsCookieService::Init()
|
|||
mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// init our pref and observer
|
||||
nsCOMPtr<nsIPrefBranch2> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefBranch) {
|
||||
|
@ -810,9 +814,12 @@ nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
|
|||
|
||||
// get the base domain for the host URI.
|
||||
// e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
|
||||
PRBool isIPAddress;
|
||||
// file:// URI's (i.e. with an empty host) are allowed, but any other
|
||||
// scheme must have a non-empty host. A trailing dot in the host
|
||||
// is acceptable, and will be stripped.
|
||||
PRBool requireHostMatch;
|
||||
nsCAutoString baseDomain;
|
||||
nsresult rv = GetBaseDomain(aHostURI, baseDomain, isIPAddress);
|
||||
nsresult rv = GetBaseDomain(aHostURI, baseDomain, requireHostMatch);
|
||||
if (NS_FAILED(rv)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"couldn't get base domain from URI");
|
||||
|
@ -821,7 +828,7 @@ nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
|
|||
|
||||
// check default prefs
|
||||
PRUint32 cookieStatus = CheckPrefs(aHostURI, aChannel, baseDomain,
|
||||
isIPAddress, aCookieHeader);
|
||||
requireHostMatch, aCookieHeader);
|
||||
// fire a notification if cookie was rejected (but not if there was an error)
|
||||
switch (cookieStatus) {
|
||||
case STATUS_REJECTED:
|
||||
|
@ -850,7 +857,7 @@ nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
|
|||
|
||||
// switch to a nice string type now, and process each cookie in the header
|
||||
nsDependentCString cookieHeader(aCookieHeader);
|
||||
while (SetCookieInternal(aHostURI, aChannel, baseDomain, isIPAddress,
|
||||
while (SetCookieInternal(aHostURI, aChannel, baseDomain, requireHostMatch,
|
||||
cookieHeader, serverTime, aFromHttp));
|
||||
|
||||
return NS_OK;
|
||||
|
@ -972,7 +979,7 @@ nsCookieService::GetEnumerator(nsISimpleEnumerator **aEnumerator)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCookieService::Add(const nsACString &aDomain,
|
||||
nsCookieService::Add(const nsACString &aHost,
|
||||
const nsACString &aPath,
|
||||
const nsACString &aName,
|
||||
const nsACString &aValue,
|
||||
|
@ -981,16 +988,21 @@ nsCookieService::Add(const nsACString &aDomain,
|
|||
PRBool aIsSession,
|
||||
PRInt64 aExpiry)
|
||||
{
|
||||
// first, normalize the hostname, and fail if it contains illegal characters.
|
||||
nsCAutoString host(aHost);
|
||||
nsresult rv = NormalizeHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// get the base domain for the host URI.
|
||||
// e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
|
||||
nsCAutoString baseDomain;
|
||||
nsresult rv = GetBaseDomainFromHost(aDomain, baseDomain);
|
||||
rv = GetBaseDomainFromHost(host, baseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 currentTimeInUsec = PR_Now();
|
||||
|
||||
nsRefPtr<nsCookie> cookie =
|
||||
nsCookie::Create(aName, aValue, aDomain, aPath,
|
||||
nsCookie::Create(aName, aValue, host, aPath,
|
||||
aExpiry,
|
||||
currentTimeInUsec,
|
||||
currentTimeInUsec,
|
||||
|
@ -1011,13 +1023,18 @@ nsCookieService::Remove(const nsACString &aHost,
|
|||
const nsACString &aPath,
|
||||
PRBool aBlocked)
|
||||
{
|
||||
// first, normalize the hostname, and fail if it contains illegal characters.
|
||||
nsCAutoString host(aHost);
|
||||
nsresult rv = NormalizeHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString baseDomain;
|
||||
nsresult rv = GetBaseDomainFromHost(aHost, baseDomain);
|
||||
rv = GetBaseDomainFromHost(host, baseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsListIter matchIter;
|
||||
if (FindCookie(baseDomain,
|
||||
PromiseFlatCString(aHost),
|
||||
host,
|
||||
PromiseFlatCString(aName),
|
||||
PromiseFlatCString(aPath),
|
||||
matchIter,
|
||||
|
@ -1029,13 +1046,11 @@ nsCookieService::Remove(const nsACString &aHost,
|
|||
|
||||
// check if we need to add the host to the permissions blacklist.
|
||||
if (aBlocked && mPermissionService) {
|
||||
nsCAutoString host(NS_LITERAL_CSTRING("http://"));
|
||||
|
||||
// strip off the domain dot, if necessary
|
||||
if (aHost.First() == '.')
|
||||
host.Append(Substring(aHost, 1, aHost.Length() - 1));
|
||||
else
|
||||
host.Append(aHost);
|
||||
if (!host.IsEmpty() && host.First() == '.')
|
||||
host.Cut(0, 1);
|
||||
|
||||
host.Insert(NS_LITERAL_CSTRING("http://"), 0);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), host);
|
||||
|
@ -1323,23 +1338,27 @@ nsCookieService::GetCookieInternal(nsIURI *aHostURI,
|
|||
|
||||
// get the base domain, host, and path from the URI.
|
||||
// e.g. for "www.bbc.co.uk", the base domain would be "bbc.co.uk".
|
||||
PRBool isIPAddress;
|
||||
// file:// URI's (i.e. with an empty host) are allowed, but any other
|
||||
// scheme must have a non-empty host. A trailing dot in the host
|
||||
// is acceptable, and will be stripped.
|
||||
PRBool requireHostMatch;
|
||||
nsCAutoString baseDomain, hostFromURI, pathFromURI;
|
||||
nsresult rv = GetBaseDomain(aHostURI, baseDomain, isIPAddress);
|
||||
nsresult rv = GetBaseDomain(aHostURI, baseDomain, requireHostMatch);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = aHostURI->GetAsciiHost(hostFromURI);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = aHostURI->GetPath(pathFromURI);
|
||||
// trim trailing dots
|
||||
hostFromURI.Trim(".");
|
||||
if (NS_FAILED(rv) || hostFromURI.IsEmpty()) {
|
||||
// trim any trailing dot
|
||||
if (!hostFromURI.IsEmpty() && hostFromURI.Last() == '.')
|
||||
hostFromURI.Truncate(hostFromURI.Length() - 1);
|
||||
if (NS_FAILED(rv)) {
|
||||
COOKIE_LOGFAILURE(GET_COOKIE, aHostURI, nsnull, "invalid host/path from URI");
|
||||
return;
|
||||
}
|
||||
|
||||
// check default prefs
|
||||
PRUint32 cookieStatus = CheckPrefs(aHostURI, aChannel, baseDomain,
|
||||
isIPAddress, nsnull);
|
||||
requireHostMatch, nsnull);
|
||||
// for GetCookie(), we don't fire rejection notifications.
|
||||
switch (cookieStatus) {
|
||||
case STATUS_REJECTED:
|
||||
|
@ -1481,7 +1500,7 @@ PRBool
|
|||
nsCookieService::SetCookieInternal(nsIURI *aHostURI,
|
||||
nsIChannel *aChannel,
|
||||
const nsCString &aBaseDomain,
|
||||
PRBool aIsIPAddress,
|
||||
PRBool aRequireHostMatch,
|
||||
nsDependentCString &aCookieHeader,
|
||||
PRInt64 aServerTime,
|
||||
PRBool aFromHttp)
|
||||
|
@ -1519,7 +1538,7 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI,
|
|||
}
|
||||
|
||||
// domain & path checks
|
||||
if (!CheckDomain(cookieAttributes, aHostURI, aBaseDomain, aIsIPAddress)) {
|
||||
if (!CheckDomain(cookieAttributes, aHostURI, aBaseDomain, aRequireHostMatch)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "failed the domain tests");
|
||||
return newCookie;
|
||||
}
|
||||
|
@ -1920,55 +1939,108 @@ nsCookieService::ParseAttributes(nsDependentCString &aCookieHeader,
|
|||
* private domain & permission compliance enforcement functions
|
||||
******************************************************************************/
|
||||
|
||||
// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
|
||||
// "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing
|
||||
// dot may be present (and will be stripped). If aHostURI is an IP address,
|
||||
// an alias such as 'localhost', an eTLD such as 'co.uk', or the empty string,
|
||||
// aBaseDomain will be the exact host, and aRequireHostMatch will be true to
|
||||
// indicate that substring matches should not be performed.
|
||||
nsresult
|
||||
nsCookieService::GetBaseDomain(nsIURI *aHostURI,
|
||||
nsCString &aBaseDomain,
|
||||
PRBool &aIsIPAddress)
|
||||
PRBool &aRequireHostMatch)
|
||||
{
|
||||
// get the base domain for the host URI.
|
||||
// e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
|
||||
// get the base domain. this will fail if the host contains a leading dot,
|
||||
// more than one trailing dot, or is otherwise malformed.
|
||||
nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain);
|
||||
aIsIPAddress = rv == NS_ERROR_HOST_IS_IP_ADDRESS;
|
||||
if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
// address is either an IP address or an alias such as 'localhost'.
|
||||
// use the host as a key in such cases.
|
||||
aRequireHostMatch = rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS;
|
||||
if (aRequireHostMatch) {
|
||||
// aHostURI is either an IP address, an alias such as 'localhost', an eTLD
|
||||
// such as 'co.uk', or the empty string. use the host as a key in such
|
||||
// cases.
|
||||
rv = aHostURI->GetAsciiHost(aBaseDomain);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// trim trailing dots
|
||||
aBaseDomain.Trim(".");
|
||||
if (aBaseDomain.IsEmpty())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
// aHost (and thus aBaseDomain) may contain a trailing dot; if so, trim it.
|
||||
if (!aBaseDomain.IsEmpty() && aBaseDomain.Last() == '.')
|
||||
aBaseDomain.Truncate(aBaseDomain.Length() - 1);
|
||||
|
||||
// block any URIs without a host that aren't file:// URIs.
|
||||
if (aBaseDomain.IsEmpty()) {
|
||||
PRBool isFileURI = PR_FALSE;
|
||||
aHostURI->SchemeIs("file", &isFileURI);
|
||||
if (!isFileURI)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
aIsIPAddress = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the base domain for aHost; e.g. for "www.bbc.co.uk", this would be
|
||||
// "bbc.co.uk". This is done differently than GetBaseDomain(): it is assumed
|
||||
// that aHost is already normalized, and it may contain a leading dot
|
||||
// (indicating that it represents a domain). A trailing dot must not be present.
|
||||
// If aHost is an IP address, an alias such as 'localhost', an eTLD such as
|
||||
// 'co.uk', or the empty string, aBaseDomain will be the exact host, and a
|
||||
// leading dot will be treated as an error.
|
||||
nsresult
|
||||
nsCookieService::GetBaseDomainFromHost(const nsACString &aHost,
|
||||
nsCString &aBaseDomain)
|
||||
{
|
||||
// trim leading and trailing dots
|
||||
nsCAutoString host(aHost);
|
||||
host.Trim(".");
|
||||
if (host.IsEmpty())
|
||||
// aHost must not contain a trailing dot, or be the string '.'.
|
||||
if (!aHost.IsEmpty() && aHost.Last() == '.')
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// get the base domain for the host.
|
||||
// e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
|
||||
// aHost may contain a leading dot; if so, strip it now.
|
||||
nsDependentCString host(aHost);
|
||||
PRBool domain = !host.IsEmpty() && host.First() == '.';
|
||||
if (domain)
|
||||
host.Rebind(host.BeginReading() + 1, host.EndReading());
|
||||
|
||||
// get the base domain. this will fail if the host contains a leading dot,
|
||||
// more than one trailing dot, or is otherwise malformed.
|
||||
nsresult rv = mTLDService->GetBaseDomainFromHost(host, 0, aBaseDomain);
|
||||
if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
// address is either an IP address or an alias such as 'localhost'.
|
||||
// use the host as a key in such cases.
|
||||
// aHost is either an IP address, an alias such as 'localhost', an eTLD
|
||||
// such as 'co.uk', or the empty string. use the host as a key in such
|
||||
// cases; however, we reject any such hosts with a leading dot, since it
|
||||
// doesn't make sense for them to be domain cookies.
|
||||
if (domain)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
aBaseDomain = host;
|
||||
return NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Normalizes the given hostname, component by component. ASCII/ACE
|
||||
// components are lower-cased, and UTF-8 components are normalized per
|
||||
// RFC 3454 and converted to ACE. Any trailing dot is stripped.
|
||||
nsresult
|
||||
nsCookieService::NormalizeHost(nsCString &aHost)
|
||||
{
|
||||
if (!IsASCII(aHost)) {
|
||||
nsCAutoString host;
|
||||
nsresult rv = mIDNService->ConvertUTF8toACE(aHost, host);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
aHost = host;
|
||||
}
|
||||
|
||||
// Only strip the trailing dot if it wouldn't result in the empty string;
|
||||
// in that case, treat it like a leading dot.
|
||||
if (aHost.Length() > 1 && aHost.Last() == '.')
|
||||
aHost.Truncate(aHost.Length() - 1);
|
||||
|
||||
ToLowerCase(aHost);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// returns PR_TRUE if 'a' is equal to or a subdomain of 'b',
|
||||
// assuming no leading or trailing dots are present.
|
||||
static inline PRBool IsSubdomainOf(const nsCString &a, const nsCString &b)
|
||||
|
@ -1982,7 +2054,7 @@ static inline PRBool IsSubdomainOf(const nsCString &a, const nsCString &b)
|
|||
|
||||
PRBool
|
||||
nsCookieService::IsForeign(const nsCString &aBaseDomain,
|
||||
PRBool aHostIsIPAddress,
|
||||
PRBool aRequireHostMatch,
|
||||
nsIURI *aFirstURI)
|
||||
{
|
||||
nsCAutoString firstHost;
|
||||
|
@ -1990,19 +2062,19 @@ nsCookieService::IsForeign(const nsCString &aBaseDomain,
|
|||
// assume foreign
|
||||
return PR_TRUE;
|
||||
}
|
||||
// trim trailing dots
|
||||
firstHost.Trim(".");
|
||||
|
||||
// if we're dealing with IP addresses, require an exact match. this
|
||||
// eliminates any chance of IP address funkiness (e.g. the alias 127.1
|
||||
// domain-matching 99.54.127.1). note that the base domain parameter will be
|
||||
// equivalent to the host IP in this case.
|
||||
if (aHostIsIPAddress)
|
||||
// trim any trailing dot
|
||||
if (!firstHost.IsEmpty() && firstHost.Last() == '.')
|
||||
firstHost.Truncate(firstHost.Length() - 1);
|
||||
|
||||
// check whether the host is either an IP address, an alias such as
|
||||
// 'localhost', an eTLD such as 'co.uk', or the empty string. in these
|
||||
// cases, require an exact string match for the domain. note that the base
|
||||
// domain parameter will be equivalent to the host in this case.
|
||||
if (aRequireHostMatch)
|
||||
return !firstHost.Equals(aBaseDomain);
|
||||
|
||||
// ensure the originating domain is also derived from the host's base domain.
|
||||
// note that if the host is an alias such as 'localhost', the base domain
|
||||
// parameter will also be 'localhost', and this comparison will work.
|
||||
return !IsSubdomainOf(firstHost, aBaseDomain);
|
||||
}
|
||||
|
||||
|
@ -2010,7 +2082,7 @@ PRUint32
|
|||
nsCookieService::CheckPrefs(nsIURI *aHostURI,
|
||||
nsIChannel *aChannel,
|
||||
const nsCString &aBaseDomain,
|
||||
PRBool aIsIPAddress,
|
||||
PRBool aRequireHostMatch,
|
||||
const char *aCookieHeader)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -2057,7 +2129,7 @@ nsCookieService::CheckPrefs(nsIURI *aHostURI,
|
|||
nsCOMPtr<nsIURI> firstURI;
|
||||
rv = mPermissionService->GetOriginatingURI(aChannel, getter_AddRefs(firstURI));
|
||||
|
||||
if (NS_FAILED(rv) || IsForeign(aBaseDomain, aIsIPAddress, firstURI)) {
|
||||
if (NS_FAILED(rv) || IsForeign(aBaseDomain, aRequireHostMatch, firstURI)) {
|
||||
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "originating server test failed");
|
||||
return STATUS_REJECTED;
|
||||
}
|
||||
|
@ -2072,15 +2144,15 @@ PRBool
|
|||
nsCookieService::CheckDomain(nsCookieAttributes &aCookieAttributes,
|
||||
nsIURI *aHostURI,
|
||||
const nsCString &aBaseDomain,
|
||||
PRBool aIsIPAddress)
|
||||
PRBool aRequireHostMatch)
|
||||
{
|
||||
// get host from aHostURI
|
||||
nsCAutoString hostFromURI;
|
||||
aHostURI->GetAsciiHost(hostFromURI);
|
||||
|
||||
// trim trailing dots
|
||||
hostFromURI.Trim(".");
|
||||
NS_ASSERTION(!hostFromURI.IsEmpty(), "empty host");
|
||||
// trim any trailing dot
|
||||
if (!hostFromURI.IsEmpty() && hostFromURI.Last() == '.')
|
||||
hostFromURI.Truncate(hostFromURI.Length() - 1);
|
||||
|
||||
// if a domain is given, check the host has permission
|
||||
if (!aCookieAttributes.host.IsEmpty()) {
|
||||
|
@ -2091,12 +2163,12 @@ nsCookieService::CheckDomain(nsCookieAttributes &aCookieAttributes,
|
|||
// switch to lowercase now, to avoid case-insensitive compares everywhere
|
||||
ToLowerCase(aCookieAttributes.host);
|
||||
|
||||
// check whether the host is an IP address, and leave the cookie as
|
||||
// a non-domain one. this will require an exact host match for the cookie,
|
||||
// so we eliminate any chance of IP address funkiness (e.g. the alias 127.1
|
||||
// domain-matching 99.54.127.1). bug 105917 originally noted the
|
||||
// requirement to deal with IP addresses.
|
||||
if (aIsIPAddress)
|
||||
// check whether the host is either an IP address, an alias such as
|
||||
// 'localhost', an eTLD such as 'co.uk', or the empty string. in these
|
||||
// cases, require an exact string match for the domain, and leave the cookie
|
||||
// as a non-domain one. bug 105917 originally noted the requirement to deal
|
||||
// with IP addresses.
|
||||
if (aRequireHostMatch)
|
||||
return hostFromURI.Equals(aCookieAttributes.host);
|
||||
|
||||
// ensure the proposed domain is derived from the base domain; and also
|
||||
|
@ -2468,12 +2540,14 @@ NS_IMETHODIMP
|
|||
nsCookieService::CountCookiesFromHost(const nsACString &aHost,
|
||||
PRUint32 *aCountFromHost)
|
||||
{
|
||||
// first, normalize the hostname, and fail if it contains illegal characters.
|
||||
nsCAutoString host(aHost);
|
||||
nsresult rv = NormalizeHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString baseDomain;
|
||||
nsresult rv = GetBaseDomainFromHost(aHost, baseDomain);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aCountFromHost = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
rv = GetBaseDomainFromHost(host, baseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// we don't care about finding the oldest cookie here, so disable the search
|
||||
nsEnumerationData data(PR_Now() / PR_USEC_PER_SEC, LL_MININT);
|
||||
|
@ -2487,10 +2561,14 @@ NS_IMETHODIMP
|
|||
nsCookieService::GetCookiesFromHost(const nsACString &aHost,
|
||||
nsISimpleEnumerator **aEnumerator)
|
||||
{
|
||||
// first, normalize the hostname, and fail if it contains illegal characters.
|
||||
nsCAutoString host(aHost);
|
||||
nsresult rv = NormalizeHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString baseDomain;
|
||||
nsresult rv = GetBaseDomainFromHost(aHost, baseDomain);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_NewEmptyEnumerator(aEnumerator);
|
||||
rv = GetBaseDomainFromHost(host, baseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMArray<nsICookie> cookieList(mMaxCookiesPerHost);
|
||||
PRInt64 currentTime = PR_Now() / PR_USEC_PER_SEC;
|
||||
|
|
|
@ -62,6 +62,7 @@ struct nsEnumerationData;
|
|||
|
||||
class nsICookiePermission;
|
||||
class nsIEffectiveTLDService;
|
||||
class nsIIDNService;
|
||||
class nsIPrefBranch;
|
||||
class nsIObserverService;
|
||||
class nsIURI;
|
||||
|
@ -168,20 +169,21 @@ class nsCookieService : public nsICookieService
|
|||
nsresult CreateTable();
|
||||
void CloseDB();
|
||||
nsresult Read();
|
||||
nsresult GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, PRBool &aIsIPAddress);
|
||||
nsresult NormalizeHost(nsCString &aHost);
|
||||
nsresult GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, PRBool &aRequireHostMatch);
|
||||
nsresult GetBaseDomainFromHost(const nsACString &aHost, nsCString &aBaseDomain);
|
||||
void GetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, PRBool aHttpBound, char **aCookie);
|
||||
nsresult SetCookieStringInternal(nsIURI *aHostURI, nsIPrompt *aPrompt, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, PRBool aFromHttp);
|
||||
PRBool SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString& aBaseDomain, PRBool aIsIPAddress, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp);
|
||||
PRBool SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString& aBaseDomain, PRBool aRequireHostMatch, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp);
|
||||
void AddInternal(const nsCString& aBaseDomain, nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
|
||||
void RemoveCookieFromList(const nsListIter &aIter);
|
||||
PRBool AddCookieToList(const nsCString& aBaseDomain, nsCookie *aCookie, PRBool aWriteToDB = PR_TRUE);
|
||||
void UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed);
|
||||
static PRBool GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, PRBool &aEqualsFound);
|
||||
static PRBool ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie);
|
||||
PRBool IsForeign(const nsCString &aBaseDomain, PRBool aHostIsIPAddress, nsIURI *aFirstURI);
|
||||
PRUint32 CheckPrefs(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString &aBaseDomain, PRBool aIsIPAddress, const char *aCookieHeader);
|
||||
PRBool CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, PRBool aIsIPAddress);
|
||||
PRBool IsForeign(const nsCString &aBaseDomain, PRBool aRequireHostMatch, nsIURI *aFirstURI);
|
||||
PRUint32 CheckPrefs(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString &aBaseDomain, PRBool aRequireHostMatch, const char *aCookieHeader);
|
||||
PRBool CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, PRBool aRequireHostMatch);
|
||||
static PRBool CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
|
||||
static PRBool GetExpiry(nsCookieAttributes &aCookie, PRInt64 aServerTime, PRInt64 aCurrentTime);
|
||||
void RemoveAllFromMemory();
|
||||
|
@ -196,6 +198,7 @@ class nsCookieService : public nsICookieService
|
|||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
nsCOMPtr<nsICookiePermission> mPermissionService;
|
||||
nsCOMPtr<nsIEffectiveTLDService> mTLDService;
|
||||
nsCOMPtr<nsIIDNService> mIDNService;
|
||||
|
||||
// we have two separate DB states: one for normal browsing and one for
|
||||
// private browsing, switching between them as appropriate. this state
|
||||
|
|
Загрузка…
Ссылка в новой задаче