diff --git a/libc/src/__support/high_precision_decimal.h b/libc/src/__support/high_precision_decimal.h --- a/libc/src/__support/high_precision_decimal.h +++ b/libc/src/__support/high_precision_decimal.h @@ -285,14 +285,18 @@ // handle leading spaces. HighPrecisionDecimal(const char *__restrict numString) { bool saw_dot = false; + // This counts the digits in the number, even if there isn't space to store + // them all. + uint32_t total_digits = 0; while (isdigit(*numString) || *numString == '.') { if (*numString == '.') { if (saw_dot) { break; } - this->decimal_point = this->num_digits; + this->decimal_point = total_digits; saw_dot = true; } else { + ++total_digits; if (*numString == '0' && this->num_digits == 0) { --this->decimal_point; ++numString; @@ -309,9 +313,8 @@ ++numString; } - if (!saw_dot) { - this->decimal_point = this->num_digits; - } + if (!saw_dot) + this->decimal_point = total_digits; if ((*numString | 32) == 'e') { ++numString; diff --git a/libc/test/src/__support/str_to_float_comparison_data.txt b/libc/test/src/__support/str_to_float_comparison_data.txt --- a/libc/test/src/__support/str_to_float_comparison_data.txt +++ b/libc/test/src/__support/str_to_float_comparison_data.txt @@ -5,3 +5,4 @@ 57B7 42F6E979 405EDD2F1A9FBE77 123.456 622A 44454000 4088A80000000000 789 7C00 7F800000 7FF0000000000000 123.456e789 +0000 00000000 3FF0000000000000 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-800 diff --git a/libc/test/src/stdlib/strtod_test.cpp b/libc/test/src/stdlib/strtod_test.cpp --- a/libc/test/src/stdlib/strtod_test.cpp +++ b/libc/test/src/stdlib/strtod_test.cpp @@ -80,6 +80,86 @@ run_test("2.16656806400000023841857910156251e9", 36, uint64_t(0x41e0246690000001)); run_test("27949676547093071875", 20, uint64_t(0x43f83e132bc608c9)); + run_test( + "100000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000e-800", + 806, 0x3ff0000000000000); + run_test( + "100000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000e-799", + 806, 0x4024000000000000); + run_test( + "100000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000e-800", + 807, 0x4024000000000000); + run_test( + "10000000000000000000000000000000000000000000000000000000000000000e-64", + 69, 0x3ff0000000000000); + run_test( + "100000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000e-128", + 134, 0x3ff0000000000000); + run_test("1000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000e-256", + 262, 0x3ff0000000000000); + run_test("1000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000e-512", + 518, 0x3ff0000000000000); + run_test( + "100000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000e-1024", + 1031, 0x3ff0000000000000); } TEST_F(LlvmLibcStrToDTest, FuzzFailures) {