]> git.kaiwu.me - njs.git/commitdiff
Fixed njs_vmcode_interpreter() when "toString" conversion fails.
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 28 Mar 2022 16:22:17 +0000 (16:22 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 28 Mar 2022 16:22:17 +0000 (16:22 +0000)
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.

src/njs_vmcode.c
src/test/njs_unit_test.c

index 0b07ec67ea680532cb357e975ffe65bf200c3261..6b10200ee19eb8c17370f739b2db2a1c9ad9b71e 100644 (file)
@@ -700,7 +700,7 @@ next:
                 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);
@@ -779,12 +779,12 @@ next:
                 }
 
                 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);
@@ -950,7 +950,8 @@ next:
                 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);
@@ -967,7 +968,8 @@ next:
 
                 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;
index ef5b3ca452ce82445e01145cde9443fa4cd2907e..186defa1afd405d8ae3bd41a484ac1c98584b64f 100644 (file)
@@ -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") },