Skip to content

Commit

Permalink
Bug 1271516 - Introducing nsIWebNavigation.setOriginAttributesBeforeL…
Browse files Browse the repository at this point in the history
…oading, r=smaug
  • Loading branch information
bakulf committed Jun 7, 2016
1 parent aa9c6fd commit dd6cbda
Showing 14 changed files with 154 additions and 33 deletions.
32 changes: 26 additions & 6 deletions browser/base/content/browser.js
Original file line number Diff line number Diff line change
@@ -831,6 +831,10 @@ function _loadURIWithFlags(browser, uri, params) {
}
try {
if (!mustChangeProcess) {
if (params.userContextId) {
browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
}

browser.webNavigation.loadURIWithOptions(uri, flags,
referrer, referrerPolicy,
postData, null, null);
@@ -839,13 +843,19 @@ function _loadURIWithFlags(browser, uri, params) {
postData = NetUtil.readInputStreamToString(postData, postData.available());
}

LoadInOtherProcess(browser, {
let loadParams = {
uri: uri,
flags: flags,
referrer: referrer ? referrer.spec : null,
referrerPolicy: referrerPolicy,
postData: postData,
});
postData: postData
}

if (params.userContextId) {
loadParams.userContextId = params.userContextId;
}

LoadInOtherProcess(browser, loadParams);
}
} catch (e) {
// If anything goes wrong when switching remoteness, just switch remoteness
@@ -856,6 +866,11 @@ function _loadURIWithFlags(browser, uri, params) {
if (mustChangeProcess) {
Cu.reportError(e);
gBrowser.updateBrowserRemotenessByURL(browser, uri);

if (params.userContextId) {
browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
}

browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
postData, null, null);
} else {
@@ -1126,6 +1141,7 @@ var gBrowserInit = {
// [3]: postData (nsIInputStream)
// [4]: allowThirdPartyFixup (bool)
// [5]: referrerPolicy (int)
// [6]: userContextId (int)
else if (window.arguments.length >= 3) {
let referrerURI = window.arguments[2];
if (typeof(referrerURI) == "string") {
@@ -1137,8 +1153,10 @@ var gBrowserInit = {
}
let referrerPolicy = (window.arguments[5] != undefined ?
window.arguments[5] : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
let userContextId = (window.arguments[6] != undefined ?
window.arguments[6] : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID);
loadURI(uriToLoad, referrerURI, window.arguments[3] || null,
window.arguments[4] || false, referrerPolicy);
window.arguments[4] || false, referrerPolicy, userContextId);
window.focus();
}
// Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
@@ -1999,13 +2017,15 @@ function BrowserTryToCloseWindow()
window.close(); // WindowIsClosing does all the necessary checks
}

function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy) {
function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
userContextId) {
try {
openLinkIn(uri, "current",
{ referrerURI: referrer,
referrerPolicy: referrerPolicy,
postData: postData,
allowThirdPartyFixup: allowThirdPartyFixup });
allowThirdPartyFixup: allowThirdPartyFixup,
userContextId: userContextId });
} catch (e) {}
}

7 changes: 6 additions & 1 deletion browser/base/content/tab-content.js
Original file line number Diff line number Diff line change
@@ -887,7 +887,12 @@ var UserContextIdNotifier = {
// Just because we cannot change the userContextId from an active docShell,
// we don't need to check DOMContentLoaded again.
this.uninit();
let userContextId = content.document.nodePrincipal.originAttributes.userContextId;

// We use the docShell because content.document can have been loaded before
// setting the originAttributes.
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
let userContextId = loadContext.originAttributes.userContextId;

sendAsyncMessage("Browser:WindowCreated", { userContextId });
}
};
6 changes: 6 additions & 0 deletions browser/base/content/utilityOverlay.js
Original file line number Diff line number Diff line change
@@ -274,12 +274,17 @@ function openLinkIn(url, where, params) {
createInstance(Ci.nsISupportsPRUint32);
referrerPolicySupports.data = aReferrerPolicy;

var userContextIdSupports = Cc["@mozilla.org/supports-PRUint32;1"].
createInstance(Ci.nsISupportsPRUint32);
userContextIdSupports.data = aUserContextId;

sa.AppendElement(wuri);
sa.AppendElement(charset);
sa.AppendElement(referrerURISupports);
sa.AppendElement(aPostData);
sa.AppendElement(allowThirdPartyFixupSupports);
sa.AppendElement(referrerPolicySupports);
sa.AppendElement(userContextIdSupports);

let features = "chrome,dialog=no,all";
if (aIsPrivate) {
@@ -352,6 +357,7 @@ function openLinkIn(url, where, params) {
referrerURI: aNoReferrer ? null : aReferrerURI,
referrerPolicy: aReferrerPolicy,
postData: aPostData,
userContextId: aUserContextId
});
break;
case "tabshifted":
5 changes: 5 additions & 0 deletions browser/components/sessionstore/ContentRestore.jsm
Original file line number Diff line number Diff line change
@@ -204,6 +204,11 @@ ContentRestoreInternal.prototype = {
: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
let postData = loadArguments.postData ?
Utils.makeInputStream(loadArguments.postData) : null;

if (loadArguments.userContextId) {
webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId });
}

webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
referrer, referrerPolicy, postData,
null, null);
61 changes: 50 additions & 11 deletions docshell/base/nsDocShell.cpp
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/Casting.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
@@ -3664,7 +3665,7 @@ nsDocShell::FindItemWithName(const char16_t* aName,
}

void
nsDocShell::AssertOriginAttributesMatchPrivateBrowsing(){
nsDocShell::AssertOriginAttributesMatchPrivateBrowsing() {
MOZ_ASSERT((mOriginAttributes.mPrivateBrowsingId != 0) == mInPrivateBrowsing);
}

@@ -7935,6 +7936,13 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
// mContentViewer->PermitUnload may release |this| docshell.
nsCOMPtr<nsIDocShell> kungFuDeathGrip(this);

if (aPrincipal && !nsContentUtils::IsSystemPrincipal(aPrincipal) &&
mItemType != typeChrome) {
MOZ_ASSERT(ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
BasePrincipal::Cast(aPrincipal)->OriginAttributesRef(),
mOriginAttributes));
}

// Make sure timing is created. But first record whether we had it
// already, so we don't clobber the timing for an in-progress load.
bool hadTiming = mTiming;
@@ -10752,7 +10760,10 @@ nsDocShell::DoURILoad(nsIURI* aURI,
// parent document.
NeckoOriginAttributes neckoAttrs;
neckoAttrs.InheritFromDocShellToNecko(GetOriginAttributes());
loadInfo->SetOriginAttributes(neckoAttrs);
rv = loadInfo->SetOriginAttributes(neckoAttrs);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

if (!isSrcdoc) {
rv = NS_NewChannelInternal(getter_AddRefs(channel),
@@ -14126,28 +14137,57 @@ nsDocShell::GetOriginAttributes(JSContext* aCx,
return NS_OK;
}

void
nsresult
nsDocShell::SetOriginAttributes(const DocShellOriginAttributes& aAttrs)
{
MOZ_ASSERT(mChildList.Length() == 0);
MOZ_ASSERT(mChildList.IsEmpty());
if (!mChildList.IsEmpty()) {
return NS_ERROR_FAILURE;
}

// TODO: Bug 1273058 - mContentViewer should be null when setting origin
// attributes.
if (mContentViewer) {
nsIDocument* doc = mContentViewer->GetDocument();
if (doc) {
nsIURI* uri = doc->GetDocumentURI();
MOZ_ASSERT(uri);
if (uri) {
nsAutoCString uriSpec;
uri->GetSpec(uriSpec);
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
if (!uri) {
return NS_ERROR_FAILURE;
}
nsAutoCString uriSpec;
uri->GetSpec(uriSpec);
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
if (!uriSpec.EqualsLiteral("about:blank")) {
return NS_ERROR_FAILURE;
}
}
}

mOriginAttributes = aAttrs;
SetPrivateBrowsing(mOriginAttributes.mPrivateBrowsingId > 0);
return NS_OK;
}

NS_IMETHODIMP
nsDocShell::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)
{
if (!aOriginAttributes.isObject()) {
return NS_ERROR_INVALID_ARG;
}

AutoJSAPI jsapi;
jsapi.Init(&aOriginAttributes.toObject());
JSContext* cx = jsapi.cx();
if (NS_WARN_IF(!cx)) {
return NS_ERROR_FAILURE;
}

DocShellOriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(cx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}

return SetOriginAttributes(attrs);
}

NS_IMETHODIMP
@@ -14159,8 +14199,7 @@ nsDocShell::SetOriginAttributes(JS::Handle<JS::Value> aOriginAttributes,
return NS_ERROR_INVALID_ARG;
}

SetOriginAttributes(attrs);
return NS_OK;
return SetOriginAttributes(attrs);
}

NS_IMETHODIMP
2 changes: 1 addition & 1 deletion docshell/base/nsDocShell.h
Original file line number Diff line number Diff line change
@@ -277,7 +277,7 @@ class nsDocShell final
return mOriginAttributes;
}

void SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);
nsresult SetOriginAttributes(const mozilla::DocShellOriginAttributes& aAttrs);

void GetInterceptedDocumentId(nsAString& aId)
{
6 changes: 6 additions & 0 deletions docshell/base/nsIWebNavigation.idl
Original file line number Diff line number Diff line change
@@ -355,4 +355,10 @@ interface nsIWebNavigation : nsISupports
* The session history object used by this web navigation instance.
*/
attribute nsISHistory sessionHistory;

/**
* Set an OriginAttributes dictionary in the docShell. This can be done only
* before loading any content.
*/
void setOriginAttributesBeforeLoading(in jsval originAttributes);
};
6 changes: 6 additions & 0 deletions docshell/shistory/nsSHistory.cpp
Original file line number Diff line number Diff line change
@@ -1496,6 +1496,12 @@ nsSHistory::LoadURIWithOptions(const char16_t* aURI,
return NS_OK;
}

NS_IMETHODIMP
nsSHistory::SetOriginAttributesBeforeLoading(JS::HandleValue aOriginAttributes)
{
return NS_OK;
}

NS_IMETHODIMP
nsSHistory::LoadURI(const char16_t* aURI,
uint32_t aLoadFlags,
11 changes: 11 additions & 0 deletions dom/base/ChromeUtils.cpp
Original file line number Diff line number Diff line change
@@ -183,5 +183,16 @@ ChromeUtils::IsOriginAttributesEqual(dom::GlobalObject& aGlobal,
aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
}

/* static */ bool
ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB)
{
return aA.mAppId == aB.mAppId &&
aA.mInIsolatedMozBrowser == aB.mInIsolatedMozBrowser &&
aA.mSignedPkg == aB.mSignedPkg &&
aA.mUserContextId == aB.mUserContextId &&
aA.mPrivateBrowsingId == aB.mPrivateBrowsingId;
}

} // namespace dom
} // namespace mozilla
4 changes: 4 additions & 0 deletions dom/base/ChromeUtils.h
Original file line number Diff line number Diff line change
@@ -87,6 +87,10 @@ class ChromeUtils : public ThreadSafeChromeUtils
IsOriginAttributesEqual(dom::GlobalObject& aGlobal,
const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);

static bool
IsOriginAttributesEqualIgnoringAddonId(const dom::OriginAttributesDictionary& aA,
const dom::OriginAttributesDictionary& aB);
};

} // namespace dom
6 changes: 6 additions & 0 deletions embedding/browser/nsWebBrowser.cpp
Original file line number Diff line number Diff line change
@@ -657,6 +657,12 @@ nsWebBrowser::LoadURIWithOptions(const char16_t* aURI, uint32_t aLoadFlags,
aExtraHeaderStream, aBaseURI);
}

NS_IMETHODIMP
nsWebBrowser::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)
{
return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes);
}

NS_IMETHODIMP
nsWebBrowser::LoadURI(const char16_t* aURI, uint32_t aLoadFlags,
nsIURI* aReferringURI,
26 changes: 12 additions & 14 deletions embedding/components/windowwatcher/nsWindowWatcher.cpp
Original file line number Diff line number Diff line change
@@ -942,6 +942,18 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
nullptr;

if (windowIsNew) {
auto* docShell = static_cast<nsDocShell*>(newDocShell.get());

// If this is not a chrome docShell, we apply originAttributes from the
// subjectPrincipal.
if (subjectPrincipal &&
docShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
DocShellOriginAttributes attrs;
attrs.InheritFromDocToChildDocShell(BasePrincipal::Cast(subjectPrincipal)->OriginAttributesRef());

docShell->SetOriginAttributes(attrs);
}

// Now set the opener principal on the new window. Note that we need to do
// this no matter whether we were opened from JS; if there is nothing on
// the JS stack, just use the principal of our parent window. In those
@@ -1026,20 +1038,6 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
}
}

// If this is a new window, we must set the userContextId from the
// subjectPrincipal.
if (windowIsNew && subjectPrincipal) {
uint32_t userContextId;
rv = subjectPrincipal->GetUserContextId(&userContextId);
NS_ENSURE_SUCCESS(rv, rv);

auto* docShell = static_cast<nsDocShell*>(newDocShell.get());

DocShellOriginAttributes attr = docShell->GetOriginAttributes();
attr.mUserContextId = userContextId;
docShell->SetOriginAttributes(attr);
}

if (isNewToplevelWindow) {
// Notify observers that the window is open and ready.
// The window has not yet started to load a document.
5 changes: 5 additions & 0 deletions toolkit/components/remotebrowserutils/RemoteWebNavigation.js
Original file line number Diff line number Diff line change
@@ -87,6 +87,11 @@ RemoteWebNavigation.prototype = {
baseURI: aBaseURI ? aBaseURI.spec : null,
});
},
setOriginAttributesBeforeLoading: function(aOriginAttributes) {
this._sendMessage("WebNavigation:SetOriginAttributes", {
originAttributes: aOriginAttributes,
});
},
reload: function(aReloadFlags) {
this._sendMessage("WebNavigation:Reload", {flags: aReloadFlags});
},
Loading

0 comments on commit dd6cbda

Please sign in to comment.