[libc] Fix strtod hex exponent overflow bug
authorMichael Jones <michaelrj@google.com>
Mon, 17 Apr 2023 17:30:28 +0000 (10:30 -0700)
committerMichael Jones <michaelrj@google.com>
Wed, 19 Apr 2023 23:32:20 +0000 (16:32 -0700)
Same issue as was fixed in commit 3d95323, but for hexadecimal floats.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D148545

libc/src/__support/str_to_float.h
libc/test/src/stdlib/strtod_test.cpp

index 6c298d4..0697cf0 100644 (file)
@@ -1052,13 +1052,12 @@ hexadecimal_string_to_float(const char *__restrict src,
 
       // If the result is in the valid range, then we use it. The valid range is
       // also within the int32 range, so this prevents overflow issues.
-      if (temp_exponent < fputil::FPBits<T>::MAX_EXPONENT &&
-          temp_exponent > -fputil::FPBits<T>::MAX_EXPONENT) {
-        exponent = static_cast<int32_t>(temp_exponent);
-      } else if (temp_exponent > fputil::FPBits<T>::MAX_EXPONENT) {
+      if (temp_exponent > fputil::FPBits<T>::MAX_EXPONENT) {
         exponent = fputil::FPBits<T>::MAX_EXPONENT;
-      } else {
+      } else if (temp_exponent < -fputil::FPBits<T>::MAX_EXPONENT) {
         exponent = -fputil::FPBits<T>::MAX_EXPONENT;
+      } else {
+        exponent = static_cast<int32_t>(temp_exponent);
       }
     }
   }
index aa81eca..fee32cd 100644 (file)
@@ -220,6 +220,9 @@ TEST_F(LlvmLibcStrToDTest, FuzzFailures) {
       "200000000000000000E608",
       1462, uint64_t(0x7ff0000000000000), ERANGE);
 
+  // Same as above but for hex.
+  run_test("0x0164810157p2047", 17, uint64_t(0x7ff0000000000000), ERANGE);
+
   // This bug was in the handling of very large exponents in the exponent
   // marker. Previously anything greater than 10,000 would be set to 10,000.
   // This caused incorrect behavior if there were more than 10,000 '0's in the