shithub: libmujs

Download patch

ref: 134134e8998b35fb98b59d20a9448c33af9a73d9
parent: 2b4d05a575dae7837fda17b3ec8e240654f5a752
author: Tor Andersson <tor.andersson@gmail.com>
date: Tue May 9 10:23:57 EDT 2017

Don't do unprotected js_tostring calls in js_dostring/file.

Since js_tostring can invoke a toString method, we should guard against
uncaught exceptions when trying to convert the error object to a string.

Add a public function, js_trystring that does a "safe" conversion
to a string.

--- a/jsstate.c
+++ b/jsstate.c
@@ -18,7 +18,7 @@
 
 static void js_defaultpanic(js_State *J)
 {
-	fprintf(stderr, "uncaught exception: %s\n", js_tostring(J, -1));
+	fprintf(stderr, "uncaught exception\n");
 	/* return to javascript to abort */
 }
 
@@ -40,6 +40,18 @@
 	return 0;
 }
 
+const char *js_trystring(js_State *J, int idx, const char *error)
+{
+	const char *s;
+	if (js_try(J)) {
+		js_pop(J, 1);
+		return error;
+	}
+	s = js_tostring(J, idx);
+	js_endtry(J);
+	return s;
+}
+
 static void js_loadstringx(js_State *J, const char *filename, const char *source, int iseval)
 {
 	js_Ast *P;
@@ -126,7 +138,7 @@
 int js_dostring(js_State *J, const char *source)
 {
 	if (js_try(J)) {
-		fprintf(stderr, "%s\n", js_tostring(J, -1));
+		fprintf(stderr, "%s\n", js_trystring(J, -1, "Error"));
 		js_pop(J, 1);
 		return 1;
 	}
@@ -141,7 +153,7 @@
 int js_dofile(js_State *J, const char *filename)
 {
 	if (js_try(J)) {
-		fprintf(stderr, "%s\n", js_tostring(J, -1));
+		fprintf(stderr, "%s\n", js_trystring(J, -1, "Error"));
 		js_pop(J, 1);
 		return 1;
 	}
--- a/main.c
+++ b/main.c
@@ -129,18 +129,18 @@
 static int eval_print(js_State *J, const char *source)
 {
 	if (js_ploadstring(J, "[string]", source)) {
-		fprintf(stderr, "%s\n", js_tostring(J, -1));
+		fprintf(stderr, "%s\n", js_trystring(J, -1, "Error"));
 		js_pop(J, 1);
 		return 1;
 	}
 	js_pushglobal(J);
 	if (js_pcall(J, 0)) {
-		fprintf(stderr, "%s\n", js_tostring(J, -1));
+		fprintf(stderr, "%s\n", js_trystring(J, -1, "Error"));
 		js_pop(J, 1);
 		return 1;
 	}
 	if (js_isdefined(J, -1))
-		printf("%s\n", js_tostring(J, -1));
+		printf("%s\n", js_trystring(J, -1, "can't convert to string"));
 	js_pop(J, 1);
 	return 0;
 }
--- a/mujs.h
+++ b/mujs.h
@@ -172,6 +172,8 @@
 const char *js_tostring(js_State *J, int idx);
 void *js_touserdata(js_State *J, int idx, const char *tag);
 
+const char *js_trystring(js_State *J, int idx, const char *error);
+
 int js_tointeger(js_State *J, int idx);
 int js_toint32(js_State *J, int idx);
 unsigned int js_touint32(js_State *J, int idx);