зеркало из https://github.com/mozilla/pjs.git
bug 124053 Fix invalid use of JVMContext TLS to map between threads, JSContexts and JSJavaThreadStates
patch by beard@netscape.com r=bnesse sr=rpotts
This commit is contained in:
Родитель
b86b5bd53c
Коммит
37f9e4c821
|
@ -42,7 +42,7 @@
|
|||
#include "ProxyJNI.h"
|
||||
#include "lcglue.h"
|
||||
#include "nsCSecurityContext.h"
|
||||
#include "nsISecurityContext.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
|
||||
static NS_DEFINE_CID(kJVMManagerCID, NS_JVMMANAGER_CID);
|
||||
static NS_DEFINE_IID(kIJVMConsoleIID, NS_IJVMCONSOLE_IID);
|
||||
|
@ -362,157 +362,12 @@ JVM_IsLiveConnectEnabled(void)
|
|||
}
|
||||
|
||||
|
||||
static
|
||||
JVMSecurityStack *
|
||||
findPrevNode(JSStackFrame *pCurrentFrame)
|
||||
{
|
||||
JVMContext* context = GetJVMContext();
|
||||
JVMSecurityStack *pSecInfoBottom = context->securityStack;
|
||||
if (pSecInfoBottom == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JVMSecurityStack *pSecInfoTop = pSecInfoBottom->prev;
|
||||
if (pCurrentFrame == NULL)
|
||||
{
|
||||
return pSecInfoTop;
|
||||
}
|
||||
if ( pSecInfoBottom->pJavaToJSFrame == pCurrentFrame )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
JVMSecurityStack *pTempSecNode = pSecInfoTop;
|
||||
|
||||
while( pTempSecNode->pJSToJavaFrame != pCurrentFrame )
|
||||
{
|
||||
pTempSecNode = pTempSecNode->prev;
|
||||
if ( pTempSecNode == pSecInfoTop )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( pTempSecNode->pJSToJavaFrame == pCurrentFrame )
|
||||
{
|
||||
return pTempSecNode;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRBool)
|
||||
JVM_NSISecurityContextImplies(JSStackFrame *pCurrentFrame, const char* target, const char* action)
|
||||
{
|
||||
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
|
||||
|
||||
if (pSecInfo == NULL)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsISecurityContext *pNSISecurityContext = (nsISecurityContext *)pSecInfo->pNSISecurityContext;
|
||||
PRBool bAllowedAccess = PR_FALSE;
|
||||
if (pNSISecurityContext != NULL)
|
||||
{
|
||||
pNSISecurityContext->Implies(target, action, &bAllowedAccess);
|
||||
}
|
||||
return bAllowedAccess;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void *)
|
||||
JVM_GetJavaPrincipalsFromStackAsNSVector(JSStackFrame *pCurrentFrame)
|
||||
{
|
||||
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
|
||||
|
||||
if (pSecInfo == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JVMContext* context = GetJVMContext();
|
||||
JSContext *pJSCX = context->js_context;
|
||||
if (pJSCX == NULL)
|
||||
{
|
||||
//TODO: Get to the new context from DOM.
|
||||
//pJSCX = LM_GetCrippledContext();
|
||||
}
|
||||
/*
|
||||
** TODO: Get raman's help here. I don't know how we are going to give back a nsPrincipals array.
|
||||
** Tom's new code should now use a different signature and accept a nsIPrincipal vector object
|
||||
** instead in lm_taint.c and then call into caps. Caps needs to change to accommodate this.
|
||||
void *pNSPrincipalArray = ConvertNSIPrincipalToNSPrincipalArray(NULL, pJSCX, pSecInfo->pNSIPrincipaArray,
|
||||
pSecInfo->numPrincipals, pSecInfo->pNSISecurityContext);
|
||||
if (pNSPrincipalArray != NULL)
|
||||
{
|
||||
return pNSPrincipalArray;
|
||||
}
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PR_IMPLEMENT(JSPrincipals*)
|
||||
JVM_GetJavaPrincipalsFromStack(JSStackFrame *pCurrentFrame)
|
||||
{
|
||||
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
|
||||
|
||||
if (pSecInfo == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JVMContext* context = GetJVMContext();
|
||||
JSContext *pJSCX = context->js_context;
|
||||
if (pJSCX == NULL)
|
||||
{
|
||||
//TODO: Get to the new context from DOM.
|
||||
//pJSCX = LM_GetCrippledContext();
|
||||
}
|
||||
/* TODO:
|
||||
** Get raman's help here. We should not need to convert nsIPrincipal to nsPrincipal anymore.
|
||||
** But we should convert from nsIPrincipal array to a nsIPrincipal array object represented as
|
||||
** nsVector. Use this vector to pass into Tom's code to get to the JSPrinciapals
|
||||
void *pNSPrincipalArray = ConvertNSIPrincipalArrayToObject(NULL, pJSCX, pSecInfo->pNSIPrincipaArray,
|
||||
pSecInfo->numPrincipals, pSecInfo->pNSISecurityContext);
|
||||
if (pNSPrincipalArray != NULL)
|
||||
{
|
||||
return LM_GetJSPrincipalsFromJavaCaller(pJSCX, pNSPrincipalArray, pSecInfo->pNSISecurityContext);
|
||||
}
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSStackFrame*)
|
||||
JVM_GetEndJSFrameFromParallelStack(JSStackFrame *pCurrentFrame)
|
||||
{
|
||||
JVMSecurityStack *pSecInfo = findPrevNode(pCurrentFrame);
|
||||
|
||||
if (pSecInfo == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return pSecInfo->pJavaToJSFrame;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSStackFrame**)
|
||||
JVM_GetStartJSFrameFromParallelStack()
|
||||
{
|
||||
JVMContext* context = GetJVMContext();
|
||||
return &context->js_startframe;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(nsISecurityContext*)
|
||||
JVM_GetJSSecurityContext()
|
||||
{
|
||||
JVMContext* context = GetJVMContext();
|
||||
JVMSecurityStack *securityStack = context->securityStack;
|
||||
JVMSecurityStack *securityStackTop = NULL;
|
||||
JSContext *cx = context->js_context;
|
||||
|
||||
if(securityStack != NULL) {
|
||||
securityStackTop = securityStack->prev;
|
||||
JSStackFrame *fp = NULL;
|
||||
securityStackTop->pJSToJavaFrame = JS_FrameIterator(cx, &fp);
|
||||
}
|
||||
JSContext *cx = nsnull;
|
||||
nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
if (stack) stack->Peek(&cx);
|
||||
|
||||
nsCSecurityContext *securityContext = new nsCSecurityContext(cx);
|
||||
if (securityContext == nsnull) {
|
||||
|
|
|
@ -109,11 +109,7 @@ JVMContext* GetJVMContext()
|
|||
if (context == NULL) {
|
||||
context = new JVMContext;
|
||||
context->proxyEnv = NULL;
|
||||
context->securityStack = NULL;
|
||||
context->jsj_env = NULL;
|
||||
context->js_context = NULL;
|
||||
context->js_startframe = NULL;
|
||||
context->java_applet_obj = NULL;
|
||||
localContext.set(context);
|
||||
}
|
||||
return context;
|
||||
|
@ -130,22 +126,6 @@ JS_BEGIN_EXTERN_C
|
|||
JS_STATIC_DLL_CALLBACK(JSContext*)
|
||||
map_jsj_thread_to_js_context_impl(JSJavaThreadState *jsj_env, void* java_applet_obj, JNIEnv *env, char **errp)
|
||||
{
|
||||
#if 0
|
||||
JVMContext* context = GetJVMContext();
|
||||
JSContext *cx = context->js_context;
|
||||
|
||||
/*
|
||||
** This callback is called for spontaneous calls only. Either create a new JSContext
|
||||
** or return the crippled context.
|
||||
** TODO: Get to some kind of script manager via service manager and then get to script context
|
||||
** and then to get to the native context.
|
||||
*/
|
||||
//JSContext *cx = LM_GetCrippledContext();
|
||||
//JSContext *cx = NULL;
|
||||
|
||||
*errp = NULL;
|
||||
return cx;
|
||||
#else
|
||||
// Guess what? This design is totally invalid under Gecko, because there isn't a 1 to 1 mapping
|
||||
// between NSPR threads and JSContexts. We have to ask the plugin instance peer what JSContext
|
||||
// it lives in to make any sense of all this.
|
||||
|
@ -163,7 +143,6 @@ map_jsj_thread_to_js_context_impl(JSJavaThreadState *jsj_env, void* java_applet_
|
|||
}
|
||||
}
|
||||
return context;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -177,21 +156,20 @@ map_js_context_to_jsj_thread_impl(JSContext *cx, char **errp)
|
|||
{
|
||||
*errp = NULL;
|
||||
|
||||
// FIXME: how do we ever break the association between the jsj_env and the
|
||||
// JVMContext? This needs to be figured out. Otherwise, we'll end up with the
|
||||
// same dangling JSContext problem we are trying to weed out.
|
||||
|
||||
JVMContext* context = GetJVMContext();
|
||||
JSJavaThreadState* jsj_env = context->jsj_env;
|
||||
if (jsj_env != NULL)
|
||||
return jsj_env;
|
||||
/*/TODO: Figure out if moja intiailzation went ok.
|
||||
if (ET_InitMoja(0) != LM_MOJA_OK) {
|
||||
*errp = strdup("LiveConnect initialization failed.");
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
JSJavaVM* js_jvm = NULL;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIJVMManager> managerService = do_GetService(kJVMManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return NULL;
|
||||
nsJVMManager* pJVMMgr = (nsJVMManager *)managerService.get();
|
||||
nsJVMManager* pJVMMgr = (nsJVMManager*) managerService.get();
|
||||
if (pJVMMgr != NULL) {
|
||||
js_jvm = pJVMMgr->GetJSJavaVM();
|
||||
if (js_jvm == NULL) {
|
||||
|
@ -202,7 +180,6 @@ map_js_context_to_jsj_thread_impl(JSContext *cx, char **errp)
|
|||
|
||||
jsj_env = JSJ_AttachCurrentThreadToJava(js_jvm, NULL, NULL);
|
||||
context->jsj_env = jsj_env;
|
||||
context->js_context = cx;
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
@ -269,70 +246,6 @@ map_java_object_to_js_object_impl(JNIEnv *env, void *pluginInstancePtr, char* *e
|
|||
return window;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// This needs to be modified at least temporarily. Caps is undergoing some rearchitecture
|
||||
// nsPrincipal doesn't exist anymore, we're trying to move towards using nsIPrincipal and a PrincipalTools.h
|
||||
// which includes the definitions for arrays.
|
||||
// TODO: Need raman's help. This needs to convert between C++ [] array data type to a nsVector object.
|
||||
void*
|
||||
ConvertNSIPrincipalArrayToObject(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext)
|
||||
{
|
||||
nsIPrincipal **ppNSIPrincipalArray = NS_REINTERPRET_CAST(nsIPrincipal**, ppNSIPrincipalArrayIN);
|
||||
PRInt32 length = numPrincipals;
|
||||
nsresult err = NS_OK;
|
||||
nsCOMPtr<nsIJVMManager> managerService = do_GetService(kJVMManagerCID, &err);
|
||||
if (NS_FAILED(err)) return NULL;
|
||||
nsJVMManager* pJVMMgr = (nsJVMManager *)managerService.get();
|
||||
void *pNSPrincipalArray = NULL;
|
||||
if (pJVMMgr != NULL) {
|
||||
if (ppNSIPrincipalArray != NULL) {
|
||||
nsIPluginManager *pNSIPluginManager = NULL;
|
||||
NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
||||
err = pJVMMgr->QueryInterface(kIPluginManagerIID,
|
||||
(void**)&pNSIPluginManager);
|
||||
|
||||
if( (err == NS_OK)
|
||||
&& (pNSIPluginManager != NULL )
|
||||
)
|
||||
{
|
||||
nsCCapsManager *pNSCCapsManager = NULL;
|
||||
NS_DEFINE_IID(kICapsManagerIID, NS_ICAPSMANAGER_IID);
|
||||
err = pNSIPluginManager->QueryInterface(kICapsManagerIID, (void**)&pNSCCapsManager);
|
||||
if( (err == NS_OK)
|
||||
&& (pNSCCapsManager != NULL)
|
||||
)
|
||||
{
|
||||
PRInt32 i=0;
|
||||
nsPrincipal *pNSPrincipal = NULL;
|
||||
pNSPrincipalArray = nsCapsNewPrincipalArray(length);
|
||||
if (pNSPrincipalArray != NULL)
|
||||
{
|
||||
while( i<length )
|
||||
{
|
||||
err = pNSCCapsManager->GetNSPrincipal(ppNSIPrincipalArray[i], &pNSPrincipal);
|
||||
nsCapsSetPrincipalArrayElement(pNSPrincipalArray, i, pNSPrincipal);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
pNSCCapsManager->Release();
|
||||
}
|
||||
pNSIPluginManager->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( (pNSPrincipalArray != NULL)
|
||||
&&(length != 0)
|
||||
)
|
||||
{
|
||||
return pNSPrincipalArray;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif //0
|
||||
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSPrincipals*)
|
||||
get_JSPrincipals_from_java_caller_impl(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext)
|
||||
{
|
||||
|
@ -491,31 +404,6 @@ enter_js_from_java_impl(JNIEnv *jEnv, char **errp,
|
|||
JS_STATIC_DLL_CALLBACK(void)
|
||||
exit_js_impl(JNIEnv *jEnv, JSContext *cx)
|
||||
{
|
||||
//TODO:
|
||||
//LM_UnlockJS();
|
||||
|
||||
// Pop the security context stack
|
||||
JVMContext* context = GetJVMContext();
|
||||
JVMSecurityStack *pSecInfoBottom = context->securityStack;
|
||||
if (pSecInfoBottom != NULL)
|
||||
{
|
||||
if(pSecInfoBottom->next == pSecInfoBottom)
|
||||
{
|
||||
context->securityStack = NULL;
|
||||
pSecInfoBottom->next = NULL;
|
||||
pSecInfoBottom->prev = NULL;
|
||||
delete pSecInfoBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
JVMSecurityStack *top = pSecInfoBottom->prev;
|
||||
top->next = NULL;
|
||||
pSecInfoBottom->prev = top->prev;
|
||||
top->prev->next = pSecInfoBottom;
|
||||
top->prev = NULL;
|
||||
delete top;
|
||||
}
|
||||
}
|
||||
// The main idea is to execute terminate function if have any;
|
||||
if (cx)
|
||||
{
|
||||
|
|
|
@ -46,33 +46,16 @@
|
|||
#include "nsIThreadManager.h"
|
||||
#include "nsISecurityContext.h"
|
||||
|
||||
struct JVMSecurityStack {
|
||||
void **pNSIPrincipaArray;
|
||||
int numPrincipals;
|
||||
void *pNSISecurityContext;
|
||||
JSStackFrame *pJavaToJSFrame;
|
||||
JSStackFrame *pJSToJavaFrame;
|
||||
JVMSecurityStack *next;
|
||||
JVMSecurityStack *prev;
|
||||
};
|
||||
typedef struct JVMSecurityStack JVMSecurityStack;
|
||||
|
||||
/**
|
||||
* JVMContext is maintained as thread local storage. The current thread's
|
||||
* context is accessed by calling GetJVMContext().
|
||||
*/
|
||||
struct JVMContext {
|
||||
JNIEnv *proxyEnv; /* thread local proxy JNI */
|
||||
JVMSecurityStack *securityStack; /* thread local security stack. */
|
||||
JSJavaThreadState *jsj_env; /* thread local JavaScript execution env. */
|
||||
JSContext *js_context; /* thread local JavaScript context. */
|
||||
JSStackFrame *js_startframe; /* thread local JavaScript stack frame. */
|
||||
void *java_applet_obj;
|
||||
};
|
||||
|
||||
JVMContext* GetJVMContext();
|
||||
void JVM_InitLCGlue(void); // in lcglue.cpp
|
||||
extern "C" void*
|
||||
ConvertNSIPrincipalToNSPrincipalArray(JNIEnv *pJNIEnv, JSContext *pJSContext, void **ppNSIPrincipalArrayIN, int numPrincipals, void *pNSISecurityContext);
|
||||
|
||||
#endif /* lcglue_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче