зеркало из https://github.com/mozilla/pjs.git
Give a saner principal to documents created via DOMImplementation. Bug 324601,
r=sicking, sr=jst
This commit is contained in:
Родитель
dd08ffa550
Коммит
7375357ffc
|
@ -1004,12 +1004,18 @@ NS_NewImageDocument(nsIDocument** aInstancePtrResult);
|
|||
nsresult
|
||||
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager);
|
||||
|
||||
// Note: it's the caller's responsibility to create or get aPrincipal as needed
|
||||
// -- this method will not attempt to get a principal based on aDocumentURI.
|
||||
// Also, both aDocumentURI and aBaseURI must not be null.
|
||||
nsresult
|
||||
NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
|
||||
const nsAString& aNamespaceURI,
|
||||
const nsAString& aQualifiedName,
|
||||
nsIDOMDocumentType* aDoctype,
|
||||
nsIURI* aBaseURI);
|
||||
nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal);
|
||||
nsresult
|
||||
NS_NewPluginDocument(nsIDocument** aInstancePtrResult);
|
||||
|
||||
|
|
|
@ -41,21 +41,23 @@
|
|||
#include "nsISupports.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIPrincipal;
|
||||
|
||||
/*
|
||||
* Event listener manager interface.
|
||||
*/
|
||||
#define NS_IPRIVATEDOMIMPLEMENTATION_IID \
|
||||
{ /* d3205fb8-2652-11d4-ba06-0060b0fc76dd */ \
|
||||
0xd3205fb8, 0x2652, 0x11d4, \
|
||||
{0xba, 0x06, 0x00, 0x60, 0xb0, 0xfc, 0x76, 0xdd} }
|
||||
{ /* 87c20441-8b0d-4383-a189-52fef1dd5d8a */ \
|
||||
0x87c20441, 0x8b0d, 0x4383, \
|
||||
{ 0xa1, 0x89, 0x52, 0xfe, 0xf1, 0xdd, 0x5d, 0x8a } }
|
||||
|
||||
class nsIPrivateDOMImplementation : public nsISupports {
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATEDOMIMPLEMENTATION_IID)
|
||||
|
||||
NS_IMETHOD Init(nsIURI* aBaseURI) = 0;
|
||||
NS_IMETHOD Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateDOMImplementation,
|
||||
|
|
|
@ -476,7 +476,9 @@ class nsDOMImplementation : public nsIDOMDOMImplementation,
|
|||
public nsIPrivateDOMImplementation
|
||||
{
|
||||
public:
|
||||
nsDOMImplementation(nsIURI* aBaseURI = nsnull);
|
||||
nsDOMImplementation(nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal);
|
||||
virtual ~nsDOMImplementation();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -485,17 +487,20 @@ public:
|
|||
NS_DECL_NSIDOMDOMIMPLEMENTATION
|
||||
|
||||
// nsIPrivateDOMImplementation
|
||||
NS_IMETHOD Init(nsIURI* aBaseURI);
|
||||
NS_IMETHOD Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewDOMImplementation(nsIDOMDOMImplementation** aInstancePtrResult)
|
||||
{
|
||||
*aInstancePtrResult = new nsDOMImplementation();
|
||||
*aInstancePtrResult = new nsDOMImplementation(nsnull, nsnull, nsnull);
|
||||
if (!*aInstancePtrResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -505,9 +510,13 @@ NS_NewDOMImplementation(nsIDOMDOMImplementation** aInstancePtrResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDOMImplementation::nsDOMImplementation(nsIURI* aBaseURI)
|
||||
nsDOMImplementation::nsDOMImplementation(nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: mDocumentURI(aDocumentURI),
|
||||
mBaseURI(aBaseURI),
|
||||
mPrincipal(aPrincipal)
|
||||
{
|
||||
mBaseURI = aBaseURI;
|
||||
}
|
||||
|
||||
nsDOMImplementation::~nsDOMImplementation()
|
||||
|
@ -550,14 +559,8 @@ nsDOMImplementation::CreateDocumentType(const nsAString& aQualifiedName,
|
|||
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aQualifiedName);
|
||||
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// XXXbz shouldn't this use the original document principal instead?
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
GetCodebasePrincipal(mBaseURI, getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_NewDOMDocumentType(aReturn, nsnull, principal, name, nsnull,
|
||||
return NS_NewDOMDocumentType(aReturn, nsnull, mPrincipal, name, nsnull,
|
||||
nsnull, aPublicId, aSystemId, EmptyString());
|
||||
}
|
||||
|
||||
|
@ -600,7 +603,7 @@ nsDOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
|
|||
}
|
||||
|
||||
rv = NS_NewDOMDocument(aReturn, aNamespaceURI, aQualifiedName, aDoctype,
|
||||
mBaseURI);
|
||||
mDocumentURI, mBaseURI, mPrincipal);
|
||||
|
||||
nsIDocShell *docShell = nsContentUtils::GetDocShellFromCaller();
|
||||
if (docShell) {
|
||||
|
@ -619,9 +622,14 @@ nsDOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMImplementation::Init(nsIURI* aBaseURI)
|
||||
nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
// Note: can't require that the args be non-null, since at least one
|
||||
// caller (XMLHttpRequest) doesn't have decent args to pass in.
|
||||
mDocumentURI = aDocumentURI;
|
||||
mBaseURI = aBaseURI;
|
||||
mPrincipal = aPrincipal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2578,7 +2586,11 @@ nsDocument::GetImplementation(nsIDOMDOMImplementation** aImplementation)
|
|||
{
|
||||
// For now, create a new implementation every time. This shouldn't
|
||||
// be a high bandwidth operation
|
||||
*aImplementation = new nsDOMImplementation(mDocumentURI);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), "about:blank");
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aImplementation = new nsDOMImplementation(uri, uri, GetNodePrincipal());
|
||||
if (!*aImplementation) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -109,8 +109,14 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
|
|||
const nsAString& aNamespaceURI,
|
||||
const nsAString& aQualifiedName,
|
||||
nsIDOMDocumentType* aDoctype,
|
||||
nsIURI* aBaseURI)
|
||||
nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
// Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null,
|
||||
// since at least one caller (XMLHttpRequest) doesn't have decent args to
|
||||
// pass in.
|
||||
|
||||
nsresult rv;
|
||||
|
||||
*aInstancePtrResult = nsnull;
|
||||
|
@ -125,7 +131,9 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
|
|||
return rv;
|
||||
}
|
||||
|
||||
doc->nsIDocument::SetDocumentURI(aBaseURI);
|
||||
doc->nsIDocument::SetDocumentURI(aDocumentURI);
|
||||
// Must set the principal first, since SetBaseURI checks it.
|
||||
doc->SetPrincipal(aPrincipal);
|
||||
doc->SetBaseURI(aBaseURI);
|
||||
|
||||
if (aDoctype) {
|
||||
|
@ -694,7 +702,8 @@ nsXMLDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||
|
||||
// Create an empty document
|
||||
rv = NS_NewDOMDocument(getter_AddRefs(newDoc), EmptyString(), EmptyString(),
|
||||
newDocType, mDocumentURI);
|
||||
newDocType, nsIDocument::GetDocumentURI(),
|
||||
nsIDocument::GetBaseURI(), GetNodePrincipal());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (aDeep) {
|
||||
|
|
|
@ -219,7 +219,12 @@ nsWebDAVService::CreatePropfindDocument(nsIURI *resourceURI,
|
|||
|
||||
nsCOMPtr<nsIPrivateDOMImplementation>
|
||||
privImpl(do_QueryInterface(implementation));
|
||||
privImpl->Init(resourceURI);
|
||||
// XXXbz I doubt this is right, but I have no idea what this code is doing
|
||||
// or why it's creating documents without a useful principal... so I'm just
|
||||
// going to make the fact that those documents have no principal very
|
||||
// explicit, and if this causes issues then someone familiar with this code
|
||||
// should figure out what principals this _should_ be using.
|
||||
privImpl->Init(resourceURI, resourceURI, nsnull);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
rv = implementation->CreateDocument(mDAVNSString, EmptyString(), nsnull,
|
||||
|
|
|
@ -1,412 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsDOMParser.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDOMImplementation.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrivateDOMImplementation.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsLoadListenerProxy.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
static const char* kLoadAsData = "loadAsData";
|
||||
|
||||
static NS_DEFINE_CID(kIDOMDOMImplementationCID, NS_DOM_IMPLEMENTATION_CID);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
|
||||
// nsIDOMEventListener
|
||||
nsresult
|
||||
nsDOMParser::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIDOMLoadListener
|
||||
nsresult
|
||||
nsDOMParser::Load(nsIDOMEvent* aEvent)
|
||||
{
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMParser::BeforeUnload(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMParser::Unload(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMParser::Abort(nsIDOMEvent* aEvent)
|
||||
{
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMParser::Error(nsIDOMEvent* aEvent)
|
||||
{
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDOMParser::nsDOMParser()
|
||||
: mLoopingForSyncLoad(PR_FALSE)
|
||||
{
|
||||
mEventQService = do_GetService(kEventQueueServiceCID);
|
||||
}
|
||||
|
||||
nsDOMParser::~nsDOMParser()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mLoopingForSyncLoad, "we rather crash than hang");
|
||||
mLoopingForSyncLoad = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// QueryInterface implementation for nsDOMParser
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMParser)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMParser)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(DOMParser)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsDOMParser)
|
||||
NS_IMPL_RELEASE(nsDOMParser)
|
||||
|
||||
/* nsIDOMDocument parseFromString (in wstring str, in string contentType); */
|
||||
NS_IMETHODIMP
|
||||
nsDOMParser::ParseFromString(const PRUnichar *str,
|
||||
const char *contentType,
|
||||
nsIDOMDocument **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG(str);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
NS_ConvertUTF16toUTF8 data(str);
|
||||
|
||||
// The new stream holds a reference to the buffer
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
data.get(), data.Length(),
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return ParseFromStream(stream, "UTF-8", data.Length(), contentType, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMDocument parseFromBuffer([const,array,size_is(bufLen)] in octet buf, in PRUint32 bufLen, in string contentType); */
|
||||
NS_IMETHODIMP
|
||||
nsDOMParser::ParseFromBuffer(const PRUint8 *buf,
|
||||
PRUint32 bufLen,
|
||||
const char *contentType,
|
||||
nsIDOMDocument **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(buf);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
// The new stream holds a reference to the buffer
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
NS_REINTERPRET_CAST(const char *, buf),
|
||||
bufLen, NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return ParseFromStream(stream, nsnull, bufLen, contentType, _retval);
|
||||
}
|
||||
|
||||
|
||||
/* nsIDOMDocument parseFromStream (in nsIInputStream stream, in string charset, in string contentType); */
|
||||
NS_IMETHODIMP
|
||||
nsDOMParser::ParseFromStream(nsIInputStream *stream,
|
||||
const char *charset,
|
||||
PRInt32 contentLength,
|
||||
const char *contentType,
|
||||
nsIDOMDocument **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG(stream);
|
||||
NS_ENSURE_ARG(contentType);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nsnull;
|
||||
|
||||
// For now, we can only create XML documents.
|
||||
if ((nsCRT::strcmp(contentType, "text/xml") != 0) &&
|
||||
(nsCRT::strcmp(contentType, "application/xml") != 0) &&
|
||||
(nsCRT::strcmp(contentType, "application/xhtml+xml") != 0))
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// Put the nsCOMPtr out here so we hold a ref to the stream as needed
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIBufferedInputStream> bufferedStream;
|
||||
if (!NS_InputStreamIsBuffered(stream)) {
|
||||
bufferedStream = do_CreateInstance(NS_BUFFEREDINPUTSTREAM_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = bufferedStream->Init(stream, 4096);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
stream = bufferedStream;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
secMan->GetSubjectPrincipal(getter_AddRefs(principal));
|
||||
}
|
||||
|
||||
// Try to find a base URI for the document we're creating.
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
|
||||
nsCOMPtr<nsIXPCNativeCallContext> cc;
|
||||
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
|
||||
if(NS_SUCCEEDED(rv)) {
|
||||
rv = xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && cc) {
|
||||
JSContext* cx;
|
||||
rv = cc->GetJSContext(&cx);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
|
||||
if (scriptContext) {
|
||||
nsCOMPtr<nsIDOMWindow> window =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
window->GetDocument(getter_AddRefs(domdoc));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (doc) {
|
||||
baseURI = doc->GetBaseURI();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!baseURI) {
|
||||
// No URI from script environment (we are running from command line, for example).
|
||||
// Create a dummy one.
|
||||
// XXX Is this safe? Could we get the URI from stream or something?
|
||||
if (!mBaseURI) {
|
||||
rv = NS_NewURI(getter_AddRefs(baseURI),
|
||||
"about:blank" );
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
} else {
|
||||
baseURI = mBaseURI;
|
||||
}
|
||||
}
|
||||
|
||||
// Get and initialize a DOMImplementation
|
||||
nsCOMPtr<nsIDOMDOMImplementation> implementation(do_CreateInstance(kIDOMDOMImplementationCID, &rv));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
if (baseURI) {
|
||||
nsCOMPtr<nsIPrivateDOMImplementation> privImpl(do_QueryInterface(implementation));
|
||||
if (privImpl) {
|
||||
privImpl->Init(baseURI);
|
||||
}
|
||||
}
|
||||
|
||||
// Create an empty document from it
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = implementation->CreateDocument(EmptyString(),
|
||||
EmptyString(),
|
||||
nsnull,
|
||||
getter_AddRefs(domDocument));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
// Register as a load listener on the document
|
||||
nsCOMPtr<nsIDOMEventReceiver> target(do_QueryInterface(domDocument));
|
||||
if (target) {
|
||||
nsWeakPtr requestWeak(do_GetWeakReference(NS_STATIC_CAST(nsIDOMParser*, this)));
|
||||
nsLoadListenerProxy* proxy = new nsLoadListenerProxy(requestWeak);
|
||||
if (!proxy) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// This will addref the proxy
|
||||
rv = target->AddEventListenerByIID(NS_STATIC_CAST(nsIDOMEventListener*,
|
||||
proxy),
|
||||
NS_GET_IID(nsIDOMLoadListener));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create a fake channel
|
||||
nsCOMPtr<nsIChannel> parserChannel;
|
||||
NS_NewInputStreamChannel(getter_AddRefs(parserChannel), baseURI, nsnull,
|
||||
nsDependentCString(contentType), nsnull);
|
||||
NS_ENSURE_STATE(parserChannel);
|
||||
|
||||
// Hold a reference to it in this method
|
||||
if (principal) {
|
||||
parserChannel->SetOwner(principal);
|
||||
}
|
||||
|
||||
if (charset) {
|
||||
parserChannel->SetContentCharset(nsDependentCString(charset));
|
||||
}
|
||||
|
||||
// Tell the document to start loading
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
if (!document) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEventQueue> modalEventQueue;
|
||||
|
||||
if(!mEventQService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mLoopingForSyncLoad = PR_TRUE;
|
||||
|
||||
rv = mEventQService->PushThreadEventQueue(getter_AddRefs(modalEventQueue));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Have to pass PR_FALSE for reset here, else the reset will remove
|
||||
// our event listener. Should that listener addition move to later
|
||||
// than this call?
|
||||
rv = document->StartDocumentLoad(kLoadAsData, parserChannel,
|
||||
nsnull, nsnull,
|
||||
getter_AddRefs(listener),
|
||||
PR_FALSE);
|
||||
|
||||
if (principal) {
|
||||
// Make sure to give this document the right principal
|
||||
document->SetPrincipal(principal);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || !listener) {
|
||||
if (modalEventQueue) {
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Now start pumping data to the listener
|
||||
nsresult status;
|
||||
|
||||
rv = listener->OnStartRequest(parserChannel, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
parserChannel->Cancel(rv);
|
||||
parserChannel->GetStatus(&status);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
|
||||
rv = listener->OnDataAvailable(parserChannel, nsnull, stream, 0,
|
||||
contentLength);
|
||||
if (NS_FAILED(rv))
|
||||
parserChannel->Cancel(rv);
|
||||
parserChannel->GetStatus(&status);
|
||||
}
|
||||
|
||||
rv = listener->OnStopRequest(parserChannel, nsnull, status);
|
||||
// Failure returned from OnStopRequest does not affect the final status of
|
||||
// the channel, so we do not need to call Cancel(rv) as we do above.
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (modalEventQueue) {
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
while (mLoopingForSyncLoad) {
|
||||
modalEventQueue->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
mEventQService->PopThreadEventQueue(modalEventQueue);
|
||||
|
||||
*_retval = domDocument;
|
||||
NS_ADDREF(*_retval);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMParser::GetBaseURI(nsIURI **aBaseURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aBaseURI);
|
||||
*aBaseURI = mBaseURI;
|
||||
NS_IF_ADDREF(*aBaseURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMParser::SetBaseURI(nsIURI *aBaseURI)
|
||||
{
|
||||
mBaseURI = aBaseURI;
|
||||
return NS_OK;
|
||||
}
|
|
@ -1233,7 +1233,15 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
|||
nsCOMPtr<nsIPrivateDOMImplementation> privImpl =
|
||||
do_QueryInterface(implementation);
|
||||
if (privImpl) {
|
||||
privImpl->Init(GetBaseURI());
|
||||
// XXXbz this is probably all wrong when not called from JS... and possibly
|
||||
// even then! Fixing that requires giving XMLHttpRequest some principals
|
||||
// when inited. Until then, cases when we don't actually parse the
|
||||
// document will give our mDocument he wrong principal. I'm just not sure
|
||||
// how wrong it can get... Shouldn't be too bad as long as mScriptContext
|
||||
// is sane, I guess.
|
||||
nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(mScriptContext);
|
||||
nsIURI* uri = GetBaseURI();
|
||||
privImpl->Init(uri, uri, doc->GetNodePrincipal());
|
||||
}
|
||||
|
||||
// Create an empty document from it (resets current document as well)
|
||||
|
|
Загрузка…
Ссылка в новой задаче