From 358b7a9e747549f85c1d1631dfb21210b52b36f5 Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Sat, 29 Oct 2022 14:43:47 +0200 Subject: [PATCH] QByteArray: don't detach in remove() - If this bytearray isn't shared call d->erase() as needed - if it's shared, instead of detaching, create a new bytearray, and copy all characters except for the ones that would be removed See task for details. Adjust unittest to test both code paths. Task-number: QTBUG-106182 Change-Id: I806e4d1707004345a2472e056905fbf675f765ab Reviewed-by: Thiago Macieira --- src/corelib/text/qbytearray.cpp | 15 ++++++++++++--- .../corelib/text/qbytearray/tst_qbytearray.cpp | 9 ++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index 55c622b6cb1..a8d131dbc5d 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -2253,11 +2253,20 @@ QByteArray &QByteArray::remove(qsizetype pos, qsizetype len) { if (len <= 0 || pos < 0 || size_t(pos) >= size_t(size())) return *this; - detach(); if (pos + len > d->size) len = d->size - pos; - d->erase(d.begin() + pos, len); - d.data()[d.size] = '\0'; + + auto begin = d.begin(); + if (!d->isShared()) { + d->erase(begin + pos, len); + d.data()[d.size] = '\0'; + } else { + QByteArray copy{size() - len, Qt::Uninitialized}; + const auto toRemove_start = d.begin() + pos; + copy.d->copyRanges({{d.begin(), toRemove_start}, + {toRemove_start + len, d.end()}}); + swap(copy); + } return *this; } diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 60bddc20df5..e72d21ed0a0 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -1258,7 +1258,14 @@ void tst_QByteArray::remove() QFETCH(int, position); QFETCH(int, length); QFETCH(QByteArray, expected); - QCOMPARE(src.remove(position, length), expected); + // Test when it's shared + QByteArray ba1 = src; + QCOMPARE(ba1.remove(position, length), expected); + + // Test when it's not shared + QByteArray ba2 = src; + ba2.detach(); + QCOMPARE(ba2.remove(position, length), expected); } void tst_QByteArray::removeIf()