From 2f2bf4fb99b3fb5e9ce9b731d11c7cb464545982 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 14 Aug 2019 20:22:32 +0300 Subject: [PATCH] Fixed handling of NJS_DECLINED returned by NJS_PROPERTY_HANDLER. --- src/njs_array.c | 5 +++-- src/njs_object_prop.c | 9 ++++----- src/njs_value.c | 5 +++-- src/njs_value.h | 3 ++- src/njs_vmcode.c | 10 +++++++--- src/test/njs_unit_test.c | 3 +++ 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/njs_array.c b/src/njs_array.c index 1ea1a4ef..3da31f03 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -331,8 +331,8 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, } while (proto != NULL); if (njs_slow_path(proto == NULL)) { - njs_internal_error(vm, "no array in proto chain"); - return NJS_ERROR; + njs_set_undefined(retval); + return NJS_DECLINED; } array = (njs_array_t *) proto; @@ -342,6 +342,7 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, } if (proto->type != NJS_ARRAY) { + njs_set_undefined(retval); return NJS_DECLINED; } diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index 509de6d5..01524408 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -324,10 +324,9 @@ done: if (njs_is_valid(&prop->value)) { if (prev->type == NJS_PROPERTY_HANDLER) { if (njs_is_data_descriptor(prev) && prev->writable) { - ret = prev->value.data.u.prop_handler(vm, object, - &prop->value, - &vm->retval); - if (njs_slow_path(ret != NJS_OK)) { + ret = prev->value.data.u.prop_handler(vm, object, &prop->value, + &vm->retval); + if (njs_slow_path(ret == NJS_ERROR)) { return ret; } } @@ -519,7 +518,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, prop = &pq.scratch; ret = prop->value.data.u.prop_handler(vm, value, NULL, &prop->value); - if (njs_slow_path(ret != NJS_OK)) { + if (njs_slow_path(ret == NJS_ERROR)) { return ret; } diff --git a/src/njs_value.c b/src/njs_value.c index f97d270a..9a034d19 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -1018,11 +1018,12 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, ret = prop->value.data.u.prop_handler(vm, value, NULL, &prop->value); - if (njs_slow_path(ret != NJS_OK)) { + if (njs_slow_path(ret == NJS_ERROR)) { return ret; } *retval = prop->value; + break; default: @@ -1096,7 +1097,7 @@ njs_value_property_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, if (prop->type == NJS_PROPERTY_HANDLER) { ret = prop->value.data.u.prop_handler(vm, value, setval, &vm->retval); - if (ret != NJS_DECLINED) { + if (njs_slow_path(ret != NJS_DECLINED)) { return ret; } } diff --git a/src/njs_value.h b/src/njs_value.h index 592269ef..79bc90d6 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -85,7 +85,8 @@ typedef enum { * njs_prop_handler_t is expected to return: * NJS_OK - handler executed successfully; * NJS_ERROR - some error, vm->retval contains appropriate exception; - * NJS_DECLINED - handler was applied to inappropriate object. + * NJS_DECLINED - handler was applied to inappropriate object, vm->retval + * contains undefined value. */ typedef njs_int_t (*njs_prop_handler_t) (njs_vm_t *vm, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 2f32f600..d4b8878b 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -1168,11 +1168,15 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, if (prop->type == NJS_PROPERTY_HANDLER) { ret = prop->value.data.u.prop_handler(vm, value, init, &vm->retval); - if (njs_slow_path(ret != NJS_OK)) { + if (njs_slow_path(ret == NJS_ERROR)) { return ret; } - break; + if (ret == NJS_OK) { + break; + } + + /* NJS_DECLINED */ } } } @@ -1273,7 +1277,7 @@ njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key) if (njs_is_external(value)) { ret = prop->value.data.u.prop_handler(vm, value, NULL, NULL); if (njs_slow_path(ret != NJS_OK)) { - return ret; + return NJS_ERROR; } goto done; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 6fb8a59f..aadb8f33 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -8807,6 +8807,9 @@ static njs_unit_test_t njs_test[] = "Object.getPrototypeOf(o) === Object.prototype"), njs_str("true") }, + { njs_str("var o = {__proto__: Array.prototype, length:3}; o.fill('a')[2]"), + njs_str("a") }, + { njs_str("({}).__proto__.constructor === Object"), njs_str("true") }, -- 2.47.3