summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2022-11-11 10:41:49 +0100
committerRémi Verschelde <rverschelde@gmail.com>2022-11-11 10:41:49 +0100
commit6dc8e0a7dd83559a8a3bcaa307e65def8e0a4512 (patch)
treeefe42b396685efdb52d5534469dd71422b12582a
parent90761a8df9ce20d1f49b55bb5a230eb383d9143d (diff)
parent75e617c05d3b3d7a53458e21fa2615044f190f24 (diff)
Merge pull request #67247 from Gnumaru/Gnumaru/master
Fix a buffer overflow due to a misbehaving vcrt snprintf call on String::num, at core/string/ustring.cpp
-rw-r--r--core/string/ustring.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index c6cc4cc4ac..2ba389fc4d 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1460,15 +1460,25 @@ String String::num(double p_num, int p_decimals) {
fmt[5] = 'f';
fmt[6] = 0;
}
- char buf[256];
+ // if we want to convert a double with as much decimal places as as
+ // DBL_MAX or DBL_MIN then we would theoretically need a buffer of at least
+ // DBL_MAX_10_EXP + 2 for DBL_MAX and DBL_MAX_10_EXP + 4 for DBL_MIN.
+ // BUT those values where still giving me exceptions, so I tested from
+ // DBL_MAX_10_EXP + 10 incrementing one by one and DBL_MAX_10_EXP + 17 (325)
+ // was the first buffer size not to throw an exception
+ char buf[325];
#if defined(__GNUC__) || defined(_MSC_VER)
- snprintf(buf, 256, fmt, p_num);
+ // PLEASE NOTE that, albeit vcrt online reference states that snprintf
+ // should safely truncate the output to the given buffer size, we have
+ // found a case where this is not true, so we should create a buffer
+ // as big as needed
+ snprintf(buf, 325, fmt, p_num);
#else
sprintf(buf, fmt, p_num);
#endif
- buf[255] = 0;
+ buf[324] = 0;
//destroy trailing zeroes
{
bool period = false;