merge inbound to central. r=merge a=merge
This commit is contained in:
@@ -191,6 +191,7 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsRefreshTimer.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsIServiceWorkerManager.h"
|
||||
#include "nsSHistory.h"
|
||||
#include "nsStructuredCloneContainer.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
@@ -2792,7 +2793,7 @@ nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal)
|
||||
// Don't pre-allocate the client when we are sandboxed. The inherited
|
||||
// principal does not take sandboxing into account.
|
||||
// TODO: Refactor sandboxing principal code out so we can use it here.
|
||||
if (!aPrincipal && (mSandboxFlags & SANDBOXED_ORIGIN)) {
|
||||
if (!aPrincipal && mSandboxFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2834,18 +2835,34 @@ nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal)
|
||||
return;
|
||||
}
|
||||
|
||||
// We're done if there is no parent controller or if this docshell
|
||||
// is not permitted to control for some reason.
|
||||
Maybe<ServiceWorkerDescriptor> controller(parentInner->GetController());
|
||||
if (controller.isNothing()) {
|
||||
if (controller.isNothing() || !ServiceWorkerAllowedToControlWindow(nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
||||
if (!swm) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the parent is controlled then propagate that controller to the
|
||||
// initial about:blank client as well. This will set the controller
|
||||
// in the ClientManagerService in the parent.
|
||||
RefPtr<ClientHandle> handle =
|
||||
ClientManager::CreateHandle(mInitialClientSource->Info(),
|
||||
parentInner->EventTargetFor(TaskCategory::Other));
|
||||
handle->Control(controller.ref());
|
||||
//
|
||||
// Note: If the registration is missing from the SWM we avoid setting
|
||||
// the controller on the client. We can do this synchronously
|
||||
// for now since SWM is in the child process. In the future
|
||||
// when SWM is in the parent process we will probably have to
|
||||
// always set the initial client source and then somehow clear
|
||||
// it if we find the registration is acutally gone. Its also
|
||||
// possible this race only occurs in cases where the resulting
|
||||
// window is no longer exposed. For example, in theory the SW
|
||||
// should not go away if our parent window is controlled.
|
||||
if (!swm->StartControlling(mInitialClientSource->Info(), controller.ref())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Also mark the ClientSource as controlled directly in case script
|
||||
// immediately accesses navigator.serviceWorker.controller.
|
||||
@@ -14085,6 +14102,54 @@ nsDocShell::CanSetOriginAttributes()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocShell::ServiceWorkerAllowedToControlWindow(nsIURI* aURI)
|
||||
{
|
||||
// NOTE: Ideally this method would call one of the
|
||||
// nsContentUtils::StorageAllowed*() methods to determine if the
|
||||
// interception is allowed. Unfortunately we cannot safely do this
|
||||
// before the first window loads in the child process because the
|
||||
// permission manager might not have all its data yet. Therefore,
|
||||
// we use this somewhat lame alternate implementation here. Once
|
||||
// interception is moved to the parent process we should switch
|
||||
// to calling nsContentUtils::StorageAllowed*(). See bug 1428130.
|
||||
|
||||
if (UsePrivateBrowsing() || mSandboxFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t cookieBehavior = nsContentUtils::CookiesBehavior();
|
||||
uint32_t lifetimePolicy = nsContentUtils::CookiesLifetimePolicy();
|
||||
if (cookieBehavior == nsICookieService::BEHAVIOR_REJECT ||
|
||||
lifetimePolicy == nsICookieService::ACCEPT_SESSION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aURI || cookieBehavior == nsICookieService::BEHAVIOR_ACCEPT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
GetSameTypeParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parent ? parent->GetWindow()
|
||||
: nullptr;
|
||||
if (parentWindow) {
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
|
||||
if (thirdPartyUtil) {
|
||||
bool isThirdPartyURI = true;
|
||||
rv = thirdPartyUtil->IsThirdPartyWindow(parentWindow, aURI,
|
||||
&isThirdPartyURI);
|
||||
if (NS_SUCCEEDED(rv) && isThirdPartyURI) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::SetOriginAttributes(const OriginAttributes& aAttrs)
|
||||
{
|
||||
@@ -14289,27 +14354,11 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
|
||||
bool* aShouldIntercept)
|
||||
{
|
||||
*aShouldIntercept = false;
|
||||
// No in private browsing
|
||||
if (UsePrivateBrowsing()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mSandboxFlags) {
|
||||
// If we're sandboxed, don't intercept.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t cookieBehavior = nsContentUtils::CookiesBehavior();
|
||||
if (cookieBehavior == nsICookieService::BEHAVIOR_REJECT) {
|
||||
// If cookies are disabled, don't intercept.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For subresource requests we base our decision solely on the client's
|
||||
// controller value. Any settings that would have blocked service worker
|
||||
// access should have been set before the initial navigation created the
|
||||
// window.
|
||||
if (!aIsNonSubresourceRequest) {
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
if (!doc) {
|
||||
@@ -14325,27 +14374,19 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the user has set a cookie policy that restricts cookies, then
|
||||
// avoid intercepting 3rd party iframes.
|
||||
if (cookieBehavior != nsICookieService::BEHAVIOR_ACCEPT) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
GetSameTypeParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parent ? parent->GetWindow()
|
||||
: nullptr;
|
||||
if (parentWindow) {
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool isThirdPartyURI = true;
|
||||
rv = thirdPartyUtil->IsThirdPartyWindow(parentWindow, aURI, &isThirdPartyURI);
|
||||
if (NS_SUCCEEDED(rv) && isThirdPartyURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
// For navigations, first check to see if we are allowed to control a
|
||||
// window with the given URL.
|
||||
if (!ServiceWorkerAllowedToControlWindow(aURI)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We're allowed to control a window, so check with the ServiceWorkerManager
|
||||
// for a matching service worker.
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
BasePrincipal::CreateCodebasePrincipal(aURI, mOriginAttributes);
|
||||
*aShouldIntercept = swm->IsAvailable(principal, aURI);
|
||||
|
||||
Reference in New Issue
Block a user