summaryrefslogtreecommitdiff
path: root/javascript
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2016-01-31 01:38:34 +0000
committerJohn-Mark Bell <jmb@netsurf-browser.org>2016-01-31 01:39:13 +0000
commit720a8fec0e2b435e09d76eabf3c40e78dba414cc (patch)
treecbdd294b5578079cc9e569a40e1c90fae4e7dfc1 /javascript
parentf5ab5703207975bd266356aea95b58cdc91347e9 (diff)
downloadnetsurf-720a8fec0e2b435e09d76eabf3c40e78dba414cc.tar.gz
netsurf-720a8fec0e2b435e09d76eabf3c40e78dba414cc.tar.bz2
Javascript: introduce script execution timeout. For #2413.
Diffstat (limited to 'javascript')
-rw-r--r--javascript/duktape/duk_custom.h6
-rw-r--r--javascript/duktape/dukky.c32
2 files changed, 37 insertions, 1 deletions
diff --git a/javascript/duktape/duk_custom.h b/javascript/duktape/duk_custom.h
index 95a47ac04..1f98b7825 100644
--- a/javascript/duktape/duk_custom.h
+++ b/javascript/duktape/duk_custom.h
@@ -29,3 +29,9 @@
#endif
#define DUK_USE_REGEXP_CANON_WORKAROUND
+
+/* Required for execution timeout checking */
+#define DUK_USE_INTERRUPT_COUNTER
+
+extern duk_bool_t dukky_check_timeout(void *udata);
+#define DUK_USE_EXEC_TIMEOUT_CHECK dukky_check_timeout
diff --git a/javascript/duktape/dukky.c b/javascript/duktape/dukky.c
index d583484bf..2c929b8ce 100644
--- a/javascript/duktape/dukky.c
+++ b/javascript/duktape/dukky.c
@@ -21,6 +21,10 @@
* Duktapeish implementation of javascript engine functions.
*/
+#include <inttypes.h>
+
+#include <nsutils/time.h>
+
#include "content/content.h"
#include "utils/nsoption.h"
@@ -328,6 +332,7 @@ static void dukky_free_function(void *udata, void *ptr)
struct jscontext {
duk_context *ctx;
duk_context *thread;
+ uint64_t exec_start_time;
};
#define CTX (ctx->thread)
@@ -363,7 +368,7 @@ nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
dukky_alloc_function,
dukky_realloc_function,
dukky_free_function,
- NULL,
+ ret,
NULL);
if (ret->ctx == NULL) { free(ret); return NSERROR_NOMEM; }
/* Create the prototype stuffs */
@@ -425,6 +430,22 @@ static duk_ret_t eval_top_string(duk_context *ctx)
return 0;
}
+duk_bool_t dukky_check_timeout(void *udata)
+{
+#define JS_EXEC_TIMEOUT_MS 10000 /* 10 seconds */
+ jscontext *ctx = (jscontext *) udata;
+ uint64_t now;
+
+ (void) nsu_getmonotonic_ms(&now);
+
+ /* This function may be called during duk heap construction,
+ * so only test for execution timeout if we've recorded a
+ * start time.
+ */
+ return ctx->exec_start_time != 0 &&
+ now > (ctx->exec_start_time + JS_EXEC_TIMEOUT_MS);
+}
+
bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
{
assert(ctx);
@@ -432,6 +453,7 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
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, 1, 1) == DUK_EXEC_ERROR) {
duk_get_prop_string(CTX, 0, "name");
duk_get_prop_string(CTX, 0, "message");
@@ -581,12 +603,18 @@ bool dukky_get_current_value_of_event_handler(duk_context *ctx,
static void dukky_generic_event_handler(dom_event *evt, void *pw)
{
+ duk_memory_functions funcs;
duk_context *ctx = (duk_context *)pw;
+ jscontext *jsctx;
dom_string *name;
dom_exception exc;
dom_event_target *targ;
dom_event_flow_phase phase;
+ /* Retrieve the JS context from the Duktape context */
+ duk_get_memory_functions(ctx, &funcs);
+ jsctx = funcs.udata;
+
LOG("WOOP WOOP, An event:");
exc = dom_event_get_type(evt, &name);
if (exc != DOM_NO_ERR) {
@@ -633,6 +661,7 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
/* ... handler node */
dukky_push_event(ctx, evt);
/* ... handler node event */
+ (void) nsu_getmonotonic_ms(&jsctx->exec_start_time);
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... err */
@@ -874,6 +903,7 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
/* ... handler Window */
dukky_push_event(CTX, evt);
/* ... handler Window event */
+ (void) nsu_getmonotonic_ms(&ctx->exec_start_time);
if (duk_pcall_method(CTX, 1) != 0) {
/* Failed to run the handler */
/* ... err */