diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2020-05-13 20:11:35 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2020-05-15 03:00:45 +0000 |
commit | b655734965155146290f3f3a9205243af11e42fb (patch) | |
tree | 326e5ca5dcc0cdb10de37682350f34a1f542ac6c | |
parent | f468f76455c91cf1c5b477ab9348337522b4d9aa (diff) |
QString: fix an aliasing issue in remove(QString)
Even in Qt 5, remove() can be passed an alias to *this. In Qt 6, with
the advent of substring sharing, this will become even more
pronounced. Use the same fix as was already used in QString::insert().
Pick-to: 5.15
Change-Id: I1a0d3d99fd7dff6e727661646d2cbfdc94df2682
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r-- | src/corelib/text/qstring.cpp | 10 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstring/tst_qstring.cpp | 10 |
2 files changed, 19 insertions, 1 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index fc1a9f2a83..631b279332 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2883,7 +2883,15 @@ static void removeStringImpl(QString &s, const T &needle, Qt::CaseSensitivity cs */ QString &QString::remove(const QString &str, Qt::CaseSensitivity cs) { - removeStringImpl(*this, str, cs); + const auto s = reinterpret_cast<const ushort *>(str.data()); + const std::less<const ushort *> less; + if (!less(s, d.data()) && less(s, d.data() + d.size)) { + // Part of me - take a copy + const QVarLengthArray<ushort> copy(s, s + str.size()); + removeStringImpl(*this, QStringView{copy.data(), copy.size()}, cs); + } else { + removeStringImpl(*this, qToStringViewIgnoringNull(str), cs); + } return *this; } diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index cefcd4f2e5..38df331cc2 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -388,6 +388,7 @@ private slots: void remove_string(); void remove_regexp_data(); void remove_regexp(); + void remove_extra(); void swap(); void prepend_qstring() { prepend_impl<QString>(); } @@ -3028,6 +3029,15 @@ void tst_QString::remove_regexp() } } +void tst_QString::remove_extra() +{ + { + QString s = "The quick brown fox jumps over the lazy dog. " + "The lazy dog jumps over the quick brown fox."; + s.remove(s); + } +} + void tst_QString::toNum() { #if defined (Q_OS_WIN) && defined (Q_CC_MSVC) |