[njs] Native methods and non-constructor functions must throw

Igor Sysoev igor at sysoev.ru
Tue Nov 15 15:02:46 UTC 2016


details:   http://hg.nginx.org/njs/rev/d2ab98ea87ad
branches:  
changeset: 254:d2ab98ea87ad
user:      Igor Sysoev <igor at sysoev.ru>
date:      Tue Nov 15 17:43:05 2016 +0300
description:
Native methods and non-constructor functions must throw
TypeError exception if they are called as constructor.

diffstat:

 njs/njs_builtin.c        |   1 +
 njs/njs_vm.c             |  22 +++++++++++++++++-----
 njs/njs_vm.h             |  16 +++-------------
 njs/test/njs_unit_test.c |   6 ++++++
 4 files changed, 27 insertions(+), 18 deletions(-)

diffs (127 lines):

diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_builtin.c
--- a/njs/njs_builtin.c	Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/njs_builtin.c	Tue Nov 15 17:43:05 2016 +0300
@@ -237,6 +237,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
     for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) {
         constructors[i].object.shared = 0;
         constructors[i].native = 1;
+        constructors[i].ctor = 1;
         constructors[i].args_offset = 1;
         constructors[i].u.native = native_constructors[i].native;
         constructors[i].args_types[0] = native_constructors[i].args_types[0];
diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_vm.c
--- a/njs/njs_vm.c	Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/njs_vm.c	Tue Nov 15 17:43:05 2016 +0300
@@ -2152,6 +2152,7 @@ njs_ret_t
 njs_vmcode_function_frame(njs_vm_t *vm, njs_value_t *value, njs_value_t *nargs)
 {
     njs_ret_t                    ret;
+    nxt_bool_t                   ctor;
     njs_value_t                  val, *this;
     njs_object_t                 *object;
     njs_function_t               *function;
@@ -2160,13 +2161,17 @@ njs_vmcode_function_frame(njs_vm_t *vm, 
     if (nxt_fast_path(njs_is_function(value))) {
 
         func = (njs_vmcode_function_frame_t *) vm->current;
+        ctor = func->code.ctor;
 
         function = value->data.u.function;
 
         if (function->native) {
+            if (ctor && !function->ctor) {
+                goto fail;
+            }
+
             ret = njs_function_native_frame(vm, function, &njs_value_void,
-                                            NULL, (uintptr_t) nargs, 0,
-                                            func->code.ctor);
+                                            NULL, (uintptr_t) nargs, 0, ctor);
 
             if (nxt_fast_path(ret == NXT_OK)) {
                 return sizeof(njs_vmcode_function_frame_t);
@@ -2175,7 +2180,7 @@ njs_vmcode_function_frame(njs_vm_t *vm, 
             return ret;
         }
 
-        if (func->code.ctor) {
+        if (ctor) {
             object = njs_function_new_object(vm, value);
             if (nxt_slow_path(object == NULL)) {
                 return NXT_ERROR;
@@ -2191,7 +2196,7 @@ njs_vmcode_function_frame(njs_vm_t *vm, 
         }
 
         ret = njs_function_frame(vm, function, this, NULL, (uintptr_t) nargs,
-                                 func->code.ctor);
+                                 ctor);
 
         if (nxt_fast_path(ret == NXT_OK)) {
             return sizeof(njs_vmcode_function_frame_t);
@@ -2200,6 +2205,8 @@ njs_vmcode_function_frame(njs_vm_t *vm, 
         return ret;
     }
 
+fail:
+
     vm->exception = &njs_exception_type_error;
 
     return NXT_ERROR;
@@ -2329,8 +2336,13 @@ njs_vmcode_method_call(njs_vm_t *vm, njs
         return ret;
     }
 
+    if (method->code.ctor) {
+        vm->exception = &njs_exception_type_error;
+        return NXT_ERROR;
+    }
+
     ret = njs_function_native_frame(vm, function, object, NULL, method->nargs,
-                                    0, method->code.ctor);
+                                    0, 0);
 
     if (nxt_fast_path(ret == NXT_OK)) {
         njs_retain(object);
diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_vm.h
--- a/njs/njs_vm.h	Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/njs_vm.h	Tue Nov 15 17:43:05 2016 +0300
@@ -230,20 +230,10 @@ struct njs_function_s {
 
     uint8_t                           args_types[NJS_ARGS_TYPES_MAX];
     uint8_t                           args_offset;
-
-    /*
-     * TODO Shared
-     * When function object is used as value: in assignments,
-     * as function argument, as property and as object to get properties.
-     */
+    uint8_t                           continuation_size;
 
-#if (NXT_64BIT)
-    uint8_t                           native;
-    uint8_t                           continuation_size;
-#else
-    uint8_t                           native;
-    uint8_t                           continuation_size;
-#endif
+    uint8_t                           native:1;
+    uint8_t                           ctor:1;
 
     union {
         njs_function_lambda_t         *lambda;
diff -r 91640c0405f4 -r d2ab98ea87ad njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/test/njs_unit_test.c	Tue Nov 15 17:43:05 2016 +0300
@@ -4223,6 +4223,12 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var F = function (){}; typeof F.prototype"),
       nxt_string("object") },
 
+    { nxt_string("new decodeURI('%00')"),
+      nxt_string("TypeError")},
+
+    { nxt_string("new ''.toString"),
+      nxt_string("TypeError")},
+
     { nxt_string("function F() { return Number }"
                  "var o = new (F())(5);"
                  "typeof o +' '+ o"),



More information about the nginx-devel mailing list