[njs] Fixed function "prototype" property handler while setting.

Dmitry Volyntsev xeioex at nginx.com
Tue Aug 18 16:54:44 UTC 2020


details:   https://hg.nginx.org/njs/rev/c9d18ab3eb85
branches:  
changeset: 1497:c9d18ab3eb85
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Aug 18 16:53:46 2020 +0000
description:
Fixed function "prototype" property handler while setting.

njs_function_prototype_create() works as a getter and setter.  As a
getter the function is expected to create "prototype" property on the
first access, it also sets F.prototype.constructor property to ensure
F.prototype.constructor === F.

Setting of "constructor" property is not needed in setter context, as
it may overwrite existing "constructor" property in setval.

This closes #333 issue on Github.

diffstat:

 src/njs_function.c       |   9 +++++----
 src/test/njs_unit_test.c |  10 ++++++++++
 2 files changed, 15 insertions(+), 4 deletions(-)

diffs (50 lines):

diff -r 94499cbdf990 -r c9d18ab3eb85 src/njs_function.c
--- a/src/njs_function.c	Tue Aug 18 11:52:17 2020 +0000
+++ b/src/njs_function.c	Tue Aug 18 16:53:46 2020 +0000
@@ -776,7 +776,7 @@ njs_function_frame_free(njs_vm_t *vm, nj
 
 
 static njs_value_t *
-njs_function_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
     njs_value_t *prototype)
 {
     njs_int_t           ret;
@@ -845,13 +845,14 @@ njs_function_prototype_create(njs_vm_t *
         return NJS_ERROR;
     }
 
-    proto = njs_function_property_prototype_create(vm, &function->object.hash,
-                                                   setval);
+    proto = njs_function_property_prototype_set(vm, njs_object_hash(value),
+                                                setval);
     if (njs_slow_path(proto == NULL)) {
         return NJS_ERROR;
     }
 
-    if (njs_is_object(proto)) {
+    if (setval == &proto_value && njs_is_object(proto)) {
+        /* Only in getter context. */
         cons = njs_property_constructor_create(vm, njs_object_hash(proto),
                                                value);
         if (njs_slow_path(cons == NULL)) {
diff -r 94499cbdf990 -r c9d18ab3eb85 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Tue Aug 18 11:52:17 2020 +0000
+++ b/src/test/njs_unit_test.c	Tue Aug 18 16:53:46 2020 +0000
@@ -9393,6 +9393,16 @@ static njs_unit_test_t  njs_test[] =
               "x.t == 1 && y.t == 2"),
       njs_str("true") },
 
+    { njs_str("function A(){}; A.tag = 'A'; var a = new A();"
+              "(function B(){}).prototype = A.prototype;"
+              "a.constructor.tag"),
+      njs_str("A") },
+
+    { njs_str("function A(){}; A.tag = 'A'; var a = new A();"
+              "(function B(){}).prototype = a.constructor.prototype;"
+              "a.constructor.tag"),
+      njs_str("A") },
+
     { njs_str("var x = {}, y = function() {}, z; y.prototype = x; z = new y();"
               "(z instanceof y) && (z.__proto__ == y.prototype) && (x.isPrototypeOf(z))"),
       njs_str("true") },


More information about the nginx-devel mailing list