Skip to content

Commit

Permalink
Fixed njs_vmcode_interpreter() when "toString" conversion fails.
Browse files Browse the repository at this point in the history
Previously, while interpreting a user function, njs_vmcode_interpreter()
might return prematurely when an error happens.  This is not correct
because the current frame has to be unwound (or exception caught)
first.

The fix is exit through only 5 appropriate exit points to ensure
proper unwinding.

This closes #467 issue on Github.
  • Loading branch information
xeioex committed Mar 28, 2022
1 parent 7723f9d commit 222d6fd
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/njs_vmcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, void *promise_cap,
ret = njs_object_prop_define(vm, value1, &name, function,
accessor->type);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
goto error;
}

ret = sizeof(njs_vmcode_prop_accessor_t);
Expand Down Expand Up @@ -779,12 +779,12 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, void *promise_cap,
}

if (njs_slow_path(!njs_is_function(&dst))) {
ret = njs_value_to_key(vm, value2, value2);
ret = njs_value_to_key(vm, &dst, value2);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
goto error;
}

njs_key_string_get(vm, value2, &string);
njs_key_string_get(vm, &dst, &string);
njs_type_error(vm,
"(intermediate value)[\"%V\"] is not a function",
&string);
Expand Down Expand Up @@ -950,7 +950,8 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, void *promise_cap,
if (njs_is_valid(value1)) {
value1 = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t));
if (njs_slow_path(value1 == NULL)) {
return NJS_ERROR;
njs_memory_error(vm);
goto error;
}

njs_scope_value_set(vm, var->dst, value1);
Expand All @@ -967,7 +968,8 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, void *promise_cap,

value1 = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t));
if (njs_slow_path(value1 == NULL)) {
return NJS_ERROR;
njs_memory_error(vm);
goto error;
}

*value1 = *value2;
Expand Down
5 changes: 5 additions & 0 deletions src/test/njs_unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3409,6 +3409,11 @@ static njs_unit_test_t njs_test[] =

/**/

{ njs_str("function f() { Object.prototype.toString = 1; };"
"Object.prototype.toString = f;"
"(function () { try { 's'[{}](); } catch (e) { throw e; } })()"),
njs_str("TypeError: Cannot convert object to primitive value") },

{ njs_str("var i; for (i = 0; i < 10; i++) { i += 1 } i"),
njs_str("10") },

Expand Down

0 comments on commit 222d6fd

Please sign in to comment.