From 4e6d424aab753ff8d1661db164b09ecd0244401c Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Thu, 25 Apr 2019 15:19:37 +0300 Subject: [PATCH] Fixed special getters for objects created using Object.create(). This closes #124 issue on Github. --- njs/njs_array.c | 13 ++++++++++++- njs/njs_function.c | 13 ++++++++++++- njs/njs_object.c | 1 - njs/njs_string.c | 23 +++++++++++++++++++---- njs/test/njs_unit_test.c | 12 ++++++++++++ 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/njs/njs_array.c b/njs/njs_array.c index f421f6e1..934f6256 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -420,8 +420,19 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_ret_t ret; njs_value_t *val; njs_array_t *array; + njs_object_t *proto; - array = value->data.u.array; + proto = value->data.u.object; + + do { + if (nxt_fast_path(proto->type == NJS_ARRAY)) { + break; + } + + proto = proto->__proto__; + } while (proto != NULL); + + array = (njs_array_t *) proto; if (setval != NULL) { if (!njs_is_number(setval)) { diff --git a/njs/njs_function.c b/njs/njs_function.c index cb3f4018..6d36f9ff 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -894,10 +894,21 @@ njs_function_instance_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { nxt_uint_t n; + njs_object_t *proto; njs_function_t *function; njs_function_lambda_t *lambda; - function = value->data.u.function; + proto = value->data.u.object; + + do { + if (nxt_fast_path(proto->type == NJS_FUNCTION)) { + break; + } + + proto = proto->__proto__; + } while (proto != NULL); + + function = (njs_function_t *) proto; if (function->native) { for (n = function->args_offset; n < NJS_ARGS_TYPES_MAX; n++) { diff --git a/njs/njs_object.c b/njs/njs_object.c index 8526dda3..3018d71f 100644 --- a/njs/njs_object.c +++ b/njs/njs_object.c @@ -283,7 +283,6 @@ njs_object_property(njs_vm_t *vm, const njs_object_t *object, * NXT_ERROR exception has been thrown. * * TODO: - * Object.create([1,2]).length * Object.defineProperty([1,2], '1', {configurable:false}) */ diff --git a/njs/njs_string.c b/njs/njs_string.c index 1a483c25..982399da 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -626,8 +626,10 @@ static njs_ret_t njs_string_instance_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { - size_t size; - uintptr_t length; + size_t size; + uintptr_t length; + njs_object_t *proto; + njs_object_value_t *ov; /* * This getter can be called for string primitive, String object, @@ -635,8 +637,21 @@ njs_string_instance_length(njs_vm_t *vm, njs_value_t *value, */ length = 0; - if (value->type == NJS_OBJECT_STRING) { - value = &value->data.u.object_value->value; + if (nxt_slow_path(njs_is_object(value))) { + proto = value->data.u.object; + + do { + if (nxt_fast_path(proto->type == NJS_OBJECT_STRING)) { + break; + } + + proto = proto->__proto__; + } while (proto != NULL); + + if (proto != NULL) { + ov = (njs_object_value_t *) proto; + value = &ov->value; + } } if (njs_is_string(value)) { diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 7bd183dd..6f4c90a4 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -9110,6 +9110,18 @@ static njs_unit_test_t njs_test[] = "1..isPrototypeOf(p)"), nxt_string("false") }, + { nxt_string("Object.create(new String('asdf')).length"), + nxt_string("4") }, + + { nxt_string("Object.create(Object('123')).length"), + nxt_string("3") }, + + { nxt_string("Object.create([1,2]).length"), + nxt_string("2") }, + + { nxt_string("Object.create(function(a,b,c){}).length"), + nxt_string("3") }, + { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').value"), nxt_string("1") }, -- 2.47.3