diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2021-08-27 15:25:26 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2021-08-30 17:46:00 +0200 |
commit | 7d33779a795afb54af1a96c0da93b532f9db3ba2 (patch) | |
tree | a760a2777d752fba7f91135ae7b80d37750d5745 | |
parent | 5644af6f8a800a1516360a42ba4c1a8dc61fc516 (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.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qipaddress.cpp | 7 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_unix.cpp | 11 | ||||
-rw-r--r-- | src/corelib/text/qlocale_tools.cpp | 2 | ||||
-rw-r--r-- | src/corelib/text/qlocale_win.cpp | 6 | ||||
-rw-r--r-- | src/corelib/text/qstring.cpp | 13 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_tz.cpp | 12 | ||||
-rw-r--r-- | src/corelib/tools/qversionnumber.cpp | 4 |
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)); |