]> git.kaiwu.me - njs.git/commitdiff
Native methods and non-constructor functions must throw
authorIgor Sysoev <igor@sysoev.ru>
Tue, 15 Nov 2016 14:43:05 +0000 (17:43 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Tue, 15 Nov 2016 14:43:05 +0000 (17:43 +0300)
TypeError exception if they are called as constructor.

njs/njs_builtin.c
njs/njs_vm.c
njs/njs_vm.h
njs/test/njs_unit_test.c

index e3dace3c8a97dc75d4b7c7f7ff85db404c03d050..35a7f42dc3dfa3baeef6d0d153f4d03b6e9685b1 100644 (file)
@@ -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];
index cff396b7ba081ba7b19ef99b7273c64533c0a0f4..ee86bf4daa64afd499f19c2e8f1098579984d88e 100644 (file)
@@ -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, njs_value_t *value, njs_value_t *nargs)
     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, njs_value_t *value, njs_value_t *nargs)
             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, njs_value_t *value, njs_value_t *nargs)
         }
 
         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, njs_value_t *value, njs_value_t *nargs)
         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_value_t *object, njs_value_t *value)
         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);
index 06ed0cf3d092d43cb1cddf826b6027524a303838..af185ca66c08b8707ac9b2fa078610dab0c6d815 100644 (file)
@@ -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.
-     */
-
-#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;
index 311c7974ef1ecc1d959f121a5abce01f2de226b7..7950735c8255be3526a97167c4b57a93fe2fd8c7 100644 (file)
@@ -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"),