merge inbound to central. r=merge a=merge

This commit is contained in:
Sebastian Hengst
2018-01-06 00:27:10 +02:00
142 changed files with 3655 additions and 2289 deletions

View File

@@ -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);