/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
nsAutoCString scheme;
nsCOMPtr<nsIURI> uri = aURI; // The URI could be nested (for example view-source:http://example.com), in // that case we want to get the innermost URI (http://example.com).
nsCOMPtr<nsINestedURI> nestedURI; do {
NS_ENSURE_SUCCESS_VOID(uri->GetScheme(scheme));
nestedURI = do_QueryInterface(uri); // We can't just use GetInnermostURI on the nested URI, since that would // also unwrap some about: URIs to hidden moz-safe-about: URIs, which we do // not want. Thus we loop through with GetInnerURI until the URI isn't // nested anymore or we encounter a about: scheme.
} while (nestedURI && !scheme.EqualsLiteral("about") &&
NS_SUCCEEDED(nestedURI->GetInnerURI(getter_AddRefs(uri))));
if (scheme.EqualsLiteral("about")) {
MakeTopLevelInfo(scheme, nsLiteralCString(ABOUT_URI_FIRST_PARTY_DOMAIN),
aForeignByAncestorContext, aUseSite, topLevelInfo); return;
}
// If a null principal URI was provided, extract the UUID portion of the URI // to use for the first-party domain. if (scheme.EqualsLiteral("moz-nullprincipal")) { // Get the UUID portion of the URI, ignoring the precursor principal.
nsAutoCString filePath;
rv = uri->GetFilePath(filePath);
MOZ_ASSERT(NS_SUCCEEDED(rv)); // Remove the `{}` characters from both ends.
filePath.Mid(filePath, 1, filePath.Length() - 2);
filePath.AppendLiteral(".mozilla"); // Store the generated file path.
topLevelInfo = NS_ConvertUTF8toUTF16(filePath); return;
}
// Add-on principals should never get any first-party domain // attributes in order to guarantee their storage integrity when switching // FPI on and off. if (scheme.EqualsLiteral("moz-extension")) { return;
}
if (isIpAddress) { // If the host is an IPv4/IPv6 address, we still accept it as a // valid topLevelInfo.
nsAutoCString ipAddr;
if (net_IsValidIPv6Addr(host)) { // According to RFC2732, the host of an IPv6 address should be an // IPv6reference. The GetHost() of nsIURI will only return the IPv6 // address. So, we need to convert it back to IPv6reference here.
ipAddr.AssignLiteral("[");
ipAddr.Append(host);
ipAddr.AppendLiteral("]");
} else {
ipAddr = host;
}
void OriginAttributes::SetFirstPartyDomain(constbool aIsTopLevelDocument, const nsAString& aDomain, bool aForced) { // If the pref is off or this is not a top level load, bail out. if ((!IsFirstPartyEnabled() || !aIsTopLevelDocument) && !aForced) { return;
}
// // Important: While serializing any string-valued attributes, perform a // release-mode assertion to make sure that they don't contain characters that // will break the quota manager when it uses the serialization for file // naming. //
if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
value.Truncate();
value.AppendInt(mUserContextId);
params.Set("userContextId"_ns, value);
}
if (mPrivateBrowsingId) {
value.Truncate();
value.AppendInt(mPrivateBrowsingId);
params.Set("privateBrowsingId"_ns, value);
}
if (!mFirstPartyDomain.IsEmpty()) {
nsAutoString sanitizedFirstPartyDomain(mFirstPartyDomain);
sanitizedFirstPartyDomain.ReplaceChar(kSourceChar, kSanitizedChar);
params.Set("firstPartyDomain"_ns,
NS_ConvertUTF16toUTF8(sanitizedFirstPartyDomain));
}
if (!attrs.mFirstPartyDomain.IsEmpty()) {
attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
}
if (!attrs.mPartitionKey.IsEmpty()) {
attrs.mPartitionKey.AssignLiteral("_anonymizedPartitionKey_");
}
attrs.CreateSuffix(aStr);
}
bool OriginAttributes::PopulateFromSuffix(const nsACString& aStr) { if (aStr.IsEmpty()) { returntrue;
}
if (aStr[0] != '^') { returnfalse;
}
// If a non-default mPrivateBrowsingId is passed and is not present in the // suffix, then it will retain the id when it should be default according // to the suffix. Set to default before iterating to fix this.
mPrivateBrowsingId = nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
if (aName.EqualsLiteral("addonId") || aName.EqualsLiteral("appId")) { // No longer supported. Silently ignore so that legacy origin strings // don't cause failures. returntrue;
}
if (aName.EqualsLiteral("userContextId")) {
nsresult rv;
int64_t val = aValue.ToInteger64(&rv);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
mUserContextId = static_cast<uint32_t>(val);
returntrue;
}
if (aName.EqualsLiteral("privateBrowsingId")) {
nsresult rv;
int64_t val = aValue.ToInteger64(&rv);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
mPrivateBrowsingId = static_cast<uint32_t>(val);
returntrue;
}
if (aName.EqualsLiteral("firstPartyDomain")) {
nsAutoCString firstPartyDomain(aValue);
firstPartyDomain.ReplaceChar(kSanitizedChar, kSourceChar);
mFirstPartyDomain.Assign(NS_ConvertUTF8toUTF16(firstPartyDomain)); returntrue;
}
if (aName.EqualsLiteral("geckoViewUserContextId")) {
mGeckoViewSessionContextId.Assign(NS_ConvertUTF8toUTF16(aValue)); returntrue;
}
if (aName.EqualsLiteral("partitionKey")) {
nsAutoCString partitionKey(aValue);
partitionKey.ReplaceChar(kSanitizedChar, kSourceChar);
mPartitionKey.Assign(NS_ConvertUTF8toUTF16(partitionKey)); returntrue;
}
// No other attributes are supported. returnfalse;
});
}
bool OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
nsACString& aOriginNoSuffix) { // RFindChar is only available on nsCString.
nsCString origin(aOrigin);
int32_t pos = origin.RFindChar('^');
if (pos == kNotFound) {
aOriginNoSuffix = origin; returntrue;
}
// Partition keys have the format // "(<scheme>,<baseDomain>[,port][,foreignancestorbit])". The port and // ancestor bits are optional. For example: "(https,example.com,8443)" or // "(http,example.org)", or "(http,example.info,f)", or // "(http,example.biz,8443,f)". When privacy.dynamic_firstparty.use_site = // false, the partitionKey contains only the host, e.g. "example.com". See // MakeTopLevelInfo for the partitionKey serialization code.
if (aPartitionKey.IsEmpty()) { returntrue;
}
// PartitionKey contains only the host. if (!StaticPrefs::privacy_dynamic_firstparty_use_site()) {
outBaseDomain = aPartitionKey; returntrue;
}
// Smallest possible partitionKey is "(x,x)". Scheme and base domain are // mandatory. if (NS_WARN_IF(aPartitionKey.Length() < 5)) { returnfalse;
}
// Remove outer brackets so we can string split.
nsAutoString str(Substring(aPartitionKey, 1, aPartitionKey.Length() - 2));
uint32_t fieldIndex = 0; for (const nsAString& field : str.Split(',')) { if (NS_WARN_IF(field.IsEmpty())) { // There cannot be empty fields. returnfalse;
}
if (fieldIndex == 0) {
outScheme.Assign(field);
} elseif (fieldIndex == 1) {
outBaseDomain.Assign(field);
} elseif (fieldIndex == 2) { // The first optional argument is either "f" or a port number if (field.EqualsLiteral("f")) {
outForeignByAncestorContext = true;
} else { // Parse the port which is represented in the partitionKey string as a // decimal (base 10) number. long port = strtol(NS_ConvertUTF16toUTF8(field).get(), nullptr, 10); // Invalid port. if (NS_WARN_IF(port == 0)) { returnfalse;
}
outPort = static_cast<int32_t>(port);
}
} elseif (fieldIndex == 3) { // The second optional argument, if it exists, is "f" and the first // optional argument was a port if (!field.EqualsLiteral("f") || outPort != -1) {
NS_WARNING("Invalid partitionKey. Invalid token."); returnfalse;
}
outForeignByAncestorContext = true;
} else {
NS_WARNING("Invalid partitionKey. Too many tokens"); returnfalse;
}
fieldIndex++;
}
// scheme and base domain are required. return fieldIndex > 1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.