Skip to content

Commit ff2db17

Browse files
committed
Fix buffer overrun in make_float()
Fixes #2220
1 parent 464b054 commit ff2db17

3 files changed

Lines changed: 41 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ HEAD
66

77
* Improve error messages when using `char` or `char*` (issue #2043)
88
* Make string support even more generic (PR #2084 by @d-a-v)
9+
* Fix a buffer overrun in `as<T>()` when `T` is a numeric type and
10+
the variant contains a string representing a floating point number
11+
with a large number of digits (issue #2220)
912

1013
v6.21.5 (2024-01-10)
1114
-------

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
typedef int16_t exponent_type;
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
typedef int8_t exponent_type;
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)