mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1114299 - Be more strict about which window chromeFlags we compute from content. r=smaug
We don't ever want to accept "private", "non-private", "remote" or "non-remote" from the content process. We only let the parent decide when to open those types of windows. --HG-- extra : commitid : 9MGeXNdb9US extra : rebase_source : 41a4d9785bd667b84c255eda0ac7fedf44733736 extra : histedit_source : 698c707b68c60108e0631b775a98fb4e241c009b
This commit is contained in:
parent
8461bab676
commit
c86643f748
@ -9837,13 +9837,9 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
}
|
||||
nsAutoString features;
|
||||
if (mInPrivateBrowsing) {
|
||||
features.AssignLiteral("private");
|
||||
}
|
||||
rv = win->OpenNoNavigate(NS_ConvertUTF8toUTF16(spec),
|
||||
name, // window name
|
||||
features,
|
||||
EmptyString(), // Features
|
||||
getter_AddRefs(newWin));
|
||||
|
||||
// In some cases the Open call doesn't actually result in a new
|
||||
|
@ -1597,10 +1597,6 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
|
||||
nsAutoCString baseURIString;
|
||||
baseURI->GetSpec(baseURIString);
|
||||
|
||||
// We can assume that if content is requesting to open a window from a remote
|
||||
// tab, then we want to enforce that the new window is also a remote tab.
|
||||
features.AppendLiteral(",remote");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (!SendCreateWindow(newChild,
|
||||
|
@ -622,6 +622,13 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
|
||||
// We always expect to open a new window here. If we don't, it's an error.
|
||||
*aWindowIsNew = true;
|
||||
|
||||
// The content process should never be in charge of computing whether or
|
||||
// not a window should be private or remote - the parent will do that.
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
|
||||
|
||||
if (NS_WARN_IF(IsBrowserOrApp()))
|
||||
return false;
|
||||
|
||||
@ -735,9 +742,11 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
|
||||
|
||||
AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||
|
||||
const char* features = aFeatures.Length() ? aFeatures.get() : nullptr;
|
||||
|
||||
*aResult = pwwatch->OpenWindow2(parent, finalURIString.get(),
|
||||
NS_ConvertUTF16toUTF8(aName).get(),
|
||||
aFeatures.get(), aCalledFromJS,
|
||||
features, aCalledFromJS,
|
||||
false, false, this, nullptr, getter_AddRefs(window));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
||||
|
@ -562,7 +562,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
||||
// security checks.
|
||||
chromeFlags = CalculateChromeFlags(aParent, features.get(), featuresSpecified,
|
||||
aDialog, uriToLoadIsChrome,
|
||||
hasChromeParent, openedFromRemoteTab);
|
||||
hasChromeParent, aCalledFromJS,
|
||||
openedFromRemoteTab);
|
||||
|
||||
// If we are opening a window from a remote browser, the resulting window
|
||||
// should also be remote.
|
||||
@ -1466,8 +1467,8 @@ nsWindowWatcher::URIfromURL(const char* aURL,
|
||||
|
||||
#define NS_CALCULATE_CHROME_FLAG_FOR(feature, flag) \
|
||||
prefBranch->GetBoolPref(feature, &forceEnable); \
|
||||
if (forceEnable && !(aDialog && isCallerChrome) && \
|
||||
!(isCallerChrome && aHasChromeParent) && !aChromeURL) { \
|
||||
if (forceEnable && !(aDialog && !openedFromContentScript) && \
|
||||
!(!openedFromContentScript && aHasChromeParent) && !aChromeURL) { \
|
||||
chromeFlags |= flag; \
|
||||
} else { \
|
||||
chromeFlags |= \
|
||||
@ -1491,26 +1492,30 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent,
|
||||
bool aDialog,
|
||||
bool aChromeURL,
|
||||
bool aHasChromeParent,
|
||||
bool aCalledFromJS,
|
||||
bool aOpenedFromRemoteTab)
|
||||
{
|
||||
const bool inContentProcess = XRE_IsContentProcess();
|
||||
uint32_t chromeFlags = 0;
|
||||
bool isCallerChrome =
|
||||
nsContentUtils::IsCallerChrome() && !aOpenedFromRemoteTab;
|
||||
|
||||
bool onlyPrivateFlag = aFeaturesSpecified && aFeatures && isCallerChrome &&
|
||||
nsCRT::strcasecmp(aFeatures, "private") == 0;
|
||||
if (!aFeaturesSpecified || !aFeatures || onlyPrivateFlag) {
|
||||
if (!aFeaturesSpecified || !aFeatures) {
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_ALL;
|
||||
if (aDialog) {
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
|
||||
}
|
||||
if (onlyPrivateFlag) {
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
||||
|
||||
if (inContentProcess) {
|
||||
return chromeFlags;
|
||||
}
|
||||
return chromeFlags;
|
||||
} else {
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_BORDERS;
|
||||
}
|
||||
|
||||
bool openedFromContentScript =
|
||||
aOpenedFromRemoteTab ? aCalledFromJS
|
||||
: !nsContentUtils::IsCallerChrome();
|
||||
|
||||
/* This function has become complicated since browser windows and
|
||||
dialogs diverged. The difference is, browser windows assume all
|
||||
chrome not explicitly mentioned is off, if the features string
|
||||
@ -1520,30 +1525,32 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent,
|
||||
in the standards-compliant window.(normal)open. */
|
||||
|
||||
bool presenceFlag = false;
|
||||
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_BORDERS;
|
||||
if (aDialog && WinHasOption(aFeatures, "all", 0, &presenceFlag)) {
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_ALL;
|
||||
}
|
||||
|
||||
/* Next, allow explicitly named options to override the initial settings */
|
||||
|
||||
// Determine whether the window is a private browsing window
|
||||
if (isCallerChrome) {
|
||||
if (!inContentProcess && !openedFromContentScript) {
|
||||
// Determine whether the window is a private browsing window
|
||||
chromeFlags |= WinHasOption(aFeatures, "private", 0, &presenceFlag) ?
|
||||
nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "non-private", 0, &presenceFlag) ?
|
||||
nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW : 0;
|
||||
}
|
||||
|
||||
// Determine whether the window should have remote tabs.
|
||||
if (isCallerChrome || aOpenedFromRemoteTab) {
|
||||
bool remote;
|
||||
if (BrowserTabsRemoteAutostart()) {
|
||||
remote = !WinHasOption(aFeatures, "non-remote", 0, &presenceFlag);
|
||||
} else {
|
||||
remote = WinHasOption(aFeatures, "remote", 0, &presenceFlag);
|
||||
if (!inContentProcess) {
|
||||
// Determine whether the window should have remote tabs.
|
||||
bool remote = BrowserTabsRemoteAutostart();
|
||||
|
||||
if (!openedFromContentScript) {
|
||||
if (remote) {
|
||||
remote = !WinHasOption(aFeatures, "non-remote", 0, &presenceFlag);
|
||||
} else {
|
||||
remote = WinHasOption(aFeatures, "remote", 0, &presenceFlag);
|
||||
}
|
||||
}
|
||||
|
||||
if (remote) {
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
|
||||
}
|
||||
@ -1644,7 +1651,7 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent,
|
||||
if (aParent) {
|
||||
aParent->GetFullScreen(&isFullScreen);
|
||||
}
|
||||
if (isFullScreen && !isCallerChrome) {
|
||||
if (isFullScreen && openedFromContentScript) {
|
||||
// If the parent window is in fullscreen & the caller context is content,
|
||||
// dialog feature is disabled. (see bug 803675)
|
||||
disableDialogFeature = true;
|
||||
@ -1671,7 +1678,7 @@ nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow* aParent,
|
||||
*/
|
||||
|
||||
// Check security state for use in determing window dimensions
|
||||
if (!isCallerChrome || !aHasChromeParent) {
|
||||
if (openedFromContentScript || !aHasChromeParent) {
|
||||
// If priv check fails (or if we're called from chrome, but the
|
||||
// parent is not a chrome window), set all elements to minimum
|
||||
// reqs., else leave them alone.
|
||||
@ -2270,12 +2277,19 @@ nsWindowWatcher::GetWindowOpenLocation(nsIDOMWindow* aParent,
|
||||
return nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
||||
}
|
||||
|
||||
if (restrictionPref == 2 &&
|
||||
// Only continue if there are no size/position features and no special
|
||||
// chrome flags.
|
||||
(aChromeFlags != nsIWebBrowserChrome::CHROME_ALL ||
|
||||
aPositionSpecified || aSizeSpecified)) {
|
||||
return nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
||||
if (restrictionPref == 2) {
|
||||
// Only continue if there are no size/position features and no special
|
||||
// chrome flags - with the exception of the remoteness and private flags,
|
||||
// which might have been automatically flipped by Gecko.
|
||||
int32_t uiChromeFlags = aChromeFlags;
|
||||
uiChromeFlags &= ~(nsIWebBrowserChrome::CHROME_REMOTE_WINDOW |
|
||||
nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
|
||||
nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
|
||||
nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME);
|
||||
if (uiChromeFlags != nsIWebBrowserChrome::CHROME_ALL ||
|
||||
aPositionSpecified || aSizeSpecified) {
|
||||
return nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ protected:
|
||||
bool aDialog,
|
||||
bool aChromeURL,
|
||||
bool aHasChromeParent,
|
||||
bool aCalledFromJS,
|
||||
bool aOpenedFromRemoteTab);
|
||||
static int32_t WinHasOption(const char* aOptions, const char* aName,
|
||||
int32_t aDefault, bool* aPresenceFlag);
|
||||
|
Loading…
Reference in New Issue
Block a user