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);