From 24f49e9636c04fe3b75dec077dad4bc22d9237fa Mon Sep 17 00:00:00 2001 From: "mrbkap%gmail.com" Date: Sat, 24 Jun 2006 04:33:24 +0000 Subject: [PATCH] Keep a strong reference to the context that we're operating on. This involves giving the sandbox context an nsISupports private data that controls its lifetime. bug 337462, r+sr=jst git-svn-id: svn://10.0.0.236/trunk@200788 18797224-902f-48f8-a5cc-f745e15eee43 --- .../js/src/xpconnect/src/xpccomponents.cpp | 48 +++++++++++++++---- mozilla/security/manager/ssl/src/nsCrypto.cpp | 12 ++++- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/mozilla/js/src/xpconnect/src/xpccomponents.cpp b/mozilla/js/src/xpconnect/src/xpccomponents.cpp index 3b34c86917b..5ccd59c6c90 100644 --- a/mozilla/js/src/xpconnect/src/xpccomponents.cpp +++ b/mozilla/js/src/xpconnect/src/xpccomponents.cpp @@ -2394,6 +2394,36 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe #endif } +class ContextHolder : public nsISupports +{ +public: + ContextHolder(JSContext *aOuterCx, JSObject *aSandbox); + + JSContext * GetJSContext() + { + return mJSContext; + } + + NS_DECL_ISUPPORTS + +private: + XPCAutoJSContext mJSContext; +}; + +NS_IMPL_ISUPPORTS0(ContextHolder) + +ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox) + : mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024), JS_FALSE) +{ + if (mJSContext) { + JS_SetOptions(mJSContext, + JSOPTION_DONT_REPORT_UNCAUGHT | + JSOPTION_PRIVATE_IS_NSISUPPORTS); + JS_SetGlobalObject(mJSContext, aSandbox); + JS_SetContextPrivate(mJSContext, this); + } +} + /***************************************************************************/ /* void evalInSandbox(in AString source, in nativeobj sandbox); */ @@ -2460,21 +2490,18 @@ nsXPCComponents_Utils::EvalInSandbox(const nsAString &source) return NS_ERROR_FAILURE; } - XPCAutoJSContext sandcx(JS_NewContext(JS_GetRuntime(cx), 1024), false); - if(!sandcx) { + nsRefPtr sandcx = new ContextHolder(cx, sandbox); + if(!sandcx || !sandcx->GetJSContext()) { JS_ReportError(cx, "Can't prepare context for evalInSandbox"); JSPRINCIPALS_DROP(cx, jsPrincipals); return NS_ERROR_OUT_OF_MEMORY; } - JS_SetOptions(sandcx, JSOPTION_DONT_REPORT_UNCAUGHT); - JS_SetGlobalObject(sandcx, sandbox); - XPCPerThreadData *data = XPCPerThreadData::GetData(); XPCJSContextStack *stack; PRBool popContext = PR_FALSE; if (data && (stack = data->GetJSContextStack())) { - if (NS_FAILED(stack->Push(sandcx))) { + if (NS_FAILED(stack->Push(sandcx->GetJSContext()))) { JS_ReportError(cx, "Unable to initialize XPConnect with the sandbox context"); JSPRINCIPALS_DROP(cx, jsPrincipals); @@ -2500,15 +2527,16 @@ nsXPCComponents_Utils::EvalInSandbox(const nsAString &source) } } - AutoJSRequestWithNoCallContext req(sandcx); - if (!JS_EvaluateUCScriptForPrincipals(sandcx, sandbox, jsPrincipals, + AutoJSRequestWithNoCallContext req(sandcx->GetJSContext()); + if (!JS_EvaluateUCScriptForPrincipals(sandcx->GetJSContext(), sandbox, + jsPrincipals, NS_REINTERPRET_CAST(const jschar *, PromiseFlatString(source).get()), source.Length(), filename.get(), lineNo, rval)) { jsval exn; - if (JS_GetPendingException(sandcx, &exn)) { - AutoJSSuspendRequestWithNoCallContext sus(sandcx); + if (JS_GetPendingException(sandcx->GetJSContext(), &exn)) { + AutoJSSuspendRequestWithNoCallContext sus(sandcx->GetJSContext()); AutoJSRequestWithNoCallContext cxreq(cx); JS_SetPendingException(cx, exn); diff --git a/mozilla/security/manager/ssl/src/nsCrypto.cpp b/mozilla/security/manager/ssl/src/nsCrypto.cpp index a92a99ef416..c5002f044f3 100644 --- a/mozilla/security/manager/ssl/src/nsCrypto.cpp +++ b/mozilla/security/manager/ssl/src/nsCrypto.cpp @@ -155,6 +155,7 @@ class nsCryptoRunArgs : public nsISupports { public: nsCryptoRunArgs(); virtual ~nsCryptoRunArgs(); + nsCOMPtr m_kungFuDeathGrip; JSContext *m_cx; JSObject *m_scope; nsCOMPtr m_principals; @@ -1413,7 +1414,15 @@ loser: return nsnull;; } - +static nsISupports * +GetISupportsFromContext(JSContext *cx) +{ + if (JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS) + return NS_STATIC_CAST(nsISupports *, JS_GetContextPrivate(cx)); + + return nsnull; +} + //The top level method which is a member of nsIDOMCrypto //for generate a base64 encoded CRMF request. NS_IMETHODIMP @@ -1620,6 +1629,7 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMFObject** aReturn) return NS_ERROR_OUT_OF_MEMORY; args->m_cx = cx; + args->m_kungFuDeathGrip = GetISupportsFromContext(cx); args->m_scope = JS_GetParent(cx, script_obj); args->m_jsCallback.Adopt(jsCallback ? nsCRT::strdup(jsCallback) : 0); args->m_principals = principals;