Bug 1453517 - Consolidate popup permission checks to nsContentUtils; r=bz
authorKyle Machulis <kyle@nonpolynomial.com>
Wed, 11 Apr 2018 16:18:20 -0700
changeset 467482 77694987ba61cf176fc403badc29431158f3f831
parent 467481 32220a5b1ba8827b89a099b1c7ebd02a88e18241
child 467483 f154057ddc01b537e163386065a768bf514d2c4b
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1453517
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1453517 - Consolidate popup permission checks to nsContentUtils; r=bz Permissions checks for popups were happening in nsIPopupWindowManager, but that really only required a pref and perm check. The XPCOM machinery around this isn't really needed, and the check was only called from two places in content, so this fits in nsContentUtils. MozReview-Commit-ID: 9x60x1BKWcr
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsGlobalWindowOuter.cpp
dom/html/HTMLInputElement.cpp
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -271,16 +271,17 @@ nsIBidiKeyboard *nsContentUtils::sBidiKe
 uint32_t nsContentUtils::sScriptBlockerCount = 0;
 uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
 AutoTArray<nsCOMPtr<nsIRunnable>, 8>* nsContentUtils::sBlockedScriptRunners = nullptr;
 uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
 nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nullptr;
 
 bool nsContentUtils::sIsHandlingKeyBoardEvent = false;
 bool nsContentUtils::sAllowXULXBL_for_file = false;
+bool nsContentUtils::sDisablePopups = false;
 
 nsString* nsContentUtils::sShiftText = nullptr;
 nsString* nsContentUtils::sControlText = nullptr;
 nsString* nsContentUtils::sMetaText = nullptr;
 nsString* nsContentUtils::sOSText = nullptr;
 nsString* nsContentUtils::sAltText = nullptr;
 nsString* nsContentUtils::sModifierSeparator = nullptr;
 
@@ -728,16 +729,19 @@ nsContentUtils::Init()
                                "dom.placeholder.show_on_focus", true);
 
   Preferences::AddBoolVarCache(&sAutoFocusEnabled,
                                "browser.autofocus", true);
 
   Preferences::AddBoolVarCache(&sIsBytecodeCacheEnabled,
                                "dom.script_loader.bytecode_cache.enabled", false);
 
+  Preferences::AddBoolVarCache(&sDisablePopups,
+                               "dom.disable_open_during_load", false);
+
   Preferences::AddIntVarCache(&sBytecodeCacheStrategy,
                               "dom.script_loader.bytecode_cache.strategy", 0);
 
   nsDependentCString buildID(mozilla::PlatformBuildID());
   sJSBytecodeMimeType = new nsCString(NS_LITERAL_CSTRING("javascript/moz-bytecode-") + buildID);
 
   Element::InitCCCallbacks();
 
@@ -11008,8 +11012,29 @@ nsContentUtils::InnerOrOuterWindowCreate
 
 /* static */ void
 nsContentUtils::InnerOrOuterWindowDestroyed()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(sInnerOrOuterWindowCount > 0);
   --sInnerOrOuterWindowCount;
 }
+
+/* static */ bool
+nsContentUtils::CanShowPopup(nsIPrincipal* aPrincipal)
+{
+  MOZ_ASSERT(aPrincipal);
+  uint32_t permit;
+  nsCOMPtr<nsIPermissionManager> permissionManager =
+    services::GetPermissionManager();
+
+  if (permissionManager &&
+      NS_SUCCEEDED(permissionManager->TestPermissionFromPrincipal(aPrincipal, "popup", &permit))) {
+    if (permit == nsIPermissionManager::ALLOW_ACTION) {
+      return true;
+    }
+    if (permit == nsIPermissionManager::DENY_ACTION) {
+      return false;
+    }
+  }
+
+  return !sDisablePopups;
+}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -3286,16 +3286,18 @@ public:
 
   // Get a serial number for a newly created inner or outer window.
   static uint32_t InnerOrOuterWindowCreated();
   // Record that an inner or outer window has been destroyed.
   static void InnerOrOuterWindowDestroyed();
   // Get the current number of inner or outer windows.
   static int32_t GetCurrentInnerOrOuterWindowCount() { return sInnerOrOuterWindowCount; }
 
+  static bool CanShowPopup(nsIPrincipal* aPrincipal);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
@@ -3413,16 +3415,17 @@ private:
   static AutoTArray<nsCOMPtr<nsIRunnable>, 8>* sBlockedScriptRunners;
   static uint32_t sRunnersCountAtFirstBlocker;
   static uint32_t sScriptBlockerCountWhereRunnersPrevented;
 
   static nsIInterfaceRequestor* sSameOriginChecker;
 
   static bool sIsHandlingKeyBoardEvent;
   static bool sAllowXULXBL_for_file;
+  static bool sDisablePopups;
   static bool sIsFullScreenApiEnabled;
   static bool sIsUnprefixedFullscreenApiEnabled;
   static bool sTrustedFullScreenOnly;
   static bool sIsCutCopyAllowed;
   static uint32_t sHandlingInputTimeout;
   static bool sIsPerformanceTimingEnabled;
   static bool sIsResourceTimingEnabled;
   static bool sIsPerformanceNavigationTimingEnabled;
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -5345,35 +5345,16 @@ nsGlobalWindowOuter::GetTopWindowRoot()
   if (!piWin) {
     return nullptr;
   }
 
   nsCOMPtr<nsPIWindowRoot> window = do_QueryInterface(piWin->GetChromeEventHandler());
   return window.forget();
 }
 
-static
-bool IsPopupBlocked(nsIDocument* aDoc)
-{
-  nsCOMPtr<nsIPopupWindowManager> pm =
-    do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
-
-  if (!pm) {
-    return false;
-  }
-
-  if (!aDoc) {
-    return true;
-  }
-
-  uint32_t permission = nsIPopupWindowManager::ALLOW_POPUP;
-  pm->TestPermission(aDoc->NodePrincipal(), &permission);
-  return permission == nsIPopupWindowManager::DENY_POPUP;
-}
-
 void
 nsGlobalWindowOuter::FirePopupBlockedEvent(nsIDocument* aDoc,
                                            nsIURI* aPopupURI,
                                            const nsAString& aPopupWindowName,
                                            const nsAString& aPopupWindowFeatures)
 {
   MOZ_ASSERT(aDoc);
 
@@ -5411,18 +5392,20 @@ nsGlobalWindowOuter::CanSetProperty(cons
   // If the pref is set to true, we can not set the property
   // and vice versa.
   return !Preferences::GetBool(aPrefName, true);
 }
 
 bool
 nsGlobalWindowOuter::PopupWhitelisted()
 {
-  if (!IsPopupBlocked(mDoc))
+  if (mDoc && nsContentUtils::CanShowPopup(mDoc->NodePrincipal()))
+  {
     return true;
+  }
 
   nsCOMPtr<nsPIDOMWindowOuter> parent = GetParent();
   if (parent == this)
   {
     return false;
   }
 
   return nsGlobalWindowOuter::Cast(parent)->PopupWhitelisted();
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -690,24 +690,17 @@ HTMLInputElement::IsPopupBlocked() const
     return true;
   }
 
   // Check if page can open a popup without abuse regardless of allowed events
   if (win->GetPopupControlState() <= openBlocked) {
     return false;
   }
 
-  nsCOMPtr<nsIPopupWindowManager> pm = do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
-  if (!pm) {
-    return true;
-  }
-
-  uint32_t permission;
-  pm->TestPermission(OwnerDoc()->NodePrincipal(), &permission);
-  return permission == nsIPopupWindowManager::DENY_POPUP;
+  return !nsContentUtils::CanShowPopup(OwnerDoc()->NodePrincipal());
 }
 
 nsresult
 HTMLInputElement::InitColorPicker()
 {
   if (mPickerRunning) {
     NS_WARNING("Just one nsIColorPicker is allowed");
     return NS_ERROR_FAILURE;