From 3b337ab6aff980948fc40a4e45d559cd87d4401f Mon Sep 17 00:00:00 2001 From: "mccabe%netscape.com" Date: Tue, 6 Jun 2000 00:01:25 +0000 Subject: [PATCH] Fix to potential leak introduced with fix to 40406. Be conservative in handling the lifetime of the safe context created by XPConnect to execute JS Components, and save it off to be destroyed at cleanup time, even if some other safe context is registered with XPConnect via SetSafeJSContext. r=vishy, a=brendan --- js/src/xpconnect/src/xpcprivate.h | 5 ++++- js/src/xpconnect/src/xpcthreadcontext.cpp | 22 ++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index 479ae68d2f19..5ecc718bb9d9 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -1370,8 +1370,11 @@ private: nsIXPCException* mException; nsDeque* mJSContextStack; JSContext* mSafeJSContext; + + // If if non-null, we own it; same as mSafeJSContext if SetSafeJSContext + // not called. + JSContext* mOwnSafeJSContext; xpcPerThreadData* mNextThread; - PRBool mSafeContextIsFromSetter; static PRLock* gLock; static xpcPerThreadData* gThreads; diff --git a/js/src/xpconnect/src/xpcthreadcontext.cpp b/js/src/xpconnect/src/xpcthreadcontext.cpp index f59a0a0deab5..824a2eef3cfe 100644 --- a/js/src/xpconnect/src/xpcthreadcontext.cpp +++ b/js/src/xpconnect/src/xpcthreadcontext.cpp @@ -198,8 +198,8 @@ xpcPerThreadData::xpcPerThreadData() : mException(nsnull), mJSContextStack(new nsDeque(nsnull)), mSafeJSContext(nsnull), - mNextThread(nsnull), - mSafeContextIsFromSetter(PR_FALSE) + mOwnSafeJSContext(nsnull), + mNextThread(nsnull) { if(gLock) { @@ -220,10 +220,10 @@ xpcPerThreadData::Cleanup() mJSContextStack = nsnull; } - if(mSafeJSContext && !mSafeContextIsFromSetter) + if(mOwnSafeJSContext) { - JS_DestroyContext(mSafeJSContext); - mSafeJSContext = nsnull; + JS_DestroyContext(mOwnSafeJSContext); + mOwnSafeJSContext = nsnull; } } @@ -319,6 +319,13 @@ xpcPerThreadData::GetSafeJSContext() JS_DestroyContext(mSafeJSContext); mSafeJSContext = nsnull; } + // Save it off so we can destroy it later, even if + // mSafeJSContext has been set to another context + // via SetSafeJSContext. If we don't get here, + // then mSafeJSContext must have been set via + // SetSafeJSContext, and we're not responsible for + // destroying the passed-in context. + mOwnSafeJSContext = mSafeJSContext; } } } @@ -329,8 +336,11 @@ xpcPerThreadData::GetSafeJSContext() nsresult xpcPerThreadData::SetSafeJSContext(JSContext *cx) { + NS_ASSERTION(cx, "SetSafeJSContext called with a null context"); + + if(!cx) + return NS_ERROR_INVALID_ARG; mSafeJSContext = cx; - mSafeContextIsFromSetter = PR_TRUE; return NS_OK; }