From 8f00ae1dc960b4fd662d7350005a5ed0f7bb564b Mon Sep 17 00:00:00 2001 From: Andrey Zelenkov Date: Fri, 31 Mar 2017 14:02:38 +0300 Subject: [PATCH] Fixed Number.prototype.toString() method. Found with afl-fuzz. --- njs/njs_number.c | 30 +++++++++++++++++------------- njs/test/njs_unit_test.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/njs/njs_number.c b/njs/njs_number.c index 544c7147..a11bae1f 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -34,7 +34,7 @@ static njs_ret_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, - const njs_value_t *number, uint32_t radix); + double number, uint32_t radix); double @@ -483,7 +483,7 @@ static njs_ret_t njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - double radix; + double number, radix; njs_value_t *value; value = &args[0]; @@ -499,18 +499,22 @@ njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args, } } - if (nargs == 1 || args[1].data.u.number == 10) { - return njs_number_to_string(vm, &vm->retval, value); - } + if (nargs > 1) { + radix = args[1].data.u.number; + + if (radix < 2 || radix > 36 || radix != (int) radix) { + vm->exception = &njs_exception_range_error; + return NXT_ERROR; + } - radix = args[1].data.u.number; + number = value->data.u.number; - if (radix < 2 || radix > 36 || radix != (int) radix) { - vm->exception = &njs_exception_range_error; - return NXT_ERROR; + if (radix != 10 && !isnan(number) && !isinf(number)) { + return njs_number_to_string_radix(vm, &vm->retval, number, radix); + } } - return njs_number_to_string_radix(vm, &vm->retval, value, radix); + return njs_number_to_string(vm, &vm->retval, value); } @@ -527,7 +531,7 @@ njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args, static njs_ret_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, - const njs_value_t *number, uint32_t radix) + double number, uint32_t radix) { u_char *p, *f, *end; double n, next; @@ -540,7 +544,7 @@ njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, end = buf + NJS_STRING_RADIX_LEN; p = buf + NJS_STRING_RADIX_INTERGRAL_LEN; - n = number->data.u.number; + n = number; if (n < 0) { n = -n; @@ -553,7 +557,7 @@ njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, n = next; } while (n != 0); - n = number->data.u.number; + n = number; if (n < 0) { *(--p) = '-'; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 453b427b..9ef2a613 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -156,6 +156,42 @@ static njs_unit_test_t njs_test[] = { nxt_string("1845449130881..toString(36)"), nxt_string("njscript") }, + { nxt_string("Infinity.toString()"), + nxt_string("Infinity") }, + + { nxt_string("Infinity.toString(2)"), + nxt_string("Infinity") }, + + { nxt_string("Infinity.toString(10)"), + nxt_string("Infinity") }, + + { nxt_string("Infinity.toString(NaN)"), + nxt_string("RangeError") }, + + { nxt_string("Infinity.toString({})"), + nxt_string("RangeError") }, + + { nxt_string("Infinity.toString(Infinity)"), + nxt_string("RangeError") }, + + { nxt_string("NaN.toString()"), + nxt_string("NaN") }, + + { nxt_string("NaN.toString(2)"), + nxt_string("NaN") }, + + { nxt_string("NaN.toString(10)"), + nxt_string("NaN") }, + + { nxt_string("NaN.toString(Infinity)"), + nxt_string("RangeError") }, + + { nxt_string("NaN.toString({})"), + nxt_string("RangeError") }, + + { nxt_string("NaN.toString(NaN)"), + nxt_string("RangeError") }, + /* An object "valueOf/toString" methods. */ { nxt_string("var a = { valueOf: function() { return 1 } }; +a"), -- 2.47.3