Bug 957479. Make pushState work correctly after document.open(). r=smaug

This commit is contained in:
Boris Zbarsky 2014-01-13 15:08:56 -05:00
parent d1ac48fef2
commit eeb4fae2b3
4 changed files with 67 additions and 9 deletions

View File

@ -10566,10 +10566,18 @@ nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
// Step 2: Resolve aURL
bool equalURIs = true;
nsCOMPtr<nsIURI> oldURI = mCurrentURI;
nsCOMPtr<nsIURI> currentURI;
if (sURIFixup && mCurrentURI) {
rv = sURIFixup->CreateExposableURI(mCurrentURI,
getter_AddRefs(currentURI));
NS_ENSURE_SUCCESS(rv, rv);
} else {
currentURI = mCurrentURI;
}
nsCOMPtr<nsIURI> oldURI = currentURI;
nsCOMPtr<nsIURI> newURI;
if (aURL.Length() == 0) {
newURI = mCurrentURI;
newURI = currentURI;
}
else {
// 2a: Resolve aURL relative to mURI
@ -10599,7 +10607,7 @@ nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
// the new URI has the same origin as our current URI, we also
// check that the two URIs have the same userpass. (The
// security manager says that |http://foo.com| and
// |http://me@foo.com| have the same origin.) mCurrentURI
// |http://me@foo.com| have the same origin.) currentURI
// won't contain the password part of the userpass, so this
// means that it's never valid to specify a password in a
// pushState or replaceState URI.
@ -10609,14 +10617,14 @@ nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
// It's very important that we check that newURI is of the same
// origin as mCurrentURI, not docBaseURI, because a page can
// origin as currentURI, not docBaseURI, because a page can
// set docBaseURI arbitrarily to any domain.
nsAutoCString currentUserPass, newUserPass;
NS_ENSURE_SUCCESS(mCurrentURI->GetUserPass(currentUserPass),
NS_ENSURE_SUCCESS(currentURI->GetUserPass(currentUserPass),
NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(newURI->GetUserPass(newUserPass),
NS_ERROR_FAILURE);
if (NS_FAILED(secMan->CheckSameOriginURI(mCurrentURI,
if (NS_FAILED(secMan->CheckSameOriginURI(currentURI,
newURI, true)) ||
!currentUserPass.Equals(newUserPass)) {
@ -10641,8 +10649,8 @@ nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
}
}
if (mCurrentURI) {
mCurrentURI->Equals(newURI, &equalURIs);
if (currentURI) {
currentURI->Equals(newURI, &equalURIs);
}
else {
equalURIs = false;
@ -10704,7 +10712,7 @@ nsDocShell::AddState(const JS::Value &aData, const nsAString& aTitle,
// 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, oldURIWasModified = false;
newURI->EqualsExceptRef(mCurrentURI, &sameExceptHashes);
newURI->EqualsExceptRef(currentURI, &sameExceptHashes);
oldOSHE->GetURIWasModified(&oldURIWasModified);
newSHEntry->SetURIWasModified(!sameExceptHashes || oldURIWasModified);

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<script>
document.addEventListener("DOMContentLoaded", function() {
document.open();
document.write("<!DOCTYPE html>New Document here");
document.close();
// Notify parent via postMessage, since otherwise exceptions will not get
// caught by its onerror handler.
parent.postMessage("doTest", "*");
});
</script>

View File

@ -32,6 +32,7 @@ support-files =
file_bug680257.html
file_bug703855.html
file_bug728939.html
file_pushState_after_document_open.html
historyframes.html
[test_anchor_scroll_after_document_open.html]
@ -71,4 +72,5 @@ support-files =
[test_bug728939.html]
[test_bug797909.html]
[test_framedhistoryframes.html]
[test_pushState_after_document_open.html]
[test_windowedhistoryframes.html]

View File

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=957479
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 957479</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 957479 **/
SimpleTest.waitForExplicitFinish();
// Child needs to invoke us, otherwise our onload will fire before the child
// has done the write/close bit.
onmessage = function doTest() {
is(frames[0].location.pathname, "/tests/docshell/test/file_pushState_after_document_open.html", "Should have the right path here");
is(frames[0].location.hash, "", "Should have the right hash here");
frames[0].history.pushState({}, '', frames[0].document.URL + "#foopy");
is(frames[0].location.pathname, "/tests/docshell/test/file_pushState_after_document_open.html", "Pathname should not have changed");
is(frames[0].location.hash, "#foopy", "Hash should have changed");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957479">Mozilla Bug 957479</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe src="file_pushState_after_document_open.html"></iframe>
</div>
<pre id="test">
</pre>
</body>
</html>