/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 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/. */
// Our current idiom is that storage-related APIs specialize for the system // principal themselves, which is consistent with StorageAllowedForwindow not // specializing for the system principal. Without this specialization we // would end up with ePrivateBrowsing for system principaled private browsing // windows which is explicitly not what we want. System Principal code always // should have access to storage. It may make sense to enhance // StorageAllowedForWindow in the future to handle this after comprehensive // auditing.
nsCOMPtr<nsIPrincipal> principal = aGlobal.GetSubjectPrincipal();
StorageAccess storageAllowed; if (principal && principal->IsSystemPrincipal()) {
storageAllowed = StorageAccess::eAllow;
} else {
storageAllowed = StorageAllowedForWindow(window);
}
if (storageAllowed == StorageAccess::eDeny) {
aRv.ThrowSecurityError("StorageAccess denied."); return nullptr;
}
if (ShouldPartitionStorage(storageAllowed) &&
!StoragePartitioningEnabled(
storageAllowed, window->GetExtantDoc()->CookieJarSettings())) {
aRv.ThrowSecurityError("StoragePartitioning not enabled."); return nullptr;
}
// Assert that the principal private browsing state matches the // StorageAccess value. #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED if (storageAllowed == StorageAccess::ePrivateBrowsing) {
uint32_t privateBrowsingId = 0; if (principal) {
MOZ_ALWAYS_SUCCEEDS(principal->GetPrivateBrowsingId(&privateBrowsingId));
}
MOZ_DIAGNOSTIC_ASSERT(privateBrowsingId != 0);
} #endif// MOZ_DIAGNOSTIC_ASSERT_ENABLED
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread(); if (!actorChild || !actorChild->CanSend()) {
aRv.ThrowSecurityError("PBackground not available."); return nullptr;
}
WorkerLoadInfo loadInfo;
aRv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, *compliantString,
aOptions.mType, aOptions.mCredentials, false,
WorkerPrivate::OverrideLoadGroup,
WorkerKindShared, &loadInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
PrincipalInfo principalInfo;
aRv = PrincipalToPrincipalInfo(loadInfo.mPrincipal, &principalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
PrincipalInfo loadingPrincipalInfo;
aRv = PrincipalToPrincipalInfo(loadInfo.mLoadingPrincipal,
&loadingPrincipalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
// Here, the PartitionedPrincipal is always equal to the SharedWorker's // principal because the channel is not opened yet, and, because of this, it's // not classified. We need to force the correct originAttributes. // // The sharedWorker's principal could be a null principal, e.g. loading a // data url. In this case, we don't need to force the OAs for the partitioned // principal because creating storage from a null principal will fail anyway. // We should only do this for content principals. // // You can find more details in StoragePrincipalHelper.h if (ShouldPartitionStorage(storageAllowed) &&
BasePrincipal::Cast(loadInfo.mPrincipal)->IsContentPrincipal()) {
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(window); if (!sop) {
aRv.ThrowSecurityError("ScriptObjectPrincipal not available."); return nullptr;
}
nsIPrincipal* windowPrincipal = sop->GetPrincipal(); if (!windowPrincipal) {
aRv.ThrowSecurityError("WindowPrincipal not available."); return nullptr;
}
nsIPrincipal* windowPartitionedPrincipal = sop->PartitionedPrincipal(); if (!windowPartitionedPrincipal) {
aRv.ThrowSecurityError("WindowPartitionedPrincipal not available."); return nullptr;
}
PrincipalInfo partitionedPrincipalInfo; if (loadInfo.mPrincipal->Equals(loadInfo.mPartitionedPrincipal)) {
partitionedPrincipalInfo = principalInfo;
} else {
aRv = PrincipalToPrincipalInfo(loadInfo.mPartitionedPrincipal,
&partitionedPrincipalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
}
// We don't actually care about this MessageChannel, but we use it to 'steal' // its 2 connected ports.
RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr;
}
RefPtr<SharedWorkerChild> actor = static_cast<SharedWorkerChild*>(pActor);
RefPtr<SharedWorker> sharedWorker = new SharedWorker(window, actor, channel->Port2());
// Let's inform the window about this SharedWorker.
nsGlobalWindowInner::Cast(window)->StoreSharedWorker(sharedWorker);
actor->SetParent(sharedWorker);
if (nsGlobalWindowInner::Cast(window)->IsSuspended()) {
sharedWorker->Suspend();
}
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.