[njs] Fixed Number.prototype.toString() method.
Igor Sysoev
igor at sysoev.ru
Fri Mar 31 13:07:59 UTC 2017
details: http://hg.nginx.org/njs/rev/8e20f235b71e
branches:
changeset: 325:8e20f235b71e
user: Andrey Zelenkov <zelenkov at nginx.com>
date: Fri Mar 31 14:02:38 2017 +0300
description:
Fixed Number.prototype.toString() method.
Found with afl-fuzz.
diffstat:
njs/njs_number.c | 34 +++++++++++++++++++---------------
njs/test/njs_unit_test.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 15 deletions(-)
diffs (127 lines):
diff -r b7d65eb7d6fa -r 8e20f235b71e njs/njs_number.c
--- a/njs/njs_number.c Thu Mar 30 22:01:17 2017 +0300
+++ b/njs/njs_number.c Fri Mar 31 14:02:38 2017 +0300
@@ -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
}
}
- 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;
+ }
+
+ number = value->data.u.number;
+
+ if (radix != 10 && !isnan(number) && !isinf(number)) {
+ return njs_number_to_string_radix(vm, &vm->retval, number, radix);
+ }
}
- radix = args[1].data.u.number;
-
- if (radix < 2 || radix > 36 || radix != (int) radix) {
- vm->exception = &njs_exception_range_error;
- return NXT_ERROR;
- }
-
- 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
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,
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,
n = next;
} while (n != 0);
- n = number->data.u.number;
+ n = number;
if (n < 0) {
*(--p) = '-';
diff -r b7d65eb7d6fa -r 8e20f235b71e njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Thu Mar 30 22:01:17 2017 +0300
+++ b/njs/test/njs_unit_test.c Fri Mar 31 14:02:38 2017 +0300
@@ -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"),
More information about the nginx-devel
mailing list