[njs] Fixed handling of NJS_DECLINED returned by NJS_PROPERTY_HANDLER.

Dmitry Volyntsev xeioex at nginx.com
Wed Aug 14 17:24:15 UTC 2019


details:   https://hg.nginx.org/njs/rev/8b2f303ab48a
branches:  
changeset: 1131:8b2f303ab48a
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Aug 14 20:22:32 2019 +0300
description:
Fixed handling of NJS_DECLINED returned by NJS_PROPERTY_HANDLER.

diffstat:

 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(-)

diffs (130 lines):

diff -r 857ecc6fbd25 -r 8b2f303ab48a src/njs_array.c
--- a/src/njs_array.c	Wed Aug 14 20:22:26 2019 +0300
+++ b/src/njs_array.c	Wed Aug 14 20:22:32 2019 +0300
@@ -331,8 +331,8 @@ njs_array_length(njs_vm_t *vm, njs_value
         } 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
     }
 
     if (proto->type != NJS_ARRAY) {
+        njs_set_undefined(retval);
         return NJS_DECLINED;
     }
 
diff -r 857ecc6fbd25 -r 8b2f303ab48a src/njs_object_prop.c
--- a/src/njs_object_prop.c	Wed Aug 14 20:22:26 2019 +0300
+++ b/src/njs_object_prop.c	Wed Aug 14 20:22:32 2019 +0300
@@ -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,
             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 -r 857ecc6fbd25 -r 8b2f303ab48a src/njs_value.c
--- a/src/njs_value.c	Wed Aug 14 20:22:26 2019 +0300
+++ b/src/njs_value.c	Wed Aug 14 20:22:32 2019 +0300
@@ -1018,11 +1018,12 @@ njs_value_property(njs_vm_t *vm, njs_val
             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
         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 -r 857ecc6fbd25 -r 8b2f303ab48a src/njs_value.h
--- a/src/njs_value.h	Wed Aug 14 20:22:26 2019 +0300
+++ b/src/njs_value.h	Wed Aug 14 20:22:32 2019 +0300
@@ -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 -r 857ecc6fbd25 -r 8b2f303ab48a src/njs_vmcode.c
--- a/src/njs_vmcode.c	Wed Aug 14 20:22:26 2019 +0300
+++ b/src/njs_vmcode.c	Wed Aug 14 20:22:32 2019 +0300
@@ -1168,11 +1168,15 @@ njs_vmcode_property_init(njs_vm_t *vm, n
                 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,
             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 -r 857ecc6fbd25 -r 8b2f303ab48a src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Aug 14 20:22:26 2019 +0300
+++ b/src/test/njs_unit_test.c	Wed Aug 14 20:22:32 2019 +0300
@@ -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") },
 


More information about the nginx-devel mailing list