]> git.kaiwu.me - njs.git/commitdiff
Fixed equality operator with object and string.
authorValentin Bartenev <vbart@nginx.com>
Fri, 9 Nov 2018 15:22:01 +0000 (18:22 +0300)
committerValentin Bartenev <vbart@nginx.com>
Fri, 9 Nov 2018 15:22:01 +0000 (18:22 +0300)
njs/njs_vm.c
njs/test/njs_unit_test.c

index 1baf4dedc49786a34ceae8ccc86cfcc5a83bb537..cdf80a5dc06e6125ac2ae3c5b9bf3c2d6ff40265 100644 (file)
@@ -1519,7 +1519,8 @@ njs_vmcode_not_equal(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2)
 static nxt_noinline njs_ret_t
 njs_values_equal(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2)
 {
-    nxt_bool_t  nv1, nv2;
+    nxt_bool_t         nv1, nv2;
+    const njs_value_t  *hv, *lv;
 
     nv1 = njs_is_null_or_void(val1);
     nv2 = njs_is_null_or_void(val2);
@@ -1543,11 +1544,29 @@ njs_values_equal(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2)
         return (val1->data.u.object == val2->data.u.object);
     }
 
-    if (njs_is_object(val1) && njs_is_object(val2)) {
+    /* Sort values as: numeric < string < objects. */
+
+    if (val1->type > val2->type) {
+        hv = val1;
+        lv = val2;
+
+    } else {
+        hv = val2;
+        lv = val1;
+    }
+
+    /* If "lv" is an object then "hv" can only be another object. */
+    if (njs_is_object(lv)) {
         return 0;
     }
 
-    return njs_trap(vm, NJS_TRAP_NUMBERS);
+    /* If "hv" is a string then "lv" can only be a numeric. */
+    if (njs_is_string(hv)) {
+        return (lv->data.u.number == njs_string_to_number(hv, 0));
+    }
+
+    /* "hv" is an object and "lv" is either a string or a numeric. */
+    return njs_trap(vm, NJS_TRAP_COMPARISON);
 }
 
 
index c8557381d345af4c6df159c642b08b02cfab283a..4033e2af6be557de31a0926487c92ece54ee47d6 100644 (file)
@@ -1142,6 +1142,15 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = Object; a == Object"),
       nxt_string("true") },
 
+    { nxt_string("'1' == new Number(1)"),
+      nxt_string("true") },
+
+    { nxt_string("new String('abc') == 'abc'"),
+      nxt_string("true") },
+
+    { nxt_string("false == new String('0')"),
+      nxt_string("true") },
+
     { nxt_string("var a = { valueOf: function() { return 5 } };   a == 5"),
       nxt_string("true") },
 
@@ -1151,6 +1160,16 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = { valueOf: function() { return '5' } }; a == '5'"),
       nxt_string("true") },
 
+    { nxt_string("var a = { valueOf: function() { return 5 } }; a == '5'"),
+      nxt_string("true") },
+
+    { nxt_string("var a = { toString: function() { return true } }; '1' == a"),
+      nxt_string("true") },
+
+    { nxt_string("var a = { valueOf: function() { return 'b' },"
+                 "          toString: function() { return 'a' } }; a == 'a'"),
+      nxt_string("false") },
+
     /* Comparisions. */
 
     { nxt_string("1 < 2"),