Bug 1489308 part 2. Allow UpdateURLAndHistory to work even if mOSHE is null, if we're doing a replace. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 27 Feb 2019 06:01:57 +0000
changeset 461571 f2b0ceb55cedd2cffea476c0ff187d4b283ec4e2
parent 461570 6f00a2d89b5fa9785dac8ea8d4f47dfe17827702
child 461572 b393e04da7e97d49c577c5537c1f62cb0cc6b91e
push id35625
push usercsabou@mozilla.com
push dateThu, 28 Feb 2019 10:55:23 +0000
treeherdermozilla-central@fd53d5e80bca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1489308
milestone67.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 1489308 part 2. Allow UpdateURLAndHistory to work even if mOSHE is null, if we're doing a replace. r=smaug We're going to end up hitting this if someone does a document.open() before mOSHE has been set. We shouldn't need to worry about mLSHE, because the document.open() will cancel the corresponding load. Differential Revision: https://phabricator.services.mozilla.com/D17319
docshell/base/nsDocShell.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -11085,17 +11085,17 @@ nsresult nsDocShell::UpdateURLAndHistory
                                          nsIURI* aCurrentURI, bool aEqualURIs) {
   // Implements
   // https://html.spec.whatwg.org/multipage/history.html#url-and-history-update-steps
 
   // Step 2, if aReplace is false: Create a new entry in the session
   // history. This will erase all SHEntries after the new entry and make this
   // entry the current one.  This operation may modify mOSHE, which we need
   // later, so we keep a reference here.
-  NS_ENSURE_TRUE(mOSHE, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(mOSHE || aReplace, NS_ERROR_FAILURE);
   nsCOMPtr<nsISHEntry> oldOSHE = mOSHE;
 
   mLoadType = LOAD_PUSHSTATE;
 
   nsCOMPtr<nsISHEntry> newSHEntry;
   if (!aReplace) {
     // Step 2.
     // Save the current scroll position (bug 590573).  Step 2.3.
@@ -11142,33 +11142,49 @@ nsresult nsDocShell::UpdateURLAndHistory
     GetOSHEId(&id);
     profiler_register_page(mHistoryID, id, aNewURI->GetSpecOrDefault(),
                            IsFrame());
 #endif
 
   } else {
     // Step 3.
     newSHEntry = mOSHE;
+
+    // Currently the NodePrincipal holds the CSP for that document,
+    // after Bug 965637 we can query the CSP directly from
+    // the doc instead of the NodePrincipal.
+    nsCOMPtr<nsIContentSecurityPolicy> csp;
+    aDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp));
+
+    // Since we're not changing which page we have loaded, pass
+    if (!newSHEntry) {
+      nsresult rv = AddToSessionHistory(
+          aNewURI, nullptr,
+          aDocument->NodePrincipal(),  // triggeringPrincipal
+          nullptr, csp, true, getter_AddRefs(newSHEntry));
+      NS_ENSURE_SUCCESS(rv, rv);
+      mOSHE = newSHEntry;
+    }
     newSHEntry->SetURI(aNewURI);
     newSHEntry->SetOriginalURI(aNewURI);
     newSHEntry->SetLoadReplace(false);
   }
 
   // Step 2.4 and 3: Modify new/original session history entry and clear its
   // POST data, if there is any.
   newSHEntry->SetStateData(aData);
   newSHEntry->SetPostData(nullptr);
 
   // If this push/replaceState changed the document's current URI and the new
   // URI differs from the old URI in more than the hash, or if the old
   // SHEntry's URI was modified in this way by a push/replaceState call
   // set URIWasModified to true for the current SHEntry (bug 669671).
   bool sameExceptHashes = true;
   aNewURI->EqualsExceptRef(aCurrentURI, &sameExceptHashes);
-  bool oldURIWasModified = oldOSHE->GetURIWasModified();
+  bool oldURIWasModified = oldOSHE && oldOSHE->GetURIWasModified();
   newSHEntry->SetURIWasModified(!sameExceptHashes || oldURIWasModified);
 
   // Step E as described at the top of AddState: If aReplace is false,
   // indicating that we're doing a pushState rather than a replaceState, notify
   // bfcache that we've added a page to the history so it can evict content
   // viewers if appropriate. Otherwise call ReplaceEntry so that we notify
   // nsIHistoryListeners that an entry was replaced.
   RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();