diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 9cecd7b8269..d06ac392a89 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2882,6 +2882,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 cd750aa268b..f38c8ee681e 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -81,6 +81,7 @@ private slots: void prependExtended_data(); void prependExtended(); void append(); + void appendFromRawData(); void appendExtended_data(); void appendExtended(); void insert(); @@ -1142,6 +1143,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. + QVERIFY(copy.constData() != 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 861f2b77e21..7ea7c4ba0aa 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -434,6 +434,8 @@ private slots: void append_bytearray_special_cases_data(); void append_bytearray_special_cases(); + void appendFromRawData(); + void operator_pluseq_qstring() { operator_pluseq_impl(); } void operator_pluseq_qstring_data() { operator_pluseq_data(); } void operator_pluseq_qstringview() { operator_pluseq_impl(); } @@ -3015,6 +3017,21 @@ void tst_QString::append_bytearray_special_cases() } } +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. + QVERIFY(copy.constData() != str.constData()); +} + void tst_QString::operator_pluseq_special_cases() { {