From: Dmitry Volyntsev Date: Thu, 30 Aug 2018 17:21:18 +0000 (+0300) Subject: Fixed comparison of objects and strings. X-Git-Tag: 0.2.4~12 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=5e4ec704081b525e384769369838b30ba0cd5427;p=njs.git Fixed comparison of objects and strings. --- diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 7ca11110..0c68234e 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -1814,6 +1814,7 @@ njs_vmcode_greater_or_equal(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) /* + * 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))) { + double num1, num2; - if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { + 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; - /* NaN and void values are not comparable with anything. */ - if (isnan(val1->data.u.number) || isnan(val2->data.u.number)) { - return -1; + } 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); - } + /* NaN and void values are not comparable with anything. */ + if (isnan(num1) || isnan(num2)) { + return -1; + } - if (nxt_fast_path(njs_is_string(val1) && njs_is_string(val2))) { - return (njs_string_cmp(val1, val2) < 0) ? 1 : 0; + /* Infinities are handled correctly by comparision. */ + return (num1 < num2); } return njs_trap(vm, NJS_TRAP_COMPARISON); diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 842d5afd..e30f2331 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -1527,6 +1527,34 @@ static njs_unit_test_t njs_test[] = { nxt_string("[0] >= ({})"), 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"),