From 41b49c3f49255cacf103a0e21ecdffaf61c8074c Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Tue, 18 Aug 2020 16:53:46 +0000 Subject: [PATCH] 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. --- src/njs_function.c | 9 +++++---- src/test/njs_unit_test.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/njs_function.c b/src/njs_function.c index 5bd8fe92..796624e6 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -776,7 +776,7 @@ njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *native) 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 *vm, njs_object_prop_t *prop, 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 --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index a020d16a..d8dcddd4 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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") }, -- 2.47.3