summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-10-15 12:37:33 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2021-10-26 17:38:22 +0200
commitbb220f2d99261eaa7c5021988a9443735ed2a93d (patch)
treedc6d38ec5eaaa7178e73db52570d90347bb05884 /src/corelib
parent25e85ec45fe5ca00c90fab4ab764f46117fbcb24 (diff)
Fix overflow issue on parsing min-qint64 with its minus sign repeated
The call to std::from_chars() accepts a sign, but we've already dealt with a sign, so that would be a second sign. Check the first character after any prefix is in fact a digit (for the base in use). This is a follow-up to commit 5644af6f8a800a1516360a42ba4c1a8dc61fc516. Fixes: QTBUG-97521 Change-Id: I65fb144bf6a8430da90ec5f65088ca20e79bf02f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/text/qlocale_tools.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/corelib/text/qlocale_tools.cpp b/src/corelib/text/qlocale_tools.cpp
index 18dd24daf1..c133a028c0 100644
--- a/src/corelib/text/qlocale_tools.cpp
+++ b/src/corelib/text/qlocale_tools.cpp
@@ -437,6 +437,19 @@ static auto scanPrefix(const char *p, const char *stop, int base)
return R{p, base};
}
+static bool isDigitForBase(char d, int base)
+{
+ if (d < '0')
+ return false;
+ if (d - '0' < qMin(base, 10))
+ return true;
+ if (base > 10) {
+ d |= 0x20; // tolower
+ return d >= 'a' && d < 'a' + base - 10;
+ }
+ return false;
+}
+
unsigned long long
qstrntoull(const char *begin, qsizetype size, const char **endptr, int base, bool *ok)
{
@@ -479,7 +492,9 @@ qstrntoll(const char *begin, qsizetype size, const char **endptr, int base, bool
++p;
const auto prefix = scanPrefix(p, stop, base);
- if (!prefix.base || prefix.next >= stop) {
+ // Must check for digit, as from_chars() will accept a sign, which would be
+ // a second sign, that we should reject.
+ if (!prefix.base || prefix.next >= stop || !isDigitForBase(*prefix.next, prefix.base)) {
if (endptr)
*endptr = begin;
*ok = false;