Bug 1238160 - Set docshell isolation mode. r=smaug

Renames nsDocShell isBrowser* attributes to add a "Moz" prefix for clarity.

Adds nsDocShell::GetIsIsolatedMozBrowserElement, which parallels
GetIsInIsolatedMozBrowserElement, but only checks the immediate docshell.

Adds nsDocShell::SetIsInIsolatedMozBrowserElement for the frame loader and tab
child to set the isolation state.

nsDocShell methods related to mozbrowser elements (and their callers) are
updated to use GetIs(In)?IsolatedMozBrowserElement when checking isolation /
origins and GetIsMozBrowserElement when checking frame types.

MozReview-Commit-ID: 6pGD5fF47ZN
This commit is contained in:
J. Ryan Stinnett 2016-02-17 21:53:32 -06:00
parent 23f50b043f
commit 6cde63d471
12 changed files with 76 additions and 51 deletions

View File

@ -34,7 +34,7 @@ function getTopWindow(win) {
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!docShell.isBrowserOrApp) {
if (!docShell.isMozBrowserOrApp) {
return win.top;
}
@ -94,7 +94,7 @@ function getParentWindow(win) {
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!docShell.isBrowserOrApp) {
if (!docShell.isMozBrowserOrApp) {
return win.parent;
}

View File

@ -332,7 +332,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) &&
parentDocShellItem) {
nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
if (curDocShell && curDocShell->GetIsBrowserOrApp()) {
if (curDocShell && curDocShell->GetIsMozBrowserOrApp()) {
break;
}

View File

@ -805,6 +805,7 @@ nsDocShell::nsDocShell()
, mDefaultLoadFlags(nsIRequest::LOAD_NORMAL)
, mBlankTiming(false)
, mFrameType(eFrameTypeRegular)
, mIsInIsolatedMozBrowser(false)
, mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
, mUserContextId(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID)
, mParentCharsetSource(0)
@ -2556,7 +2557,7 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
NS_IMETHODIMP
nsDocShell::SetFullscreenAllowed(bool aFullscreenAllowed)
{
if (!nsIDocShell::GetIsBrowserOrApp()) {
if (!nsIDocShell::GetIsMozBrowserOrApp()) {
// Only allow setting of fullscreenAllowed on content/process boundaries.
// At non-boundaries the fullscreenAllowed attribute is calculated based on
// whether all enclosing frames have the "mozFullscreenAllowed" attribute
@ -3364,7 +3365,7 @@ nsDocShell::GetSameTypeParent(nsIDocShellTreeItem** aParent)
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nullptr;
if (nsIDocShell::GetIsBrowserOrApp()) {
if (nsIDocShell::GetIsMozBrowserOrApp()) {
return NS_OK;
}
@ -4016,6 +4017,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild)
aChild->SetTreeOwner(mTreeOwner);
childDocShell->SetUserContextId(mUserContextId);
childDocShell->SetIsInIsolatedMozBrowserElement(mIsInIsolatedMozBrowser);
nsCOMPtr<nsIDocShell> childAsDocShell(do_QueryInterface(aChild));
if (!childAsDocShell) {
@ -6129,7 +6131,7 @@ nsDocShell::SetIsActiveInternal(bool aIsActive, bool aIsHidden)
continue;
}
if (!docshell->GetIsBrowserOrApp()) {
if (!docshell->GetIsMozBrowserOrApp()) {
if (aIsHidden) {
docshell->SetIsActive(aIsActive);
} else {
@ -13890,13 +13892,6 @@ nsDocShell::SetUserContextId(uint32_t aUserContextId)
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
{
*aIsBrowser = (mFrameType == eFrameTypeBrowser);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp)
{
@ -13905,15 +13900,15 @@ nsDocShell::GetIsApp(bool* aIsApp)
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserOrApp(bool* aIsBrowserOrApp)
nsDocShell::GetIsMozBrowserOrApp(bool* aIsMozBrowserOrApp)
{
switch (mFrameType) {
case eFrameTypeRegular:
*aIsBrowserOrApp = false;
*aIsMozBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsBrowserOrApp = true;
*aIsMozBrowserOrApp = true;
break;
}
@ -13939,22 +13934,42 @@ nsDocShell::GetInheritedFrameType()
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
nsDocShell::GetIsIsolatedMozBrowserElement(bool* aIsIsolatedMozBrowserElement)
{
*aIsInIsolatedMozBrowserElement = (GetInheritedFrameType() == eFrameTypeBrowser);
bool result = mFrameType == eFrameTypeBrowser && mIsInIsolatedMozBrowser;
*aIsIsolatedMozBrowserElement = result;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInBrowserOrApp(bool* aIsInBrowserOrApp)
nsDocShell::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
{
MOZ_ASSERT(!mIsInIsolatedMozBrowser ||
(GetInheritedFrameType() == eFrameTypeBrowser),
"Isolated mozbrowser should only be true inside browser frames");
bool result = (GetInheritedFrameType() == eFrameTypeBrowser) &&
mIsInIsolatedMozBrowser;
*aIsInIsolatedMozBrowserElement = result;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::SetIsInIsolatedMozBrowserElement(bool aIsInIsolatedMozBrowserElement)
{
mIsInIsolatedMozBrowser = aIsInIsolatedMozBrowserElement;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInMozBrowserOrApp(bool* aIsInMozBrowserOrApp)
{
switch (GetInheritedFrameType()) {
case eFrameTypeRegular:
*aIsInBrowserOrApp = false;
*aIsInMozBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsInBrowserOrApp = true;
*aIsInMozBrowserOrApp = true;
break;
}
@ -14000,10 +14015,7 @@ nsDocShell::GetOriginAttributes()
}
attrs.mUserContextId = mUserContextId;
if (mFrameType == eFrameTypeBrowser) {
attrs.mInIsolatedMozBrowser = true;
}
attrs.mInIsolatedMozBrowser = mIsInIsolatedMozBrowser;
return attrs;
}

View File

@ -1000,6 +1000,9 @@ protected:
// Are we a regular frame, a browser frame, or an app frame?
FrameType mFrameType;
// Whether we are in an isolated mozbrowser frame.
bool mIsInIsolatedMozBrowser;
// We only expect mOwnOrContainingAppId to be something other than
// UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes
// inside an app, we'll retrieve the containing app-id by walking up the

View File

@ -763,21 +763,27 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[noscript] void notifyScrollObservers();
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser>.
* (<iframe mozapp mozbrowser> is not considered a browser.)
*/
[infallible] readonly attribute boolean isBrowserElement;
/**
* Returns true iff the docshell corresponds to an <iframe mozapp>.
*/
[infallible] readonly attribute boolean isApp;
/**
* Returns isBrowserElement || isApp.
* Returns true if this docshell corresponds to an <iframe mozbrowser> or
* <iframe mozapp>. <xul:browser> returns false here.
*/
[infallible] readonly attribute boolean isBrowserOrApp;
[infallible] readonly attribute boolean isMozBrowserOrApp;
/**
* Returns true if this docshell corresponds to an isolated <iframe
* mozbrowser>.
*
* <iframe mozbrowser mozapp> and <xul:browser> are not considered to be
* mozbrowser elements. <iframe mozbrowser noisolation> does not count as
* isolated since isolation is disabled. Isolation can only be disabled if
* the containing document is chrome.
*/
[infallible] readonly attribute boolean isIsolatedMozBrowserElement;
/**
* Returns true if this docshell corresponds to an isolated <iframe
@ -794,18 +800,18 @@ interface nsIDocShell : nsIDocShellTreeItem
* until the hierarchy ends). Return true iff the docshell we stopped on has
* isIsolatedMozBrowserElement == true.
*/
[infallible] readonly attribute boolean isInIsolatedMozBrowserElement;
[infallible] attribute boolean isInIsolatedMozBrowserElement;
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser> or
* <iframe mozapp>, or if this docshell is contained in an <iframe mozbrowser>
* or <iframe mozapp>.
* or <iframe mozapp>. <xul:browser> returns false here.
*
* To compute this value, we walk up the docshell hierarchy. If we encounter
* a docshell with isBrowserElement or isApp before we hit the end of the
* hierarchy, we return true. Otherwise, we return false.
* a docshell with isMozBrowserOrApp before we hit the end of the hierarchy,
* we return true. Otherwise, we return false.
*/
[infallible] readonly attribute boolean isInBrowserOrApp;
[infallible] readonly attribute boolean isInMozBrowserOrApp;
/**
* Indicate that this docshell corresponds to an app with the given app id.

View File

@ -1200,8 +1200,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
return NS_ERROR_NOT_IMPLEMENTED;
}
if (ourDocshell->GetIsBrowserElement() !=
otherDocshell->GetIsBrowserElement() ||
if (ourDocshell->GetIsIsolatedMozBrowserElement() !=
otherDocshell->GetIsIsolatedMozBrowserElement() ||
ourDocshell->GetIsApp() != otherDocshell->GetIsApp()) {
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -1916,6 +1916,7 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ERROR_FAILURE);
}
mDocShell->SetIsBrowserInsideApp(containingAppId);
mDocShell->SetIsInIsolatedMozBrowserElement(OwnerIsIsolatedMozBrowserFrame());
}
if (OwnerIsMozBrowserOrAppFrame()) {

View File

@ -3802,7 +3802,7 @@ nsGlobalWindow::GetParentOuter()
}
nsCOMPtr<nsPIDOMWindowOuter> parent;
if (mDocShell->GetIsBrowserOrApp()) {
if (mDocShell->GetIsMozBrowserOrApp()) {
parent = AsOuter();
} else {
parent = GetParent();
@ -3968,7 +3968,7 @@ nsGlobalWindow::GetContentInternal(ErrorResult& aError, bool aUnprivilegedCaller
// If we're contained in <iframe mozbrowser> or <iframe mozapp>, then
// GetContent is the same as window.top.
if (mDocShell && mDocShell->GetIsInBrowserOrApp()) {
if (mDocShell && mDocShell->GetIsInMozBrowserOrApp()) {
return GetTopOuter();
}
@ -7176,7 +7176,7 @@ nsGlobalWindow::ResizeToOuter(int32_t aWidth, int32_t aHeight, ErrorResult& aErr
* If caller is a browser-element then dispatch a resize event to
* the embedder.
*/
if (mDocShell && mDocShell->GetIsBrowserOrApp()) {
if (mDocShell && mDocShell->GetIsMozBrowserOrApp()) {
CSSIntSize size(aWidth, aHeight);
if (!DispatchResizeEvent(size)) {
// The embedder chose to prevent the default action for this
@ -7226,7 +7226,7 @@ nsGlobalWindow::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
* If caller is a browser-element then dispatch a resize event to
* parent.
*/
if (mDocShell && mDocShell->GetIsBrowserOrApp()) {
if (mDocShell && mDocShell->GetIsMozBrowserOrApp()) {
CSSIntSize size;
if (NS_FAILED(GetInnerSize(size))) {
return;
@ -8175,7 +8175,7 @@ nsGlobalWindow::CloseOuter(bool aTrustedCaller)
MOZ_RELEASE_ASSERT(IsOuterWindow());
if (!mDocShell || IsInModalState() ||
(IsFrame() && !mDocShell->GetIsBrowserOrApp())) {
(IsFrame() && !mDocShell->GetIsMozBrowserOrApp())) {
// window.close() is called on a frame in a frameset, on a window
// that's already closed, or on a window for which there's
// currently a modal dialog open. Ignore such calls.
@ -8702,7 +8702,7 @@ nsGlobalWindow::GetFrameElementOuter()
{
MOZ_RELEASE_ASSERT(IsOuterWindow());
if (!mDocShell || mDocShell->GetIsBrowserOrApp()) {
if (!mDocShell || mDocShell->GetIsMozBrowserOrApp()) {
return nullptr;
}

View File

@ -26,7 +26,7 @@ function parentDocShell(docshell) {
function isTopBrowserElement(docShell) {
while (docShell) {
docShell = parentDocShell(docShell);
if (docShell && docShell.isBrowserOrApp) {
if (docShell && docShell.isMozBrowserOrApp) {
return false;
}
}

View File

@ -89,7 +89,7 @@ var CopyPasteAssistent = {
let targetDocShell = currentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation);
if(targetDocShell.isBrowserOrApp) {
if(targetDocShell.isMozBrowserOrApp) {
break;
}
}

View File

@ -867,6 +867,9 @@ TabChild::NotifyTabContextUpdated()
// UNKNOWN_APP_ID for aOwnOrContainingAppId.
if (IsBrowserElement()) {
docShell->SetIsBrowserInsideApp(BrowserOwnerAppId());
// TODO: Wants to call TabContext::IsIsolatedMozBrowserElement() based
// on isolation in principal, which is added in a later patch.
docShell->SetIsInIsolatedMozBrowserElement(IsBrowserElement());
} else {
docShell->SetIsApp(OwnAppId());
}
@ -1110,7 +1113,7 @@ TabChild::ProvideWindow(mozIDOMWindowProxy* aParent,
// isn't a request to open a modal-type window, we're going to create a new
// <iframe mozbrowser/mozapp> and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
bool iframeMoz = (docshell && docshell->GetIsInBrowserOrApp() &&
bool iframeMoz = (docshell && docshell->GetIsInMozBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME)));

View File

@ -1699,7 +1699,7 @@ nsWindowWatcher::CalculateChromeFlags(mozIDOMWindowProxy* aParent,
// Disable CHROME_OPENAS_DIALOG if the window is inside <iframe mozbrowser>.
// It's up to the embedder to interpret what dialog=1 means.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp()) {
if (docshell && docshell->GetIsInMozBrowserOrApp()) {
chromeFlags &= ~nsIWebBrowserChrome::CHROME_OPENAS_DIALOG;
}

View File

@ -887,7 +887,7 @@ nsContentTreeOwner::ProvideWindow(mozIDOMWindowProxy* aParent,
// open a modal-type window, we're going to create a new <iframe mozbrowser>
// and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp() &&
if (docshell && docshell->GetIsInMozBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {