From ff20a7b3e079916111bb28ddee398286d93ba50a Mon Sep 17 00:00:00 2001 From: "jst%netscape.com" Date: Mon, 28 Jul 2003 23:12:46 +0000 Subject: [PATCH] Fixing bug 209717. Making document.load() use the caller's URI as the base URI. r=caillon@aillon.org, sr=hjtoi-bugzilla@comcast.net --- content/xml/document/src/nsXMLDocument.cpp | 93 ++++++++++++++++------ 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/content/xml/document/src/nsXMLDocument.cpp b/content/xml/document/src/nsXMLDocument.cpp index ab016109557..7c5e93b5971 100644 --- a/content/xml/document/src/nsXMLDocument.cpp +++ b/content/xml/document/src/nsXMLDocument.cpp @@ -259,6 +259,8 @@ nsXMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) mBaseTarget.Truncate(); + mScriptContext = nsnull; + return result; } @@ -404,54 +406,91 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn) nsCOMPtr uri; nsresult rv; - // Create a new URI - rv = NS_NewURI(getter_AddRefs(uri), aUrl, nsnull, mDocumentURL); - if (NS_FAILED(rv)) return rv; - - // Get security manager, check to see if we're allowed to load this URI - nsCOMPtr secMan = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - rv = secMan->CheckConnect(nsnull, uri, "XMLDocument", "load"); - if (NS_FAILED(rv)) { - // We need to return success here so that JS will get a proper exception - // thrown later. Native calls should always result in CheckConnect() succeeding, - // but in case JS calls C++ which calls this code the exception might be lost. - return NS_OK; - } - // Partial Reset, need to restore principal for security reasons and - // event listener manager so that load listeners etc. will remain. + // event listener manager so that load listeners etc. will + // remain. This should be done before the security check is done to + // ensure that the document is reset even if the new document can't + // be loaded. nsCOMPtr principal(mPrincipal); nsCOMPtr elm(mListenerManager); Reset(nsnull, nsnull); - + mPrincipal = principal; mListenerManager = elm; - - SetDocumentURL(uri); - SetBaseURL(uri); - // Store script context, if any, in case we encounter redirect - // (because we need it there) + nsCOMPtr callingContext; + nsCOMPtr stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (stack) { JSContext *cx; if (NS_SUCCEEDED(stack->Peek(&cx)) && cx) { nsContentUtils::GetDynamicScriptContext(cx, - getter_AddRefs(mScriptContext)); + getter_AddRefs(callingContext)); } } + nsCOMPtr baseURI(mDocumentURL); + nsCAutoString charset; + + if (callingContext) { + nsCOMPtr sgo; + callingContext->GetGlobalObject(getter_AddRefs(sgo)); + + nsCOMPtr window(do_QueryInterface(sgo)); + + if (window) { + nsCOMPtr dom_doc; + window->GetDocument(getter_AddRefs(dom_doc)); + nsCOMPtr doc(do_QueryInterface(dom_doc)); + + if (doc) { + doc->GetBaseURL(getter_AddRefs(baseURI)); + doc->GetDocumentCharacterSet(charset); + } + } + } + + // Create a new URI + rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI); + if (NS_FAILED(rv)) { + return rv; + } + + // Get security manager, check to see if we're allowed to load this URI + nsCOMPtr secMan = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } + + rv = secMan->CheckConnect(nsnull, uri, "XMLDocument", "load"); + if (NS_FAILED(rv)) { + // We need to return success here so that JS will get a proper + // exception thrown later. Native calls should always result in + // CheckConnect() succeeding, but in case JS calls C++ which calls + // this code the exception might be lost. + return NS_OK; + } + + SetDocumentURL(uri); + SetBaseURL(uri); + + // Store script context, if any, in case we encounter redirect + // (because we need it there) + + mScriptContext = callingContext; + // Find out if UniversalBrowserRead privileges are enabled - we will // need this in case of a redirect PRBool crossSiteAccessEnabled; rv = secMan->IsCapabilityEnabled("UniversalBrowserRead", &crossSiteAccessEnabled); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) { + return rv; + } mCrossSiteAccessEnabled = crossSiteAccessEnabled; @@ -466,7 +505,9 @@ nsXMLDocument::Load(const nsAString& aUrl, PRBool *aReturn) // which in turn keeps STOP button from becoming active rv = NS_NewChannel(getter_AddRefs(channel), uri, nsnull, loadGroup, this, nsIRequest::LOAD_BACKGROUND); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) { + return rv; + } // Set a principal for this document nsCOMPtr channelOwner;