use QVarLengthArray<T>() instead of QSTACKARRAY() for potentially large buffers

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-05-30 02:37:12 +03:00
parent 20da2cef04
commit f20085b1c1
3 changed files with 41 additions and 41 deletions

View file

@ -1091,13 +1091,13 @@ QString QTextCodecPrivate::convertTo(const char *data, int length, const char* c
ucnv_setSubstString(conv, questionmarkchar, 1, &error); ucnv_setSubstString(conv, questionmarkchar, 1, &error);
const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv)); const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv));
QSTACKARRAY(UChar, result, maxbytes); QVarLengthArray<UChar> result(maxbytes);
error = U_ZERO_ERROR; error = U_ZERO_ERROR;
const int convresult = ucnv_toUChars(conv, result, maxbytes, data, length, &error); const int convresult = ucnv_toUChars(conv, result.data(), maxbytes, data, length, &error);
ucnv_close(conv); ucnv_close(conv);
if (Q_LIKELY(U_SUCCESS(error))) { if (Q_LIKELY(U_SUCCESS(error))) {
return QString(reinterpret_cast<QChar*>(result), convresult); return QString(reinterpret_cast<const QChar*>(result.constData()), convresult);
} }
return QString(); return QString();
@ -1115,14 +1115,14 @@ QByteArray QTextCodecPrivate::convertFrom(const QChar *unicode, int length, cons
ucnv_setSubstString(conv, questionmarkchar, 1, &error); ucnv_setSubstString(conv, questionmarkchar, 1, &error);
const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv)); const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv));
QSTACKARRAY(char, result, maxbytes); QVarLengthArray<char> result(maxbytes);
error = U_ZERO_ERROR; error = U_ZERO_ERROR;
const int convresult = ucnv_fromUChars(conv, result, maxbytes, const int convresult = ucnv_fromUChars(conv, result.data(), maxbytes,
reinterpret_cast<const UChar *>(unicode), length, &error); reinterpret_cast<const UChar *>(unicode), length, &error);
ucnv_close(conv); ucnv_close(conv);
if (Q_LIKELY(U_SUCCESS(error))) { if (Q_LIKELY(U_SUCCESS(error))) {
return QByteArray(result, convresult); return QByteArray(result.constData(), convresult);
} }
return QByteArray(); return QByteArray();
@ -1954,11 +1954,11 @@ QByteArray QTextConverter::fromUnicode(const QChar *data, int length) const
} }
const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv)); const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv));
QSTACKARRAY(char, result, maxbytes); QVarLengthArray<char> result(maxbytes);
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
const int convresult = ucnv_fromUChars(conv, result, maxbytes, const int convresult = ucnv_fromUChars(conv, result.data(), maxbytes,
reinterpret_cast<const UChar *>(data), length, &error); reinterpret_cast<const UChar *>(data), length, &error);
return QByteArray(result, convresult); return QByteArray(result.constData(), convresult);
} }
/*! /*!
@ -1974,28 +1974,28 @@ QString QTextConverter::toUnicode(const char *data, int length) const
} }
const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv)); const int maxbytes = UCNV_GET_MAX_BYTES_FOR_STRING(length, ucnv_getMaxCharSize(conv));
QSTACKARRAY(UChar, result, maxbytes); QVarLengthArray<UChar> result(maxbytes);
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
const int convresult = ucnv_toUChars(conv, result, maxbytes, data, length, &error); const int convresult = ucnv_toUChars(conv, result.data(), maxbytes, data, length, &error);
// regardless if the data has BOM or not, BOMs shall be generated explicitly only by QTextStream // regardless if the data has BOM or not, BOMs shall be generated explicitly only by QTextStream
if (convresult >= 4 && qstrnicmp("UTF-32", d_ptr->name.constData(), 6) == 0) { if (convresult >= 4 && qstrnicmp("UTF-32", d_ptr->name.constData(), 6) == 0) {
const uchar* resultuchar = reinterpret_cast<uchar*>(result); const uchar* resultuchar = reinterpret_cast<const uchar*>(result.constData());
Q_ASSERT(sizeof(qt_utf32le_bom) == sizeof(qt_utf32be_bom)); Q_ASSERT(sizeof(qt_utf32le_bom) == sizeof(qt_utf32be_bom));
if (::memcmp(resultuchar, qt_utf32le_bom, sizeof(qt_utf32le_bom)) == 0 if (::memcmp(resultuchar, qt_utf32le_bom, sizeof(qt_utf32le_bom)) == 0
|| ::memcmp(resultuchar, qt_utf32be_bom, sizeof(qt_utf32be_bom)) == 0) { || ::memcmp(resultuchar, qt_utf32be_bom, sizeof(qt_utf32be_bom)) == 0) {
const int bomoffset = (sizeof(qt_utf32le_bom) / sizeof(QChar)); const int bomoffset = (sizeof(qt_utf32le_bom) / sizeof(QChar));
return QString(reinterpret_cast<QChar*>(result) + bomoffset, convresult - bomoffset); return QString(reinterpret_cast<const QChar*>(result.constData()) + bomoffset, convresult - bomoffset);
} }
} else if (convresult >= 2 && qstrnicmp("UTF-16", d_ptr->name.constData(), 6) == 0) { } else if (convresult >= 2 && qstrnicmp("UTF-16", d_ptr->name.constData(), 6) == 0) {
const uchar* resultuchar = reinterpret_cast<uchar*>(result); const uchar* resultuchar = reinterpret_cast<const uchar*>(result.constData());
Q_ASSERT(sizeof(qt_utf16le_bom) == sizeof(qt_utf16be_bom)); Q_ASSERT(sizeof(qt_utf16le_bom) == sizeof(qt_utf16be_bom));
if (::memcmp(resultuchar, qt_utf16le_bom, sizeof(qt_utf16le_bom)) == 0 if (::memcmp(resultuchar, qt_utf16le_bom, sizeof(qt_utf16le_bom)) == 0
|| ::memcmp(resultuchar, qt_utf16be_bom, sizeof(qt_utf16be_bom)) == 0) { || ::memcmp(resultuchar, qt_utf16be_bom, sizeof(qt_utf16be_bom)) == 0) {
const int bomoffset = (sizeof(qt_utf16le_bom) / sizeof(QChar)); const int bomoffset = (sizeof(qt_utf16le_bom) / sizeof(QChar));
return QString(reinterpret_cast<QChar*>(result) + bomoffset, convresult - bomoffset); return QString(reinterpret_cast<const QChar*>(result.constData()) + bomoffset, convresult - bomoffset);
} }
} }
return QString(reinterpret_cast<QChar*>(result), convresult); return QString(reinterpret_cast<const QChar*>(result.constData()), convresult);
} }
#endif // QT_NO_TEXTCODEC #endif // QT_NO_TEXTCODEC

View file

@ -1666,14 +1666,14 @@ QString &QString::replace(const QLatin1String &before,
Qt::CaseSensitivity cs) Qt::CaseSensitivity cs)
{ {
int alen = qstrlen(after.latin1()); int alen = qstrlen(after.latin1());
QSTACKARRAY(ushort, a, alen); QVarLengthArray<ushort> a(alen);
for (int i = 0; i < alen; ++i) for (int i = 0; i < alen; ++i)
a[i] = (uchar)after.latin1()[i]; a[i] = (uchar)after.latin1()[i];
int blen = qstrlen(before.latin1()); int blen = qstrlen(before.latin1());
QSTACKARRAY(ushort, b, blen); QVarLengthArray<ushort> b(blen);
for (int i = 0; i < blen; ++i) for (int i = 0; i < blen; ++i)
b[i] = (uchar)before.latin1()[i]; b[i] = (uchar)before.latin1()[i];
return replace(reinterpret_cast<const QChar*>(b), blen, reinterpret_cast<const QChar*>(a), alen, cs); return replace(reinterpret_cast<const QChar*>(b.constData()), blen, reinterpret_cast<const QChar*>(a.constData()), alen, cs);
} }
/*! /*!
@ -3144,12 +3144,12 @@ static QByteArray toLatin1_helper(const QChar *data, int length)
if (!length) { if (!length) {
return QByteArray(); return QByteArray();
} }
QSTACKARRAY(char, result, length); QVarLengthArray<char> result(length);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
const ushort ucs = data[i].unicode(); const ushort ucs = data[i].unicode();
result[i] = (ucs > 0xff) ? '?' : char(ucs); result[i] = (ucs > 0xff) ? '?' : char(ucs);
} }
return QByteArray(result, length); return QByteArray(result.constData(), length);
} }
/*! /*!
@ -3501,7 +3501,7 @@ QString QString::simplified() const
if (d->size == 0) if (d->size == 0)
return *this; return *this;
QSTACKARRAY(QChar, result, d->size); QVarLengthArray<QChar> result(d->size);
const QChar *from = reinterpret_cast<const QChar*>(d->data); const QChar *from = reinterpret_cast<const QChar*>(d->data);
const QChar *fromend = from + d->size; const QChar *fromend = from + d->size;
int outc = 0; int outc = 0;
@ -3517,7 +3517,7 @@ QString QString::simplified() const
} }
if (outc > 0 && result[outc-1] == QLatin1Char(' ')) if (outc > 0 && result[outc-1] == QLatin1Char(' '))
outc--; outc--;
return QString(result, outc); return QString(result.constData(), outc);
} }
/*! /*!
@ -4295,13 +4295,13 @@ QString QString::toLower() const
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
const int maxchars = d->size + 1; // ICU will write zero-terminator const int maxchars = d->size + 1; // ICU will write zero-terminator
QSTACKARRAY(UChar, result, maxchars); QVarLengthArray<UChar> result(maxchars);
const int lowerresult = u_strToLower(result, maxchars, const int lowerresult = u_strToLower(result.data(), maxchars,
reinterpret_cast<const UChar*>(d->data), d->size, "C", &error); reinterpret_cast<const UChar*>(d->data), d->size, "C", &error);
if (Q_UNLIKELY(lowerresult > maxchars || U_FAILURE(error))) { if (Q_UNLIKELY(lowerresult > maxchars || U_FAILURE(error))) {
return QString(); return QString();
} }
return QString(reinterpret_cast<QChar*>(result), lowerresult); return QString(reinterpret_cast<const QChar*>(result.constData()), lowerresult);
} }
/*! /*!
@ -4310,18 +4310,18 @@ QString QString::toLower() const
*/ */
QString QString::toCaseFolded() const QString QString::toCaseFolded() const
{ {
if (!d->data || !d->size) if (!d->data || !d->size) {
return *this; return *this;
}
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
const int maxchars = d->size + 1; // ICU will write zero-terminator const int maxchars = d->size + 1; // ICU will write zero-terminator
QSTACKARRAY(UChar, result, maxchars); QVarLengthArray<UChar> result(maxchars);
const int foldresult = u_strFoldCase(result, maxchars, const int foldresult = u_strFoldCase(result.data(), maxchars,
reinterpret_cast<const UChar*>(d->data), d->size, U_FOLD_CASE_DEFAULT, &error); reinterpret_cast<const UChar*>(d->data), d->size, U_FOLD_CASE_DEFAULT, &error);
if (Q_UNLIKELY(foldresult > maxchars || U_FAILURE(error))) { if (Q_UNLIKELY(foldresult > maxchars || U_FAILURE(error))) {
return QString(); return QString();
} }
return QString(reinterpret_cast<QChar*>(result), foldresult); return QString(reinterpret_cast<const QChar*>(result.constData()), foldresult);
} }
/*! /*!
@ -4337,18 +4337,18 @@ QString QString::toCaseFolded() const
QString QString::toUpper() const QString QString::toUpper() const
{ {
if (!d->data || !d->size) if (!d->data || !d->size) {
return *this; return *this;
}
UErrorCode error = U_ZERO_ERROR; UErrorCode error = U_ZERO_ERROR;
const int maxchars = d->size + 1; // ICU will write zero-terminator const int maxchars = d->size + 1; // ICU will write zero-terminator
QSTACKARRAY(UChar, result, maxchars); QVarLengthArray<UChar> result(maxchars);
const int upperresult = u_strToUpper(result, maxchars, const int upperresult = u_strToUpper(result.data(), maxchars,
reinterpret_cast<const UChar*>(d->data), d->size, "C", &error); reinterpret_cast<const UChar*>(d->data), d->size, "C", &error);
if (Q_UNLIKELY(upperresult > maxchars || U_FAILURE(error))) { if (Q_UNLIKELY(upperresult > maxchars || U_FAILURE(error))) {
return QString(); return QString();
} }
return QString(reinterpret_cast<QChar*>(result), upperresult); return QString(reinterpret_cast<const QChar*>(result.constData()), upperresult);
} }
// ### Qt 5: Consider whether this function shouldn't be removed See task 202871. // ### Qt 5: Consider whether this function shouldn't be removed See task 202871.

View file

@ -291,8 +291,8 @@ void QTextEngine::itemize() const
if (!length) if (!length)
return; return;
QSTACKARRAY(QScriptAnalysis, scriptAnalysis, length); QVarLengthArray<QScriptAnalysis> scriptAnalysis(length);
QScriptAnalysis *analysis = scriptAnalysis; QScriptAnalysis *analysis = scriptAnalysis.data();
const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode()); const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode());
const ushort *e = uc + length; const ushort *e = uc + length;
@ -334,10 +334,10 @@ void QTextEngine::itemize() const
const QTextFragmentData * const frag = it.value(); const QTextFragmentData * const frag = it.value();
if (it == end || format != frag->format) { if (it == end || format != frag->format) {
Q_ASSERT(position <= length); Q_ASSERT(position <= length);
generateItem(scriptAnalysis, layoutData->items, prevPosition, position - prevPosition); generateItem(scriptAnalysis.constData(), layoutData->items, prevPosition, position - prevPosition);
if (it == end) { if (it == end) {
if (position < length) if (position < length)
generateItem(scriptAnalysis, layoutData->items, position, length - position); generateItem(scriptAnalysis.constData(), layoutData->items, position, length - position);
break; break;
} }
format = frag->format; format = frag->format;
@ -347,7 +347,7 @@ void QTextEngine::itemize() const
++it; ++it;
} }
} else { } else {
generateItem(scriptAnalysis, layoutData->items, 0, length); generateItem(scriptAnalysis.constData(), layoutData->items, 0, length);
} }
addRequiredBoundaries(); addRequiredBoundaries();