Skip to content
Snippets Groups Projects
Commit 02a7a84b authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Eliminate crash in js.on_exit()

Have js.on_exit() throw an exciption with a useful(?) error when the
scope already has private data, and that data is not an on_exit list.

This fixes #182.
parent e6552774
No related branches found
No related tags found
No related merge requests found
...@@ -59,6 +59,11 @@ enum { ...@@ -59,6 +59,11 @@ enum {
,PROP_GLOBAL ,PROP_GLOBAL
}; };
struct onexit_private {
char signature[7];
str_list_t list;
};
static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{ {
jsval idval; jsval idval;
...@@ -601,8 +606,9 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist) ...@@ -601,8 +606,9 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist)
JSObject *glob=JS_GetGlobalObject(cx); JSObject *glob=JS_GetGlobalObject(cx);
jsval *argv=JS_ARGV(cx, arglist); jsval *argv=JS_ARGV(cx, arglist);
global_private_t* pd; global_private_t* pd;
str_list_t list; struct onexit_private *oep = NULL;
str_list_t oldlist; str_list_t oldlist;
str_list_t list;
char *p = NULL; char *p = NULL;
JS_SET_RVAL(cx, arglist, JSVAL_VOID); JS_SET_RVAL(cx, arglist, JSVAL_VOID);
...@@ -615,11 +621,30 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist) ...@@ -615,11 +621,30 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist)
list=pd->exit_func; list=pd->exit_func;
} }
else { else {
list=(str_list_t)JS_GetPrivate(cx,scope); oep=(struct onexit_private *)JS_GetPrivate(cx,scope);
if(list==NULL) { if(oep==NULL) {
list=strListInit(); oep = malloc(sizeof(*oep));
JS_SetPrivate(cx,scope,list); if (oep == NULL) {
JS_ReportError(cx, "Unable to allocate memory for on_exit() list");
return JS_FALSE;
}
memcpy(oep->signature, "onexit", 7);
oep->list=strListInit();
JS_SetPrivate(cx,scope,oep);
}
else {
if (oep->signature[0] != 'o'
|| oep->signature[0] != 'n'
|| oep->signature[0] != 'e'
|| oep->signature[0] != 'x'
|| oep->signature[0] != 'i'
|| oep->signature[0] != 't'
|| oep->signature[0] != 0) {
JS_ReportError(cx, "on_exit not available in %s scopes", JS_GetClass(cx, scope)->name);
return JS_FALSE;
}
} }
list = oep->list;
} }
JSVALUE_TO_MSTRING(cx, argv[0], p, NULL); JSVALUE_TO_MSTRING(cx, argv[0], p, NULL);
...@@ -633,7 +658,7 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist) ...@@ -633,7 +658,7 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist)
if(glob==scope) if(glob==scope)
pd->exit_func=list; pd->exit_func=list;
else else
JS_SetPrivate(cx,scope,list); oep->list = list;
} }
return(JS_TRUE); return(JS_TRUE);
} }
...@@ -780,8 +805,15 @@ void DLLCALL js_EvalOnExit(JSContext *cx, JSObject *obj, js_callback_t* cb) ...@@ -780,8 +805,15 @@ void DLLCALL js_EvalOnExit(JSContext *cx, JSObject *obj, js_callback_t* cb)
pt=(global_private_t *)JS_GetPrivate(cx,JS_GetGlobalObject(cx)); pt=(global_private_t *)JS_GetPrivate(cx,JS_GetGlobalObject(cx));
list=pt->exit_func; list=pt->exit_func;
} }
else else {
list=JS_GetPrivate(cx,obj); struct onexit_private *oep = JS_GetPrivate(cx,obj);
if (oep == NULL)
list = NULL;
else {
list = oep->list;
free(oep);
}
}
cb->auto_terminate=FALSE; cb->auto_terminate=FALSE;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment