diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 140b665a025..0168f1573da 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -3057,6 +3057,10 @@ QString &QString::append(const QString &str) if (!str.isNull()) { if (isNull()) { operator=(str); + if (Q_UNLIKELY(!d.isMutable() && d.size > 0)) { + d.detach(); // fromRawData, so we do a deep copy + d.data()[d.size] = u'\0'; + } } else if (str.size()) { append(str.constData(), str.size()); } diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 6972541847c..0ca4f935eff 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -48,6 +48,7 @@ private slots: void prependExtended_data(); void prependExtended(); void append(); + void appendFromRawData(); void appendExtended_data(); void appendExtended(); void insert(); @@ -906,6 +907,20 @@ void tst_QByteArray::append() } } +void tst_QByteArray::appendFromRawData() +{ + char rawData[] = "Hello World!"; + QByteArray ba = QByteArray::fromRawData(rawData, std::size(rawData) - 1); + + QByteArray copy; + copy.append(ba); + QCOMPARE(copy, ba); + // We make an _actual_ copy, because appending a byte array + // created with fromRawData() might be optimized to copy the DataPointer, + // which means we may point to temporary stack data. + QCOMPARE_NE((void *)copy.constData(), (void *)ba.constData()); +} + void tst_QByteArray::appendExtended_data() { prependExtended_data(); diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index c317b1adbb6..3870dc4ee05 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -456,6 +456,8 @@ private slots: void append_bytearray_special_cases(); #endif + void appendFromRawData(); + void operator_pluseq_qstring() { operator_pluseq_impl(); } void operator_pluseq_qstring_data() { operator_pluseq_data(); } void operator_pluseq_qstringview() { operator_pluseq_impl(); } @@ -3276,6 +3278,21 @@ void tst_QString::append_bytearray_special_cases() } #endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII) +void tst_QString::appendFromRawData() +{ + const char16_t utf[] = u"Hello World!"; + auto *rawData = reinterpret_cast(utf); + QString str = QString::fromRawData(rawData, std::size(utf) - 1); + + QString copy; + copy.append(str); + QCOMPARE(copy, str); + // We make an _actual_ copy, because appending a byte array + // created with fromRawData() might be optimized to copy the DataPointer, + // which means we may point to temporary stack data. + QCOMPARE_NE((void *)copy.constData(), (void *)str.constData()); +} + void tst_QString::operator_pluseq_special_cases() { QString a;