1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/DOMParser.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,524 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/dom/DOMParser.h" 1.10 + 1.11 +#include "nsIDOMDocument.h" 1.12 +#include "nsNetUtil.h" 1.13 +#include "nsStringStream.h" 1.14 +#include "nsIScriptSecurityManager.h" 1.15 +#include "nsCRT.h" 1.16 +#include "nsStreamUtils.h" 1.17 +#include "nsContentUtils.h" 1.18 +#include "nsDOMJSUtils.h" 1.19 +#include "nsError.h" 1.20 +#include "nsPIDOMWindow.h" 1.21 +#include "mozilla/dom/BindingUtils.h" 1.22 + 1.23 +using namespace mozilla; 1.24 +using namespace mozilla::dom; 1.25 + 1.26 +DOMParser::DOMParser() 1.27 + : mAttemptedInit(false) 1.28 +{ 1.29 + SetIsDOMBinding(); 1.30 +} 1.31 + 1.32 +DOMParser::~DOMParser() 1.33 +{ 1.34 +} 1.35 + 1.36 +// QueryInterface implementation for DOMParser 1.37 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMParser) 1.38 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.39 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser) 1.40 + NS_INTERFACE_MAP_ENTRY(nsIDOMParser) 1.41 + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) 1.42 +NS_INTERFACE_MAP_END 1.43 + 1.44 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMParser, mOwner) 1.45 + 1.46 +NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMParser) 1.47 +NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMParser) 1.48 + 1.49 +static const char* 1.50 +StringFromSupportedType(SupportedType aType) 1.51 +{ 1.52 + return SupportedTypeValues::strings[static_cast<int>(aType)].value; 1.53 +} 1.54 + 1.55 +already_AddRefed<nsIDocument> 1.56 +DOMParser::ParseFromString(const nsAString& aStr, SupportedType aType, 1.57 + ErrorResult& rv) 1.58 +{ 1.59 + nsCOMPtr<nsIDOMDocument> domDocument; 1.60 + rv = ParseFromString(aStr, 1.61 + StringFromSupportedType(aType), 1.62 + getter_AddRefs(domDocument)); 1.63 + nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument)); 1.64 + return document.forget(); 1.65 +} 1.66 + 1.67 +NS_IMETHODIMP 1.68 +DOMParser::ParseFromString(const char16_t *str, 1.69 + const char *contentType, 1.70 + nsIDOMDocument **aResult) 1.71 +{ 1.72 + NS_ENSURE_ARG(str); 1.73 + // Converting a string to an enum value manually is a bit of a pain, 1.74 + // so let's just use a helper that takes a content-type string. 1.75 + return ParseFromString(nsDependentString(str), contentType, aResult); 1.76 +} 1.77 + 1.78 +nsresult 1.79 +DOMParser::ParseFromString(const nsAString& str, 1.80 + const char *contentType, 1.81 + nsIDOMDocument **aResult) 1.82 +{ 1.83 + NS_ENSURE_ARG_POINTER(aResult); 1.84 + 1.85 + nsresult rv; 1.86 + 1.87 + if (!nsCRT::strcmp(contentType, "text/html")) { 1.88 + nsCOMPtr<nsIDOMDocument> domDocument; 1.89 + rv = SetUpDocument(DocumentFlavorHTML, getter_AddRefs(domDocument)); 1.90 + NS_ENSURE_SUCCESS(rv, rv); 1.91 + nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument); 1.92 + 1.93 + // Keep the XULXBL state, base URL and principal setting in sync with the 1.94 + // XML case 1.95 + 1.96 + if (nsContentUtils::IsSystemPrincipal(mOriginalPrincipal)) { 1.97 + document->ForceEnableXULXBL(); 1.98 + } 1.99 + 1.100 + // Make sure to give this document the right base URI 1.101 + document->SetBaseURI(mBaseURI); 1.102 + // And the right principal 1.103 + document->SetPrincipal(mPrincipal); 1.104 + 1.105 + rv = nsContentUtils::ParseDocumentHTML(str, document, false); 1.106 + NS_ENSURE_SUCCESS(rv, rv); 1.107 + 1.108 + domDocument.forget(aResult); 1.109 + return rv; 1.110 + } 1.111 + 1.112 + nsAutoCString utf8str; 1.113 + // Convert from UTF16 to UTF8 using fallible allocations 1.114 + if (!AppendUTF16toUTF8(str, utf8str, mozilla::fallible_t())) { 1.115 + return NS_ERROR_OUT_OF_MEMORY; 1.116 + } 1.117 + 1.118 + // The new stream holds a reference to the buffer 1.119 + nsCOMPtr<nsIInputStream> stream; 1.120 + rv = NS_NewByteInputStream(getter_AddRefs(stream), 1.121 + utf8str.get(), utf8str.Length(), 1.122 + NS_ASSIGNMENT_DEPEND); 1.123 + if (NS_FAILED(rv)) 1.124 + return rv; 1.125 + 1.126 + return ParseFromStream(stream, "UTF-8", utf8str.Length(), contentType, aResult); 1.127 +} 1.128 + 1.129 +already_AddRefed<nsIDocument> 1.130 +DOMParser::ParseFromBuffer(const Sequence<uint8_t>& aBuf, uint32_t aBufLen, 1.131 + SupportedType aType, ErrorResult& rv) 1.132 +{ 1.133 + if (aBufLen > aBuf.Length()) { 1.134 + rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY); 1.135 + return nullptr; 1.136 + } 1.137 + nsCOMPtr<nsIDOMDocument> domDocument; 1.138 + rv = DOMParser::ParseFromBuffer(aBuf.Elements(), aBufLen, 1.139 + StringFromSupportedType(aType), 1.140 + getter_AddRefs(domDocument)); 1.141 + nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument)); 1.142 + return document.forget(); 1.143 +} 1.144 + 1.145 +already_AddRefed<nsIDocument> 1.146 +DOMParser::ParseFromBuffer(const Uint8Array& aBuf, uint32_t aBufLen, 1.147 + SupportedType aType, ErrorResult& rv) 1.148 +{ 1.149 + aBuf.ComputeLengthAndData(); 1.150 + 1.151 + if (aBufLen > aBuf.Length()) { 1.152 + rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY); 1.153 + return nullptr; 1.154 + } 1.155 + nsCOMPtr<nsIDOMDocument> domDocument; 1.156 + rv = DOMParser::ParseFromBuffer(aBuf.Data(), aBufLen, 1.157 + StringFromSupportedType(aType), 1.158 + getter_AddRefs(domDocument)); 1.159 + nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument)); 1.160 + return document.forget(); 1.161 +} 1.162 + 1.163 +NS_IMETHODIMP 1.164 +DOMParser::ParseFromBuffer(const uint8_t *buf, 1.165 + uint32_t bufLen, 1.166 + const char *contentType, 1.167 + nsIDOMDocument **aResult) 1.168 +{ 1.169 + NS_ENSURE_ARG_POINTER(buf); 1.170 + NS_ENSURE_ARG_POINTER(aResult); 1.171 + 1.172 + // The new stream holds a reference to the buffer 1.173 + nsCOMPtr<nsIInputStream> stream; 1.174 + nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), 1.175 + reinterpret_cast<const char *>(buf), 1.176 + bufLen, NS_ASSIGNMENT_DEPEND); 1.177 + if (NS_FAILED(rv)) 1.178 + return rv; 1.179 + 1.180 + return ParseFromStream(stream, nullptr, bufLen, contentType, aResult); 1.181 +} 1.182 + 1.183 + 1.184 +already_AddRefed<nsIDocument> 1.185 +DOMParser::ParseFromStream(nsIInputStream* aStream, 1.186 + const nsAString& aCharset, 1.187 + int32_t aContentLength, 1.188 + SupportedType aType, 1.189 + ErrorResult& rv) 1.190 +{ 1.191 + nsCOMPtr<nsIDOMDocument> domDocument; 1.192 + rv = DOMParser::ParseFromStream(aStream, 1.193 + NS_ConvertUTF16toUTF8(aCharset).get(), 1.194 + aContentLength, 1.195 + StringFromSupportedType(aType), 1.196 + getter_AddRefs(domDocument)); 1.197 + nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument)); 1.198 + return document.forget(); 1.199 +} 1.200 + 1.201 +NS_IMETHODIMP 1.202 +DOMParser::ParseFromStream(nsIInputStream *stream, 1.203 + const char *charset, 1.204 + int32_t contentLength, 1.205 + const char *contentType, 1.206 + nsIDOMDocument **aResult) 1.207 +{ 1.208 + NS_ENSURE_ARG(stream); 1.209 + NS_ENSURE_ARG(contentType); 1.210 + NS_ENSURE_ARG_POINTER(aResult); 1.211 + *aResult = nullptr; 1.212 + 1.213 + bool svg = nsCRT::strcmp(contentType, "image/svg+xml") == 0; 1.214 + 1.215 + // For now, we can only create XML documents. 1.216 + //XXXsmaug Should we create an HTMLDocument (in XHTML mode) 1.217 + // for "application/xhtml+xml"? 1.218 + if ((nsCRT::strcmp(contentType, "text/xml") != 0) && 1.219 + (nsCRT::strcmp(contentType, "application/xml") != 0) && 1.220 + (nsCRT::strcmp(contentType, "application/xhtml+xml") != 0) && 1.221 + !svg) 1.222 + return NS_ERROR_NOT_IMPLEMENTED; 1.223 + 1.224 + nsresult rv; 1.225 + 1.226 + // Put the nsCOMPtr out here so we hold a ref to the stream as needed 1.227 + nsCOMPtr<nsIInputStream> bufferedStream; 1.228 + if (!NS_InputStreamIsBuffered(stream)) { 1.229 + rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream, 1.230 + 4096); 1.231 + NS_ENSURE_SUCCESS(rv, rv); 1.232 + 1.233 + stream = bufferedStream; 1.234 + } 1.235 + 1.236 + nsCOMPtr<nsIDOMDocument> domDocument; 1.237 + rv = SetUpDocument(svg ? DocumentFlavorSVG : DocumentFlavorLegacyGuess, 1.238 + getter_AddRefs(domDocument)); 1.239 + NS_ENSURE_SUCCESS(rv, rv); 1.240 + 1.241 + // Create a fake channel 1.242 + nsCOMPtr<nsIChannel> parserChannel; 1.243 + NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, nullptr, 1.244 + nsDependentCString(contentType), nullptr); 1.245 + NS_ENSURE_STATE(parserChannel); 1.246 + 1.247 + // More principal-faking here 1.248 + parserChannel->SetOwner(mOriginalPrincipal); 1.249 + 1.250 + if (charset) { 1.251 + parserChannel->SetContentCharset(nsDependentCString(charset)); 1.252 + } 1.253 + 1.254 + // Tell the document to start loading 1.255 + nsCOMPtr<nsIStreamListener> listener; 1.256 + 1.257 + // Have to pass false for reset here, else the reset will remove 1.258 + // our event listener. Should that listener addition move to later 1.259 + // than this call? Then we wouldn't need to mess around with 1.260 + // SetPrincipal, etc, probably! 1.261 + nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument)); 1.262 + if (!document) return NS_ERROR_FAILURE; 1.263 + 1.264 + // Keep the XULXBL state, base URL and principal setting in sync with the 1.265 + // HTML case 1.266 + 1.267 + if (nsContentUtils::IsSystemPrincipal(mOriginalPrincipal)) { 1.268 + document->ForceEnableXULXBL(); 1.269 + } 1.270 + 1.271 + rv = document->StartDocumentLoad(kLoadAsData, parserChannel, 1.272 + nullptr, nullptr, 1.273 + getter_AddRefs(listener), 1.274 + false); 1.275 + 1.276 + // Make sure to give this document the right base URI 1.277 + document->SetBaseURI(mBaseURI); 1.278 + 1.279 + // And the right principal 1.280 + document->SetPrincipal(mPrincipal); 1.281 + 1.282 + if (NS_FAILED(rv) || !listener) { 1.283 + return NS_ERROR_FAILURE; 1.284 + } 1.285 + 1.286 + // Now start pumping data to the listener 1.287 + nsresult status; 1.288 + 1.289 + rv = listener->OnStartRequest(parserChannel, nullptr); 1.290 + if (NS_FAILED(rv)) 1.291 + parserChannel->Cancel(rv); 1.292 + parserChannel->GetStatus(&status); 1.293 + 1.294 + if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) { 1.295 + rv = listener->OnDataAvailable(parserChannel, nullptr, stream, 0, 1.296 + contentLength); 1.297 + if (NS_FAILED(rv)) 1.298 + parserChannel->Cancel(rv); 1.299 + parserChannel->GetStatus(&status); 1.300 + } 1.301 + 1.302 + rv = listener->OnStopRequest(parserChannel, nullptr, status); 1.303 + // Failure returned from OnStopRequest does not affect the final status of 1.304 + // the channel, so we do not need to call Cancel(rv) as we do above. 1.305 + 1.306 + if (NS_FAILED(rv)) { 1.307 + return NS_ERROR_FAILURE; 1.308 + } 1.309 + 1.310 + domDocument.swap(*aResult); 1.311 + 1.312 + return NS_OK; 1.313 +} 1.314 + 1.315 +NS_IMETHODIMP 1.316 +DOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI, 1.317 + nsIURI* baseURI, nsIScriptGlobalObject* aScriptObject) 1.318 +{ 1.319 + NS_ENSURE_STATE(!mAttemptedInit); 1.320 + mAttemptedInit = true; 1.321 + 1.322 + NS_ENSURE_ARG(principal || documentURI); 1.323 + 1.324 + mDocumentURI = documentURI; 1.325 + 1.326 + if (!mDocumentURI) { 1.327 + principal->GetURI(getter_AddRefs(mDocumentURI)); 1.328 + // If we have the system principal, then we'll just use the null principals 1.329 + // uri. 1.330 + if (!mDocumentURI && !nsContentUtils::IsSystemPrincipal(principal)) { 1.331 + return NS_ERROR_INVALID_ARG; 1.332 + } 1.333 + } 1.334 + 1.335 + mScriptHandlingObject = do_GetWeakReference(aScriptObject); 1.336 + mPrincipal = principal; 1.337 + nsresult rv; 1.338 + if (!mPrincipal) { 1.339 + nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); 1.340 + NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE); 1.341 + rv = 1.342 + secMan->GetSimpleCodebasePrincipal(mDocumentURI, 1.343 + getter_AddRefs(mPrincipal)); 1.344 + NS_ENSURE_SUCCESS(rv, rv); 1.345 + mOriginalPrincipal = mPrincipal; 1.346 + } else { 1.347 + mOriginalPrincipal = mPrincipal; 1.348 + if (nsContentUtils::IsSystemPrincipal(mPrincipal)) { 1.349 + // Don't give DOMParsers the system principal. Use a null 1.350 + // principal instead. 1.351 + mPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); 1.352 + NS_ENSURE_SUCCESS(rv, rv); 1.353 + 1.354 + if (!mDocumentURI) { 1.355 + rv = mPrincipal->GetURI(getter_AddRefs(mDocumentURI)); 1.356 + NS_ENSURE_SUCCESS(rv, rv); 1.357 + } 1.358 + } 1.359 + } 1.360 + 1.361 + mBaseURI = baseURI; 1.362 + // Note: if mBaseURI is null, fine. Leave it like that; that will use the 1.363 + // documentURI as the base. Otherwise for null principals we'll get 1.364 + // nsDocument::SetBaseURI giving errors. 1.365 + 1.366 + NS_POSTCONDITION(mPrincipal, "Must have principal"); 1.367 + NS_POSTCONDITION(mOriginalPrincipal, "Must have original principal"); 1.368 + NS_POSTCONDITION(mDocumentURI, "Must have document URI"); 1.369 + return NS_OK; 1.370 +} 1.371 + 1.372 +/*static */already_AddRefed<DOMParser> 1.373 +DOMParser::Constructor(const GlobalObject& aOwner, 1.374 + nsIPrincipal* aPrincipal, nsIURI* aDocumentURI, 1.375 + nsIURI* aBaseURI, ErrorResult& rv) 1.376 +{ 1.377 + if (!nsContentUtils::IsCallerChrome()) { 1.378 + rv.Throw(NS_ERROR_DOM_SECURITY_ERR); 1.379 + return nullptr; 1.380 + } 1.381 + nsRefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports()); 1.382 + rv = domParser->InitInternal(aOwner.GetAsSupports(), aPrincipal, aDocumentURI, 1.383 + aBaseURI); 1.384 + if (rv.Failed()) { 1.385 + return nullptr; 1.386 + } 1.387 + return domParser.forget(); 1.388 +} 1.389 + 1.390 +/*static */already_AddRefed<DOMParser> 1.391 +DOMParser::Constructor(const GlobalObject& aOwner, 1.392 + ErrorResult& rv) 1.393 +{ 1.394 + nsCOMPtr<nsIPrincipal> prin; 1.395 + nsCOMPtr<nsIURI> documentURI; 1.396 + nsCOMPtr<nsIURI> baseURI; 1.397 + // No arguments; use the subject principal 1.398 + nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); 1.399 + if (!secMan) { 1.400 + rv.Throw(NS_ERROR_UNEXPECTED); 1.401 + return nullptr; 1.402 + } 1.403 + 1.404 + rv = secMan->GetSubjectPrincipal(getter_AddRefs(prin)); 1.405 + if (rv.Failed()) { 1.406 + return nullptr; 1.407 + } 1.408 + 1.409 + // We're called from JS; there better be a subject principal, really. 1.410 + if (!prin) { 1.411 + rv.Throw(NS_ERROR_UNEXPECTED); 1.412 + return nullptr; 1.413 + } 1.414 + 1.415 + nsRefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports()); 1.416 + rv = domParser->InitInternal(aOwner.GetAsSupports(), prin, documentURI, baseURI); 1.417 + if (rv.Failed()) { 1.418 + return nullptr; 1.419 + } 1.420 + return domParser.forget(); 1.421 +} 1.422 + 1.423 +nsresult 1.424 +DOMParser::InitInternal(nsISupports* aOwner, nsIPrincipal* prin, 1.425 + nsIURI* documentURI, nsIURI* baseURI) 1.426 +{ 1.427 + AttemptedInitMarker marker(&mAttemptedInit); 1.428 + if (!documentURI) { 1.429 + // No explicit documentURI; grab document and base URIs off the window our 1.430 + // constructor was called on. Error out if anything untoward happens. 1.431 + 1.432 + // Note that this is a behavior change as far as I can tell -- we're now 1.433 + // using the base URI and document URI of the window off of which the 1.434 + // DOMParser is created, not the window in which parse*() is called. 1.435 + // Does that matter? 1.436 + 1.437 + // Also note that |cx| matches what GetDocumentFromContext() would return, 1.438 + // while GetDocumentFromCaller() gives us the window that the DOMParser() 1.439 + // call was made on. 1.440 + 1.441 + nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner); 1.442 + if (!window) { 1.443 + return NS_ERROR_UNEXPECTED; 1.444 + } 1.445 + 1.446 + baseURI = window->GetDocBaseURI(); 1.447 + documentURI = window->GetDocumentURI(); 1.448 + if (!documentURI) { 1.449 + return NS_ERROR_UNEXPECTED; 1.450 + } 1.451 + } 1.452 + 1.453 + nsCOMPtr<nsIScriptGlobalObject> scriptglobal = do_QueryInterface(aOwner); 1.454 + return Init(prin, documentURI, baseURI, scriptglobal); 1.455 +} 1.456 + 1.457 +void 1.458 +DOMParser::Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI, 1.459 + nsIURI* aBaseURI, mozilla::ErrorResult& rv) 1.460 +{ 1.461 + AttemptedInitMarker marker(&mAttemptedInit); 1.462 + 1.463 + JSContext *cx = nsContentUtils::GetCurrentJSContext(); 1.464 + if (!cx) { 1.465 + rv.Throw(NS_ERROR_UNEXPECTED); 1.466 + return; 1.467 + } 1.468 + 1.469 + nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx); 1.470 + 1.471 + nsCOMPtr<nsIPrincipal> principal = aPrincipal; 1.472 + 1.473 + if (!principal && !aDocumentURI) { 1.474 + nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); 1.475 + if (!secMan) { 1.476 + rv.Throw(NS_ERROR_UNEXPECTED); 1.477 + return; 1.478 + } 1.479 + 1.480 + rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal)); 1.481 + if (rv.Failed()) { 1.482 + return; 1.483 + } 1.484 + 1.485 + // We're called from JS; there better be a subject principal, really. 1.486 + if (!principal) { 1.487 + rv.Throw(NS_ERROR_UNEXPECTED); 1.488 + return; 1.489 + } 1.490 + } 1.491 + 1.492 + rv = Init(principal, aDocumentURI, aBaseURI, 1.493 + scriptContext ? scriptContext->GetGlobalObject() : nullptr); 1.494 +} 1.495 + 1.496 +nsresult 1.497 +DOMParser::SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult) 1.498 +{ 1.499 + nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject = 1.500 + do_QueryReferent(mScriptHandlingObject); 1.501 + nsresult rv; 1.502 + if (!mPrincipal) { 1.503 + NS_ENSURE_TRUE(!mAttemptedInit, NS_ERROR_NOT_INITIALIZED); 1.504 + AttemptedInitMarker marker(&mAttemptedInit); 1.505 + 1.506 + nsCOMPtr<nsIPrincipal> prin = 1.507 + do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); 1.508 + NS_ENSURE_SUCCESS(rv, rv); 1.509 + 1.510 + rv = Init(prin, nullptr, nullptr, scriptHandlingObject); 1.511 + NS_ENSURE_SUCCESS(rv, rv); 1.512 + } 1.513 + 1.514 + NS_ASSERTION(mPrincipal, "Must have principal by now"); 1.515 + NS_ASSERTION(mDocumentURI, "Must have document URI by now"); 1.516 + 1.517 + // Here we have to cheat a little bit... Setting the base URI won't 1.518 + // work if the document has a null principal, so use 1.519 + // mOriginalPrincipal when creating the document, then reset the 1.520 + // principal. 1.521 + return NS_NewDOMDocument(aResult, EmptyString(), EmptyString(), nullptr, 1.522 + mDocumentURI, mBaseURI, 1.523 + mOriginalPrincipal, 1.524 + true, 1.525 + scriptHandlingObject, 1.526 + aFlavor); 1.527 +}