diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 23bc4d4572f..86a647296d8 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -305,6 +305,8 @@ private: static nsINameSpaceManager *sNameSpaceManager; static nsIIOService *sIOService; + + static PRBool sInitialized; }; diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 0b15d0de282..a4c4ebdac8b 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -89,36 +89,51 @@ nsIParserService *nsContentUtils::sParserService = nsnull; nsINameSpaceManager *nsContentUtils::sNameSpaceManager = nsnull; nsIIOService *nsContentUtils::sIOService = nsnull; +PRBool nsContentUtils::sInitialized = PR_FALSE; + // static nsresult nsContentUtils::Init() { - NS_ENSURE_TRUE(!sXPConnect, NS_ERROR_ALREADY_INITIALIZED); + if (sInitialized) { + NS_WARNING("Init() called twice"); - nsresult rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect); + return NS_OK; + } + + nsresult rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, + &sSecurityManager); NS_ENSURE_SUCCESS(rv, rv); - rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, - &sSecurityManager); + rv = NS_GetNameSpaceManager(&sNameSpaceManager); + NS_ENSURE_SUCCESS(rv, rv); + + rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect); if (NS_FAILED(rv)) { - // We can run without a security manager, so don't return early. - sSecurityManager = nsnull; + // We could be a standalone DOM engine without JS, so no + // nsIXPConnect is actually ok... + + sXPConnect = nsnull; } - rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService); - if (NS_FAILED(rv)) { - // If this fails, that's ok - sIOService = nsnull; - } - rv = CallGetService(kJSStackContractID, &sThreadJSContextStack); - if (NS_FAILED(rv)) { - sThreadJSContextStack = nsnull; + if (NS_FAILED(rv) && sXPConnect) { + // However, if we can't get a context stack after getting + // an nsIXPConnect, things are broken, so let's fail here. return rv; } - return NS_GetNameSpaceManager(&sNameSpaceManager); + rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService); + if (NS_FAILED(rv)) { + // This makes life easier, but we can live without it. + + sIOService = nsnull; + } + + sInitialized = PR_TRUE; + + return NS_OK; } /** @@ -387,6 +402,8 @@ nsContentUtils::CopyNewlineNormalizedUnicodeTo(nsReadingIterator& aSr void nsContentUtils::Shutdown() { + sInitialized = PR_FALSE; + NS_IF_RELEASE(sDOMScriptObjectFactory); NS_IF_RELEASE(sXPConnect); NS_IF_RELEASE(sSecurityManager); @@ -501,12 +518,6 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode, { NS_PRECONDITION(aTrustedNode, "There must be a trusted node"); - // If there isn't a security manager it is probably because it is not - // installed so we don't care about security anyway - if (!sSecurityManager) { - return NS_OK; - } - PRBool isSystem = PR_FALSE; sSecurityManager->SubjectPrincipalIsSystem(&isSystem); if (isSystem) { @@ -603,12 +614,6 @@ nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode, PRBool nsContentUtils::CanCallerAccess(nsIDOMNode *aNode) { - if (!sSecurityManager) { - // No security manager available, let any calls go through... - - return PR_TRUE; - } - nsCOMPtr subjectPrincipal; sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)); @@ -900,10 +905,6 @@ nsContentUtils::GetDocumentFromCaller(nsIDOMDocument** aDocument) PRBool nsContentUtils::IsCallerChrome() { - if (!sSecurityManager) { - return PR_FALSE; - } - PRBool is_caller_chrome = PR_FALSE; nsresult rv = sSecurityManager->SubjectPrincipalIsSystem(&is_caller_chrome); if (NS_FAILED(rv)) { diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index f935986075f..809f61d391b 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -170,6 +170,9 @@ NS_IMETHODIMP NS_NewXULTreeBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult); #endif +PR_STATIC_CALLBACK(nsresult) Initialize(nsIModule* aSelf); +PR_STATIC_CALLBACK(void) Shutdown(nsIModule* aSelf); + #ifdef MOZ_MATHML #include "nsMathMLAtoms.h" #include "nsMathMLOperators.h" @@ -186,7 +189,9 @@ NS_NewXULTreeBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult); class ContentShutdownObserver : public nsIObserver { public: - ContentShutdownObserver() { NS_INIT_ISUPPORTS(); } + ContentShutdownObserver() + { + } NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER @@ -208,18 +213,26 @@ ContentShutdownObserver::Observe(nsISupports *aSubject, static PRBool gInitialized = PR_FALSE; // Perform our one-time intialization for this module -PR_STATIC_CALLBACK(nsresult) + +// static +nsresult PR_CALLBACK Initialize(nsIModule* aSelf) { - static PRBool initializing = PR_FALSE; - NS_PRECONDITION(!gInitialized || initializing, "module already initialized"); - if (gInitialized) + NS_PRECONDITION(!gInitialized, "module already initialized"); + if (gInitialized) { return NS_OK; + } - initializing = PR_TRUE; gInitialized = PR_TRUE; - nsContentUtils::Init(); + nsresult rv = nsContentUtils::Init(); + if (NS_FAILED(rv)) { + NS_ERROR("Could not initialize nsContentUtils"); + + Shutdown(aSelf); + + return rv; + } // Register all of our atoms once nsCSSAnonBoxes::AddRefAtoms(); @@ -234,7 +247,14 @@ Initialize(nsIModule* aSelf) nsXULAtoms::AddRefAtoms(); #ifdef MOZ_XUL - nsXULContentUtils::Init(); + rv = nsXULContentUtils::Init(); + if (NS_FAILED(rv)) { + NS_ERROR("Could not initialize nsXULContentUtils"); + + Shutdown(aSelf); + + return rv; + } #endif #ifdef MOZ_MATHML @@ -249,7 +269,15 @@ Initialize(nsIModule* aSelf) #ifdef DEBUG nsFrame::DisplayReflowStartup(); #endif - nsTextTransformer::Initialize(); + rv = nsTextTransformer::Initialize(); + if (NS_FAILED(rv)) { + NS_ERROR("Could not initialize nsTextTransformer"); + + Shutdown(aSelf); + + return rv; + } + nsImageLoadingContent::Initialize(); // Add our shutdown observer. @@ -260,20 +288,28 @@ Initialize(nsIModule* aSelf) ContentShutdownObserver* observer = new ContentShutdownObserver(); - if (observer) - observerService->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE); + if (!observer) { + Shutdown(aSelf); + + return NS_ERROR_OUT_OF_MEMORY; + } + + observerService->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE); + } else { + NS_WARNING("Could not get an observer service. We will leak on shutdown."); } - initializing = PR_FALSE; return NS_OK; } // Shutdown this module, releasing all of the module resources -PR_STATIC_CALLBACK(void) + +// static +void PR_CALLBACK Shutdown(nsIModule* aSelf) { NS_PRECONDITION(gInitialized, "module not initialized"); - if (! gInitialized) + if (!gInitialized) return; gInitialized = PR_FALSE;