From 02a7a84b48438a8dcffb7015da69d093d1ec47ea Mon Sep 17 00:00:00 2001 From: Stephen Hurd <shurd@sasktel.net> Date: Wed, 18 Nov 2020 02:42:31 -0500 Subject: [PATCH] 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. --- src/sbbs3/js_internal.c | 48 ++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c index f56a94feb4..2f3b3b9fbb 100644 --- a/src/sbbs3/js_internal.c +++ b/src/sbbs3/js_internal.c @@ -59,6 +59,11 @@ enum { ,PROP_GLOBAL }; +struct onexit_private { + char signature[7]; + str_list_t list; +}; + static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { jsval idval; @@ -601,8 +606,9 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist) JSObject *glob=JS_GetGlobalObject(cx); jsval *argv=JS_ARGV(cx, arglist); global_private_t* pd; - str_list_t list; + struct onexit_private *oep = NULL; str_list_t oldlist; + str_list_t list; char *p = NULL; JS_SET_RVAL(cx, arglist, JSVAL_VOID); @@ -615,11 +621,30 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist) list=pd->exit_func; } else { - list=(str_list_t)JS_GetPrivate(cx,scope); - if(list==NULL) { - list=strListInit(); - JS_SetPrivate(cx,scope,list); + oep=(struct onexit_private *)JS_GetPrivate(cx,scope); + if(oep==NULL) { + oep = malloc(sizeof(*oep)); + 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); @@ -633,7 +658,7 @@ js_on_exit(JSContext *cx, uintN argc, jsval *arglist) if(glob==scope) pd->exit_func=list; else - JS_SetPrivate(cx,scope,list); + oep->list = list; } return(JS_TRUE); } @@ -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)); list=pt->exit_func; } - else - list=JS_GetPrivate(cx,obj); + else { + struct onexit_private *oep = JS_GetPrivate(cx,obj); + if (oep == NULL) + list = NULL; + else { + list = oep->list; + free(oep); + } + } cb->auto_terminate=FALSE; -- GitLab