[njs] Fixed comparison of objects and strings.
Dmitry Volyntsev
xeioex at nginx.com
Thu Aug 30 17:37:22 UTC 2018
details: http://hg.nginx.org/njs/rev/5dd7d38bb08c
branches:
changeset: 595:5dd7d38bb08c
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Aug 30 20:21:18 2018 +0300
description:
Fixed comparison of objects and strings.
diffstat:
njs/njs_vm.c | 40 ++++++++++++++++++++++++++--------------
njs/test/njs_unit_test.c | 28 ++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 14 deletions(-)
diffs (99 lines):
diff -r 6931a42f5bed -r 5dd7d38bb08c njs/njs_vm.c
--- a/njs/njs_vm.c Thu Aug 30 17:21:51 2018 +0300
+++ b/njs/njs_vm.c Thu Aug 30 20:21:18 2018 +0300
@@ -1814,6 +1814,7 @@ njs_vmcode_greater_or_equal(njs_vm_t *vm
/*
+ * ECMAScript 5.1: 11.8.5
* njs_values_compare() returns
* 1 if val1 is less than val2,
* 0 if val1 is greater than or equal to val2,
@@ -1825,24 +1826,35 @@ static nxt_noinline njs_ret_t
njs_values_compare(njs_vm_t *vm, const njs_value_t *val1,
const njs_value_t *val2)
{
- if (nxt_fast_path(njs_is_numeric(val1) || njs_is_numeric(val2))) {
-
- if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) {
-
- /* NaN and void values are not comparable with anything. */
- if (isnan(val1->data.u.number) || isnan(val2->data.u.number)) {
- return -1;
+ double num1, num2;
+
+ if (nxt_fast_path(njs_is_primitive(val1) && njs_is_primitive(val2))) {
+
+ if (nxt_fast_path(njs_is_numeric(val1))) {
+ num1 = val1->data.u.number;
+
+ if (nxt_fast_path(njs_is_numeric(val2))) {
+ num2 = val2->data.u.number;
+
+ } else {
+ num2 = njs_string_to_number(val2, 0);
}
- /* Infinities are handled correctly by comparision. */
- return (val1->data.u.number < val2->data.u.number);
+ } else if (njs_is_numeric(val2)) {
+ num1 = njs_string_to_number(val1, 0);
+ num2 = val2->data.u.number;
+
+ } else {
+ return (njs_string_cmp(val1, val2) < 0) ? 1 : 0;
}
- return njs_trap(vm, NJS_TRAP_NUMBERS);
- }
-
- if (nxt_fast_path(njs_is_string(val1) && njs_is_string(val2))) {
- return (njs_string_cmp(val1, val2) < 0) ? 1 : 0;
+ /* NaN and void values are not comparable with anything. */
+ if (isnan(num1) || isnan(num2)) {
+ return -1;
+ }
+
+ /* Infinities are handled correctly by comparision. */
+ return (num1 < num2);
}
return njs_trap(vm, NJS_TRAP_COMPARISON);
diff -r 6931a42f5bed -r 5dd7d38bb08c njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Thu Aug 30 17:21:51 2018 +0300
+++ b/njs/test/njs_unit_test.c Thu Aug 30 20:21:18 2018 +0300
@@ -1528,6 +1528,34 @@ static njs_unit_test_t njs_test[] =
nxt_string("false") },
/**/
+ { nxt_string("new String('1') > new Number(1)"),
+ nxt_string("false") },
+
+ { nxt_string("new Boolean(true) > '1'"),
+ nxt_string("false") },
+
+ { nxt_string("'0' >= new Number(1)"),
+ nxt_string("false") },
+
+ { nxt_string("'1' >= new Number(1)"),
+ nxt_string("true") },
+
+ { nxt_string("new String('1') < new Number(1)"),
+ nxt_string("false") },
+
+ { nxt_string("new Boolean(true) < '1'"),
+ nxt_string("false") },
+
+ { nxt_string("new String('1') <= new Number(1)"),
+ nxt_string("true") },
+
+ { nxt_string("new Boolean(true) <= '1'"),
+ nxt_string("true") },
+
+ { nxt_string("'-1' < {valueOf: function() {return -2}}"),
+ nxt_string("false") },
+
+ /**/
{ nxt_string("var a; a = 1 ? 2 : 3"),
nxt_string("2") },
More information about the nginx-devel
mailing list