зеркало из https://github.com/mozilla/gecko-dev.git
Bug 482659. Give about:blank documents the base URI of the document that did the load. r=dcamp, sr=jst
This commit is contained in:
Родитель
ab208487d4
Коммит
0c6cf95474
|
@ -159,7 +159,7 @@ nsFrameLoader::LoadFrame()
|
|||
// If the URI was malformed, try to recover by loading about:blank.
|
||||
if (rv == NS_ERROR_MALFORMED_URI) {
|
||||
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("about:blank"),
|
||||
charset);
|
||||
charset, base_uri);
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -89,6 +89,7 @@ _TEST_FILES = test_bug1682.html \
|
|||
bug448564-iframe-3.html \
|
||||
bug448564-echo.sjs \
|
||||
bug448564-submit.js \
|
||||
test_bug482659.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=482659
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 482659</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482659">Mozilla Bug 482659</a>
|
||||
<p id="display">
|
||||
<iframe></iframe>
|
||||
<iframe src="about:blank"></iframe>
|
||||
<iframe></iframe>
|
||||
<iframe src="about:blank"></iframe>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 482659 **/
|
||||
SimpleTest.waitForExplicitFinish()
|
||||
|
||||
function testFrame(num) {
|
||||
is(window.frames[num].document.baseURI, document.baseURI,
|
||||
"Unexpected base URI in frame " + num);
|
||||
is(window.frames[num].document.documentURI, "about:blank",
|
||||
"Unexpected document URI in frame " + num);
|
||||
}
|
||||
|
||||
function appendScript(doc) {
|
||||
var s = doc.createElement("script");
|
||||
s.textContent = "document.write('executed'); document.close()";
|
||||
doc.body.appendChild(s);
|
||||
}
|
||||
|
||||
function verifyScriptRan(num) {
|
||||
is(window.frames[num].document.documentElement.textContent, "executed",
|
||||
"write didn't happen in frame " + num);
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
appendScript(window.frames[2].document);
|
||||
appendScript(window.frames[3].document);
|
||||
|
||||
verifyScriptRan(2);
|
||||
verifyScriptRan(3);
|
||||
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
testFrame(i);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=482659
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 482659</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482659">Mozilla Bug 482659</a>
|
||||
<p id="display">
|
||||
<iframe></iframe>
|
||||
<iframe src="about:blank"></iframe>
|
||||
<iframe></iframe>
|
||||
<iframe src="about:blank"></iframe>
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 482659 **/
|
||||
SimpleTest.waitForExplicitFinish()
|
||||
|
||||
function testFrame(num) {
|
||||
is(window.frames[num].document.baseURI, document.baseURI,
|
||||
"Unexpected base URI in frame " + num);
|
||||
is(window.frames[num].document.documentURI, "about:blank",
|
||||
"Unexpected document URI in frame " + num);
|
||||
}
|
||||
|
||||
function appendScript(doc) {
|
||||
var s = doc.createElement("script");
|
||||
s.textContent = "document.write('executed'); document.close()";
|
||||
doc.body.appendChild(s);
|
||||
}
|
||||
|
||||
function verifyScriptRan(num) {
|
||||
is(window.frames[num].document.documentElement.textContent, "executed",
|
||||
"write didn't happen in frame " + num);
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
appendScript(window.frames[2].document);
|
||||
appendScript(window.frames[3].document);
|
||||
|
||||
verifyScriptRan(2);
|
||||
verifyScriptRan(3);
|
||||
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
testFrame(i);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<iframe src="subdir/445004-ref-subsubframe.html"></iframe>
|
||||
</body>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
"<img src='passouter.png' " +
|
||||
"onload='window.parent.document.documentElement.className = ""'";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
"<img src='passouter.png' " +
|
||||
"onload='window.parent.document.documentElement.className = ""'";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="about:blank"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window.frames[0].location =
|
||||
'javascript:document.write(""); document.close(); ' +
|
||||
'parent.continueTest();'
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
// Do this part async just in case
|
||||
setTimeout(function() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
"<img src='passouter.png' " +
|
||||
"onload='window.parent.document.documentElement.className = ""'";
|
||||
}, 0);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
window.frames[0].location =
|
||||
'javascript:document.write(""); document.close(); ' +
|
||||
'parent.continueTest();'
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
// Do this part async just in case
|
||||
setTimeout(function() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
"<img src='passouter.png' " +
|
||||
"onload='window.parent.document.documentElement.className = ""'";
|
||||
}, 0);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="about:blank"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1107,3 +1107,7 @@ fails == 461512-1.html 461512-1-ref.html # Bug 461512
|
|||
== 480880-2c.html about:blank
|
||||
== 482592-1a.xhtml 482592-1-ref.html
|
||||
== 482592-1b.xhtml 482592-1-ref.html
|
||||
== 482659-1a.html 482659-1-ref.html
|
||||
== 482659-1b.html 482659-1-ref.html
|
||||
== 482659-1c.html 482659-1-ref.html
|
||||
== 482659-1d.html 482659-1-ref.html
|
||||
|
|
|
@ -123,6 +123,16 @@
|
|||
{ 0xa7, 0x85, 0x85, 0xc3, 0x94, 0x01, 0x25, 0x03 } \
|
||||
}
|
||||
|
||||
// component inheriting from the nested simple URI component and also
|
||||
// carrying along its base URI
|
||||
#define NS_NESTEDABOUTURI_CID \
|
||||
{ /* 2f277c00-0eaf-4ddb-b936-41326ba48aae */ \
|
||||
0x2f277c00, \
|
||||
0x0eaf, \
|
||||
0x4ddb, \
|
||||
{ 0xb9, 0x36, 0x41, 0x32, 0x6b, 0xa4, 0x8a, 0xae } \
|
||||
}
|
||||
|
||||
// component implementing nsIStandardURL, nsIURI, nsIURL, nsISerializable,
|
||||
// and nsIClassInfo.
|
||||
#define NS_STANDARDURL_CLASSNAME \
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "nsMimeTypes.h"
|
||||
#include "nsNetStrings.h"
|
||||
#include "nsDNSPrefetch.h"
|
||||
#include "nsAboutProtocolHandler.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
|
||||
|
@ -179,6 +180,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCookieService, nsCookieService::GetSi
|
|||
#include "nsAboutBlank.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeAboutProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNestedAboutURI)
|
||||
|
||||
#ifdef NECKO_PROTOCOL_about
|
||||
// about
|
||||
|
@ -1014,6 +1016,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
|
|||
NS_ABOUT_MODULE_CONTRACTID_PREFIX "blank",
|
||||
nsAboutBlank::Create
|
||||
},
|
||||
{ "Nested about: URI",
|
||||
NS_NESTEDABOUTURI_CID,
|
||||
nsnull,
|
||||
nsNestedAboutURIConstructor },
|
||||
#ifdef NECKO_PROTOCOL_about
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
{ "about:bloat",
|
||||
|
|
|
@ -49,9 +49,13 @@
|
|||
#include "nsAboutProtocolUtils.h"
|
||||
#include "nsNetError.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSimpleNestedURI.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIWritablePropertyBag2.h"
|
||||
|
||||
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
||||
static NS_DEFINE_CID(kNestedAboutURICID, NS_NESTEDABOUTURI_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -131,7 +135,7 @@ nsAboutProtocolHandler::NewURI(const nsACString &aSpec,
|
|||
rv = NS_NewURI(getter_AddRefs(inner), spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsSimpleNestedURI* outer = new nsSimpleNestedURI(inner);
|
||||
nsSimpleNestedURI* outer = new nsNestedAboutURI(inner, aBaseURI);
|
||||
NS_ENSURE_TRUE(outer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Take a ref to it in the COMPtr we plan to return
|
||||
|
@ -158,7 +162,22 @@ nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
|||
nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// The standard return case:
|
||||
return aboutMod->NewChannel(uri, result);
|
||||
rv = aboutMod->NewChannel(uri, result);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsRefPtr<nsNestedAboutURI> aboutURI;
|
||||
rv = uri->QueryInterface(kNestedAboutURICID,
|
||||
getter_AddRefs(aboutURI));
|
||||
if (NS_SUCCEEDED(rv) && aboutURI->GetBaseURI()) {
|
||||
nsCOMPtr<nsIWritablePropertyBag2> writableBag =
|
||||
do_QueryInterface(*result);
|
||||
if (writableBag) {
|
||||
writableBag->
|
||||
SetPropertyAsInterface(NS_LITERAL_STRING("baseURI"),
|
||||
aboutURI->GetBaseURI());
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// mumble...
|
||||
|
@ -245,3 +264,76 @@ nsSafeAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *
|
|||
*_retval = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// nsNestedAboutURI implementation
|
||||
NS_INTERFACE_MAP_BEGIN(nsNestedAboutURI)
|
||||
if (aIID.Equals(kNestedAboutURICID))
|
||||
foundInterface = static_cast<nsIURI*>(this);
|
||||
else
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSimpleNestedURI)
|
||||
|
||||
// nsISerializable
|
||||
NS_IMETHODIMP
|
||||
nsNestedAboutURI::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
nsresult rv = nsSimpleNestedURI::Read(aStream);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRBool haveBase;
|
||||
rv = aStream->ReadBoolean(&haveBase);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (haveBase) {
|
||||
rv = aStream->ReadObject(PR_TRUE, getter_AddRefs(mBaseURI));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNestedAboutURI::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
nsresult rv = nsSimpleNestedURI::Write(aStream);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = aStream->WriteBoolean(mBaseURI != nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mBaseURI) {
|
||||
rv = aStream->WriteObject(mBaseURI, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsSimpleURI
|
||||
/* virtual */ nsSimpleURI*
|
||||
nsNestedAboutURI::StartClone()
|
||||
{
|
||||
// Sadly, we can't make use of nsSimpleNestedURI::StartClone here.
|
||||
NS_ENSURE_TRUE(mInnerURI, nsnull);
|
||||
|
||||
nsCOMPtr<nsIURI> innerClone;
|
||||
nsresult rv = mInnerURI->Clone(getter_AddRefs(innerClone));
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsNestedAboutURI* url = new nsNestedAboutURI(innerClone, mBaseURI);
|
||||
if (url) {
|
||||
url->SetMutable(PR_FALSE);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
// nsIClassInfo
|
||||
NS_IMETHODIMP
|
||||
nsNestedAboutURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
*aClassIDNoAlloc = kNestedAboutURICID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define nsAboutProtocolHandler_h___
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsSimpleNestedURI.h"
|
||||
|
||||
class nsCString;
|
||||
class nsIAboutModule;
|
||||
|
@ -72,4 +73,36 @@ private:
|
|||
};
|
||||
|
||||
|
||||
// Class to allow us to propagate the base URI to about:blank correctly
|
||||
class nsNestedAboutURI : public nsSimpleNestedURI {
|
||||
public:
|
||||
nsNestedAboutURI(nsIURI* aInnerURI, nsIURI* aBaseURI)
|
||||
: nsSimpleNestedURI(aInnerURI)
|
||||
, mBaseURI(aBaseURI)
|
||||
{}
|
||||
|
||||
// For use only from deserialization
|
||||
nsNestedAboutURI() : nsSimpleNestedURI() {}
|
||||
|
||||
virtual ~nsNestedAboutURI() {}
|
||||
|
||||
// Override QI so we can QI to our CID as needed
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
|
||||
// Override StartClone(), the nsISerializable methods, and
|
||||
// GetClassIDNoAlloc; this last is needed to make our nsISerializable impl
|
||||
// work right.
|
||||
virtual nsSimpleURI* StartClone();
|
||||
NS_IMETHOD Read(nsIObjectInputStream* aStream);
|
||||
NS_IMETHOD Write(nsIObjectOutputStream* aStream);
|
||||
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc);
|
||||
|
||||
nsIURI* GetBaseURI() const {
|
||||
return mBaseURI;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
};
|
||||
|
||||
#endif /* nsAboutProtocolHandler_h___ */
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
function run_test() {
|
||||
var ioServ = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
|
||||
var base = ioServ.newURI("http://www.example.com", null, null);
|
||||
|
||||
var about1 = ioServ.newURI("about:blank", null, null);
|
||||
var about2 = ioServ.newURI("about:blank", null, base);
|
||||
|
||||
var chan1 = ioServ.newChannelFromURI(about1)
|
||||
.QueryInterface(Components.interfaces.nsIPropertyBag2);
|
||||
var chan2 = ioServ.newChannelFromURI(about2)
|
||||
.QueryInterface(Components.interfaces.nsIPropertyBag2);
|
||||
|
||||
var haveProp = false;
|
||||
var propVal = null;
|
||||
try {
|
||||
propVal = chan1.getPropertyAsInterface("baseURI",
|
||||
Components.interfaces.nsIURI);
|
||||
haveProp = true;
|
||||
} catch (e if e.result == Components.results.NS_ERROR_NOT_AVAILABLE) {
|
||||
// Property shouldn't be there.
|
||||
}
|
||||
do_check_eq(propVal, null);
|
||||
do_check_eq(haveProp, false);
|
||||
do_check_eq(chan2.getPropertyAsInterface("baseURI",
|
||||
Components.interfaces.nsIURI),
|
||||
base);
|
||||
}
|
Загрузка…
Ссылка в новой задаче