diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c index 7fa8ed28a4ecb94bc78ec8cf998471741c79acce..17f5e49337e77bd9f8c6d97804f3c60ca004c3ff 100644 --- a/src/sbbs3/js_internal.c +++ b/src/sbbs3/js_internal.c @@ -400,10 +400,29 @@ js_execfile(JSContext *cx, uintN argc, jsval *arglist) JS_DefineProperty(cx, js_scope, "argv", OBJECT_TO_JSVAL(nargv) ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE); - for(i=arg; i<argc; i++) - JS_SetElement(cx, nargv, i-arg, &argv[i]); + uintN nargc = 0; + for(i=arg; i<argc; i++) { + if(JSVAL_IS_OBJECT(argv[i]) && !JSVAL_IS_NULL(argv[i])) { + JSObject* objarg = JSVAL_TO_OBJECT(argv[i]); + if(JS_IsArrayObject(cx, objarg)) { /* argument is an array (e.g. of strings) */ + jsuint array_length = 0; + if(JS_GetArrayLength(cx, objarg, &array_length) && array_length) { + for(jsuint n = 0; n < array_length; n++) { + if(JS_GetElement(cx, objarg, n, &val)) { + JS_SetElement(cx, nargv, nargc, &val); + nargc++; + } + } + continue; + } + + } + } + JS_SetElement(cx, nargv, nargc, &argv[i]); + nargc++; + } - JS_DefineProperty(cx, js_scope, "argc", INT_TO_JSVAL(argc-arg) + JS_DefineProperty(cx, js_scope, "argc", INT_TO_JSVAL(nargc) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY); js_obj = js_CreateInternalJsObject(cx, js_scope, js_callback, NULL); @@ -709,15 +728,18 @@ static jsSyncMethodSpec js_functions[] = { ,316 }, {"flatten_string", js_flatten, 1, JSTYPE_VOID, JSDOCSTR("[string]") - ,JSDOCSTR("flattens a string, optimizing allocated memory used for concatenated strings") + ,JSDOCSTR("flatten a string, optimizing allocated memory used for concatenated strings") ,316 }, - {"exec", js_execfile, 1, JSTYPE_NUMBER, JSDOCSTR("filename [, startup_dir], obj [,...]") - ,JSDOCSTR("Executes a script optionally with a custom scope. The main difference between this " - "and load() is that scripts called this way can call exit() without terminating the caller. If it does, any " - "on_exit() handlers will be evaluated in scripts scope when the script exists. " - "NOTE: To get a child of the current scope, you need to create an object in the current scope. " - "An anonymous object can be created using 'new function(){}'.") + {"exec", js_execfile, 1, JSTYPE_NUMBER, JSDOCSTR("filename [, startup_dir], <i>object</i> scope [,...]") + ,JSDOCSTR("execute a script within the specified scope. The main difference between this method " + "and <tt>load()</tt> is that scripts called this way can call <tt>exit()</tt> without terminating the caller. If it does, any " + "<tt>on_exit()</tt> handlers will be evaluated in scripts scope when the script exists. <br>" + "NOTE: to get a child of the current scope, you need to create an object in the current scope. " + "An anonymous object can be created using '<tt>new function(){}</tt>'. <br>" + "NOTE: array-type arguments are treated specially: each element of the array is passed " + "as a separate argument (e.g. string) to the script in <tt>argv[]</tt>. " + "This allows one script to generate a variable-length list of arguments to be passed to another.") ,31702 }, {0}