[njs] Fixed "in" operator for values with accessor descriptors.

Dmitry Volyntsev xeioex at nginx.com
Mon Aug 5 18:17:52 UTC 2019


details:   https://hg.nginx.org/njs/rev/dda649936723
branches:  
changeset: 1108:dda649936723
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Aug 05 21:17:27 2019 +0300
description:
Fixed "in" operator for values with accessor descriptors.

diffstat:

 src/njs_vmcode.c         |  38 ++++++++++++++++----------------------
 src/test/njs_unit_test.c |   9 +++++++++
 2 files changed, 25 insertions(+), 22 deletions(-)

diffs (84 lines):

diff -r 439e2f67acf8 -r dda649936723 src/njs_vmcode.c
--- a/src/njs_vmcode.c	Mon Aug 05 19:02:17 2019 +0300
+++ b/src/njs_vmcode.c	Mon Aug 05 21:17:27 2019 +0300
@@ -1182,45 +1182,39 @@ njs_vmcode_property_init(njs_vm_t *vm, n
 static njs_jump_off_t
 njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
 {
-    njs_jump_off_t        ret;
+    njs_int_t             ret;
+    njs_bool_t            found;
     njs_object_prop_t     *prop;
-    const njs_value_t     *retval;
     njs_property_query_t  pq;
 
-    retval = &njs_value_false;
+    found = 0;
 
     njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
 
     ret = njs_property_query(vm, &pq, value, key);
-
-    switch (ret) {
-
-    case NJS_OK:
-        prop = pq.lhq.value;
+    if (njs_slow_path(ret == NJS_ERROR)) {
+        return ret;
+    }
 
-        if (!njs_is_valid(&prop->value)) {
-            break;
-        }
-
-        retval = &njs_value_true;
-        break;
-
-    case NJS_DECLINED:
+    if (ret == NJS_DECLINED) {
         if (!njs_is_object(value) && !njs_is_external(value)) {
             njs_type_error(vm, "property in on a primitive value");
 
             return NJS_ERROR;
         }
 
-        break;
+    } else {
+        prop = pq.lhq.value;
 
-    case NJS_ERROR:
-    default:
-
-        return ret;
+        if (/* !njs_is_data_descriptor(prop) */
+            prop->writable == NJS_ATTRIBUTE_UNSET
+            || njs_is_valid(&prop->value))
+        {
+            found = 1;
+        }
     }
 
-    vm->retval = *retval;
+    njs_set_boolean(&vm->retval, found);
 
     return sizeof(njs_vmcode_3addr_t);
 }
diff -r 439e2f67acf8 -r dda649936723 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Mon Aug 05 19:02:17 2019 +0300
+++ b/src/test/njs_unit_test.c	Mon Aug 05 21:17:27 2019 +0300
@@ -3309,6 +3309,15 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("'a' in {a:1}"),
       njs_str("true") },
 
+    { njs_str("'1' in [0,,2]"),
+      njs_str("false") },
+
+    { njs_str("var o = {}; Object.defineProperty(o, 'a', {get:()=>und}); 'a' in o"),
+      njs_str("true") },
+
+    { njs_str("var o = {}; Object.defineProperty(o, 'a', {value:1}); ({toString(){return 'a'}}) in o"),
+      njs_str("true") },
+
     { njs_str("'a' in Object.create({a:1})"),
       njs_str("true") },
 


More information about the nginx-devel mailing list