From 079cdc8e1483c42d5318a02bd300670cc5b7d477 Mon Sep 17 00:00:00 2001 From: thestig Date: Thu, 1 Sep 2016 18:45:52 -0700 Subject: [PATCH] Fix parsing of exponents in StringToDouble. BUG=542881 Review-Url: https://codereview.chromium.org/2296503003 Cr-Commit-Position: refs/heads/master@{#416158} --- .../string_number_conversions_unittest.cc | 34 +++++++++++++++++++ base/third_party/dmg_fp/README.chromium | 3 +- base/third_party/dmg_fp/dtoa.cc | 5 ++- base/third_party/dmg_fp/exp_length.patch | 17 ++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 base/third_party/dmg_fp/exp_length.patch diff --git a/base/strings/string_number_conversions_unittest.cc b/base/strings/string_number_conversions_unittest.cc index 640468c33d5c62..0576302a0798c9 100644 --- a/base/strings/string_number_conversions_unittest.cc +++ b/base/strings/string_number_conversions_unittest.cc @@ -719,17 +719,49 @@ TEST(StringNumberConversionsTest, StringToDouble) { double output; bool success; } cases[] = { + // Test different forms of zero. {"0", 0.0, true}, + {"+0", 0.0, true}, + {"-0", 0.0, true}, + {"0.0", 0.0, true}, + {"000000000000000000000000000000.0", 0.0, true}, + {"0.000000000000000000000000000", 0.0, true}, + + // Test the answer. {"42", 42.0, true}, {"-42", -42.0, true}, + + // Test variances of an ordinary number. {"123.45", 123.45, true}, {"-123.45", -123.45, true}, {"+123.45", 123.45, true}, + + // Test different forms of representation. {"2.99792458e8", 299792458.0, true}, {"149597870.691E+3", 149597870691.0, true}, {"6.", 6.0, true}, + + // Test around the largest/smallest value that a double can represent. + {"9e307", 9e307, true}, + {"1.7976e308", 1.7976e308, true}, + {"1.7977e308", HUGE_VAL, false}, + {"9e308", HUGE_VAL, false}, + {"9e309", HUGE_VAL, false}, + {"9e999", HUGE_VAL, false}, + {"9e1999", HUGE_VAL, false}, + {"9e19999", HUGE_VAL, false}, {"9e99999999999999999999", HUGE_VAL, false}, + {"-9e307", -9e307, true}, + {"-1.7976e308", -1.7976e308, true}, + {"-1.7977e308", -HUGE_VAL, false}, + {"-9e308", -HUGE_VAL, false}, + {"-9e309", -HUGE_VAL, false}, + {"-9e999", -HUGE_VAL, false}, + {"-9e1999", -HUGE_VAL, false}, + {"-9e19999", -HUGE_VAL, false}, {"-9e99999999999999999999", -HUGE_VAL, false}, + + // Test more exponents. {"1e-2", 0.01, true}, {"42 ", 42.0, false}, {" 1e-2", 0.01, false}, @@ -737,6 +769,8 @@ TEST(StringNumberConversionsTest, StringToDouble) { {"-1E-7", -0.0000001, true}, {"01e02", 100, true}, {"2.3e15", 2.3e15, true}, + + // Test some invalid cases. {"\t\n\v\f\r -123.45e2", -12345.0, false}, {"+123 e4", 123.0, false}, {"123e ", 123.0, false}, diff --git a/base/third_party/dmg_fp/README.chromium b/base/third_party/dmg_fp/README.chromium index 4538b7e4653482..8a4d42362158d4 100644 --- a/base/third_party/dmg_fp/README.chromium +++ b/base/third_party/dmg_fp/README.chromium @@ -17,4 +17,5 @@ List of changes made to original code: - made minor changes for -Wextra for Mac build, see mac_wextra.patch - crash fix for running with reduced CPU float precision, see float_precision_crash.patch and crbug.com/123157 - - fixed warnings under msvc, see msvc_warnings.patch \ No newline at end of file + - fixed warnings under msvc, see msvc_warnings.patch + - fixed parsing of long exponents, see exp_length.patch and crbug.com/542881 diff --git a/base/third_party/dmg_fp/dtoa.cc b/base/third_party/dmg_fp/dtoa.cc index 502c16cc72f3cc..f3d793edc48be8 100644 --- a/base/third_party/dmg_fp/dtoa.cc +++ b/base/third_party/dmg_fp/dtoa.cc @@ -2597,8 +2597,11 @@ strtod if (c > '0' && c <= '9') { L = c - '0'; s1 = s; - while((c = *++s) >= '0' && c <= '9') + while((c = *++s) >= '0' && c <= '9') { L = 10*L + c - '0'; + if (L > DBL_MAX_10_EXP) + break; + } if (s - s1 > 8 || L > 19999) /* Avoid confusion from exponents * so large that e might overflow. diff --git a/base/third_party/dmg_fp/exp_length.patch b/base/third_party/dmg_fp/exp_length.patch new file mode 100644 index 00000000000000..65d033a403e9f3 --- /dev/null +++ b/base/third_party/dmg_fp/exp_length.patch @@ -0,0 +1,17 @@ +diff --git a/base/third_party/dmg_fp/dtoa.cc b/base/third_party/dmg_fp/dtoa.cc +index 502c16c..f3d793e 100644 +--- a/base/third_party/dmg_fp/dtoa.cc ++++ b/base/third_party/dmg_fp/dtoa.cc +@@ -2597,8 +2597,11 @@ strtod + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; +- while((c = *++s) >= '0' && c <= '9') ++ while((c = *++s) >= '0' && c <= '9') { + L = 10*L + c - '0'; ++ if (L > DBL_MAX_10_EXP) ++ break; ++ } + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow.