OSDN Git Service

use QVarLengthArray<T>() instead of QSTACKARRAY() for potentially large buffers
authorIvailo Monev <xakepa10@gmail.com>
Mon, 29 May 2023 23:37:12 +0000 (02:37 +0300)
committerIvailo Monev <xakepa10@gmail.com>
Mon, 29 May 2023 23:42:39 +0000 (02:42 +0300)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/core/codecs/qtextcodec.cpp
src/core/tools/qstring.cpp
src/gui/text/qtextengine.cpp

index 04d9c4f..f181e93 100644 (file)
@@ -1091,13 +1091,13 @@ QString QTextCodecPrivate::convertTo(const char *data, int length, const char* c
     ucnv_setSubstString(conv, questionmarkchar, 1, &error);
 
     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;
-    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);
 
     if (Q_LIKELY(U_SUCCESS(error))) {
-        return QString(reinterpret_cast<QChar*>(result), convresult);
+        return QString(reinterpret_cast<const QChar*>(result.constData()), convresult);
     }
 
     return QString();
@@ -1115,14 +1115,14 @@ QByteArray QTextCodecPrivate::convertFrom(const QChar *unicode, int length, cons
     ucnv_setSubstString(conv, questionmarkchar, 1, &error);
 
     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;
-    const int convresult = ucnv_fromUChars(conv, result, maxbytes,
+    const int convresult = ucnv_fromUChars(conv, result.data(), maxbytes,
         reinterpret_cast<const UChar *>(unicode), length, &error);
     ucnv_close(conv);
 
     if (Q_LIKELY(U_SUCCESS(error))) {
-        return QByteArray(result, convresult);
+        return QByteArray(result.constData(), convresult);
     }
 
     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));
-    QSTACKARRAY(char, result, maxbytes);
+    QVarLengthArray<char> result(maxbytes);
     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);
-    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));
-    QSTACKARRAY(UChar, result, maxbytes);
+    QVarLengthArray<UChar> result(maxbytes);
     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
     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));
         if (::memcmp(resultuchar, qt_utf32le_bom, sizeof(qt_utf32le_bom)) == 0
             || ::memcmp(resultuchar, qt_utf32be_bom, sizeof(qt_utf32be_bom)) == 0) {
             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) {
-        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));
         if (::memcmp(resultuchar, qt_utf16le_bom, sizeof(qt_utf16le_bom)) == 0
             || ::memcmp(resultuchar, qt_utf16be_bom, sizeof(qt_utf16be_bom)) == 0) {
             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
index 58b62a4..02f2da3 100644 (file)
@@ -1666,14 +1666,14 @@ QString &QString::replace(const QLatin1String &before,
                           Qt::CaseSensitivity cs)
 {
     int alen = qstrlen(after.latin1());
-    QSTACKARRAY(ushort, a, alen);
+    QVarLengthArray<ushort> a(alen);
     for (int i = 0; i < alen; ++i)
         a[i] = (uchar)after.latin1()[i];
     int blen = qstrlen(before.latin1());
-    QSTACKARRAY(ushort, b, blen);
+    QVarLengthArray<ushort> b(blen);
     for (int i = 0; i < blen; ++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) {
         return QByteArray();
     }
-    QSTACKARRAY(char, result, length);
+    QVarLengthArray<char> result(length);
     for (int i = 0; i < length; i++) {
         const ushort ucs = data[i].unicode();
         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)
         return *this;
 
-    QSTACKARRAY(QChar, result, d->size);
+    QVarLengthArray<QChar> result(d->size);
     const QChar *from = reinterpret_cast<const QChar*>(d->data);
     const QChar *fromend = from + d->size;
     int outc = 0;
@@ -3517,7 +3517,7 @@ QString QString::simplified() const
     }
     if (outc > 0 && result[outc-1] == QLatin1Char(' '))
         outc--;
-    return QString(result, outc);
+    return QString(result.constData(), outc);
 }
 
 /*!
@@ -4295,13 +4295,13 @@ QString QString::toLower() const
 
     UErrorCode error = U_ZERO_ERROR;
     const int maxchars = d->size + 1; // ICU will write zero-terminator
-    QSTACKARRAY(UChar, result, maxchars);
-    const int lowerresult = u_strToLower(result, maxchars,
+    QVarLengthArray<UChar> result(maxchars);
+    const int lowerresult = u_strToLower(result.data(), maxchars,
         reinterpret_cast<const UChar*>(d->data), d->size, "C", &error);
     if (Q_UNLIKELY(lowerresult > maxchars || U_FAILURE(error))) {
         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
 {
-    if (!d->data || !d->size)
+    if (!d->data || !d->size) {
         return *this;
-
+    }
     UErrorCode error = U_ZERO_ERROR;
     const int maxchars = d->size + 1; // ICU will write zero-terminator
-    QSTACKARRAY(UChar, result, maxchars);
-    const int foldresult = u_strFoldCase(result, maxchars,
+    QVarLengthArray<UChar> result(maxchars);
+    const int foldresult = u_strFoldCase(result.data(), maxchars,
         reinterpret_cast<const UChar*>(d->data), d->size, U_FOLD_CASE_DEFAULT, &error);
     if (Q_UNLIKELY(foldresult > maxchars || U_FAILURE(error))) {
         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
 {
-    if (!d->data || !d->size)
+    if (!d->data || !d->size) {
         return *this;
-
+    }
     UErrorCode error = U_ZERO_ERROR;
     const int maxchars = d->size + 1; // ICU will write zero-terminator
-    QSTACKARRAY(UChar, result, maxchars);
-    const int upperresult = u_strToUpper(result, maxchars,
+    QVarLengthArray<UChar> result(maxchars);
+    const int upperresult = u_strToUpper(result.data(), maxchars,
         reinterpret_cast<const UChar*>(d->data), d->size, "C", &error);
     if (Q_UNLIKELY(upperresult > maxchars || U_FAILURE(error))) {
         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.
index 7a4a3b1..3a537fb 100644 (file)
@@ -291,8 +291,8 @@ void QTextEngine::itemize() const
     if (!length)
         return;
 
-    QSTACKARRAY(QScriptAnalysis, scriptAnalysis, length);
-    QScriptAnalysis *analysis = scriptAnalysis;
+    QVarLengthArray<QScriptAnalysis> scriptAnalysis(length);
+    QScriptAnalysis *analysis = scriptAnalysis.data();
 
     const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode());
     const ushort *e = uc + length;
@@ -334,10 +334,10 @@ void QTextEngine::itemize() const
             const QTextFragmentData * const frag = it.value();
             if (it == end || format != frag->format) {
                 Q_ASSERT(position <= length);
-                generateItem(scriptAnalysis, layoutData->items, prevPosition, position - prevPosition);
+                generateItem(scriptAnalysis.constData(), layoutData->items, prevPosition, position - prevPosition);
                 if (it == end) {
                     if (position < length)
-                        generateItem(scriptAnalysis, layoutData->items, position, length - position);
+                        generateItem(scriptAnalysis.constData(), layoutData->items, position, length - position);
                     break;
                 }
                 format = frag->format;
@@ -347,7 +347,7 @@ void QTextEngine::itemize() const
             ++it;
         }
     } else {
-        generateItem(scriptAnalysis, layoutData->items, 0, length);
+        generateItem(scriptAnalysis.constData(), layoutData->items, 0, length);
     }
 
     addRequiredBoundaries();