Bug 774633 - Factor nsWindowWatcher call to SetOpenerScriptPrincipal into a method on nsGlobalWindow. r=jst
authorBobby Holley <bobbyholley@gmail.com>
Wed, 05 Sep 2012 11:32:06 -0700
changeset 104315 5cb753a50e2224f84671e06e806a8241a8e964c0
parent 104314 8d5589b88c8b1f34d4302fbda921d1dde76c6acf
child 104316 4885a6b70c02bfd9e5769bf417ce891aa92fdf5e
push id23417
push userryanvm@gmail.com
push dateThu, 06 Sep 2012 02:27:31 +0000
treeherdermozilla-central@501f4e46a88c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs774633
milestone18.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 774633 - Factor nsWindowWatcher call to SetOpenerScriptPrincipal into a method on nsGlobalWindow. r=jst This doesn't change any functionality in the code. Note that the name is currently a bit of a misnomer, but we change that in the next patch when we rip out the arguments.
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsPIDOMWindow.h
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1541,16 +1541,49 @@ nsGlobalWindow::SetOpenerScriptPrincipal
       // Ensure that if someone plays with this document they will get
       // layout happening.
       nsRect r = shell->GetPresContext()->GetVisibleArea();
       shell->InitialReflow(r.width, r.height);
     }
   }
 }
 
+void
+nsGlobalWindow::SetInitialPrincipalToSubject(nsIDocShellTreeItem* aItem,
+                                             nsIDOMWindow* aParent)
+{
+  nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
+  MOZ_ASSERT(ssm);
+
+  nsresult rv;
+  nsCOMPtr<nsIPrincipal> newWindowPrincipal;
+  rv = ssm->GetSubjectPrincipal(getter_AddRefs(newWindowPrincipal));
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+  if (!newWindowPrincipal && aParent) {
+    nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aParent));
+    if (sop) {
+      newWindowPrincipal = sop->GetPrincipal();
+    }
+  }
+
+  bool isSystem;
+  rv = ssm->IsSystemPrincipal(newWindowPrincipal, &isSystem);
+  if (NS_FAILED(rv) || isSystem) {
+    // Don't pass this principal along to content windows
+    int32_t itemType;
+    rv = aItem->GetItemType(&itemType);
+    if (NS_FAILED(rv) || itemType != nsIDocShellTreeItem::typeChrome) {
+      newWindowPrincipal = nullptr;
+    }
+  }
+
+  SetOpenerScriptPrincipal(newWindowPrincipal);
+}
+
 nsIPrincipal*
 nsGlobalWindow::GetOpenerScriptPrincipal()
 {
   FORWARD_TO_OUTER(GetOpenerScriptPrincipal, (), nullptr);
 
   return mOpenerScriptPrincipal;
 }
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -338,16 +338,18 @@ public:
   // nsPIDOMWindow
   virtual NS_HIDDEN_(nsPIDOMWindow*) GetPrivateRoot();
   virtual NS_HIDDEN_(void) ActivateOrDeactivate(bool aActivate);
   virtual NS_HIDDEN_(void) SetActive(bool aActive);
   virtual NS_HIDDEN_(void) SetIsBackground(bool aIsBackground);
   virtual NS_HIDDEN_(void) SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler);
 
   virtual NS_HIDDEN_(void) SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal);
+  virtual NS_HIDDEN_(void) SetInitialPrincipalToSubject(nsIDocShellTreeItem* aItem,
+                                                        nsIDOMWindow* aParent);
   virtual NS_HIDDEN_(nsIPrincipal*) GetOpenerScriptPrincipal();
 
   virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, bool aForce) const;
   virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
   virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const;
 
   virtual NS_HIDDEN_(nsresult) SaveWindowState(nsISupports **aState);
   virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState);
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -19,16 +19,17 @@
 #include "nsIURI.h"
 
 #define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed"
 #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen"
 #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
 
 class nsIIdleObserver;
 class nsIPrincipal;
+class nsIDocShellTreeItem; // XXX - Temporary! Goes away in the next patch
 
 // Popup control state enum. The values in this enum must go from most
 // permissive to least permissive so that it's safe to push state in
 // all situations. Pushing popup state onto the stack never makes the
 // current popup state less permissive (see
 // nsGlobalWindow::PushPopupControlState()).
 enum PopupControlState {
   openAllowed = 0,  // open that window without worries
@@ -43,18 +44,18 @@ class nsIDocument;
 class nsIScriptTimeoutHandler;
 struct nsTimeout;
 template <class> class nsScriptObjectHolder;
 class nsXBLPrototypeHandler;
 class nsIArray;
 class nsPIWindowRoot;
 
 #define NS_PIDOMWINDOW_IID \
-{0x66660102, 0xd875, 0x47e2, \
-  {0xa1, 0xf7, 0x12, 0xbc, 0x83, 0xc9, 0x93, 0xa9}}
+{ 0x0c5763c6, 0x5e87, 0x4f6f, \
+  { 0xa2, 0xef, 0xcf, 0x4d, 0xeb, 0xd1, 0xbc, 0xc3 } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -281,16 +282,19 @@ public:
   }
 
   // Tell this window who opened it.  This only has an effect if there is
   // either no document currently in the window or if the document is the
   // original document this window came with (an about:blank document either
   // preloaded into it when it was created, or created by
   // CreateAboutBlankContentViewer()).
   virtual void SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal) = 0;
+  virtual void SetInitialPrincipalToSubject(nsIDocShellTreeItem* aItem,
+                                            nsIDOMWindow* aParent) = 0;
+
   // Ask this window who opened it.
   virtual nsIPrincipal* GetOpenerScriptPrincipal() = 0;
 
   virtual PopupControlState PushPopupControlState(PopupControlState aState,
                                                   bool aForce) const = 0;
   virtual void PopPopupControlState(PopupControlState state) const = 0;
   virtual PopupControlState GetPopupControlState() const = 0;
 
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -868,42 +868,23 @@ nsWindowWatcher::OpenWindowInternal(nsID
   }
 
   if (windowIsNew) {
     // Now set the opener principal on the new window.  Note that we need to do
     // this no matter whether we were opened from JS; if there is nothing on
     // the JS stack, just use the principal of our parent window.  In those
     // cases we do _not_ set the parent window principal as the owner of the
     // load--since we really don't know who the owner is, just leave it null.
-    nsIPrincipal* newWindowPrincipal = subjectPrincipal;
-    if (!newWindowPrincipal && aParent) {
-      nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aParent));
-      if (sop) {
-        newWindowPrincipal = sop->GetPrincipal();
-      }
-    }
-
-    bool isSystem;
-    rv = sm->IsSystemPrincipal(newWindowPrincipal, &isSystem);
-    if (NS_FAILED(rv) || isSystem) {
-      // Don't pass this principal along to content windows
-      int32_t itemType;
-      rv = newDocShellItem->GetItemType(&itemType);
-      if (NS_FAILED(rv) || itemType != nsIDocShellTreeItem::typeChrome) {
-        newWindowPrincipal = nullptr;        
-      }
-    }
-
     nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(*_retval);
 #ifdef DEBUG
     nsCOMPtr<nsPIDOMWindow> newDebugWindow = do_GetInterface(newDocShell);
     NS_ASSERTION(newWindow == newDebugWindow, "Different windows??");
 #endif
     if (newWindow) {
-      newWindow->SetOpenerScriptPrincipal(newWindowPrincipal);
+      newWindow->SetInitialPrincipalToSubject(newDocShellItem, aParent);
     }
   }
 
   if (uriToLoad && aNavigate) { // get the script principal and pass it to docshell
     JSContextAutoPopper contextGuard;
 
     cx = GetJSContextFromCallStack();