summaryrefslogtreecommitdiffstats
path: root/src/corelib/text
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2021-12-20 21:52:45 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-12-21 17:14:29 +0000
commit4b2c03a6de7a842e1591b529242c032b97d74169 (patch)
treeae28394e03bbb6da6dcf1b6ddfdfc469ea1729fe /src/corelib/text
parent7cbc3a65a39b109a23c3d2a3b3fd62f8776774a6 (diff)
QStringBuilder: handle freeSpaceAtBegin() in op+=
Amends 9b320edb535a0fbe118933d2e983b73f90c32685. The above commit made the mistake of relying on the 30yr+ old fundamental relation size() - capacity() == freeSpaceAtEnd() which, however, Qt 6's prepend()-optimization (freeSpaceAtBegin()) broke. Because of that, while size() - capacity() may be large enough to hold the new data, if freeSpaceAtBegin() > 0, then freeSpaceAtEnd() may not. Fix by inspecting freeSpaceAtEnd() instead of capacity(). The following reserve() call is unaffected, since it internally already adds freeSpaceAtBegin() to the requested size, which is why the unconditional reserve() in 9b320edb535a0fbe118933d2e983b73f90c32685^ worked while 9b320edb535a0fbe118933d2e983b73f90c32685's capacity() check did not. Fixes: QTBUG-99330 Change-Id: I520f36216011423f97a24484263acd40d8b1fa43 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> (cherry picked from commit 11409f4c023d7a9596ab5c0ca98256f650be9a90) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/corelib/text')
-rw-r--r--src/corelib/text/qstringbuilder.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/corelib/text/qstringbuilder.h b/src/corelib/text/qstringbuilder.h
index c5449ce660..8ed250d238 100644
--- a/src/corelib/text/qstringbuilder.h
+++ b/src/corelib/text/qstringbuilder.h
@@ -429,7 +429,7 @@ QByteArray &appendToByteArray(QByteArray &a, const QStringBuilder<A, B> &b, char
// append 8-bit data to a byte array
qsizetype len = a.size() + QConcatenable< QStringBuilder<A, B> >::size(b);
a.detach(); // a detach() in a.data() could reset a.capacity() to a.size()
- if (len > a.capacity())
+ if (len > a.data_ptr().freeSpaceAtEnd()) // capacity() was broken when prepend()-optimization landed
a.reserve(qMax(len, 2 * a.capacity()));
char *it = a.data() + a.size();
QConcatenable< QStringBuilder<A, B> >::appendTo(b, it);
@@ -458,7 +458,7 @@ QString &operator+=(QString &a, const QStringBuilder<A, B> &b)
{
qsizetype len = a.size() + QConcatenable< QStringBuilder<A, B> >::size(b);
a.detach(); // a detach() in a.data() could reset a.capacity() to a.size()
- if (len > a.capacity())
+ if (len > a.data_ptr().freeSpaceAtEnd()) // capacity() was broken when prepend()-optimization landed
a.reserve(qMax(len, 2 * a.capacity()));
QChar *it = a.data() + a.size();
QConcatenable< QStringBuilder<A, B> >::appendTo(b, it);