Bug 943418. Check for active documents, not current inners, in History APIs. r=bholley

This commit is contained in:
Boris Zbarsky 2013-11-27 11:16:07 -05:00
Родитель ae71929347
Коммит 10d5e6c2be
5 изменённых файлов: 60 добавлений и 8 удалений

Просмотреть файл

@ -907,7 +907,7 @@ public:
* this document. If you're not absolutely sure you need this, use
* GetWindow().
*/
nsPIDOMWindow* GetInnerWindow()
nsPIDOMWindow* GetInnerWindow() const
{
return mRemovedFromDocShell ? nullptr : mWindow;
}
@ -1613,7 +1613,10 @@ public:
/**
* Return true when this document is active, i.e., the active document
* in a content viewer.
* in a content viewer. Note that this will return true for bfcached
* documents, so this does NOT match the "active document" concept in
* the WHATWG spec. That would correspond to GetInnerWindow() &&
* GetInnerWindow()->IsCurrentInnerWindow().
*/
bool IsActive() const { return mDocumentContainer && !mRemovedFromDocShell; }

Просмотреть файл

@ -70,7 +70,7 @@ uint32_t
nsHistory::GetLength(ErrorResult& aRv) const
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->IsCurrentInnerWindow()) {
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return 0;
@ -106,7 +106,7 @@ nsHistory::GetState(JSContext* aCx, ErrorResult& aRv) const
return JS::UndefinedValue();
}
if (!win->IsCurrentInnerWindow()) {
if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return JS::UndefinedValue();
@ -146,7 +146,7 @@ void
nsHistory::Go(int32_t aDelta, ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->IsCurrentInnerWindow()) {
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
@ -202,7 +202,7 @@ void
nsHistory::Back(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->IsCurrentInnerWindow()) {
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
@ -223,7 +223,7 @@ void
nsHistory::Forward(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->IsCurrentInnerWindow()) {
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
@ -268,7 +268,7 @@ nsHistory::PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
return;
}
if (!win->IsCurrentInnerWindow()) {
if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;

Просмотреть файл

@ -336,6 +336,17 @@ public:
return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this;
}
// Returns true if the document of this window is the active document. This
// is not identical to IsCurrentInnerWindow() because document.open() will
// keep the same document active but create a new window.
bool HasActiveDocument()
{
return IsCurrentInnerWindow() ||
(GetOuterWindow() &&
GetOuterWindow()->GetCurrentInnerWindow() &&
GetOuterWindow()->GetCurrentInnerWindow()->GetDoc() == mDoc);
}
bool IsOuterWindow() const
{
return !IsInnerWindow();

Просмотреть файл

@ -18,6 +18,7 @@ support-files =
[test_gsp-qualified.html]
[test_gsp-quirks.html]
[test_gsp-standards.html]
[test_history_document_open.html]
[test_innersize_scrollport.html]
[test_messageChannel.html]
[test_messageChannel_cloning.html]

Просмотреть файл

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=943418
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 943418</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 943418 **/
SimpleTest.waitForExplicitFinish();
function continueTest(f) {
// Make sure we're the entry script so errors get reported here
setTimeout(finishTest, 0, f);
}
function finishTest(f) {
f();
ok(true, "Got here");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=943418">Mozilla Bug 943418</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe src="data:text/html,<script>function f() { history.length; } window.onload = function() { var f = window.f; document.open(); document.close(); parent.continueTest(f); }</script>" </script>
</div>
<pre id="test">
</pre>
</body>
</html>