[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