[njs] parseInt() did not test invalid values.

Igor Sysoev igor at sysoev.ru
Fri May 26 17:14:30 UTC 2017


details:   http://hg.nginx.org/njs/rev/be8d68d4b8b5
branches:  
changeset: 342:be8d68d4b8b5
user:      Igor Sysoev <igor at sysoev.ru>
date:      Fri May 26 20:07:24 2017 +0300
description:
parseInt() did not test invalid values.

diffstat:

 njs/njs_number.c         |  22 ++++++++++++----------
 njs/njs_number.h         |   3 +--
 njs/njs_parser.c         |   7 ++++---
 njs/test/njs_unit_test.c |  10 ++++++++--
 4 files changed, 25 insertions(+), 17 deletions(-)

diffs (117 lines):

diff -r fc6c8da00858 -r be8d68d4b8b5 njs/njs_number.c
--- a/njs/njs_number.c	Thu May 25 14:16:31 2017 +0300
+++ b/njs/njs_number.c	Fri May 26 20:07:24 2017 +0300
@@ -132,9 +132,11 @@ njs_number_parse(const u_char **start, c
 
 
 int64_t
-njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix, nxt_bool_t exact)
+njs_number_radix_parse(u_char **start, u_char *end, uint8_t radix)
 {
+    u_char    *p;
     uint8_t   d;
+    int64_t   num;
     uint64_t  n;
 
     static const int8_t  digits[256]
@@ -158,19 +160,23 @@ njs_number_radix_parse(u_char *p, u_char
         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     };
 
+    num = -1;
     n = 0;
 
-    while (p < end) {
-        d = digits[*p++];
+    for (p = *start; p < end; p++) {
+        d = digits[*p];
 
         if (nxt_slow_path(d >= radix)) {
-            return (exact) ? -1 : (int64_t) n;
+            break;
         }
 
         n = (n * radix) + d;
+        num = n;
     }
 
-    return n;
+    *start = p;
+
+    return num;
 }
 
 
@@ -715,11 +721,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_v
             radix = 16;
         }
 
-        if (p == end) {
-            goto done;
-        }
-
-        n = njs_number_radix_parse(p, end, radix, 0);
+        n = njs_number_radix_parse(&p, end, radix);
 
         if (n >= 0) {
             num = (minus) ? -n : n;
diff -r fc6c8da00858 -r be8d68d4b8b5 njs/njs_number.h
--- a/njs/njs_number.h	Thu May 25 14:16:31 2017 +0300
+++ b/njs/njs_number.h	Fri May 26 20:07:24 2017 +0300
@@ -13,8 +13,7 @@
 
 double njs_value_to_number(njs_value_t *value);
 double njs_number_parse(const u_char **start, const u_char *end);
-int64_t njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix,
-    nxt_bool_t exact);
+int64_t njs_number_radix_parse(u_char **start, u_char *end, uint8_t radix);
 njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
     const njs_value_t *number);
 njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args,
diff -r fc6c8da00858 -r be8d68d4b8b5 njs/njs_parser.c
--- a/njs/njs_parser.c	Thu May 25 14:16:31 2017 +0300
+++ b/njs/njs_parser.c	Fri May 26 20:07:24 2017 +0300
@@ -2429,12 +2429,13 @@ njs_parser_escape_string_create(njs_vm_t
                 goto invalid;
             }
 
-            u = njs_number_radix_parse(src, hex_end, 16, 1);
-            if (nxt_slow_path(u < 0)) {
+            u = njs_number_radix_parse(&src, hex_end, 16);
+
+            if (nxt_slow_path(src != hex_end)) {
                 goto invalid;
             }
 
-            src = hex_end + skip;
+            src += skip;
             size += nxt_utf8_size(u);
             length++;
 
diff -r fc6c8da00858 -r be8d68d4b8b5 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Thu May 25 14:16:31 2017 +0300
+++ b/njs/test/njs_unit_test.c	Fri May 26 20:07:24 2017 +0300
@@ -3139,6 +3139,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("'\\u'"),
       nxt_string("SyntaxError: Invalid Unicode code point \"\\u\" in 1") },
 
+    { nxt_string("'\\uzzzz'"),
+      nxt_string("SyntaxError: Invalid Unicode code point \"\\uzzzz\" in 1") },
+
     { nxt_string("'\\u03B'"),
       nxt_string("SyntaxError: Invalid Unicode code point \"\\u03B\" in 1") },
 
@@ -7050,8 +7053,11 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("parseInt('0x')"),
       nxt_string("NaN") },
 
-    { nxt_string("parseInt('0x', 10)"),
-      nxt_string("0") },
+    { nxt_string("parseInt('z')"),
+      nxt_string("NaN") },
+
+    { nxt_string("parseInt('0xz')"),
+      nxt_string("NaN") },
 
     { nxt_string("parseInt('0x', 16)"),
       nxt_string("NaN") },


More information about the nginx-devel mailing list