]> git.kaiwu.me - njs.git/commitdiff
Fixed integer-overflow while parsing exponent of number literals.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 27 Aug 2019 15:58:43 +0000 (18:58 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 27 Aug 2019 15:58:43 +0000 (18:58 +0300)
src/njs_strtod.c
src/njs_unix.h
src/test/njs_unit_test.c

index 898cebe49756451a905699a2c2cc57e1a3ce93ec..1cc3a924f8a9821db0ad357be634241b15645087 100644 (file)
@@ -251,6 +251,7 @@ njs_diyfp_strtod(const u_char *start, size_t length, int exp)
 static double
 njs_strtod_internal(const u_char *start, size_t length, int exp)
 {
+    int           shift;
     size_t        left, right;
     const u_char  *p, *e, *b;
 
@@ -291,17 +292,17 @@ njs_strtod_internal(const u_char *start, size_t length, int exp)
         return 0.0;
     }
 
-    exp += (int) (left - right);
+    shift = (int) (left - right);
 
-    if (exp + (int) length - 1 >= NJS_DECIMAL_POWER_MAX) {
+    if (exp >= NJS_DECIMAL_POWER_MAX - shift - (int) length + 1) {
         return INFINITY;
     }
 
-    if (exp + (int) length <= NJS_DECIMAL_POWER_MIN) {
+    if (exp <= NJS_DECIMAL_POWER_MIN - shift - (int) length) {
         return 0.0;
     }
 
-    return njs_diyfp_strtod(start, length, exp);
+    return njs_diyfp_strtod(start, length, exp + shift);
 }
 
 
@@ -386,7 +387,9 @@ njs_strtod(const u_char **start, const u_char *end)
                     break;
                 }
 
-                exp = exp * 10 + c;
+                if (exp < (INT_MAX - 9) / 10) {
+                    exp = exp * 10 + c;
+                }
             }
 
             exponent += minus ? -exp : exp;
index 89e8a6b7031e21199ae2a37ca0addff88606ac8c..c9fc2f07feb61f30de652fbbc9da82d6d29f2c01 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <math.h>
 #include <float.h>
+#include <limits.h>
 #include <time.h>
 #include <fcntl.h>
 
index f61eb3f32d72f870146f4b099635def8af2a2c0f..64e316eb90add7493a1538df6b21757173c1e540 100644 (file)
@@ -12366,6 +12366,21 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("parseFloat('12345abc')"),
       njs_str("12345") },
 
+    { njs_str("parseFloat('1e2147483647')"),
+      njs_str("Infinity") },
+
+    { njs_str("parseFloat('1e-2147483647')"),
+      njs_str("0") },
+
+    { njs_str("parseFloat('1e-2147483648')"),
+      njs_str("0") },
+
+    { njs_str("parseFloat('1e' + '5'.repeat(16))"),
+      njs_str("Infinity") },
+
+    { njs_str("parseFloat('1e-' + '5'.repeat(16))"),
+      njs_str("0") },
+
     { njs_str("parseFloat('0x')"),
       njs_str("0") },