summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-08-27 15:25:26 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2021-08-30 17:46:00 +0200
commit7d33779a795afb54af1a96c0da93b532f9db3ba2 (patch)
treea760a2777d752fba7f91135ae7b80d37750d5745
parent5644af6f8a800a1516360a42ba4c1a8dc61fc516 (diff)
Convert various callers of strtou?ll() to call strntou?ll()
Where size is known or can readily be determined. Change-Id: I442e7ebb3757fdbf7d021a15e19aeba533b590a5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/corelib/global/qglobal.cpp6
-rw-r--r--src/corelib/io/qipaddress.cpp7
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp11
-rw-r--r--src/corelib/text/qlocale_tools.cpp2
-rw-r--r--src/corelib/text/qlocale_win.cpp6
-rw-r--r--src/corelib/text/qstring.cpp13
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp12
-rw-r--r--src/corelib/tools/qversionnumber.cpp4
8 files changed, 32 insertions, 29 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 2a659e4172..e613266d7b 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -3529,6 +3529,7 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
(std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit;
const auto locker = qt_scoped_lock(environmentMutex);
+ size_t size;
#ifdef Q_CC_MSVC
// we provide a buffer that can hold any int value:
char buffer[MaxDigitsForOctalInt + 2]; // +1 for NUL +1 for optional '-'
@@ -3538,9 +3539,10 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
*ok = false;
return 0;
}
+ size = strlen(buffer);
#else
const char * const buffer = ::getenv(varName);
- if (!buffer || strlen(buffer) > MaxDigitsForOctalInt + 2) {
+ if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt + 2) {
if (ok)
*ok = false;
return 0;
@@ -3548,7 +3550,7 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
#endif
bool ok_ = true;
const char *endptr;
- const qlonglong value = qstrtoll(buffer, &endptr, 0, &ok_);
+ const qlonglong value = qstrntoll(buffer, size, &endptr, 0, &ok_);
// Keep the following checks in sync with QByteArray::toInt()
if (!ok_) {
diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp
index 15f759156d..93a74ccd09 100644
--- a/src/corelib/io/qipaddress.cpp
+++ b/src/corelib/io/qipaddress.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -86,6 +87,7 @@ static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptL
{
address = 0;
int dotCount = 0;
+ const char *const stop = ptr + qstrlen(ptr);
while (dotCount < 4) {
if (!acceptLeadingZero && *ptr == '0' &&
ptr[1] != '.' && ptr[1] != '\0')
@@ -93,7 +95,7 @@ static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptL
const char *endptr;
bool ok;
- quint64 ll = qstrtoull(ptr, &endptr, 0, &ok);
+ quint64 ll = qstrntoull(ptr, stop - ptr, &endptr, 0, &ok);
quint32 x = ll;
if (!ok || endptr == ptr || ll != x)
return false;
@@ -158,6 +160,7 @@ const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end
return ret;
const char *ptr = buffer.data();
+ const char *const stop = ptr + buffer.size();
// count the colons
int colonCount = 0;
@@ -213,7 +216,7 @@ const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end
const char *endptr;
bool ok;
- quint64 ll = qstrtoull(ptr, &endptr, 16, &ok);
+ quint64 ll = qstrntoull(ptr, stop - ptr, &endptr, 16, &ok);
quint16 x = ll;
// Reject malformed fields:
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 6bb1978970..566ffe46bc 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -467,7 +467,7 @@ inline bool QStorageIterator::next()
if (fgets(ptr, buffer.size(), fp) == nullptr)
return false;
- size_t len = strlen(buffer.data());
+ size_t len = strlen(ptr);
if (len == 0)
return false;
while (Q_UNLIKELY(ptr[len - 1] != '\n' && !feof(fp))) {
@@ -482,27 +482,28 @@ inline bool QStorageIterator::next()
Q_ASSERT(len < size_t(buffer.size()));
}
ptr[len - 1] = '\0';
+ const char *const stop = ptr + len - 1;
// parse the line
bool ok;
mnt.mnt_freq = 0;
mnt.mnt_passno = 0;
- mnt.mount_id = qstrtoll(ptr, const_cast<const char **>(&ptr), 10, &ok);
+ mnt.mount_id = qstrntoll(ptr, stop - ptr, const_cast<const char **>(&ptr), 10, &ok);
if (!ok)
return false;
- int parent_id = qstrtoll(ptr, const_cast<const char **>(&ptr), 10, &ok);
+ int parent_id = qstrntoll(ptr, stop - ptr, const_cast<const char **>(&ptr), 10, &ok);
Q_UNUSED(parent_id);
if (!ok)
return false;
- int rdevmajor = qstrtoll(ptr, const_cast<const char **>(&ptr), 10, &ok);
+ int rdevmajor = qstrntoll(ptr, stop - ptr, const_cast<const char **>(&ptr), 10, &ok);
if (!ok)
return false;
if (*ptr != ':')
return false;
- int rdevminor = qstrtoll(ptr + 1, const_cast<const char **>(&ptr), 10, &ok);
+ int rdevminor = qstrntoll(ptr + 1, stop - ptr - 1, const_cast<const char **>(&ptr), 10, &ok);
if (!ok)
return false;
mnt.rdev = makedev(rdevmajor, rdevminor);
diff --git a/src/corelib/text/qlocale_tools.cpp b/src/corelib/text/qlocale_tools.cpp
index c144dba938..18dd24daf1 100644
--- a/src/corelib/text/qlocale_tools.cpp
+++ b/src/corelib/text/qlocale_tools.cpp
@@ -223,7 +223,7 @@ void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, cha
// This is why the final decimal point is offset by 1, relative to the number after 'e'.
bool ok;
const char *endptr;
- decpt = qstrtoll(target.data() + eSign + 1, &endptr, 10, &ok) + 1;
+ decpt = qstrntoll(target.data() + eSign + 1, length - eSign - 1, &endptr, 10, &ok) + 1;
Q_ASSERT(ok);
Q_ASSERT(endptr - target.data() <= length);
} else {
diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp
index bfb20538eb..1dd7a1532e 100644
--- a/src/corelib/text/qlocale_win.cpp
+++ b/src/corelib/text/qlocale_win.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -982,7 +982,7 @@ static QString winIso639LangName(LCID id)
const char *endptr;
bool ok;
QByteArray latin1_lang_code = std::move(lang_code).toLatin1();
- int i = qstrtoull(latin1_lang_code, &endptr, 16, &ok);
+ int i = qstrntoull(latin1_lang_code.data(), latin1_lang_code.size(), &endptr, 16, &ok);
if (ok && *endptr == '\0') {
switch (i) {
case 0x814:
@@ -1024,7 +1024,7 @@ static QByteArray getWinLocaleName(LCID id)
if (result == "C"
|| (!result.isEmpty() && qt_splitLocaleName(QString::fromLocal8Bit(result)))) {
bool ok = false; // See if we have a Windows locale code instead of a locale name:
- long id = qstrtoll(result.data(), 0, 0, &ok);
+ long id = qstrntoll(result.data(), result.size(), 0, 0, &ok);
if (!ok || id == 0 || id < INT_MIN || id > INT_MAX) // Assume real locale name
return result;
return winLangCodeToIsoName(int(id));
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 640c1e4ee5..8dbf996f73 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -6608,17 +6608,19 @@ static uint parse_flag_characters(const char * &c) noexcept
}
}
-static int parse_field_width(const char * &c)
+static int parse_field_width(const char *&c, qsizetype size)
{
Q_ASSERT(qIsDigit(*c));
+ const char *const stop = c + size;
// can't be negative - started with a digit
// contains at least one digit
const char *endp;
bool ok;
- const qulonglong result = qstrtoull(c, &endp, 10, &ok);
+ const qulonglong result = qstrntoull(c, size, &endp, 10, &ok);
c = endp;
- while (qIsDigit(*c)) // preserve Qt 5.5 behavior of consuming all digits, no matter how many
+ // preserve Qt 5.5 behavior of consuming all digits, no matter how many
+ while (c < stop && qIsDigit(*c))
++c;
return ok && result < qulonglong(std::numeric_limits<int>::max()) ? int(result) : 0;
}
@@ -6674,6 +6676,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
QString result;
const char *c = cformat;
+ const char *formatEnd = cformat + qstrlen(cformat);
for (;;) {
// Copy non-escape chars to result
const char *cb = c;
@@ -6708,7 +6711,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
// Parse field width
int width = -1; // -1 means unspecified
if (qIsDigit(*c)) {
- width = parse_field_width(c);
+ width = parse_field_width(c, formatEnd - c);
} else if (*c == '*') { // can't parse this in another function, not portably, at least
width = va_arg(ap, int);
if (width < 0)
@@ -6726,7 +6729,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
if (*c == '.') {
++c;
if (qIsDigit(*c)) {
- precision = parse_field_width(c);
+ precision = parse_field_width(c, formatEnd - c);
} else if (*c == '*') { // can't parse this in another function, not portably, at least
precision = va_arg(ap, int);
if (precision < 0)
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index 96399b029f..c27820ca6e 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -419,23 +419,17 @@ static int parsePosixTime(const char *begin, const char *end)
// Format "hh[:mm[:ss]]"
int hour, min = 0, sec = 0;
- // Note that the calls to qstrtoll do *not* check against the end pointer,
- // which means they proceed until they find a non-digit. We check that we're
- // still in range at the end, but we may have read past end. It's the
- // caller's responsibility to ensure that begin is part of a null-terminated
- // string.
-
const int maxHour = 137; // POSIX's extended range.
bool ok = false;
const char *cut = begin;
- hour = qstrtoll(begin, &cut, 10, &ok);
+ hour = qstrntoll(begin, end - begin, &cut, 10, &ok);
if (!ok || hour < -maxHour || hour > maxHour || cut > begin + 2)
return INT_MIN;
begin = cut;
if (begin < end && *begin == ':') {
// minutes
++begin;
- min = qstrtoll(begin, &cut, 10, &ok);
+ min = qstrntoll(begin, end - begin, &cut, 10, &ok);
if (!ok || min < 0 || min > 59 || cut > begin + 2)
return INT_MIN;
@@ -443,7 +437,7 @@ static int parsePosixTime(const char *begin, const char *end)
if (begin < end && *begin == ':') {
// seconds
++begin;
- sec = qstrtoll(begin, &cut, 10, &ok);
+ sec = qstrntoll(begin, end - begin, &cut, 10, &ok);
if (!ok || sec < 0 || sec > 59 || cut > begin + 2)
return INT_MIN;
begin = cut;
diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp
index 05c38c350f..3bf3d22267 100644
--- a/src/corelib/tools/qversionnumber.cpp
+++ b/src/corelib/tools/qversionnumber.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
** Contact: https://www.qt.io/licensing/
@@ -465,7 +465,7 @@ QVersionNumber QVersionNumber::fromString(QLatin1String string, int *suffixIndex
do {
bool ok = false;
- const qulonglong value = qstrtoull(start, &end, 10, &ok);
+ const qulonglong value = qstrntoull(start, endOfString - start, &end, 10, &ok);
if (!ok || value > qulonglong(std::numeric_limits<int>::max()))
break;
seg.append(int(value));