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>
This commit is contained in:
Edward Welbourne 2021-08-27 15:25:26 +02:00
parent 5644af6f8a
commit 7d33779a79
8 changed files with 32 additions and 29 deletions

View File

@ -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_) {

View File

@ -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:

View File

@ -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);

View File

@ -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 {

View File

@ -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));

View File

@ -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)

View File

@ -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;

View File

@ -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));