Bug 1227861 - Add OriginAttributes getter/setter into nsIDocShell. r=smaug, sicking

This commit is contained in:
Yoshi Huang 2016-02-16 15:04:14 +08:00
parent 3a8e10a239
commit ce8e69a274
9 changed files with 132 additions and 213 deletions

View File

@ -264,7 +264,9 @@ var SessionHistoryInternal = {
let history = webNavigation.sessionHistory;
if ("userContextId" in tabData) {
docShell.setUserContextId(tabData.userContextId);
let attrs = docShell.getOriginAttributes();
attrs.userContextId = tabData.userContextId;
docShell.setOriginAttributes(attrs);
}
if (history.count > 0) {

View File

@ -805,10 +805,8 @@ nsDocShell::nsDocShell()
, mHasLoadedNonBlankURI(false)
, mDefaultLoadFlags(nsIRequest::LOAD_NORMAL)
, mBlankTiming(false)
, mFrameType(eFrameTypeRegular)
, mFrameType(FRAME_TYPE_REGULAR)
, mIsInIsolatedMozBrowser(false)
, mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
, mUserContextId(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID)
, mParentCharsetSource(0)
, mJSRunToCompletionDepth(0)
{
@ -4009,7 +4007,6 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild)
}
aChild->SetTreeOwner(mTreeOwner);
childDocShell->SetUserContextId(mUserContextId);
childDocShell->SetIsInIsolatedMozBrowserElement(mIsInIsolatedMozBrowser);
nsCOMPtr<nsIDocShell> childAsDocShell(do_QueryInterface(aChild));
@ -9551,7 +9548,7 @@ nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
nsIPrincipal** aResult)
{
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aReferrer);
attrs.InheritFromDocShellToDoc(mOriginAttributes, aReferrer);
nsCOMPtr<nsIPrincipal> prin =
BasePrincipal::CreateCodebasePrincipal(aReferrer, attrs);
prin.forget(aResult);
@ -13850,80 +13847,38 @@ nsDocShell::GetCanExecuteScripts(bool* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsApp(uint32_t aOwnAppId)
/* [infallible] */ NS_IMETHODIMP
nsDocShell::SetFrameType(uint32_t aFrameType)
{
mOwnOrContainingAppId = aOwnAppId;
if (aOwnAppId != nsIScriptSecurityManager::NO_APP_ID &&
aOwnAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
mFrameType = eFrameTypeApp;
} else {
mFrameType = eFrameTypeRegular;
}
mFrameType = aFrameType;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsBrowserInsideApp(uint32_t aContainingAppId)
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetFrameType(uint32_t* aFrameType)
{
mOwnOrContainingAppId = aContainingAppId;
mFrameType = eFrameTypeBrowser;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsSignedPackage(const nsAString& aSignedPkg)
{
mSignedPkg = aSignedPkg;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetUserContextId(uint32_t aUserContextId)
{
mUserContextId = aUserContextId;
nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
while (iter.HasMore()) {
nsCOMPtr<nsIDocShell> docshell = do_QueryObject(iter.GetNext());
if (!docshell || docshell->ItemType() != ItemType()) {
continue;
}
docshell->SetUserContextId(aUserContextId);
}
*aFrameType = mFrameType;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp)
{
*aIsApp = (mFrameType == eFrameTypeApp);
*aIsApp = (mFrameType == FRAME_TYPE_APP);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsMozBrowserOrApp(bool* aIsMozBrowserOrApp)
{
switch (mFrameType) {
case eFrameTypeRegular:
*aIsMozBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsMozBrowserOrApp = true;
break;
}
*aIsMozBrowserOrApp = (mFrameType != FRAME_TYPE_REGULAR);
return NS_OK;
}
nsDocShell::FrameType
uint32_t
nsDocShell::GetInheritedFrameType()
{
if (mFrameType != eFrameTypeRegular) {
if (mFrameType != FRAME_TYPE_REGULAR) {
return mFrameType;
}
@ -13932,7 +13887,7 @@ nsDocShell::GetInheritedFrameType()
nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
if (!parent) {
return eFrameTypeRegular;
return FRAME_TYPE_REGULAR;
}
return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
@ -13941,7 +13896,7 @@ nsDocShell::GetInheritedFrameType()
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsIsolatedMozBrowserElement(bool* aIsIsolatedMozBrowserElement)
{
bool result = mFrameType == eFrameTypeBrowser && mIsInIsolatedMozBrowser;
bool result = mFrameType == FRAME_TYPE_BROWSER && mIsInIsolatedMozBrowser;
*aIsIsolatedMozBrowserElement = result;
return NS_OK;
}
@ -13950,9 +13905,9 @@ nsDocShell::GetIsIsolatedMozBrowserElement(bool* aIsIsolatedMozBrowserElement)
nsDocShell::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
{
MOZ_ASSERT(!mIsInIsolatedMozBrowser ||
(GetInheritedFrameType() == eFrameTypeBrowser),
(GetInheritedFrameType() == FRAME_TYPE_BROWSER),
"Isolated mozbrowser should only be true inside browser frames");
bool result = (GetInheritedFrameType() == eFrameTypeBrowser) &&
bool result = (GetInheritedFrameType() == FRAME_TYPE_BROWSER) &&
mIsInIsolatedMozBrowser;
*aIsInIsolatedMozBrowserElement = result;
return NS_OK;
@ -13968,24 +13923,15 @@ nsDocShell::SetIsInIsolatedMozBrowserElement(bool aIsInIsolatedMozBrowserElement
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInMozBrowserOrApp(bool* aIsInMozBrowserOrApp)
{
switch (GetInheritedFrameType()) {
case eFrameTypeRegular:
*aIsInMozBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsInMozBrowserOrApp = true;
break;
}
*aIsInMozBrowserOrApp = (GetInheritedFrameType() != FRAME_TYPE_REGULAR);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetAppId(uint32_t* aAppId)
{
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
*aAppId = mOwnOrContainingAppId;
if (mOriginAttributes.mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
*aAppId = mOriginAttributes.mAppId;
return NS_OK;
}
@ -14000,42 +13946,45 @@ nsDocShell::GetAppId(uint32_t* aAppId)
return parent->GetAppId(aAppId);
}
DocShellOriginAttributes
nsDocShell::GetOriginAttributes()
{
DocShellOriginAttributes attrs;
RefPtr<nsDocShell> parent = GetParentDocshell();
if (parent) {
nsCOMPtr<nsIPrincipal> parentPrin = parent->GetDocument()->NodePrincipal();
PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
attrs.InheritFromDocToChildDocShell(poa);
} else {
// This is the topmost docshell, so we get the mSignedPkg attribute if it is
// set before.
attrs.mSignedPkg = mSignedPkg;
}
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
attrs.mAppId = mOwnOrContainingAppId;
}
attrs.mUserContextId = mUserContextId;
attrs.mInIsolatedMozBrowser = mIsInIsolatedMozBrowser;
return attrs;
}
// Implements nsILoadContext.originAttributes
NS_IMETHODIMP
nsDocShell::GetOriginAttributes(JS::MutableHandle<JS::Value> aVal)
{
JSContext* cx = nsContentUtils::GetCurrentJSContext();
MOZ_ASSERT(cx);
bool ok = ToJSValue(cx, GetOriginAttributes(), aVal);
return GetOriginAttributes(cx, aVal);
}
// Implements nsIDocShell.GetOriginAttributes()
NS_IMETHODIMP
nsDocShell::GetOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal)
{
bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
return NS_OK;
}
void
nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
{
mOriginAttributes = aAttrs;
}
NS_IMETHODIMP
nsDocShell::SetOriginAttributes(JS::Handle<JS::Value> aOriginAttributes,
JSContext* aCx)
{
DocShellOriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
SetOriginAttributes(attrs);
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetAppManifestURL(nsAString& aAppManifestURL)
{
@ -14226,7 +14175,7 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
if (aIsNonSubresourceRequest) {
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), aURI);
attrs.InheritFromDocShellToDoc(mOriginAttributes, aURI);
*aShouldIntercept = swm->IsAvailable(attrs, aURI);
return NS_OK;
}
@ -14280,7 +14229,7 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
NS_ENSURE_SUCCESS(rv, rv);
PrincipalOriginAttributes attrs;
attrs.InheritFromDocShellToDoc(GetOriginAttributes(), uri);
attrs.InheritFromDocShellToDoc(mOriginAttributes, uri);
ErrorResult error;
swm->DispatchFetchEvent(attrs, doc, mInterceptedDocumentId, aChannel,

View File

@ -270,7 +270,13 @@ public:
}
bool InFrameSwap();
mozilla::DocShellOriginAttributes GetOriginAttributes();
const mozilla::DocShellOriginAttributes&
GetOriginAttributes()
{
return mOriginAttributes;
}
void SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);
void GetInterceptedDocumentId(nsAString& aId)
{
@ -764,21 +770,14 @@ protected:
nsresult CreatePrincipalFromReferrer(nsIURI* aReferrer,
nsIPrincipal** aResult);
enum FrameType
{
eFrameTypeRegular,
eFrameTypeBrowser,
eFrameTypeApp
};
static const nsCString FrameTypeToString(FrameType aFrameType)
static const nsCString FrameTypeToString(uint32_t aFrameType)
{
switch (aFrameType) {
case FrameType::eFrameTypeApp:
case FRAME_TYPE_APP:
return NS_LITERAL_CSTRING("app");
case FrameType::eFrameTypeBrowser:
case FRAME_TYPE_BROWSER:
return NS_LITERAL_CSTRING("browser");
case FrameType::eFrameTypeRegular:
case FRAME_TYPE_REGULAR:
return NS_LITERAL_CSTRING("regular");
default:
NS_ERROR("Unknown frame type");
@ -786,7 +785,7 @@ protected:
}
}
FrameType GetInheritedFrameType();
uint32_t GetInheritedFrameType();
bool HasUnloadedParent();
@ -999,32 +998,15 @@ protected:
bool mBlankTiming;
// Are we a regular frame, a browser frame, or an app frame?
FrameType mFrameType;
uint32_t 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
// docshell hierarchy.
//
// (This needs to be the docshell's own /or containing/ app id because the
// containing app frame might be in another process, in which case we won't
// find it by walking up the docshell hierarchy.)
uint32_t mOwnOrContainingAppId;
// userContextId signifying which container we are in
uint32_t mUserContextId;
nsString mPaymentRequestId;
nsString GetInheritedPaymentRequestId();
// The packageId for a signed packaged iff this docShell is created
// for a signed package.
nsString mSignedPkg;
nsString mInterceptedDocumentId;
private:
@ -1037,6 +1019,7 @@ private:
nsTObserverArray<nsWeakPtr> mScrollObservers;
nsCString mOriginalUriString;
nsWeakPtr mOpener;
mozilla::DocShellOriginAttributes mOriginAttributes;
// A depth count of how many times NotifyRunToCompletionStart
// has been called without a matching NotifyRunToCompletionStop.

View File

@ -768,6 +768,15 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] readonly attribute boolean isApp;
/**
* The type of iframe that this docshell lives.
*/
const unsigned long FRAME_TYPE_REGULAR = 0;
const unsigned long FRAME_TYPE_BROWSER = 1;
const unsigned long FRAME_TYPE_APP = 2;
[infallible] attribute unsigned long frameType;
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser> or
* <iframe mozapp>. <xul:browser> returns false here.
@ -813,48 +822,14 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] readonly attribute boolean isInMozBrowserOrApp;
/**
* Indicate that this docshell corresponds to an app with the given app id.
*
* You may pass NO_APP_ID or UNKNOWN_APP_ID for containingAppId. If you
* pass NO_APP_ID, then this docshell will return NO_APP_ID for appId. If
* you pass UNKNOWN_APP_ID, then this docshell will search its hiearchy for
* an app frame and use that frame's appId.
*
* You can call this method more than once, but there's no guarantee that
* other components will update their view of the world if you change a
* docshell's app id, so tread lightly.
*
* If you call this method after calling setIsBrowserInsideApp, this
* docshell will forget the fact that it was a browser.
*/
void setIsApp(in unsigned long ownAppId);
/**
* Indicate that this docshell corresponds to a browser inside an app with
* the given ID. As with setIsApp, you may pass NO_APP_ID or
* UNKNOWN_APP_ID.
*
* As with setIsApp, you may call this more than once, but it's kind of a
* hack, so be careful.
*/
void setIsBrowserInsideApp(in unsigned long containingAppId);
/**
* Indicate that this docshell corresponds to a signed package with
* the given packageId.
*/
void setIsSignedPackage(in AString packageId);
/**
* Returns the id of the app associated with this docshell. If this docshell
* is an <iframe mozbrowser> inside an <iframe mozapp>, we return the app's
* appId.
*
* We compute this value by walking up the docshell hierarchy until we find a
* docshell on which setIsApp(x) or setIsBrowserInsideApp(x) was called
* (ignoring those docshells where x == UNKNOWN_APP_ID). We return the app
* id x.
* docshell on which origin attributes was set. (ignoring those docshells
* where x == UNKNOWN_APP_ID). We return the app id x.
*
* If we don't find a docshell with an associated app id in our hierarchy, we
* return NO_APP_ID. We never return UNKNOWN_APP_ID.
@ -1105,11 +1080,15 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* Sets/gets the current scroll restoration mode.
* @see https://html.spec.whatwg.org/#dom-history-scroll-restoration
*/
*/
attribute boolean currentScrollRestorationIsManual;
/*
* Sets the user context ID for this docshell.
/**
* Setter and getter for the origin attributes living on this docshell.
*/
void setUserContextId(in unsigned long aUserContextId);
[implicit_jscontext]
jsval getOriginAttributes();
[implicit_jscontext]
void setOriginAttributes(in jsval aAttrs);
};

View File

@ -1848,26 +1848,6 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell->SetName(frameName);
}
//Grab the userContextId from owner if XUL
nsAutoString userContextIdStr;
if (namespaceID == kNameSpaceID_XUL) {
if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usercontextid)) {
mOwnerContent->GetAttr(kNameSpaceID_None,
nsGkAtoms::usercontextid,
userContextIdStr);
}
}
if (!userContextIdStr.IsEmpty()) {
nsresult rv;
uint32_t userContextId =
static_cast<uint32_t>(userContextIdStr.ToInteger(&rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDocShell->SetUserContextId(userContextId);
NS_ENSURE_SUCCESS(rv, rv);
}
// Inform our docShell that it has a new child.
// Note: This logic duplicates a lot of logic in
// nsSubDocumentFrame::AttributeChanged. We should fix that.
@ -1938,6 +1918,14 @@ nsFrameLoader::MaybeCreateDocShell()
webNav->SetSessionHistory(sessionHistory);
}
DocShellOriginAttributes attrs;
if (!mOwnerContent->IsXULElement(nsGkAtoms::browser)) {
nsCOMPtr<nsIPrincipal> parentPrin = doc->NodePrincipal();
PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
attrs.InheritFromDocToChildDocShell(poa);
}
if (OwnerIsAppFrame()) {
// You can't be both an app and a browser frame.
MOZ_ASSERT(!OwnerIsMozBrowserFrame());
@ -1949,7 +1937,8 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ENSURE_SUCCESS(ownApp->GetLocalId(&ownAppId), NS_ERROR_FAILURE);
}
mDocShell->SetIsApp(ownAppId);
attrs.mAppId = ownAppId;
mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_APP);
}
if (OwnerIsMozBrowserFrame()) {
@ -1962,10 +1951,25 @@ nsFrameLoader::MaybeCreateDocShell()
NS_ENSURE_SUCCESS(containingApp->GetLocalId(&containingAppId),
NS_ERROR_FAILURE);
}
mDocShell->SetIsBrowserInsideApp(containingAppId);
attrs.mAppId = containingAppId;
attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
mDocShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
mDocShell->SetIsInIsolatedMozBrowserElement(OwnerIsIsolatedMozBrowserFrame());
}
// Grab the userContextId from owner if XUL
nsAutoString userContextIdStr;
if ((namespaceID == kNameSpaceID_XUL) &&
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usercontextid, userContextIdStr) &&
!userContextIdStr.IsEmpty()) {
nsresult rv;
attrs.mUserContextId = userContextIdStr.ToInteger(&rv);
NS_ENSURE_SUCCESS(rv, rv);
}
nsDocShell::Cast(mDocShell)->SetOriginAttributes(attrs);
if (OwnerIsMozBrowserOrAppFrame()) {
// For inproc frames, set the docshell properties.
nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);

View File

@ -859,23 +859,22 @@ TabChild::Init()
void
TabChild::NotifyTabContextUpdated()
{
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
MOZ_ASSERT(docShell);
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
MOZ_ASSERT(docShell);
if (docShell) {
// nsDocShell will do the right thing if we pass NO_APP_ID or
// UNKNOWN_APP_ID for aOwnOrContainingAppId.
if (IsMozBrowserElement()) {
docShell->SetIsBrowserInsideApp(BrowserOwnerAppId());
docShell->SetIsInIsolatedMozBrowserElement(IsIsolatedMozBrowserElement());
} else {
docShell->SetIsApp(OwnAppId());
}
if (!docShell) {
return;
}
OriginAttributes attrs = OriginAttributesRef();
docShell->SetIsSignedPackage(attrs.mSignedPkg);
docShell->SetUserContextId(attrs.mUserContextId);
}
if (IsMozBrowserElement()) {
docShell->SetIsInIsolatedMozBrowserElement(IsIsolatedMozBrowserElement());
}
docShell->SetFrameType(IsMozBrowserElement() ?
nsIDocShell::FRAME_TYPE_BROWSER :
HasOwnApp() ?
nsIDocShell::FRAME_TYPE_APP :
nsIDocShell::FRAME_TYPE_REGULAR);
nsDocShell::Cast(docShell)->SetOriginAttributes(OriginAttributesRef());
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)

View File

@ -3379,7 +3379,8 @@ Tab.prototype = {
let manifest = appsService.getAppByManifestURL(BrowserApp.manifestUrl);
if (manifest) {
let app = manifest.QueryInterface(Ci.mozIApplication);
this.browser.docShell.setIsApp(app.localId);
this.browser.docShell.frameType = Ci.nsIDocShell.FRAME_TYPE_APP;
this.browser.docShell.setOriginAttributes({appId: app.localId});
}
}

View File

@ -195,7 +195,8 @@ this.startup = function(window) {
let appBrowser = window.document.getElementById("content");
// Set the principal to the correct appID and launch the application.
appBrowser.docShell.setIsApp(WebappRT.appID);
appBrowser.docShell.frameType = Ci.nsIDocShell.FRAME_TYPE_APP;
appBrowser.docShell.setOriginAttributes({appId: WebappRT.appID});
appBrowser.setAttribute("src", WebappRT.launchURI);
if (appData.manifest.fullscreen) {

View File

@ -110,7 +110,8 @@ function onDOMContentLoaded() {
// Set the principal to the correct app ID. Since this is a subsequent
// window, we know that WebappRT.configPromise has been resolved, so we
// don't have to yield to it before accessing WebappRT.appID.
gAppBrowser.docShell.setIsApp(WebappRT.appID);
gAppBrowser.docShell.frameType = Ci.nsIDocShell.FRAME_TYPE_APP;
gAppBrowser.docShell.setOriginAttributes({appId: WebappRT.appID});
}
}
window.addEventListener("DOMContentLoaded", onDOMContentLoaded, false);