ref: 411b8b5b9c86be6a8f5c357f8f5606f1e9941669
parent: 7b37ef2b8ad907a3803c5dcc8b184f788f961b80
author: Tor Andersson <tor@ccxvii.net>
date: Fri Feb 7 09:24:45 EST 2014
Use length property of cfunctions to make sure we have at least N args. So we don't get temporary stack values that shadow undefined arguments.
--- a/jsrun.c
+++ b/jsrun.c
@@ -744,9 +744,14 @@
js_pushvalue(J, v);
}
-static void jsR_callcfunction(js_State *J, int n, js_CFunction F)
+static void jsR_callcfunction(js_State *J, int n, int min, js_CFunction F)
{
- int rv = F(J, n);
+ int rv;
+
+ while (min++ < n)
+ js_pushundefined(J);
+
+ rv = F(J, n);
if (rv) {
js_Value v = js_tovalue(J, -1);
TOP = --BOT; /* clear stack */
@@ -775,7 +780,7 @@
else if (obj->type == JS_CSCRIPT)
jsR_callscript(J, n, obj->u.f.function);
else if (obj->type == JS_CCFUNCTION)
- jsR_callcfunction(J, n, obj->u.c.function);
+ jsR_callcfunction(J, n, obj->u.c.length, obj->u.c.function);
BOT = savebot;
}
@@ -798,7 +803,7 @@
if (n > 0)
js_rot(J, n + 1);
BOT = TOP - n - 1;
- jsR_callcfunction(J, n, obj->u.c.constructor);
+ jsR_callcfunction(J, n, obj->u.c.length, obj->u.c.constructor);
BOT = savebot;
return;
}
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -272,6 +272,7 @@
js_Object *obj = jsV_newobject(J, JS_CCFUNCTION, J->Function_prototype);
obj->u.c.function = cfun;
obj->u.c.constructor = NULL;
+ obj->u.c.length = length;
js_pushobject(J, obj);
{
js_pushnumber(J, length);
--- a/jsvalue.h
+++ b/jsvalue.h
@@ -73,6 +73,7 @@
struct {
js_CFunction function;
js_CFunction constructor;
+ int length;
} c;
js_Regexp r;
struct {