Bug 1554377 - Cleanup nsCookie implementation - Get rid of nsCookieAttributes, r=Ehsan

Differential Revision: https://phabricator.services.mozilla.com/D32561

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrea Marchesini 2019-05-31 09:31:30 +00:00
Родитель a1e12567f6
Коммит 8bcf905e12
4 изменённых файлов: 117 добавлений и 130 удалений

Просмотреть файл

@ -395,16 +395,16 @@ uint32_t CookieServiceChild::CountCookiesFromHashTable(
}
void CookieServiceChild::SetCookieInternal(
nsCookieAttributes& aCookieAttributes,
const mozilla::OriginAttributes& aAttrs, nsIChannel* aChannel,
bool aFromHttp, nsICookiePermission* aPermissionService) {
const CookieStruct& aCookieData, const mozilla::OriginAttributes& aAttrs,
nsIChannel* aChannel, bool aFromHttp,
nsICookiePermission* aPermissionService) {
int64_t currentTimeInUsec = PR_Now();
RefPtr<nsCookie> cookie = nsCookie::Create(
aCookieAttributes.name, aCookieAttributes.value, aCookieAttributes.host,
aCookieAttributes.path, aCookieAttributes.expiryTime, currentTimeInUsec,
aCookieData.name(), aCookieData.value(), aCookieData.host(),
aCookieData.path(), aCookieData.expiry(), currentTimeInUsec,
nsCookie::GenerateUniqueCreationTime(currentTimeInUsec),
aCookieAttributes.isSession, aCookieAttributes.isSecure,
aCookieAttributes.isHttpOnly, aAttrs, aCookieAttributes.sameSite);
aCookieData.isSession(), aCookieData.isSecure(), aCookieData.isHttpOnly(),
aAttrs, aCookieData.sameSite());
RecordDocumentCookie(cookie, aAttrs);
}
@ -612,12 +612,11 @@ nsresult CookieServiceChild::SetCookieStringInternal(nsIURI* aHostURI,
int64_t serverTime = nsCookieService::ParseServerTime(serverTimeString);
bool moreCookies;
do {
nsCookieAttributes cookieAttributes;
CookieStruct cookieData;
bool canSetCookie = false;
moreCookies = nsCookieService::CanSetCookie(
aHostURI, key, cookieAttributes, requireHostMatch, cookieStatus,
cookieString, serverTime, aFromHttp, aChannel, canSetCookie,
mThirdPartyUtil);
aHostURI, key, cookieData, requireHostMatch, cookieStatus, cookieString,
serverTime, aFromHttp, aChannel, canSetCookie, mThirdPartyUtil);
// We need to see if the cookie we're setting would overwrite an httponly
// one. This would not affect anything we send over the net (those come from
@ -626,10 +625,9 @@ nsresult CookieServiceChild::SetCookieStringInternal(nsIURI* aHostURI,
if (cookies && canSetCookie && !aFromHttp) {
for (uint32_t i = 0; i < cookies->Length(); ++i) {
RefPtr<nsCookie> cookie = cookies->ElementAt(i);
if (cookie->Name().Equals(cookieAttributes.name) &&
cookie->Host().Equals(cookieAttributes.host) &&
cookie->Path().Equals(cookieAttributes.path) &&
cookie->IsHttpOnly()) {
if (cookie->Name().Equals(cookieData.name()) &&
cookie->Host().Equals(cookieData.host()) &&
cookie->Path().Equals(cookieData.path()) && cookie->IsHttpOnly()) {
// Can't overwrite an httponly cookie from a script context.
canSetCookie = false;
}
@ -639,7 +637,7 @@ nsresult CookieServiceChild::SetCookieStringInternal(nsIURI* aHostURI,
if (canSetCookie) {
nsCOMPtr<nsICookiePermission> permissionService =
nsCookiePermission::GetOrCreate();
SetCookieInternal(cookieAttributes, attrs, aChannel, aFromHttp,
SetCookieInternal(cookieData, attrs, aChannel, aFromHttp,
permissionService);
}

Просмотреть файл

@ -21,8 +21,6 @@ class nsICookiePermission;
class nsIEffectiveTLDService;
class nsILoadInfo;
struct nsCookieAttributes;
namespace mozilla {
namespace net {
class CookieStruct;
@ -73,7 +71,7 @@ class CookieServiceChild : public PCookieServiceChild,
void RecordDocumentCookie(nsCookie* aCookie, const OriginAttributes& aAttrs);
void SetCookieInternal(nsCookieAttributes& aCookieAttributes,
void SetCookieInternal(const CookieStruct& aCookieData,
const mozilla::OriginAttributes& aAttrs,
nsIChannel* aChannel, bool aFromHttp,
nsICookiePermission* aPermissionService);

Просмотреть файл

@ -3178,7 +3178,7 @@ void nsCookieService::GetCookieStringInternal(
// processes a single cookie, and returns true if there are more cookies
// to be processed
bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
nsCookieAttributes& aCookieAttributes,
CookieStruct& aCookieData,
bool aRequireHostMatch, CookieStatus aStatus,
nsDependentCString& aCookieHeader,
int64_t aServerTime, bool aFromHttp,
@ -3189,7 +3189,7 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
aSetCookie = false;
// init expiryTime such that session cookies won't prematurely expire
aCookieAttributes.expiryTime = INT64_MAX;
aCookieData.expiry() = INT64_MAX;
// aCookieHeader is an in/out param to point to the next cookie, if
// there is one. Save the present value for logging purposes
@ -3197,7 +3197,9 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
// newCookie says whether there are multiple cookies in the header;
// so we can handle them separately.
bool newCookie = ParseAttributes(aCookieHeader, aCookieAttributes);
nsAutoCString expires;
nsAutoCString maxage;
bool newCookie = ParseAttributes(aCookieHeader, aCookieData, expires, maxage);
// Collect telemetry on how often secure cookies are set from non-secure
// origins, and vice-versa.
@ -3209,9 +3211,9 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
bool isHTTPS = true;
nsresult rv = aHostURI->SchemeIs("https", &isHTTPS);
if (NS_SUCCEEDED(rv)) {
Telemetry::Accumulate(Telemetry::COOKIE_SCHEME_SECURITY,
((aCookieAttributes.isSecure) ? 0x02 : 0x00) |
((isHTTPS) ? 0x01 : 0x00));
Telemetry::Accumulate(
Telemetry::COOKIE_SCHEME_SECURITY,
((aCookieData.isSecure()) ? 0x02 : 0x00) | ((isHTTPS) ? 0x01 : 0x00));
// Collect telemetry on how often are first- and third-party cookies set
// from HTTPS origins:
@ -3233,24 +3235,24 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
Telemetry::Accumulate(Telemetry::COOKIE_SCHEME_HTTPS,
(isThirdParty ? 0x04 : 0x00) |
(isHTTPS ? 0x02 : 0x00) |
(aCookieAttributes.isSecure ? 0x01 : 0x00));
(aCookieData.isSecure() ? 0x01 : 0x00));
}
}
int64_t currentTimeInUsec = PR_Now();
// calculate expiry time of cookie.
aCookieAttributes.isSession =
GetExpiry(aCookieAttributes, aServerTime,
aCookieData.isSession() =
GetExpiry(aCookieData, expires, maxage, aServerTime,
currentTimeInUsec / PR_USEC_PER_SEC, aFromHttp);
if (aStatus == STATUS_ACCEPT_SESSION) {
// force lifetime to session. note that the expiration time, if set above,
// will still apply.
aCookieAttributes.isSession = true;
aCookieData.isSession() = true;
}
// reject cookie if it's over the size limit, per RFC2109
if ((aCookieAttributes.name.Length() + aCookieAttributes.value.Length()) >
if ((aCookieData.name().Length() + aCookieData.value().Length()) >
kMaxBytesPerCookie) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"cookie too big (> 4kb)");
@ -3261,26 +3263,29 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x00};
if (aCookieAttributes.name.FindCharInSet(illegalNameCharacters, 0) != -1) {
if (aCookieData.name().FindCharInSet(illegalNameCharacters, 0) != -1) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"invalid name character");
return newCookie;
}
// domain & path checks
if (!CheckDomain(aCookieAttributes, aHostURI, aKey.mBaseDomain,
if (!CheckDomain(aCookieData, aHostURI, aKey.mBaseDomain,
aRequireHostMatch)) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"failed the domain tests");
return newCookie;
}
if (!CheckPath(aCookieAttributes, aHostURI)) {
if (!CheckPath(aCookieData, aHostURI)) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"failed the path tests");
return newCookie;
}
// magic prefix checks. MUST be run after CheckDomain() and CheckPath()
if (!CheckPrefixes(aCookieAttributes, isHTTPS)) {
if (!CheckPrefixes(aCookieData, isHTTPS)) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"failed the prefix tests");
return newCookie;
@ -3298,14 +3303,14 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x3B, 0x00};
if (aFromHttp &&
(aCookieAttributes.value.FindCharInSet(illegalCharacters, 0) != -1)) {
(aCookieData.value().FindCharInSet(illegalCharacters, 0) != -1)) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"invalid value character");
return newCookie;
}
// if the new cookie is httponly, make sure we're not coming from script
if (!aFromHttp && aCookieAttributes.isHttpOnly) {
if (!aFromHttp && aCookieData.isHttpOnly()) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"cookie is httponly; coming from script");
return newCookie;
@ -3314,7 +3319,7 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
// If the new cookie is non-https and wants to set secure flag,
// browser have to ignore this new cookie.
// (draft-ietf-httpbis-cookie-alone section 3.1)
if (aCookieAttributes.isSecure && !isHTTPS) {
if (aCookieData.isSecure() && !isHTTPS) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
"non-https cookie can't set secure flag");
return newCookie;
@ -3322,7 +3327,7 @@ bool nsCookieService::CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
// If the new cookie is same-site but in a cross site context,
// browser must ignore the cookie.
if ((aCookieAttributes.sameSite != nsICookie2::SAMESITE_NONE) &&
if ((aCookieData.sameSite() != nsICookie2::SAMESITE_NONE) &&
aThirdPartyUtil) {
// Do not treat loads triggered by web extensions as foreign
bool addonAllowsLoad = false;
@ -3362,11 +3367,10 @@ bool nsCookieService::SetCookieInternal(nsIURI* aHostURI,
NS_ASSERTION(aHostURI, "null host!");
bool canSetCookie = false;
nsDependentCString savedCookieHeader(aCookieHeader);
nsCookieAttributes cookieAttributes;
bool newCookie =
CanSetCookie(aHostURI, aKey, cookieAttributes, aRequireHostMatch, aStatus,
aCookieHeader, aServerTime, aFromHttp, aChannel,
canSetCookie, mThirdPartyUtil);
CookieStruct cookieData;
bool newCookie = CanSetCookie(aHostURI, aKey, cookieData, aRequireHostMatch,
aStatus, aCookieHeader, aServerTime, aFromHttp,
aChannel, canSetCookie, mThirdPartyUtil);
if (!canSetCookie) {
return newCookie;
@ -3375,12 +3379,11 @@ bool nsCookieService::SetCookieInternal(nsIURI* aHostURI,
int64_t currentTimeInUsec = PR_Now();
// create a new nsCookie and copy attributes
RefPtr<nsCookie> cookie = nsCookie::Create(
cookieAttributes.name, cookieAttributes.value, cookieAttributes.host,
cookieAttributes.path, cookieAttributes.expiryTime, currentTimeInUsec,
cookieData.name(), cookieData.value(), cookieData.host(),
cookieData.path(), cookieData.expiry(), currentTimeInUsec,
nsCookie::GenerateUniqueCreationTime(currentTimeInUsec),
cookieAttributes.isSession, cookieAttributes.isSecure,
cookieAttributes.isHttpOnly, aKey.mOriginAttributes,
cookieAttributes.sameSite);
cookieData.isSession(), cookieData.isSecure(), cookieData.isHttpOnly(),
aKey.mOriginAttributes, cookieData.sameSite());
if (!cookie) return newCookie;
// check permissions from site permission list, or ask the user,
@ -3390,7 +3393,7 @@ bool nsCookieService::SetCookieInternal(nsIURI* aHostURI,
mPermissionService->CanSetCookie(
aHostURI, aChannel,
static_cast<nsICookie2*>(static_cast<nsCookie*>(cookie)),
&cookieAttributes.isSession, &cookieAttributes.expiryTime, &permission);
&cookieData.isSession(), &cookieData.expiry(), &permission);
if (!permission) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
"cookie rejected by permission manager");
@ -3402,8 +3405,8 @@ bool nsCookieService::SetCookieInternal(nsIURI* aHostURI,
}
// update isSession and expiry attributes, in case they changed
cookie->SetIsSession(cookieAttributes.isSession);
cookie->SetExpiry(cookieAttributes.expiryTime);
cookie->SetIsSession(cookieData.isSession());
cookie->SetExpiry(cookieData.expiry());
}
// add the cookie to the list. AddInternal() takes care of logging.
@ -3747,7 +3750,9 @@ bool nsCookieService::GetTokenValue(nsACString::const_char_iterator& aIter,
// folded into the cookie struct here, because we don't know which one to use
// until we've parsed the header.
bool nsCookieService::ParseAttributes(nsDependentCString& aCookieHeader,
nsCookieAttributes& aCookieAttributes) {
CookieStruct& aCookieData,
nsACString& aExpires,
nsACString& aMaxage) {
static const char kPath[] = "path";
static const char kDomain[] = "domain";
static const char kExpires[] = "expires";
@ -3763,9 +3768,9 @@ bool nsCookieService::ParseAttributes(nsDependentCString& aCookieHeader,
aCookieHeader.BeginReading(cookieStart);
aCookieHeader.EndReading(cookieEnd);
aCookieAttributes.isSecure = false;
aCookieAttributes.isHttpOnly = false;
aCookieAttributes.sameSite = nsICookie2::SAMESITE_NONE;
aCookieData.isSecure() = false;
aCookieData.isHttpOnly() = false;
aCookieData.sameSite() = nsICookie2::SAMESITE_NONE;
nsDependentCSubstring tokenString(cookieStart, cookieStart);
nsDependentCSubstring tokenValue(cookieStart, cookieStart);
@ -3779,10 +3784,10 @@ bool nsCookieService::ParseAttributes(nsDependentCString& aCookieHeader,
newCookie = GetTokenValue(cookieStart, cookieEnd, tokenString, tokenValue,
equalsFound);
if (equalsFound) {
aCookieAttributes.name = tokenString;
aCookieAttributes.value = tokenValue;
aCookieData.name() = tokenString;
aCookieData.value() = tokenValue;
} else {
aCookieAttributes.value = tokenString;
aCookieData.value() = tokenString;
}
// extract remaining attributes
@ -3797,31 +3802,31 @@ bool nsCookieService::ParseAttributes(nsDependentCString& aCookieHeader,
// decide which attribute we have, and copy the string
if (tokenString.LowerCaseEqualsLiteral(kPath))
aCookieAttributes.path = tokenValue;
aCookieData.path() = tokenValue;
else if (tokenString.LowerCaseEqualsLiteral(kDomain))
aCookieAttributes.host = tokenValue;
aCookieData.host() = tokenValue;
else if (tokenString.LowerCaseEqualsLiteral(kExpires))
aCookieAttributes.expires = tokenValue;
aExpires = tokenValue;
else if (tokenString.LowerCaseEqualsLiteral(kMaxage))
aCookieAttributes.maxage = tokenValue;
aMaxage = tokenValue;
// ignore any tokenValue for isSecure; just set the boolean
else if (tokenString.LowerCaseEqualsLiteral(kSecure))
aCookieAttributes.isSecure = true;
aCookieData.isSecure() = true;
// ignore any tokenValue for isHttpOnly (see bug 178993);
// just set the boolean
else if (tokenString.LowerCaseEqualsLiteral(kHttpOnly))
aCookieAttributes.isHttpOnly = true;
aCookieData.isHttpOnly() = true;
else if (tokenString.LowerCaseEqualsLiteral(kSameSite)) {
if (tokenValue.LowerCaseEqualsLiteral(kSameSiteLax)) {
aCookieAttributes.sameSite = nsICookie2::SAMESITE_LAX;
aCookieData.sameSite() = nsICookie2::SAMESITE_LAX;
} else if (tokenValue.LowerCaseEqualsLiteral(kSameSiteStrict)) {
aCookieAttributes.sameSite = nsICookie2::SAMESITE_STRICT;
aCookieData.sameSite() = nsICookie2::SAMESITE_STRICT;
}
}
}
@ -4047,8 +4052,7 @@ CookieStatus nsCookieService::CheckPrefs(
// processes domain attribute, and returns true if host has permission to set
// for this domain.
bool nsCookieService::CheckDomain(nsCookieAttributes& aCookieAttributes,
nsIURI* aHostURI,
bool nsCookieService::CheckDomain(CookieStruct& aCookieData, nsIURI* aHostURI,
const nsCString& aBaseDomain,
bool aRequireHostMatch) {
// Note: The logic in this function is mirrored in
@ -4061,29 +4065,28 @@ bool nsCookieService::CheckDomain(nsCookieAttributes& aCookieAttributes,
aHostURI->GetAsciiHost(hostFromURI);
// if a domain is given, check the host has permission
if (!aCookieAttributes.host.IsEmpty()) {
if (!aCookieData.host().IsEmpty()) {
// Tolerate leading '.' characters, but not if it's otherwise an empty host.
if (aCookieAttributes.host.Length() > 1 &&
aCookieAttributes.host.First() == '.') {
aCookieAttributes.host.Cut(0, 1);
if (aCookieData.host().Length() > 1 && aCookieData.host().First() == '.') {
aCookieData.host().Cut(0, 1);
}
// switch to lowercase now, to avoid case-insensitive compares everywhere
ToLowerCase(aCookieAttributes.host);
ToLowerCase(aCookieData.host());
// 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);
if (aRequireHostMatch) return hostFromURI.Equals(aCookieData.host());
// ensure the proposed domain is derived from the base domain; and also
// that the host domain is derived from the proposed domain (per RFC2109).
if (IsSubdomainOf(aCookieAttributes.host, aBaseDomain) &&
IsSubdomainOf(hostFromURI, aCookieAttributes.host)) {
if (IsSubdomainOf(aCookieData.host(), aBaseDomain) &&
IsSubdomainOf(hostFromURI, aCookieData.host())) {
// prepend a dot to indicate a domain cookie
aCookieAttributes.host.InsertLiteral(".", 0);
aCookieData.host().InsertLiteral(".", 0);
return true;
}
@ -4098,7 +4101,7 @@ bool nsCookieService::CheckDomain(nsCookieAttributes& aCookieAttributes,
}
// no domain specified, use hostFromURI
aCookieAttributes.host = hostFromURI;
aCookieData.host() = hostFromURI;
return true;
}
@ -4122,12 +4125,10 @@ nsAutoCString nsCookieService::GetPathFromURI(nsIURI* aHostURI) {
return path;
}
bool nsCookieService::CheckPath(nsCookieAttributes& aCookieAttributes,
nsIURI* aHostURI) {
bool nsCookieService::CheckPath(CookieStruct& aCookieData, nsIURI* aHostURI) {
// if a path is given, check the host has permission
if (aCookieAttributes.path.IsEmpty() ||
aCookieAttributes.path.First() != '/') {
aCookieAttributes.path = GetPathFromURI(aHostURI);
if (aCookieData.path().IsEmpty() || aCookieData.path().First() != '/') {
aCookieData.path() = GetPathFromURI(aHostURI);
#if 0
} else {
@ -4140,14 +4141,14 @@ bool nsCookieService::CheckPath(nsCookieAttributes& aCookieAttributes,
// get path from aHostURI
nsAutoCString pathFromURI;
if (NS_FAILED(aHostURI->GetPathQueryRef(pathFromURI)) ||
!StringBeginsWith(pathFromURI, aCookieAttributes.path)) {
!StringBeginsWith(pathFromURI, aCookieData.path())) {
return false;
}
#endif
}
if (aCookieAttributes.path.Length() > kMaxBytesPerPath ||
aCookieAttributes.path.Contains('\t'))
if (aCookieData.path().Length() > kMaxBytesPerPath ||
aCookieData.path().Contains('\t'))
return false;
return true;
@ -4160,24 +4161,23 @@ bool nsCookieService::CheckPath(nsCookieAttributes& aCookieAttributes,
// if they do not meet the criteria required by the prefix.
//
// Must not be called until after CheckDomain() and CheckPath() have
// regularized and validated the nsCookieAttributes values!
bool nsCookieService::CheckPrefixes(nsCookieAttributes& aCookieAttributes,
// regularized and validated the CookieStruct values!
bool nsCookieService::CheckPrefixes(CookieStruct& aCookieData,
bool aSecureRequest) {
static const char kSecure[] = "__Secure-";
static const char kHost[] = "__Host-";
static const int kSecureLen = sizeof(kSecure) - 1;
static const int kHostLen = sizeof(kHost) - 1;
bool isSecure =
strncmp(aCookieAttributes.name.get(), kSecure, kSecureLen) == 0;
bool isHost = strncmp(aCookieAttributes.name.get(), kHost, kHostLen) == 0;
bool isSecure = strncmp(aCookieData.name().get(), kSecure, kSecureLen) == 0;
bool isHost = strncmp(aCookieData.name().get(), kHost, kHostLen) == 0;
if (!isSecure && !isHost) {
// not one of the magic prefixes: carry on
return true;
}
if (!aSecureRequest || !aCookieAttributes.isSecure) {
if (!aSecureRequest || !aCookieData.isSecure()) {
// the magic prefixes may only be used from a secure request and
// the secure attribute must be set on the cookie
return false;
@ -4190,8 +4190,8 @@ bool nsCookieService::CheckPrefixes(nsCookieAttributes& aCookieAttributes,
// them. In particular all explicit domain attributes result in a host
// that starts with a dot, and if the host doesn't start with a dot it
// correctly matches the true host.
if (aCookieAttributes.host[0] == '.' ||
!aCookieAttributes.path.EqualsLiteral("/")) {
if (aCookieData.host()[0] == '.' ||
!aCookieData.path().EqualsLiteral("/")) {
return false;
}
}
@ -4199,9 +4199,10 @@ bool nsCookieService::CheckPrefixes(nsCookieAttributes& aCookieAttributes,
return true;
}
bool nsCookieService::GetExpiry(nsCookieAttributes& aCookieAttributes,
int64_t aServerTime, int64_t aCurrentTime,
bool aFromHttp) {
bool nsCookieService::GetExpiry(CookieStruct& aCookieData,
const nsACString& aExpires,
const nsACString& aMaxage, int64_t aServerTime,
int64_t aCurrentTime, bool aFromHttp) {
// maxageCap is in seconds.
// Disabled for HTTP cookies.
int64_t maxageCap =
@ -4216,11 +4217,10 @@ bool nsCookieService::GetExpiry(nsCookieAttributes& aCookieAttributes,
* Note: We need to consider accounting for network lag here, per RFC.
*/
// check for max-age attribute first; this overrides expires attribute
if (!aCookieAttributes.maxage.IsEmpty()) {
if (!aMaxage.IsEmpty()) {
// obtain numeric value of maxageAttribute
int64_t maxage;
int32_t numInts =
PR_sscanf(aCookieAttributes.maxage.get(), "%lld", &maxage);
int32_t numInts = PR_sscanf(aMaxage.BeginReading(), "%lld", &maxage);
// default to session cookie if the conversion failed
if (numInts != 1) {
@ -4230,17 +4230,17 @@ bool nsCookieService::GetExpiry(nsCookieAttributes& aCookieAttributes,
// if this addition overflows, expiryTime will be less than currentTime
// and the cookie will be expired - that's okay.
if (maxageCap) {
aCookieAttributes.expiryTime = aCurrentTime + std::min(maxage, maxageCap);
aCookieData.expiry() = aCurrentTime + std::min(maxage, maxageCap);
} else {
aCookieAttributes.expiryTime = aCurrentTime + maxage;
aCookieData.expiry() = aCurrentTime + maxage;
}
// check for expires attribute
} else if (!aCookieAttributes.expires.IsEmpty()) {
} else if (!aExpires.IsEmpty()) {
PRTime expires;
// parse expiry time
if (PR_ParseTimeString(aCookieAttributes.expires.get(), true, &expires) !=
if (PR_ParseTimeString(aExpires.BeginReading(), true, &expires) !=
PR_SUCCESS) {
return true;
}
@ -4251,10 +4251,10 @@ bool nsCookieService::GetExpiry(nsCookieAttributes& aCookieAttributes,
// time be set less than current time and more than server time.
// The cookie item have to be used to the expired cookie.
if (maxageCap) {
aCookieAttributes.expiryTime = std::min(
expires / int64_t(PR_USEC_PER_SEC), aCurrentTime + maxageCap);
aCookieData.expiry() = std::min(expires / int64_t(PR_USEC_PER_SEC),
aCurrentTime + maxageCap);
} else {
aCookieAttributes.expiryTime = expires / int64_t(PR_USEC_PER_SEC);
aCookieData.expiry() = expires / int64_t(PR_USEC_PER_SEC);
}
// default to session cookie if no attributes found. Here we don't need to

Просмотреть файл

@ -168,21 +168,6 @@ enum OpenDBResult { RESULT_OK, RESULT_RETRY, RESULT_FAILURE };
* class declaration
******************************************************************************/
// struct for temporarily storing cookie attributes during header parsing
struct nsCookieAttributes {
nsAutoCString name;
nsAutoCString value;
nsAutoCString host;
nsAutoCString path;
nsAutoCString expires;
nsAutoCString maxage;
int64_t expiryTime;
bool isSession;
bool isSecure;
bool isHttpOnly;
int8_t sameSite;
};
class nsCookieService final : public nsICookieService,
public nsICookieManager,
public nsIObserver,
@ -221,7 +206,7 @@ class nsCookieService final : public nsICookieService,
static bool DomainMatches(nsCookie* aCookie, const nsACString& aHost);
static bool PathMatches(nsCookie* aCookie, const nsACString& aPath);
static bool CanSetCookie(nsIURI* aHostURI, const nsCookieKey& aKey,
nsCookieAttributes& aCookieAttributes,
mozilla::net::CookieStruct& aCookieData,
bool aRequireHostMatch, CookieStatus aStatus,
nsDependentCString& aCookieHeader,
int64_t aServerTime, bool aFromHttp,
@ -313,14 +298,20 @@ class nsCookieService final : public nsICookieService,
nsDependentCSubstring& aTokenValue,
bool& aEqualsFound);
static bool ParseAttributes(nsDependentCString& aCookieHeader,
nsCookieAttributes& aCookie);
mozilla::net::CookieStruct& aCookieData,
nsACString& aExpires, nsACString& aMaxage);
bool RequireThirdPartyCheck();
static bool CheckDomain(nsCookieAttributes& aCookie, nsIURI* aHostURI,
const nsCString& aBaseDomain, bool aRequireHostMatch);
static bool CheckPath(nsCookieAttributes& aCookie, nsIURI* aHostURI);
static bool CheckPrefixes(nsCookieAttributes& aCookie, bool aSecureRequest);
static bool GetExpiry(nsCookieAttributes& aCookie, int64_t aServerTime,
int64_t aCurrentTime, bool aFromHttp);
static bool CheckDomain(mozilla::net::CookieStruct& aCookieData,
nsIURI* aHostURI, const nsCString& aBaseDomain,
bool aRequireHostMatch);
static bool CheckPath(mozilla::net::CookieStruct& aCookieData,
nsIURI* aHostURI);
static bool CheckPrefixes(mozilla::net::CookieStruct& aCookieData,
bool aSecureRequest);
static bool GetExpiry(mozilla::net::CookieStruct& aCookieData,
const nsACString& aExpires, const nsACString& aMaxage,
int64_t aServerTime, int64_t aCurrentTime,
bool aFromHttp);
void RemoveAllFromMemory();
already_AddRefed<nsIArray> PurgeCookies(int64_t aCurrentTimeInUsec);
bool FindCookie(const nsCookieKey& aKey, const nsCString& aHost,