Bug 761152 - Copy referrer info to new session history entry on history.pushState r=freddyb

Per spec [1], we should copy over the complete document state [2], which
includes the referrer info. Bug 1773192 has already added this for the
"replace" case when the session history is in parent (almost always the case),
but it is still missing for the "push" case, and the "replace" case when the
session history is not in parent.

[1] https://html.spec.whatwg.org/multipage/browsing-the-web.html#url-and-history-update-steps
[2] https://html.spec.whatwg.org/multipage/browsing-the-web.html#document-state

Differential Revision: https://phabricator.services.mozilla.com/D200684
This commit is contained in:
Malte Juergens 2024-02-22 14:29:06 +00:00
parent 7be2dd861f
commit 686328e490
4 changed files with 39 additions and 10 deletions

View File

@ -11376,11 +11376,14 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
if (mozilla::SessionHistoryInParent()) {
MOZ_LOG(gSHLog, LogLevel::Debug,
("nsDocShell %p UpdateActiveEntry (not replacing)", this));
nsString title(mActiveEntry->GetTitle());
nsCOMPtr<nsIReferrerInfo> referrerInfo = mActiveEntry->GetReferrerInfo();
UpdateActiveEntry(false,
/* aPreviousScrollPos = */ Some(scrollPos), aNewURI,
/* aOriginalURI = */ nullptr,
/* aReferrerInfo = */ nullptr,
/* aReferrerInfo = */ referrerInfo,
/* aTriggeringPrincipal = */ aDocument->NodePrincipal(),
csp, title, scrollRestorationIsManual, aData,
uriWasModified);
@ -11399,12 +11402,14 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
// mode from the current entry.
newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual);
// Set the new SHEntry's title (bug 655273).
nsString title;
mOSHE->GetTitle(title);
// Set the new SHEntry's title (bug 655273).
newSHEntry->SetTitle(title);
nsCOMPtr<nsIReferrerInfo> referrerInfo = mOSHE->GetReferrerInfo();
newSHEntry->SetReferrerInfo(referrerInfo);
// Link the new SHEntry to the old SHEntry's BFCache entry, since the
// two entries correspond to the same document.
NS_ENSURE_SUCCESS(newSHEntry->AdoptBFCacheEntry(oldOSHE),
@ -11453,6 +11458,8 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
mOSHE = newSHEntry;
}
nsCOMPtr<nsIReferrerInfo> referrerInfo = mOSHE->GetReferrerInfo();
newSHEntry->SetURI(aNewURI);
newSHEntry->SetOriginalURI(aNewURI);
// We replaced the URI of the entry, clear the unstripped URI as it
@ -11463,6 +11470,7 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
// in our case. We could also set it to aNewURI, with the same result.
newSHEntry->SetResultPrincipalURI(nullptr);
newSHEntry->SetLoadReplace(false);
newSHEntry->SetReferrerInfo(referrerInfo);
}
if (!mozilla::SessionHistoryInParent()) {

View File

@ -1,8 +1,8 @@
[DEFAULT]
support-files = ["referrer_page.sjs"]
["browser_fragment_navigation.js"]
support-files = ["file_fragment_navigation.sjs"]
["browser_session_history.js"]
support-files = ["file_session_history.sjs"]
["browser_referrer_disallow_cross_site_relaxing.js"]

View File

@ -4,7 +4,7 @@
"use strict";
const TEST_FILE =
"https://example.com/browser/dom/security/test/referrer-policy/file_fragment_navigation.sjs";
"https://example.com/browser/dom/security/test/referrer-policy/file_session_history.sjs";
add_task(async function test_browser_navigation() {
await BrowserTestUtils.withNewTab(TEST_FILE, async browser => {
@ -37,6 +37,21 @@ add_task(async function test_browser_navigation() {
content.document.getElementById("ok"),
"Page should load when checking referrer after fragment navigation and reload"
);
info("Clicking on push_state button");
content.document.getElementById("push_state").click();
});
info("Reloading tab");
loadPromise = BrowserTestUtils.browserLoaded(browser);
await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
await loadPromise;
await SpecialPowers.spawn(browser, [], () => {
ok(
content.document.getElementById("ok"),
"Page should load when checking referrer after history.pushState and reload"
);
});
});
});

View File

@ -6,16 +6,22 @@ function handleRequest(request, response) {
request.queryString === "check_referrer" &&
(!request.hasHeader("referer") ||
request.getHeader("referer") !==
"https://example.com/browser/dom/security/test/referrer-policy/file_fragment_navigation.sjs")
"https://example.com/browser/dom/security/test/referrer-policy/file_session_history.sjs")
) {
response.setStatusLine(request.httpVersion, 400, "Bad Request");
response.write("Did not receive referrer");
} else {
response.setHeader("Content-Type", "text/html");
response.write(
`<span id="ok">OK</span>
<a id="check_referrer" href="?check_referrer">check_referrer</a>
<a id="fragment" href="#fragment">fragment</a>`
`<span id="ok">OK</span>
<a id="check_referrer" href="?check_referrer">check_referrer</a>
<a id="fragment" href="#fragment">fragment</a>
<script>
function pushState(){
history.pushState({}, "", location);
}
</script>
<button id="push_state" onclick="pushState();" >push_state</button>`
);
}
}