Skip to content

Commit

Permalink
Bug 761152 - Copy referrer info to new session history entry on histo…
Browse files Browse the repository at this point in the history
…ry.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
  • Loading branch information
maltejur committed Feb 22, 2024
1 parent 7be2dd8 commit 686328e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
14 changes: 11 additions & 3 deletions docshell/base/nsDocShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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),
Expand Down Expand Up @@ -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
Expand All @@ -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()) {
Expand Down
4 changes: 2 additions & 2 deletions dom/security/test/referrer-policy/browser.toml
Original file line number Diff line number Diff line change
@@ -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"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -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"
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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>`
);
}
}

0 comments on commit 686328e

Please sign in to comment.