Эх сурвалжийг харах

Fix buffer overrun in `make_float()`

Fixes #2220
Benoit Blanchon 2 өдөр өмнө
parent
commit
d24a55a68d

+ 7 - 0
CHANGELOG.md

@@ -1,6 +1,13 @@
 ArduinoJson: change log
 =======================
 
+HEAD
+----
+
+* Fix a buffer overrun in `as<T>()` when `T` is a numeric type and
+  the variant contains a string representing a floating point number
+  with a large number of digits (issue #2220)
+
 v7.4.2 (2025-06-20)
 ------
 

+ 30 - 0
extras/tests/Numbers/parseDouble.cpp

@@ -93,4 +93,34 @@ TEST_CASE("parseNumber<double>()") {
     checkDoubleNaN("NaN");
     checkDoubleNaN("nan");
   }
+
+  SECTION("Overflow exponent with decimal part") {  // Issue #2220
+    checkDoubleNaN(
+        "0.000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000001");
+  }
+
+  SECTION("Overflow exponent with integral part") {
+    checkDoubleNaN(
+        "10000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000"
+        "00000000000000000000000000000000000000000000000000");
+  }
 }

+ 8 - 0
src/ArduinoJson/Numbers/FloatTraits.hpp

@@ -29,6 +29,8 @@ struct FloatTraits<T, 8 /*64bits*/> {
   using exponent_type = int16_t;
   static const exponent_type exponent_max = 308;
 
+  static const size_t binaryPowersOfTen = 9;
+
   static pgm_ptr<T> positiveBinaryPowersOfTen() {
     ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
         uint64_t, factors,
@@ -113,6 +115,8 @@ struct FloatTraits<T, 4 /*32bits*/> {
   using exponent_type = int8_t;
   static const exponent_type exponent_max = 38;
 
+  static const size_t binaryPowersOfTen = 6;
+
   static pgm_ptr<T> positiveBinaryPowersOfTen() {
     ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
                                      {
@@ -198,10 +202,14 @@ inline TFloat make_float(TFloat m, TExponent e) {
 
   auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen()
                            : traits::negativeBinaryPowersOfTen();
+  auto count = traits::binaryPowersOfTen;
+
   if (e <= 0)
     e = TExponent(-e);
 
   for (uint8_t index = 0; e != 0; index++) {
+    if (index >= count)
+      return traits::nan();
     if (e & 1)
       m *= powersOfTen[index];
     e >>= 1;