/* -*- 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/. */
// Specialize this if there's some class that has multiple nsISupports bases. template <class T> struct ISupportsBaseInfo { using ISupportsBase = T;
};
template <template <class> class SmartPtr, class T> inlinevoid SwapToISupportsArray(SmartPtr<T>& aSrc,
nsTArray<nsCOMPtr<nsISupports>>& aDest) {
nsCOMPtr<nsISupports>* dest = aDest.AppendElement();
// Every time we call GetChannelResultPrincipal() it will return a different // null principal for a data URL. We don't want to change the worker's // principal again, though. Instead just keep the original null principal we // first got from the channel. // // Note, we don't do this by setting principalToInherit on the channel's // load info because we don't yet have the first null principal when we // create the channel. if (mPrincipal && mPrincipal->GetIsNullPrincipal() &&
channelPrincipal->GetIsNullPrincipal()) {
channelPrincipal = mPrincipal;
channelPartitionedPrincipal = mPrincipal;
}
// If the loading principal is the system principal then the channel // principal must also be the system principal (we do not allow chrome // code to create workers with non-chrome scripts, and if we ever decide // to change this we need to make sure we don't always set // mPrincipalIsSystem to true in WorkerPrivate::GetLoadInfo()). Otherwise // this channel principal must be same origin with the load principal (we // check again here in case redirects changed the location of the script). if (mLoadingPrincipal->IsSystemPrincipal()) { if (!channelPrincipal->IsSystemPrincipal()) {
nsCOMPtr<nsIURI> finalURI;
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalURI));
NS_ENSURE_SUCCESS(rv, rv);
// See if this is a resource URI. Since JSMs usually come from // resource:// URIs we're currently considering all URIs with the // URI_IS_UI_RESOURCE flag as valid for creating privileged workers. bool isResource;
rv = NS_URIChainHasFlags(finalURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
&isResource);
NS_ENSURE_SUCCESS(rv, rv);
if (isResource) { // Assign the system principal to the resource:// worker only if it // was loaded from code using the system principal.
channelPrincipal = mLoadingPrincipal;
channelPartitionedPrincipal = mLoadingPrincipal;
} else { return NS_ERROR_DOM_BAD_URI;
}
}
}
// The principal can change, but it should still match the original // load group's browser element flag.
MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(channelLoadGroup, channelPrincipal));
// Workers themselves can have their own CSP - Workers of an opaque origin // however inherit the CSP of the document that spawned the worker.
nsCOMPtr<nsIContentSecurityPolicy> csp; if (CSP_ShouldResponseInheritCSP(aChannel)) {
nsCOMPtr<nsILoadInfo> loadinfo = aChannel->LoadInfo();
csp = loadinfo->GetCsp();
} return SetPrincipalsAndCSPOnMainThread(principal, partitionedPrincipal,
loadGroup, csp);
}
// Verify that the channel is still a null principal. We don't care // if these are the exact same null principal object, though. From // the worker's perspective its the same effect. if (principal->GetIsNullPrincipal() && mPrincipal->GetIsNullPrincipal()) { returntrue;
}
// Otherwise we require exact equality. Redirects can happen, but they // are not allowed to change our principal. if (principal->Equals(mPrincipal)) { returntrue;
}
// A null principal can occur for a data URL worker script or a blob URL // worker script from a sandboxed iframe. if (mPrincipal->GetIsNullPrincipal()) { return scheme == "data"_ns || scheme == "blob"_ns;
}
// The principal for a blob: URL worker script does not have a matching URL. // This is likely a bug in our referer setting logic, but exempt it for now. // This is another reason we should fix bug 1340694 so that referer does not // depend on the principal URI. if (scheme == "blob"_ns) { returntrue;
}
if (mPrincipal->IsSameOrigin(mBaseURI)) { returntrue;
}
// Look for an existing LoadContext. This is optional and it's ok if // we don't find one.
nsCOMPtr<nsILoadContext> baseContext; if (aLoadGroup) {
nsCOMPtr<nsIInterfaceRequestor> callbacks;
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks)); if (callbacks) {
callbacks->GetInterface(NS_GET_IID(nsILoadContext),
getter_AddRefs(baseContext));
}
mOuterRequestor = callbacks;
}
mLoadContext = new LoadContext(aPrincipal, baseContext);
}
nsCOMPtr<nsIInterfaceRequestor> callbacks;
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks)); if (!callbacks) { return;
}
nsCOMPtr<nsIBrowserChild> browserChild;
callbacks->GetInterface(NS_GET_IID(nsIBrowserChild),
getter_AddRefs(browserChild)); if (!browserChild) { return;
}
// Use weak references to the tab child. Holding a strong reference will // not prevent an ActorDestroy() from being called on the BrowserChild. // Therefore, we should let the BrowserChild destroy itself as soon as // possible.
mBrowserChildList.AppendElement(do_GetWeakReference(browserChild));
}
// If we still have an active nsIBrowserChild, then return it. Its possible, // though, that all of the BrowserChild objects have been destroyed. In that // case we return NS_NOINTERFACE. if (aIID.Equals(NS_GET_IID(nsIBrowserChild))) {
nsCOMPtr<nsIBrowserChild> browserChild = GetAnyLiveBrowserChild(); if (!browserChild) { return NS_NOINTERFACE;
}
browserChild.forget(aSink); return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsINetworkInterceptController)) &&
mOuterRequestor) { // If asked for the network intercept controller, ask the outer requestor, // which could be the docshell. return mOuterRequestor->GetInterface(aIID, aSink);
}
// Search our list of known BrowserChild objects for one that still exists. while (!mBrowserChildList.IsEmpty()) {
nsCOMPtr<nsIBrowserChild> browserChild =
do_QueryReferent(mBrowserChildList.LastElement());
// Does this tab child still exist? If so, return it. We are done. If the // PBrowser actor is no longer useful, don't bother returning this tab. if (browserChild &&
!static_cast<BrowserChild*>(browserChild.get())->IsDestroyed()) { return browserChild.forget();
}
// Otherwise remove the stale weak reference and check the next one
mBrowserChildList.RemoveLastElement();
}
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.