From 6633dd2f34ad6b41705102403e6aae42df9645c6 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Tue, 17 Mar 2009 23:27:19 +0000 Subject: [PATCH] Bug 482659. Give about:blank documents the base URI of the document that did the load. r=dcamp, sr=jst, a=dveditz git-svn-id: svn://10.0.0.236/trunk@256568 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsFrameLoader.cpp | 2 +- .../content/html/document/test/Makefile.in | 1 + .../html/document/test/test_bug482659.html | 65 ++++++++++++ .../layout/reftests/bugs/482659-1-ref.html | 4 + mozilla/layout/reftests/bugs/482659-1a.html | 16 +++ mozilla/layout/reftests/bugs/482659-1b.html | 16 +++ mozilla/layout/reftests/bugs/482659-1c.html | 25 +++++ mozilla/layout/reftests/bugs/482659-1d.html | 25 +++++ mozilla/layout/reftests/bugs/reftest.list | 4 + mozilla/netwerk/build/nsNetCID.h | 10 ++ mozilla/netwerk/build/nsNetModule.cpp | 6 ++ .../about/src/nsAboutProtocolHandler.cpp | 98 ++++++++++++++++++- .../about/src/nsAboutProtocolHandler.h | 33 +++++++ mozilla/netwerk/test/unit/test_aboutblank.js | 29 ++++++ 14 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 mozilla/content/html/document/test/test_bug482659.html create mode 100644 mozilla/layout/reftests/bugs/482659-1-ref.html create mode 100644 mozilla/layout/reftests/bugs/482659-1a.html create mode 100644 mozilla/layout/reftests/bugs/482659-1b.html create mode 100644 mozilla/layout/reftests/bugs/482659-1c.html create mode 100644 mozilla/layout/reftests/bugs/482659-1d.html create mode 100644 mozilla/netwerk/test/unit/test_aboutblank.js diff --git a/mozilla/content/base/src/nsFrameLoader.cpp b/mozilla/content/base/src/nsFrameLoader.cpp index c0d9bf70ba3..92100937ff7 100644 --- a/mozilla/content/base/src/nsFrameLoader.cpp +++ b/mozilla/content/base/src/nsFrameLoader.cpp @@ -150,7 +150,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); diff --git a/mozilla/content/html/document/test/Makefile.in b/mozilla/content/html/document/test/Makefile.in index fa2b258662b..138e0f4e23d 100644 --- a/mozilla/content/html/document/test/Makefile.in +++ b/mozilla/content/html/document/test/Makefile.in @@ -83,6 +83,7 @@ _TEST_FILES = test_bug1682.html \ bug448564-iframe-3.html \ bug448564-echo.sjs \ bug448564-submit.js \ + test_bug482659.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/mozilla/content/html/document/test/test_bug482659.html b/mozilla/content/html/document/test/test_bug482659.html new file mode 100644 index 00000000000..3131cd3e96a --- /dev/null +++ b/mozilla/content/html/document/test/test_bug482659.html @@ -0,0 +1,65 @@ + + + + + Test for Bug 482659 + + + + + +Mozilla Bug 482659 +

+ + + + +

+ +
+
+
+ + diff --git a/mozilla/layout/reftests/bugs/482659-1-ref.html b/mozilla/layout/reftests/bugs/482659-1-ref.html new file mode 100644 index 00000000000..70e76fb7b87 --- /dev/null +++ b/mozilla/layout/reftests/bugs/482659-1-ref.html @@ -0,0 +1,4 @@ + + + + diff --git a/mozilla/layout/reftests/bugs/482659-1a.html b/mozilla/layout/reftests/bugs/482659-1a.html new file mode 100644 index 00000000000..f767f4df8ea --- /dev/null +++ b/mozilla/layout/reftests/bugs/482659-1a.html @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/mozilla/layout/reftests/bugs/482659-1b.html b/mozilla/layout/reftests/bugs/482659-1b.html new file mode 100644 index 00000000000..2fd28565e5e --- /dev/null +++ b/mozilla/layout/reftests/bugs/482659-1b.html @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/mozilla/layout/reftests/bugs/482659-1c.html b/mozilla/layout/reftests/bugs/482659-1c.html new file mode 100644 index 00000000000..c41ded81496 --- /dev/null +++ b/mozilla/layout/reftests/bugs/482659-1c.html @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/mozilla/layout/reftests/bugs/482659-1d.html b/mozilla/layout/reftests/bugs/482659-1d.html new file mode 100644 index 00000000000..2f951e795c8 --- /dev/null +++ b/mozilla/layout/reftests/bugs/482659-1d.html @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/mozilla/layout/reftests/bugs/reftest.list b/mozilla/layout/reftests/bugs/reftest.list index 72f78c4af88..707d8758e09 100644 --- a/mozilla/layout/reftests/bugs/reftest.list +++ b/mozilla/layout/reftests/bugs/reftest.list @@ -839,3 +839,7 @@ fails-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 424074-1-ref2.xul 424074-1-ref3.xul == 455826-1.html 455826-1-ref.html == 459443-1.html 459443-1-ref.html == 471594-1.xhtml 471594-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 diff --git a/mozilla/netwerk/build/nsNetCID.h b/mozilla/netwerk/build/nsNetCID.h index e2c7e6fa3da..db00fc7e8ab 100644 --- a/mozilla/netwerk/build/nsNetCID.h +++ b/mozilla/netwerk/build/nsNetCID.h @@ -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 \ diff --git a/mozilla/netwerk/build/nsNetModule.cpp b/mozilla/netwerk/build/nsNetModule.cpp index ab3ebb92314..5dccc43c086 100644 --- a/mozilla/netwerk/build/nsNetModule.cpp +++ b/mozilla/netwerk/build/nsNetModule.cpp @@ -58,6 +58,7 @@ #include "nsCacheService.h" #include "nsMimeTypes.h" #include "nsNetStrings.h" +#include "nsAboutProtocolHandler.h" #include "nsNetCID.h" @@ -177,6 +178,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 @@ -1001,6 +1003,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", diff --git a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp index 594fc9a90ee..312c59fccbd 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp @@ -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 aboutURI; + nsresult rv2 = uri->QueryInterface(kNestedAboutURICID, + getter_AddRefs(aboutURI)); + if (NS_SUCCEEDED(rv2) && aboutURI->GetBaseURI()) { + nsCOMPtr 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(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 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; +} diff --git a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h index ca1a3f8a2e8..b560f5bc48b 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h +++ b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h @@ -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 mBaseURI; +}; + #endif /* nsAboutProtocolHandler_h___ */ diff --git a/mozilla/netwerk/test/unit/test_aboutblank.js b/mozilla/netwerk/test/unit/test_aboutblank.js new file mode 100644 index 00000000000..9ade3a4841b --- /dev/null +++ b/mozilla/netwerk/test/unit/test_aboutblank.js @@ -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); +}