Bug 774633 - Factor nsWindowWatcher call to SetOpenerScriptPrincipal into a method on nsGlobalWindow. r=jst
authorBobby Holley <bobbyholley@gmail.com>
Thu, 23 Aug 2012 16:44:52 -0700
changeset 105276 d84551808abb046b9a50ae923095be4e509116d9
parent 105275 dbd014cfb8488efe09a57e7f9bac5a0c93819384
child 105277 407f19deb14c6e755f1b48acbdc32e78c62b3d32
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersjst
bugs774633
milestone17.0a1
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
@@ -1543,16 +1543,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();