Bug 1279285 - Disable window.open in the thumbnail service, r=bz
MozReview-Commit-ID: FuAihM1ZthI
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -775,16 +775,17 @@ nsDocShell::nsDocShell()
, mAllowJavascript(true)
, mAllowMetaRedirects(true)
, mAllowImages(true)
, mAllowMedia(true)
, mAllowDNSPrefetch(true)
, mAllowWindowControl(true)
, mAllowContentRetargeting(true)
, mAllowContentRetargetingOnChildren(true)
+ , mAllowPopups(true)
, mUseErrorPages(false)
, mObserveErrorPages(true)
, mAllowAuth(true)
, mAllowKeywordFixup(false)
, mIsOffScreenBrowser(false)
, mIsActive(true)
, mDisableMetaRefreshWhenInactive(false)
, mIsPrerendered(false)
@@ -2667,16 +2668,30 @@ nsDocShell::GetAllowAuth(bool* aAllowAut
NS_IMETHODIMP
nsDocShell::SetAllowAuth(bool aAllowAuth)
{
mAllowAuth = aAllowAuth;
return NS_OK;
}
NS_IMETHODIMP
+nsDocShell::SetAllowPopups(bool aAllowPlugins)
+{
+ mAllowPopups = aAllowPlugins;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetAllowPopups(bool* aAllowPopups)
+{
+ *aAllowPopups = mAllowPopups;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsDocShell::GetZoom(float* aZoom)
{
NS_ENSURE_ARG_POINTER(aZoom);
*aZoom = 1.0f;
return NS_OK;
}
NS_IMETHODIMP
@@ -3346,16 +3361,19 @@ nsDocShell::SetDocLoaderParent(nsDocLoad
}
if (mAllowImages && NS_SUCCEEDED(parentAsDocShell->GetAllowImages(&value))) {
SetAllowImages(value);
}
SetAllowMedia(parentAsDocShell->GetAllowMedia() && mAllowMedia);
if (mAllowWindowControl && NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))) {
SetAllowWindowControl(value);
}
+ if (mAllowPopups && NS_SUCCEEDED(parentAsDocShell->GetAllowPopups(&value))) {
+ SetAllowPopups(value);
+ }
SetAllowContentRetargeting(mAllowContentRetargeting &&
parentAsDocShell->GetAllowContentRetargetingOnChildren());
if (parentAsDocShell->GetIsPrerendered()) {
SetIsPrerendered();
}
if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value))) {
// a prerendered docshell is not active yet
SetIsActive(value && !mIsPrerendered);
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -932,16 +932,17 @@ protected:
bool mAllowJavascript : 1;
bool mAllowMetaRedirects : 1;
bool mAllowImages : 1;
bool mAllowMedia : 1;
bool mAllowDNSPrefetch : 1;
bool mAllowWindowControl : 1;
bool mAllowContentRetargeting : 1;
bool mAllowContentRetargetingOnChildren : 1;
+ bool mAllowPopups : 1;
bool mUseErrorPages : 1;
bool mObserveErrorPages : 1;
bool mAllowAuth : 1;
bool mAllowKeywordFixup : 1;
bool mIsOffScreenBrowser : 1;
bool mIsActive : 1;
bool mDisableMetaRefreshWhenInactive : 1;
bool mIsPrerendered : 1;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -296,16 +296,21 @@ interface nsIDocShell : nsIDocShellTreeI
/**
* True if new child docshells should allow content retargeting.
* Setting allowContentRetargeting also overwrites this value.
*/
[infallible] attribute boolean allowContentRetargetingOnChildren;
/**
+ * True if this docshell is allowed to create popups
+ */
+ [infallible] attribute boolean allowPopups;
+
+ /**
* Get an enumerator over this docShell and its children.
*
* @param aItemType - Only include docShells of this type, or if typeAll,
* include all child shells.
* Uses types from nsIDocShellTreeItem.
* @param aDirection - Whether to enumerate forwards or backwards.
*/
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11719,16 +11719,22 @@ nsGlobalWindow::OpenInternal(const nsASt
if (!chrome) {
// No chrome means we don't want to go through with this open call
// -- see nsIWindowWatcher.idl
return NS_ERROR_NOT_AVAILABLE;
}
NS_ASSERTION(mDocShell, "Must have docshell here");
+ if (!mDocShell->GetAllowPopups() && !WindowExists(aName, !aCalledNoScript)) {
+ NS_WARNING("Window.open disabled by docshell flag");
+ // Look at aDoJSFixups to make our return value look like a popup was blocked
+ return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
+ }
+
// Popups from apps are never blocked.
bool isApp = false;
if (mDoc) {
isApp = mDoc->NodePrincipal()->GetAppStatus() >=
nsIPrincipal::APP_STATUS_INSTALLED;
}
// XXXbz When this gets fixed to not use LegacyIsCallerNativeCode()
--- a/dom/tests/browser/browser_test_new_window_from_content.js
+++ b/dom/tests/browser/browser_test_new_window_from_content.js
@@ -195,8 +195,33 @@ add_task(function* test_window_open_with
add_task(function* test_window_open_dialog() {
yield testLinkWithMatrix("#winOpenDialog", kWinOpenNonDefault);
});
add_task(function* test_target__blank() {
yield testLinkWithMatrix("#targetBlank", kTargetBlank);
});
+
+add_task(function* test_window_open_disable_dialogs() {
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: kContentDoc,
+ }, function* (browser) {
+ let uri = Services.io.newURI(kContentDoc, null, null);
+ Services.perms.add(uri, "popup", Ci.nsIPermissionManager.ALLOW_ACTION);
+ yield ContentTask.spawn(browser, null, function* () {
+ {
+ let window = content.window.open("dummy.html", "_blank", "");
+ ok(window, "Expected to be able to successfully open the window");
+ window.close();
+ }
+
+ content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDocShell).allowPopups = false;
+
+ {
+ let window = content.window.open("dummy.html", "_blank", "");
+ ok(!window, "Expected not to be able to open the window");
+ }
+ });
+ Services.perms.remove(uri, "popup");
+ });
+});
--- a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
+++ b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
@@ -23,16 +23,17 @@ const backgroundPageThumbsContent = {
// etc - so set it to the lowest priority available.
this._webNav.QueryInterface(Ci.nsIDocumentLoader).
loadGroup.QueryInterface(Ci.nsISupportsPriority).
priority = Ci.nsISupportsPriority.PRIORITY_LOWEST;
docShell.allowMedia = false;
docShell.allowPlugins = false;
docShell.allowContentRetargeting = false;
+ docShell.allowPopups = false;
let defaultFlags = Ci.nsIRequest.LOAD_ANONYMOUS |
Ci.nsIRequest.LOAD_BYPASS_CACHE |
Ci.nsIRequest.INHIBIT_CACHING |
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY;
docShell.defaultLoadFlags = defaultFlags;
addMessageListener("BackgroundPageThumbs:capture",
this._onCapture.bind(this));