shithub: libmujs

Download patch

ref: d59d0e2721540568c3f9c0e0ae2b464c6b289ad6
parent: 22a74771615f4c645ba27ad4b170235c96c02175
author: Tor Andersson <tor@ccxvii.net>
date: Fri Feb 7 10:45:08 EST 2014

Make argc/undefined checks more resilient.

--- a/js.h
+++ b/js.h
@@ -123,6 +123,7 @@
 void js_newuserdata(js_State *J, const char *tag, void *data);
 void js_newregexp(js_State *J, const char *pattern, int flags);
 
+int js_isdefined(js_State *J, int idx);
 int js_isundefined(js_State *J, int idx);
 int js_isnull(js_State *J, int idx);
 int js_isboolean(js_State *J, int idx);
--- a/jsarray.c
+++ b/jsarray.c
@@ -102,16 +102,19 @@
 static int Ap_join(js_State *J, int argc)
 {
 	char * volatile out = NULL;
-	const char *sep = ",";
+	const char *sep;
 	const char *r;
-	unsigned int seplen = 1;
+	unsigned int seplen;
 	unsigned int k, n, len;
 
 	len = js_getlength(J, 0);
 
-	if (argc == 1 && !js_isundefined(J, 1)) {
+	if (js_isdefined(J, 1)) {
 		sep = js_tostring(J, 1);
 		seplen = strlen(sep);
+	} else {
+		sep = ",";
+		seplen = 1;
 	}
 
 	if (len == 0) {
@@ -253,7 +256,7 @@
 
 	len = js_getlength(J, 0);
 	s = js_tointeger(J, 1);
-	e = argc > 1 ? js_tointeger(J, 2) : len;
+	e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
 
 	if (s < 0) s = s + len;
 	if (e < 0) e = e + len;
@@ -424,7 +427,7 @@
 	int k, len, from;
 
 	len = js_getlength(J, 0);
-	from = argc > 1 ? js_tointeger(J, 2) : 0;
+	from = js_isdefined(J, 2) ? js_tointeger(J, 2) : 0;
 	if (from < 0) from = len + from;
 	if (from < 0) from = 0;
 
@@ -448,7 +451,7 @@
 	int k, len, from;
 
 	len = js_getlength(J, 0);
-	from = argc > 1 ? js_tointeger(J, 2) : len;
+	from = js_isdefined(J, 2) ? js_tointeger(J, 2) : len - 1;
 	if (from > len - 1) from = len - 1;
 	if (from < 0) from = len + from;
 
--- a/jsbuiltin.c
+++ b/jsbuiltin.c
@@ -40,7 +40,7 @@
 static int jsB_parseInt(js_State *J, int argc)
 {
 	const char *s = js_tostring(J, 1);
-	double radix = argc > 1 ? js_tonumber(J, 2) : 10;
+	double radix = js_isdefined(J, 2) ? js_tonumber(J, 2) : 10;
 	js_pushnumber(J, strtol(s, NULL, radix == 0 ? 10 : radix));
 	return 1;
 }
--- a/jserror.c
+++ b/jserror.c
@@ -14,12 +14,12 @@
 		js_typeerror(J, "not an object");
 
 	js_getproperty(J, 0, "name");
-	if (!js_isundefined(J, -1))
+	if (js_isdefined(J, -1))
 		name = js_tostring(J, -1);
 	js_pop(J, 1);
 
 	js_getproperty(J, 0, "message");
-	if (!js_isundefined(J, -1))
+	if (js_isdefined(J, -1))
 		message = js_tostring(J, -1);
 	js_pop(J, 1);
 
@@ -40,7 +40,7 @@
 static int jsB_ErrorX(js_State *J, int argc, js_Object *prototype)
 {
 	js_pushobject(J, jsV_newobject(J, JS_CERROR, prototype));
-	if (argc > 0) {
+	if (js_isdefined(J, 1)) {
 		js_pushstring(J, js_tostring(J, 1));
 		js_setproperty(J, -2, "message");
 	}
--- a/jsfunction.c
+++ b/jsfunction.c
@@ -12,7 +12,7 @@
 	js_Function *fun;
 	int i;
 
-	if (argc == 0)
+	if (js_isundefined(J, 1))
 		source = "";
 	else {
 		source = js_tostring(J, argc);
--- a/jsnumber.c
+++ b/jsnumber.c
@@ -4,13 +4,13 @@
 
 static int jsB_new_Number(js_State *J, int argc)
 {
-	js_newnumber(J, argc > 0 ? js_tonumber(J, 1) : 0);
+	js_newnumber(J, js_isdefined(J, 1) ? js_tonumber(J, 1) : 0);
 	return 1;
 }
 
 static int jsB_Number(js_State *J, int argc)
 {
-	js_pushnumber(J, argc > 0 ? js_tonumber(J, 1) : 0);
+	js_pushnumber(J, js_isdefined(J, 1) ? js_tonumber(J, 1) : 0);
 	return 1;
 }
 
--- a/jsobject.c
+++ b/jsobject.c
@@ -51,7 +51,7 @@
 
 static int Op_valueOf(js_State *J, int argc)
 {
-	/* return the 'this' object */
+	js_copy(J, 0);
 	return 1;
 }
 
@@ -258,7 +258,7 @@
 	obj = jsV_newobject(J, JS_COBJECT, proto);
 	js_pushobject(J, obj);
 
-	if (!js_isundefined(J, 2)) {
+	if (js_isdefined(J, 2)) {
 		if (!js_isobject(J, 2)) js_typeerror(J, "not an object");
 		props = js_toobject(J, 2);
 		for (ref = props->head; ref; ref = ref->next) {
--- a/jsregexp.c
+++ b/jsregexp.c
@@ -115,7 +115,7 @@
 	int flags;
 
 	if (js_isregexp(J, 1)) {
-		if (argc > 1)
+		if (js_isdefined(J, 2))
 			js_typeerror(J, "cannot supply flags when creating one RegExp from another");
 		old = js_toregexp(J, 1);
 		pattern = old->source;
@@ -128,7 +128,7 @@
 		flags = 0;
 	}
 
-	if (argc > 1) {
+	if (js_isdefined(J, 2)) {
 		const char *s = js_tostring(J, 2);
 		int g = 0, i = 0, m = 0;
 		while (*s) {
--- a/jsrun.c
+++ b/jsrun.c
@@ -126,6 +126,7 @@
 	return STACK + idx;
 }
 
+int js_isdefined(js_State *J, int idx) { return stackidx(J, idx)->type != JS_TUNDEFINED; }
 int js_isundefined(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TUNDEFINED; }
 int js_isnull(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TNULL; }
 int js_isboolean(js_State *J, int idx) { return stackidx(J, idx)->type == JS_TBOOLEAN; }
--- a/jsstring.c
+++ b/jsstring.c
@@ -9,13 +9,13 @@
 
 static int jsB_new_String(js_State *J, int argc)
 {
-	js_newstring(J, argc > 0 ? js_tostring(J, 1) : "");
+	js_newstring(J, js_isdefined(J, 1) ? js_tostring(J, 1) : "");
 	return 1;
 }
 
 static int jsB_String(js_State *J, int argc)
 {
-	js_pushliteral(J, argc > 0 ? js_tostring(J, 1) : "");
+	js_pushliteral(J, js_isdefined(J, 1) ? js_tostring(J, 1) : "");
 	return 1;
 }
 
@@ -148,7 +148,7 @@
 {
 	const char *haystack = js_tostring(J, 0);
 	const char *needle = js_tostring(J, 1);
-	int pos = argc > 1 ? js_tointeger(J, 2) : strlen(haystack);
+	int pos = js_isdefined(J, 2) ? js_tointeger(J, 2) : strlen(haystack);
 	int len = strlen(needle);
 	int k = 0, last = -1;
 	Rune rune;
@@ -175,7 +175,7 @@
 	const char *ss, *ee;
 	int len = utflen(str);
 	int s = js_tointeger(J, 1);
-	int e = argc > 1 ? js_tointeger(J, 2) : len;
+	int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
 
 	s = s < 0 ? s + len : s;
 	e = e < 0 ? e + len : e;
@@ -201,7 +201,7 @@
 	const char *ss, *ee;
 	int len = utflen(str);
 	int s = js_tointeger(J, 1);
-	int e = argc > 1 ? js_tointeger(J, 2) : len;
+	int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len;
 
 	s = s < 0 ? 0 : s > len ? len : s;
 	e = e < 0 ? 0 : e > len ? len : e;
@@ -547,7 +547,7 @@
 
 	str = js_tostring(J, 0);
 	re = js_toregexp(J, 1);
-	limit = !js_isundefined(J, 2) ? js_touint32(J, 2) : 1 << 30;
+	limit = js_isdefined(J, 2) ? js_touint32(J, 2) : 1 << 30;
 
 	js_newarray(J);
 	len = 0;
@@ -602,7 +602,7 @@
 {
 	const char *str = js_tostring(J, 0);
 	const char *sep = js_tostring(J, 1);
-	unsigned int limit = !js_isundefined(J, 2) ? js_touint32(J, 2) : 1 << 30;
+	unsigned int limit = js_isdefined(J, 2) ? js_touint32(J, 2) : 1 << 30;
 	unsigned int i, n;
 
 	js_newarray(J);