Bug 1340333 - Eagerly compute whether a frame is really a browser. r=smaug
authorBobby Holley <bobbyholley@gmail.com>
Thu, 16 Feb 2017 16:16:00 -0800
changeset 390108 fa1e057ae6fde68e84393f5744a244496deb84fa
parent 390107 798dee9f4ada4e905c89d42686311f5355075073
child 390109 c3ebb1458e91e329920f6f0d9a14ec4cd3d9e2cb
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1340333
milestone54.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 1340333 - Eagerly compute whether a frame is really a browser. r=smaug MozReview-Commit-ID: Gm0oYaSKpUY
dom/html/nsGenericHTMLFrameElement.cpp
dom/html/nsGenericHTMLFrameElement.h
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -367,16 +367,27 @@ nsGenericHTMLFrameElement::MapScrollingA
       case NS_STYLE_FRAME_NO:
         mappedValue = nsIScrollable::Scrollbar_Never;
         break;
     }
   }
   return mappedValue;
 }
 
+static bool
+PrincipalAllowsBrowserFrame(nsIPrincipal* aPrincipal)
+{
+  nsCOMPtr<nsIPermissionManager> permMgr = mozilla::services::GetPermissionManager();
+  NS_ENSURE_TRUE(permMgr, false);
+  uint32_t permission = nsIPermissionManager::DENY_ACTION;
+  nsresult rv = permMgr->TestPermissionFromPrincipal(aPrincipal, "browser", &permission);
+  NS_ENSURE_SUCCESS(rv, false);
+  return permission == nsIPermissionManager::ALLOW_ACTION;
+}
+
 /* virtual */ nsresult
 nsGenericHTMLFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                         const nsAttrValue* aValue,
                                         bool aNotify)
 {
   if (aName == nsGkAtoms::scrolling && aNameSpaceID == kNameSpaceID_None) {
     if (mFrameLoader) {
       nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
@@ -396,16 +407,21 @@ nsGenericHTMLFrameElement::AfterSetAttr(
             shell->FrameNeedsReflow(rootScroll, nsIPresShell::eStyleChange,
                                     NS_FRAME_IS_DIRTY);
           }
         }
       }
     }
   }
 
+  if (aName == nsGkAtoms::mozbrowser && aNameSpaceID == kNameSpaceID_None) {
+    mReallyIsBrowser = !!aValue && BrowserFramesEnabled() &&
+                       PrincipalAllowsBrowserFrame(NodePrincipal());
+  }
+
   return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
                                             aNotify);
 }
 
 void
 nsGenericHTMLFrameElement::DestroyContent()
 {
   if (mFrameLoader) {
@@ -481,38 +497,17 @@ nsGenericHTMLFrameElement::BrowserFrames
 /**
  * Return true if this frame element really is a mozbrowser.  (It
  * needs to have the right attributes, and its creator must have the right
  * permissions.)
  */
 /* [infallible] */ nsresult
 nsGenericHTMLFrameElement::GetReallyIsBrowser(bool *aOut)
 {
-  *aOut = false;
-
-  // Fail if browser frames are globally disabled.
-  if (!nsGenericHTMLFrameElement::BrowserFramesEnabled()) {
-    return NS_OK;
-  }
-
-  // Fail if this frame doesn't have the mozbrowser attribute.
-  if (!GetBoolAttr(nsGkAtoms::mozbrowser)) {
-    return NS_OK;
-  }
-
-  // Fail if the node principal isn't trusted.
-  nsIPrincipal *principal = NodePrincipal();
-  nsCOMPtr<nsIPermissionManager> permMgr =
-    services::GetPermissionManager();
-  NS_ENSURE_TRUE(permMgr, NS_OK);
-
-  uint32_t permission = nsIPermissionManager::DENY_ACTION;
-  nsresult rv = permMgr->TestPermissionFromPrincipal(principal, "browser", &permission);
-  NS_ENSURE_SUCCESS(rv, NS_OK);
-  *aOut = permission == nsIPermissionManager::ALLOW_ACTION;
+  *aOut = mReallyIsBrowser;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
 nsGenericHTMLFrameElement::GetIsolated(bool *aOut)
 {
   *aOut = true;
 
--- a/dom/html/nsGenericHTMLFrameElement.h
+++ b/dom/html/nsGenericHTMLFrameElement.h
@@ -31,16 +31,17 @@ public:
   nsGenericHTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                             mozilla::dom::FromParser aFromParser)
     : nsGenericHTMLElement(aNodeInfo)
     , nsBrowserElement()
     , mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
     , mIsPrerendered(false)
     , mBrowserFrameListenersRegistered(false)
     , mFrameLoaderCreationDisallowed(false)
+    , mReallyIsBrowser(false)
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIFRAMELOADEROWNER
   NS_DECL_NSIDOMMOZBROWSERFRAME
   NS_DECL_NSIMOZBROWSERFRAME
@@ -120,16 +121,17 @@ protected:
    * NS_FROM_PARSER_NETWORK flag.
    * If the element is modified, it may lose the flag.
    */
   bool mNetworkCreated;
 
   bool mIsPrerendered;
   bool mBrowserFrameListenersRegistered;
   bool mFrameLoaderCreationDisallowed;
+  bool mReallyIsBrowser;
 
   // This flag is only used by <iframe>. See HTMLIFrameElement::
   // FullscreenFlag() for details. It is placed here so that we
   // do not bloat any struct.
   bool mFullscreenFlag = false;
 
 private:
   void GetManifestURL(nsAString& aOut);