Skip to content

Commit 6c6f1ba

Browse files
committed
Fix buffer overrun in make_float()
Fixes #2220
1 parent b9a3e30 commit 6c6f1ba

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
ArduinoJson: change log
22
=======================
33

4+
HEAD
5+
----
6+
7+
* Fix a buffer overrun in `as<T>()` when `T` is a numeric type and
8+
the variant contains a string representing a floating point number
9+
with a large number of digits (issue #2220)
10+
411
v7.3.1 (2025-02-27)
512
------
613

extras/tests/Numbers/parseDouble.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,34 @@ TEST_CASE("parseNumber<double>()") {
9393
checkDoubleNaN("NaN");
9494
checkDoubleNaN("nan");
9595
}
96+
97+
SECTION("Overflow exponent with decimal part") { // Issue #2220
98+
checkDoubleNaN(
99+
"0.000000000000000000000000000000000000000000000000"
100+
"00000000000000000000000000000000000000000000000000"
101+
"00000000000000000000000000000000000000000000000000"
102+
"00000000000000000000000000000000000000000000000000"
103+
"00000000000000000000000000000000000000000000000000"
104+
"00000000000000000000000000000000000000000000000000"
105+
"00000000000000000000000000000000000000000000000000"
106+
"00000000000000000000000000000000000000000000000000"
107+
"00000000000000000000000000000000000000000000000000"
108+
"00000000000000000000000000000000000000000000000000"
109+
"00000000000000000000000000000000000000000000000001");
110+
}
111+
112+
SECTION("Overflow exponent with integral part") {
113+
checkDoubleNaN(
114+
"10000000000000000000000000000000000000000000000000"
115+
"00000000000000000000000000000000000000000000000000"
116+
"00000000000000000000000000000000000000000000000000"
117+
"00000000000000000000000000000000000000000000000000"
118+
"00000000000000000000000000000000000000000000000000"
119+
"00000000000000000000000000000000000000000000000000"
120+
"00000000000000000000000000000000000000000000000000"
121+
"00000000000000000000000000000000000000000000000000"
122+
"00000000000000000000000000000000000000000000000000"
123+
"00000000000000000000000000000000000000000000000000"
124+
"00000000000000000000000000000000000000000000000000");
125+
}
96126
}

src/ArduinoJson/Numbers/FloatTraits.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ struct FloatTraits<T, 8 /*64bits*/> {
2929
using exponent_type = int16_t;
3030
static const exponent_type exponent_max = 308;
3131

32+
static const size_t binaryPowersOfTen = 9;
33+
3234
static pgm_ptr<T> positiveBinaryPowersOfTen() {
3335
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
3436
uint64_t, factors,
@@ -113,6 +115,8 @@ struct FloatTraits<T, 4 /*32bits*/> {
113115
using exponent_type = int8_t;
114116
static const exponent_type exponent_max = 38;
115117

118+
static const size_t binaryPowersOfTen = 6;
119+
116120
static pgm_ptr<T> positiveBinaryPowersOfTen() {
117121
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
118122
{
@@ -198,10 +202,14 @@ inline TFloat make_float(TFloat m, TExponent e) {
198202

199203
auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen()
200204
: traits::negativeBinaryPowersOfTen();
205+
auto count = traits::binaryPowersOfTen;
206+
201207
if (e <= 0)
202208
e = TExponent(-e);
203209

204210
for (uint8_t index = 0; e != 0; index++) {
211+
if (index >= count)
212+
return traits::nan();
205213
if (e & 1)
206214
m *= powersOfTen[index];
207215
e >>= 1;

0 commit comments

Comments
 (0)