QByteArrayList: fix narrowing in join() implementations [2/2]

We forgot to adjust the interface and implementation of join() to the
int → qsizetype change in Qt 6.

This part of the two-part patch fixes things in a non-forwards-BC way,
so it can't be picked into released versions. The forwards-BC part is
in the first patch of the series.

We can't just replace the int seplen with qsizetype, because qsizetype
is an alias to int on 32-bit platforms. So, pass the separator by
QByteArrayView.

[ChangeLog][QtCore][QByteArrayList] Fixed a bug when calling join()
with separators of length > INTMAX.

Change-Id: I2ccc61de1c8901ac5504aea1ebd895d12dbcb064
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Marc Mutz 2021-11-03 16:04:31 +01:00
parent 0b768e3c43
commit faa854ffeb
3 changed files with 16 additions and 7 deletions

View File

@ -89,6 +89,13 @@ QUuid QUuid::fromRfc4122(const QByteArray &bytes)
return fromRfc4122(qToByteArrayViewIgnoringNull(bytes)); return fromRfc4122(qToByteArrayViewIgnoringNull(bytes));
} }
#include "qbytearraylist.h"
QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char *sep, int seplen)
{
return QByteArrayList_join(that, {sep, seplen});
}
// #include <qotherheader.h> // #include <qotherheader.h>
// // implement removed functions from qotherheader.h // // implement removed functions from qotherheader.h

View File

@ -144,15 +144,15 @@ static qsizetype QByteArrayList_joinedSize(const QByteArrayList *that, qsizetype
return totalLength; return totalLength;
} }
QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char *sep, int seplen) QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, QByteArrayView sep)
{ {
QByteArray res; QByteArray res;
if (const qsizetype joinedSize = QByteArrayList_joinedSize(that, seplen)) if (const qsizetype joinedSize = QByteArrayList_joinedSize(that, sep.size()))
res.reserve(joinedSize); // don't call reserve(0) - it allocates one byte for the NUL res.reserve(joinedSize); // don't call reserve(0) - it allocates one byte for the NUL
const qsizetype size = that->size(); const qsizetype size = that->size();
for (qsizetype i = 0; i < size; ++i) { for (qsizetype i = 0; i < size; ++i) {
if (i) if (i)
res.append(sep, seplen); res.append(sep);
res += that->at(i); res += that->at(i);
} }
return res; return res;

View File

@ -58,7 +58,10 @@ typedef QMutableListIterator<QByteArray> QMutableByteArrayListIterator;
#ifndef Q_CLANG_QDOC #ifndef Q_CLANG_QDOC
namespace QtPrivate { namespace QtPrivate {
#if QT_REMOVED_SINCE(6, 3)
QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *separator, int separatorLength); QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *separator, int separatorLength);
#endif
QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, QByteArrayView separator);
} }
#endif #endif
@ -78,17 +81,16 @@ public:
using QListSpecialMethodsBase<QByteArray>::contains; using QListSpecialMethodsBase<QByteArray>::contains;
inline QByteArray join() const inline QByteArray join() const
{ return QtPrivate::QByteArrayList_join(self(), nullptr, 0); } { return join(QByteArrayView{}); }
inline QByteArray join(QByteArrayView sep) const // ### Qt 7: merge with the () overload inline QByteArray join(QByteArrayView sep) const // ### Qt 7: merge with the () overload
{ {
Q_ASSERT(sep.size() <= (std::numeric_limits<int>::max)()); return QtPrivate::QByteArrayList_join(self(), sep);
return QtPrivate::QByteArrayList_join(self(), sep.data(), sep.size());
} }
Q_WEAK_OVERLOAD Q_WEAK_OVERLOAD
inline QByteArray join(const QByteArray &sep) const inline QByteArray join(const QByteArray &sep) const
{ return join(QByteArrayView{sep}); } { return join(QByteArrayView{sep}); }
inline QByteArray join(char sep) const inline QByteArray join(char sep) const
{ return QtPrivate::QByteArrayList_join(self(), &sep, 1); } { return join({&sep, 1}); }
}; };
QT_END_NAMESPACE QT_END_NAMESPACE