shithub: libmujs

Download patch

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 {