summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2018-11-04 09:56:39 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2018-11-04 09:56:41 +0000
commit44082f9988c33b6dda519d5cb54d85ee515878b9 (patch)
treeee411c490eaa2bddb6294b95949c3a16af5ddcaa
parentf12dee199c5f6207ddddafd26c85136daa6842ad (diff)
downloadnetsurf-44082f9988c33b6dda519d5cb54d85ee515878b9.tar.gz
netsurf-44082f9988c33b6dda519d5cb54d85ee515878b9.tar.bz2
Slightly nicer handling of js_exec() and errors
-rw-r--r--content/handlers/javascript/duktape/dukky.c66
1 files changed, 47 insertions, 19 deletions
diff --git a/content/handlers/javascript/duktape/dukky.c b/content/handlers/javascript/duktape/dukky.c
index 8cfeb3985..e08a65789 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -627,12 +627,6 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
return (jsobject *)ctx;
}
-static duk_ret_t eval_top_string(duk_context *ctx, void *udata)
-{
- duk_eval(ctx);
- return 0;
-}
-
duk_bool_t dukky_check_timeout(void *udata)
{
#define JS_EXEC_TIMEOUT_MS 10000 /* 10 seconds */
@@ -649,32 +643,66 @@ duk_bool_t dukky_check_timeout(void *udata)
now > (ctx->exec_start_time + JS_EXEC_TIMEOUT_MS);
}
+static duk_ret_t dukky_safe_get(duk_context *ctx, void *udata)
+{
+ duk_get_prop_string(ctx, 0, udata);
+ return 1;
+}
+
bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
{
assert(ctx);
if (txt == NULL || txtlen == 0) return false;
duk_set_top(CTX, 0);
- duk_push_lstring(CTX, txt, txtlen);
(void) nsu_getmonotonic_ms(&ctx->exec_start_time);
- if (duk_safe_call(CTX, eval_top_string, NULL, 1, 1) == DUK_EXEC_ERROR) {
- duk_get_prop_string(CTX, 0, "name");
- duk_get_prop_string(CTX, 0, "message");
- duk_get_prop_string(CTX, 0, "fileName");
- duk_get_prop_string(CTX, 0, "lineNumber");
- duk_get_prop_string(CTX, 0, "stack");
+ duk_push_string(CTX, "?unknown source?");
+ if (duk_pcompile_lstring_filename(CTX, DUK_COMPILE_EVAL, txt, txtlen) != 0) {
+ NSLOG(netsurf, WARN, "Failed to compile JavaScript input");
+ goto handle_error;
+ }
+
+ if (duk_pcall(CTX, 0/*nargs*/) == DUK_EXEC_ERROR) {
+ NSLOG(netsurf, WARN, "Failed to execute JavaScript");
+ goto handle_error;
+ }
+
+ if (duk_get_top(CTX) == 0) duk_push_boolean(CTX, false);
+ NSLOG(netsurf, INFO, "Returning %s",
+ duk_get_boolean(CTX, 0) ? "true" : "false");
+ return duk_get_boolean(CTX, 0);
+
+handle_error:
+ if (!duk_is_error(CTX, 0)) {
+ NSLOG(netsurf, INFO, "Uncaught non-Error derived error in JS: %s", duk_safe_to_string(CTX, 0));
+ } else {
+#define GETTER(what) \
+ if (duk_has_prop_string(CTX, 0, what)) { \
+ NSLOG(netsurf, WARN, "Fetching " what); \
+ duk_dup(CTX, 0); \
+ if (duk_safe_call(CTX, dukky_safe_get, (void *)what, 1, 1) != DUK_EXEC_SUCCESS) { \
+ NSLOG(netsurf, WARN, "Error fetching " what ": %s", duk_safe_to_string(CTX, -1)); \
+ } else { \
+ NSLOG(netsurf, WARN, "Success fetching " what); \
+ } \
+ } else { \
+ NSLOG(netsurf, WARN, "Faking " what); \
+ duk_push_string(CTX, "?" what "?"); \
+ }
+ GETTER("name");
+ GETTER("message");
+ GETTER("fileName");
+ GETTER("lineNumber");
+ GETTER("stack");
NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
duk_safe_to_string(CTX, 1), duk_safe_to_string(CTX, 2));
NSLOG(netsurf, INFO, " was at: %s line %s",
- duk_safe_to_string(CTX, 3), duk_safe_to_string(CTX, 4));
+ duk_safe_to_string(CTX, 3), duk_safe_to_string(CTX, 4));
NSLOG(netsurf, INFO, " Stack trace: %s",
duk_safe_to_string(CTX, 5));
- return false;
+#undef GETTER
}
- if (duk_get_top(CTX) == 0) duk_push_boolean(CTX, false);
- NSLOG(netsurf, INFO, "Returning %s",
- duk_get_boolean(CTX, 0) ? "true" : "false");
- return duk_get_boolean(CTX, 0);
+ return false;
}
/*** New style event handling ***/