Bug 1357589: Part 1 - Use the correct default remote type for content-created tabs/windows. r=mconley r=mystor

When creating new windows/tabs from the content process, we currently choose
the default remote type based on the referrer URI, rather than the actual
remote type of the opener. While this generally works, it fails when opening
windows from URLs (particularly in iframes) which are opened in process types
other than their default process type, since the initial about:blank load gets
redirected to a new process before the child process has a chance to load its
actual target URI.

Using the actual remote type of the child opening the window fixes this
problem for URLs which are capable of being loaded into the child's process
type.

MozReview-Commit-ID: ClxVGxu52Lf

--HG--
extra : rebase_source : 3a029d207dac0b08eb7c7ce7737adfd9c1c96892
This commit is contained in:
Kris Maglione 2017-08-16 15:11:59 -07:00
Родитель 729a622270
Коммит 08ac1de819
6 изменённых файлов: 63 добавлений и 19 удалений

Просмотреть файл

@ -5195,8 +5195,8 @@ nsBrowserAccess.prototype = {
_openURIInNewTab(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
aIsExternal, aForceNotRemote = false,
aUserContextId = Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
aOpener = null, aTriggeringPrincipal = null,
aNextTabParentId = 0, aName = "") {
aOpenerWindow = null, aOpenerBrowser = null,
aTriggeringPrincipal = null, aNextTabParentId = 0, aName = "") {
let win, needToFocusWin;
// try the current window. if we're in a popup, fall back on the most recent browser window
@ -5228,7 +5228,8 @@ nsBrowserAccess.prototype = {
fromExternal: aIsExternal,
inBackground: loadInBackground,
forceNotRemote: aForceNotRemote,
opener: aOpener,
opener: aOpenerWindow,
openerBrowser: aOpenerBrowser,
nextTabParentId: aNextTabParentId,
name: aName,
});
@ -5322,7 +5323,7 @@ nsBrowserAccess.prototype = {
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
isPrivate, isExternal,
forceNotRemote, userContextId,
openerWindow, aTriggeringPrincipal);
openerWindow, null, aTriggeringPrincipal);
if (browser)
newWindow = browser.contentWindow;
break;
@ -5364,7 +5365,7 @@ nsBrowserAccess.prototype = {
aParams.referrerPolicy,
aParams.isPrivate,
isExternal, false,
userContextId, null,
userContextId, null, aParams.openerBrowser,
aParams.triggeringPrincipal,
aNextTabParentId, aName);
if (browser)

Просмотреть файл

@ -1613,6 +1613,7 @@
var aSameProcessAsFrameLoader;
var aOriginPrincipal;
var aOpener;
var aOpenerBrowser;
var aIsPrerendered;
var aCreateLazyBrowser;
var aNextTabParentId;
@ -1640,6 +1641,7 @@
aSameProcessAsFrameLoader = params.sameProcessAsFrameLoader;
aOriginPrincipal = params.originPrincipal;
aOpener = params.opener;
aOpenerBrowser = params.openerBrowser;
aIsPrerendered = params.isPrerendered;
aCreateLazyBrowser = params.createLazyBrowser;
aNextTabParentId = params.nextTabParentId;
@ -1671,6 +1673,7 @@
originPrincipal: aOriginPrincipal,
sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
opener: aOpener,
openerBrowser: aOpenerBrowser,
isPrerendered: aIsPrerendered,
nextTabParentId: aNextTabParentId,
focusUrlBar: aFocusUrlBar,
@ -2107,11 +2110,11 @@
b.setAttribute("remote", "true");
}
if (aParams.opener) {
if (aParams.openerWindow) {
if (aParams.remoteType) {
throw new Error("Cannot set opener window on a remote browser!");
}
b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.opener);
b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.openerWindow);
}
if (!aParams.isPreloadBrowser && this.hasAttribute("autocompletepopup")) {
@ -2132,6 +2135,9 @@
b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
if (aParams.nextTabParentId) {
if (!aParams.remoteType) {
throw new Error("Cannot have nextTabParentId without a remoteType");
}
// Gecko is going to read this attribute and use it.
b.setAttribute("nextTabParentId", aParams.nextTabParentId.toString());
}
@ -2400,6 +2406,7 @@
var aOriginPrincipal;
var aDisallowInheritPrincipal;
var aOpener;
var aOpenerBrowser;
var aIsPrerendered;
var aCreateLazyBrowser;
var aSkipBackgroundNotify;
@ -2431,6 +2438,7 @@
aOriginPrincipal = params.originPrincipal;
aDisallowInheritPrincipal = params.disallowInheritPrincipal;
aOpener = params.opener;
aOpenerBrowser = params.openerBrowser;
aIsPrerendered = params.isPrerendered;
aCreateLazyBrowser = params.createLazyBrowser;
aSkipBackgroundNotify = params.skipBackgroundNotify;
@ -2526,6 +2534,12 @@
this.tabContainer.updateVisibility();
// If we don't have a preferred remote type, and we have a remote
// opener, use the opener's remote type.
if (!aPreferredRemoteType && aOpenerBrowser) {
aPreferredRemoteType = aOpenerBrowser.remoteType;
}
// If URI is about:blank and we don't have a preferred remote type,
// then we need to use the referrer, if we have one, to get the
// correct remote type for the new tab.
@ -2562,7 +2576,7 @@
uriIsAboutBlank,
userContextId: aUserContextId,
sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
opener: aOpener,
openerWindow: aOpener,
isPrerendered: aIsPrerendered,
nextTabParentId: aNextTabParentId,
name: aName });

Просмотреть файл

@ -8,10 +8,20 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/dom/ToJSValue.h"
NS_IMPL_ISUPPORTS(nsOpenURIInFrameParams, nsIOpenURIInFrameParams)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsOpenURIInFrameParams)
NS_INTERFACE_MAP_ENTRY(nsIOpenURIInFrameParams)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
nsOpenURIInFrameParams::nsOpenURIInFrameParams(const mozilla::OriginAttributes& aOriginAttributes)
NS_IMPL_CYCLE_COLLECTION(nsOpenURIInFrameParams, mOpenerBrowser)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsOpenURIInFrameParams)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsOpenURIInFrameParams)
nsOpenURIInFrameParams::nsOpenURIInFrameParams(const mozilla::OriginAttributes& aOriginAttributes,
nsIFrameLoaderOwner* aOpener)
: mOpenerOriginAttributes(aOriginAttributes)
, mOpenerBrowser(aOpener)
{
}
@ -55,6 +65,14 @@ nsOpenURIInFrameParams::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipa
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::GetOpenerBrowser(nsIFrameLoaderOwner** aOpenerBrowser)
{
nsCOMPtr<nsIFrameLoaderOwner> owner = mOpenerBrowser;
owner.forget(aOpenerBrowser);
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::GetOpenerOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue)

Просмотреть файл

@ -5,7 +5,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/BasePrincipal.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIBrowserDOMWindow.h"
#include "nsIFrameLoader.h"
#include "nsString.h"
namespace mozilla {
@ -15,15 +17,18 @@ class OriginAttributes;
class nsOpenURIInFrameParams final : public nsIOpenURIInFrameParams
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsOpenURIInFrameParams)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIOPENURIINFRAMEPARAMS
explicit nsOpenURIInFrameParams(const mozilla::OriginAttributes& aOriginAttributes);
explicit nsOpenURIInFrameParams(const mozilla::OriginAttributes& aOriginAttributes,
nsIFrameLoaderOwner* aOpener);
private:
~nsOpenURIInFrameParams();
mozilla::OriginAttributes mOpenerOriginAttributes;
nsCOMPtr<nsIFrameLoaderOwner> mOpenerBrowser;
nsString mReferrer;
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
};

Просмотреть файл

@ -18,6 +18,10 @@ interface nsIOpenURIInFrameParams : nsISupports
readonly attribute boolean isPrivate;
attribute nsIPrincipal triggeringPrincipal;
// The browser or frame element in the parent process which holds the
// opener window in the content process. May be null.
readonly attribute nsIFrameLoaderOwner openerBrowser;
[implicit_jscontext]
readonly attribute jsval openerOriginAttributes;
};

Просмотреть файл

@ -1112,6 +1112,12 @@ ContentParent::CreateBrowser(const TabContext& aContext,
return nullptr;
}
nsAutoString remoteType;
if (!aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
remoteType)) {
remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
}
if (aNextTabParentId) {
if (TabParent* parent =
sNextTabParents.GetAndRemove(aNextTabParentId).valueOr(nullptr)) {
@ -1132,12 +1138,6 @@ ContentParent::CreateBrowser(const TabContext& aContext,
openerTabId = TabParent::GetTabIdFrom(docShell);
}
nsAutoString remoteType;
if (!aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
remoteType)) {
remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
}
bool isPreloadBrowser = false;
nsAutoString isPreloadBrowserStr;
if (aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::isPreloadBrowser,
@ -4595,8 +4595,10 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
return IPC_OK();
}
nsCOMPtr<nsIFrameLoaderOwner> opener = do_QueryInterface(frame);
nsCOMPtr<nsIOpenURIInFrameParams> params =
new nsOpenURIInFrameParams(openerOriginAttributes);
new nsOpenURIInFrameParams(openerOriginAttributes, opener);
params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal");
params->SetTriggeringPrincipal(aTriggeringPrincipal);