From d33fa178f92a7b38d53aa539ad59922db6777547 Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Sat, 16 Jan 2021 15:19:45 -0800
Subject: [PATCH] Fix js.exec() returned nul" unless exit() was called
 explicitly

Don't use the "exit_code" property value as the return value of js.exec() unless it's a number. As reported by mlong (thanks).

Also, "exit_code" was being set to null (instead of void/undefined) in js_PrepareToExecute(). I think this was just an oversight or typo by Deuce from his commit of 5 years ago (f3256d81). Since we're comparing exit_code with JSVAL_VOID in other places to determine if it was actually set, this appears to be a long standing bug.
---
 src/sbbs3/js_internal.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c
index afa5cd907b..f90d270d4d 100644
--- a/src/sbbs3/js_internal.c
+++ b/src/sbbs3/js_internal.c
@@ -294,7 +294,7 @@ js_execfile(JSContext *cx, uintN argc, jsval *arglist)
 	JSObject*	pscope;
 	JSObject*	js_script=NULL;
 	JSObject*	nargv;
-	jsval		rval;
+	jsval		rval = JSVAL_VOID;
 	jsrefcount	rc;
 	uintN		i;
 	jsval		val;
@@ -465,7 +465,9 @@ js_execfile(JSContext *cx, uintN argc, jsval *arglist)
 		JS_GetPendingException(cx, &rval);
 	}
 	else {
-		JS_GetProperty(cx, js_scope, "exit_code", &rval);
+		jsval exit_code = JSVAL_VOID;
+		if(JS_GetProperty(cx, js_scope, "exit_code", &exit_code) && JSVAL_IS_NUMBER(exit_code))
+			rval = exit_code;
 	}
 	JS_SET_RVAL(cx, arglist, rval);
 	JS_ClearPendingException(cx);
@@ -935,7 +937,7 @@ void DLLCALL js_PrepareToExecute(JSContext *cx, JSObject *obj, const char *filen
 		JS_DefineProperty(cx, js, "scope", OBJECT_TO_JSVAL(scope)
 			,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
 	}
-	JS_DefineProperty(cx, scope, "exit_code", JSVAL_NULL
+	JS_DefineProperty(cx, scope, "exit_code", JSVAL_VOID
 		,NULL,NULL,JSPROP_ENUMERATE|JSPROP_PERMANENT);
 #if defined(_MSC_VER)
 	_set_invalid_parameter_handler(msvc_invalid_parameter_handler);
-- 
GitLab