]> git.kaiwu.me - njs.git/commitdiff
Fixed "in" operator for values with accessor descriptors.
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 5 Aug 2019 18:17:27 +0000 (21:17 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 5 Aug 2019 18:17:27 +0000 (21:17 +0300)
src/njs_vmcode.c
src/test/njs_unit_test.c

index 51951451ac7c8c0225f5a05446687954d6664bf0..80323e70a83858e350750cf389c3fe1d7dc922dd 100644 (file)
@@ -1182,45 +1182,39 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
 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);
+    if (njs_slow_path(ret == NJS_ERROR)) {
+        return ret;
+    }
 
-    switch (ret) {
-
-    case NJS_OK:
-        prop = pq.lhq.value;
-
-        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;
-
-    case NJS_ERROR:
-    default:
+    } else {
+        prop = pq.lhq.value;
 
-        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);
 }
index a87ab398800998c2b269fb46f921e24c5720afee..c609a05065901931c76da3b28b333cf3d22d1e5c 100644 (file)
@@ -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") },