Bug 1317173 - Better propagation of private browsing flag when a new window is opened, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 08 Dec 2016 05:52:31 -1000
changeset 325439 a3945af43157bf892bb9415086406774cb380a56
parent 325438 991e29b1efd2495c5c8a35c98fed48643cd3e27f
child 325440 6fddc51e9d1530484e7875ea6b67141497db784d
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerssmaug
bugs1317173
milestone53.0a1
Bug 1317173 - Better propagation of private browsing flag when a new window is opened, r=smaug
embedding/components/windowwatcher/nsWindowWatcher.cpp
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -1088,30 +1088,48 @@ nsWindowWatcher::OpenWindowInternal(mozI
   //
   // Note: The check for the current JSContext isn't necessarily sensical.
   // It's just designed to preserve old semantics during a mass-conversion
   // patch.
   nsCOMPtr<nsIPrincipal> subjectPrincipal =
     nsContentUtils::GetCurrentJSContext() ? nsContentUtils::SubjectPrincipal() :
                                             nullptr;
 
-  bool shouldCheckPrivateBrowsingId = false;
+  bool isPrivateBrowsingWindow = false;
+
   if (windowIsNew) {
     auto* docShell = static_cast<nsDocShell*>(newDocShell.get());
 
     // If this is not a chrome docShell, we apply originAttributes from the
     // subjectPrincipal unless if it's an expanded or system principal.
     if (subjectPrincipal &&
         !nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal) &&
         docShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
-      shouldCheckPrivateBrowsingId = true;
       DocShellOriginAttributes attrs;
       attrs.InheritFromDocToChildDocShell(BasePrincipal::Cast(subjectPrincipal)->OriginAttributesRef());
+      isPrivateBrowsingWindow = !!attrs.mPrivateBrowsingId;
+      docShell->SetOriginAttributes(attrs);
+    } else {
+      nsCOMPtr<nsIDocShellTreeItem> parentItem;
+      GetWindowTreeItem(aParent, getter_AddRefs(parentItem));
+      nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(parentItem);
+      if (parentContext) {
+        isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
+      }
+    }
 
-      docShell->SetOriginAttributes(attrs);
+    bool autoPrivateBrowsing =
+      Preferences::GetBool("browser.privatebrowsing.autostart");
+
+    if (!autoPrivateBrowsing &&
+        (chromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW)) {
+      isPrivateBrowsingWindow = false;
+    } else if (autoPrivateBrowsing ||
+               (chromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW)) {
+      isPrivateBrowsingWindow = true;
     }
 
     // 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.
     nsCOMPtr<nsPIDOMWindowOuter> newWindow = do_QueryInterface(*aResult);
@@ -1131,36 +1149,16 @@ nsWindowWatcher::OpenWindowInternal(mozI
                                                // counter even if the above
                                                // assert fails.
           globalWin->SetIsPopupSpamWindow(true);
         }
       }
     }
   }
 
-  // If all windows should be private, make sure the new window is also
-  // private.  Otherwise, see if the caller has explicitly requested a
-  // private or non-private window.
-  bool isPrivateBrowsingWindow =
-    Preferences::GetBool("browser.privatebrowsing.autostart") ||
-    (!!(chromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW) &&
-     !(chromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW));
-
-  // Otherwise, propagate the privacy status of the parent window, if
-  // available, to the child.
-  if (!isPrivateBrowsingWindow &&
-      !(chromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW)) {
-    nsCOMPtr<nsIDocShellTreeItem> parentItem;
-    GetWindowTreeItem(aParent, getter_AddRefs(parentItem));
-    nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(parentItem);
-    if (parentContext) {
-      isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
-    }
-  }
-
   // We rely on CalculateChromeFlags to decide whether remote (out-of-process)
   // tabs should be used.
   bool isRemoteWindow =
     !!(chromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW);
 
   if (isNewToplevelWindow) {
     nsCOMPtr<nsIDocShellTreeItem> childRoot;
     newDocShellItem->GetRootTreeItem(getter_AddRefs(childRoot));
@@ -1230,21 +1228,16 @@ nsWindowWatcher::OpenWindowInternal(mozI
   // Copy the current session storage for the current domain.
   if (subjectPrincipal && parentDocShell) {
     nsCOMPtr<nsIDOMStorageManager> parentStorageManager =
       do_QueryInterface(parentDocShell);
     nsCOMPtr<nsIDOMStorageManager> newStorageManager =
       do_QueryInterface(newDocShell);
 
     if (parentStorageManager && newStorageManager) {
-      if (shouldCheckPrivateBrowsingId) {
-        MOZ_DIAGNOSTIC_ASSERT(
-          (subjectPrincipal->GetPrivateBrowsingId() > 0) == isPrivateBrowsingWindow);
-      }
-
       nsCOMPtr<nsIDOMStorage> storage;
       nsCOMPtr<nsPIDOMWindowInner> pInnerWin = parentWindow->GetCurrentInnerWindow();
       parentStorageManager->GetStorage(pInnerWin, subjectPrincipal,
                                        getter_AddRefs(storage));
       if (storage) {
         newStorageManager->CloneStorage(storage);
       }
     }