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) .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell); .QueryInterface(Ci.nsIDocShell);
if (!docShell.isBrowserOrApp) { if (!docShell.isMozBrowserOrApp) {
return win.top; return win.top;
} }
@ -94,7 +94,7 @@ function getParentWindow(win) {
.getInterface(Ci.nsIWebNavigation) .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell); .QueryInterface(Ci.nsIDocShell);
if (!docShell.isBrowserOrApp) { if (!docShell.isMozBrowserOrApp) {
return win.parent; return win.parent;
} }

View File

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

View File

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

View File

@ -1000,6 +1000,9 @@ protected:
// Are we a regular frame, a browser frame, or an app frame? // Are we a regular frame, a browser frame, or an app frame?
FrameType mFrameType; FrameType mFrameType;
// Whether we are in an isolated mozbrowser frame.
bool mIsInIsolatedMozBrowser;
// We only expect mOwnOrContainingAppId to be something other than // We only expect mOwnOrContainingAppId to be something other than
// UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes // UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes
// inside an app, we'll retrieve the containing app-id by walking up the // 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(); [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>. * Returns true iff the docshell corresponds to an <iframe mozapp>.
*/ */
[infallible] readonly attribute boolean isApp; [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 * 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 * until the hierarchy ends). Return true iff the docshell we stopped on has
* isIsolatedMozBrowserElement == true. * isIsolatedMozBrowserElement == true.
*/ */
[infallible] readonly attribute boolean isInIsolatedMozBrowserElement; [infallible] attribute boolean isInIsolatedMozBrowserElement;
/** /**
* Returns true if this docshell corresponds to an <iframe mozbrowser> or * Returns true if this docshell corresponds to an <iframe mozbrowser> or
* <iframe mozapp>, or if this docshell is contained in an <iframe mozbrowser> * <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 * 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 * a docshell with isMozBrowserOrApp before we hit the end of the hierarchy,
* hierarchy, we return true. Otherwise, we return false. * 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. * 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; return NS_ERROR_NOT_IMPLEMENTED;
} }
if (ourDocshell->GetIsBrowserElement() != if (ourDocshell->GetIsIsolatedMozBrowserElement() !=
otherDocshell->GetIsBrowserElement() || otherDocshell->GetIsIsolatedMozBrowserElement() ||
ourDocshell->GetIsApp() != otherDocshell->GetIsApp()) { ourDocshell->GetIsApp() != otherDocshell->GetIsApp()) {
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
@ -1916,6 +1916,7 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ERROR_FAILURE); NS_ERROR_FAILURE);
} }
mDocShell->SetIsBrowserInsideApp(containingAppId); mDocShell->SetIsBrowserInsideApp(containingAppId);
mDocShell->SetIsInIsolatedMozBrowserElement(OwnerIsIsolatedMozBrowserFrame());
} }
if (OwnerIsMozBrowserOrAppFrame()) { if (OwnerIsMozBrowserOrAppFrame()) {

View File

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

View File

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

View File

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

View File

@ -867,6 +867,9 @@ TabChild::NotifyTabContextUpdated()
// UNKNOWN_APP_ID for aOwnOrContainingAppId. // UNKNOWN_APP_ID for aOwnOrContainingAppId.
if (IsBrowserElement()) { if (IsBrowserElement()) {
docShell->SetIsBrowserInsideApp(BrowserOwnerAppId()); 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 { } else {
docShell->SetIsApp(OwnAppId()); 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 // 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. // <iframe mozbrowser/mozapp> and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent); nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
bool iframeMoz = (docshell && docshell->GetIsInBrowserOrApp() && bool iframeMoz = (docshell && docshell->GetIsInMozBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL | !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))); 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>. // Disable CHROME_OPENAS_DIALOG if the window is inside <iframe mozbrowser>.
// It's up to the embedder to interpret what dialog=1 means. // It's up to the embedder to interpret what dialog=1 means.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent); nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp()) { if (docshell && docshell->GetIsInMozBrowserOrApp()) {
chromeFlags &= ~nsIWebBrowserChrome::CHROME_OPENAS_DIALOG; 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> // open a modal-type window, we're going to create a new <iframe mozbrowser>
// and return its window here. // and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent); nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp() && if (docshell && docshell->GetIsInMozBrowserOrApp() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL | !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) { nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {