summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/doc/src/qt6-changes.qdoc18
-rw-r--r--src/corelib/global/qtypeinfo.h33
-rw-r--r--src/corelib/kernel/qjni.cpp4
-rw-r--r--src/corelib/kernel/qjniobject.cpp4
-rw-r--r--src/network/access/qdecompresshelper.cpp8
-rw-r--r--src/network/access/qdecompresshelper_p.h2
-rw-r--r--src/widgets/widgets/qmenu.cpp3
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp14
-rw-r--r--tests/auto/network/access/qdecompresshelper/10K.gzbin0 -> 55 bytes
-rw-r--r--tests/auto/network/access/qdecompresshelper/tst_qdecompresshelper.cpp40
10 files changed, 94 insertions, 32 deletions
diff --git a/src/corelib/doc/src/qt6-changes.qdoc b/src/corelib/doc/src/qt6-changes.qdoc
index 570dc45e93..7e048ead78 100644
--- a/src/corelib/doc/src/qt6-changes.qdoc
+++ b/src/corelib/doc/src/qt6-changes.qdoc
@@ -307,7 +307,7 @@
\section1 String related classes
- \section2 QStringView
+ \section2 The QStringView class
Starting with Qt6 it is generally recommended to use \l QStringView over
\c QStringRef. \l QStringView references a contiguous portion of a UTF-16
@@ -332,7 +332,7 @@
string += ...;
\endcode
- \section2 QStringRef
+ \section2 The QStringRef class
In Qt6 \l QStringRef got removed from Qt Core. To ease porting of existing
applications without touching the whole code-base, the \c QStringRef class
@@ -403,7 +403,7 @@
\section1 QFuture and Related Classes
- \section2 QFuture
+ \section2 The QFuture class
To avoid unintended usage of QFuture, there were some changes to
QFuture API in Qt 6, which may introduce source compatibility breaks.
@@ -470,14 +470,14 @@
\endlist
- \section2 QPromise
+ \section2 The QPromise class
In Qt 6, the new QPromise class should be used instead of unofficial
QFutureInterface as a "setter" counterpart of QFuture.
\section1 IO Classes
- \section2 QProcess
+ \section2 The QProcess class
In Qt 6, the QProcess::start() overload that interprets a single command string
by splitting it into program name and arguments is renamed to QProcess::startCommand().
@@ -508,7 +508,7 @@
\section1 Meta-Type system
- \section2 QVariant
+ \section2 The QVariant class
\c QVariant has been rewritten to use \c QMetaType for all of its operations. This implies
behavior changes in a few methods:
@@ -529,7 +529,7 @@
\endlist
- \section2 QMetaType
+ \section2 The QMetaType class
In Qt 6, registration of comparators, and \cQDebug and \QDataStream streaming operators is
done automatically. Consequently, \c QMetaType::registerEqualsComparator(),
@@ -555,7 +555,7 @@
\section1 Regular expression classes
- \section2 QRegularExpression
+ \section2 The QRegularExpression class
In Qt6, all methods taking the \c QRegExp got removed from our code-base.
Therefore it is very likely that you will have to port your application or
@@ -786,7 +786,7 @@
{QRegularExpression::UseUnicodePropertiesOption}
pattern option.
- \section2 QRegExp
+ \section2 The QRegExp class
In Qt6 \l QRegExp got removed from Qt Core. If your application cannot be
ported right now, \c QRegExp still exists in Qt5Compat to keep these
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index e5914414f2..fea6ecd45c 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -311,14 +311,13 @@ struct expand_operator_less_than_tuple<std::variant<T...>> : expand_operator_les
}
template<typename T, typename = void>
-struct is_dereferenceable : std::false_type {};
+inline constexpr bool is_dereferenceable_v = false;
template<typename T>
-struct is_dereferenceable<T, std::void_t<decltype(std::declval<T>().operator->())> >
- : std::true_type {};
+inline constexpr bool is_dereferenceable_v<T, std::void_t<decltype(std::declval<T>().operator->())> > = true;
template <typename T>
-inline constexpr bool is_dereferenceable_v = is_dereferenceable<T>::value;
+using is_dereferenceable = std::bool_constant<is_dereferenceable_v<T>>;
template<typename T>
struct has_operator_equal : detail::expand_operator_equal<T> {};
@@ -345,25 +344,31 @@ T &reference();
}
-template <typename Stream, typename, typename = void>
-struct has_ostream_operator : std::false_type {};
+template <typename Stream, typename T, typename = void>
+inline constexpr bool has_ostream_operator_v = false;
+
template <typename Stream, typename T>
-struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() << detail::const_reference<T>())>>
- : std::true_type {};
+inline constexpr bool has_ostream_operator_v<Stream, T, std::void_t<decltype(detail::reference<Stream>() << detail::const_reference<T>())>> = true;
+
template <typename Stream, typename T>
-inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value;
+using has_ostream_operator = std::bool_constant<has_ostream_operator_v<Stream, T>>;
+
+
+
+template <typename Stream, typename T, typename = void>
+inline constexpr bool has_istream_operator_v = false;
-template <typename Stream, typename, typename = void>
-struct has_istream_operator : std::false_type {};
template <typename Stream, typename T>
-struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>>
- : std::true_type {};
+inline constexpr bool has_istream_operator_v<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>> = true;
+
template <typename Stream, typename T>
-inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value;
+using has_istream_operator = std::bool_constant<has_istream_operator_v<Stream, T>>;
template <typename Stream, typename T>
inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>;
+template <typename Stream, typename T>
+using has_stream_operator = std::conjunction<has_ostream_operator<Stream, T>, has_istream_operator<Stream, T>>;
}
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index b593483e59..3750fdb9bc 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -280,9 +280,7 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env)
bool isCached = false;
jclass clazz = getCachedClass(classDotEnc, &isCached);
- const bool found = (clazz != 0) || (clazz == 0 && isCached);
-
- if (found)
+ if (clazz || isCached)
return clazz;
const QLatin1String key(classDotEnc);
diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp
index 43840052ae..f141c2d84e 100644
--- a/src/corelib/kernel/qjniobject.cpp
+++ b/src/corelib/kernel/qjniobject.cpp
@@ -467,9 +467,7 @@ jclass QtAndroidPrivate::findClass(const char *className, JNIEnv *env)
bool isCached = false;
jclass clazz = getCachedClass(classDotEnc, &isCached);
- const bool found = clazz || (!clazz && isCached);
-
- if (found)
+ if (clazz || isCached)
return clazz;
const QLatin1String key(classDotEnc);
diff --git a/src/network/access/qdecompresshelper.cpp b/src/network/access/qdecompresshelper.cpp
index 2e44a58cf4..d0e75ef0dc 100644
--- a/src/network/access/qdecompresshelper.cpp
+++ b/src/network/access/qdecompresshelper.cpp
@@ -405,6 +405,11 @@ void QDecompressHelper::setArchiveBombDetectionEnabled(bool enable)
countHelper->setArchiveBombDetectionEnabled(enable);
}
+void QDecompressHelper::setMinimumArchiveBombSize(qint64 threshold)
+{
+ minimumArchiveBombSize = threshold;
+}
+
bool QDecompressHelper::isPotentialArchiveBomb() const
{
if (!archiveBombDetectionEnabled)
@@ -413,6 +418,9 @@ bool QDecompressHelper::isPotentialArchiveBomb() const
if (totalCompressedBytes == 0)
return false;
+ if (totalUncompressedBytes <= minimumArchiveBombSize)
+ return false;
+
// Some protection against malicious or corrupted compressed files that expand far more than
// is reasonable.
double ratio = double(totalUncompressedBytes) / double(totalCompressedBytes);
diff --git a/src/network/access/qdecompresshelper_p.h b/src/network/access/qdecompresshelper_p.h
index 4e66581022..6a77775790 100644
--- a/src/network/access/qdecompresshelper_p.h
+++ b/src/network/access/qdecompresshelper_p.h
@@ -92,6 +92,7 @@ public:
void clear();
void setArchiveBombDetectionEnabled(bool enable);
+ void setMinimumArchiveBombSize(qint64 threshold);
static bool isSupportedEncoding(const QByteArray &encoding);
static QByteArrayList acceptedEncoding();
@@ -119,6 +120,7 @@ private:
// Used for calculating the ratio
bool archiveBombDetectionEnabled = true;
+ qint64 minimumArchiveBombSize = 10 * 1024 * 1024;
qint64 totalUncompressedBytes = 0;
qint64 totalCompressedBytes = 0;
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index c6a130195c..3f349cf8a0 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -3003,8 +3003,7 @@ void QMenu::changeEvent(QEvent *e)
/*!
\reimp
*/
-bool
-QMenu::event(QEvent *e)
+bool QMenu::event(QEvent *e)
{
Q_D(QMenu);
switch (e->type()) {
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
index 00ed82ee2d..c2f4e82896 100644
--- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -591,10 +591,22 @@ void tst_QDateTime::setMSecsSinceEpoch_data()
<< Q_INT64_C(0)
<< QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC)
<< QDateTime(QDate(1970, 1, 1), QTime(1, 0));
- QTest::newRow("-1")
+ QTest::newRow("+1ms")
+ << Q_INT64_C(+1)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0, 1), Qt::UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(1, 0, 0, 1));
+ QTest::newRow("+1s")
+ << Q_INT64_C(+1000)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 1), Qt::UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(1, 0, 1));
+ QTest::newRow("-1ms")
<< Q_INT64_C(-1)
<< QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59, 999), Qt::UTC)
<< QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59, 999));
+ QTest::newRow("-1s")
+ << Q_INT64_C(-1000)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59), Qt::UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59));
QTest::newRow("123456789")
<< Q_INT64_C(123456789)
<< QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36, 789), Qt::UTC)
diff --git a/tests/auto/network/access/qdecompresshelper/10K.gz b/tests/auto/network/access/qdecompresshelper/10K.gz
new file mode 100644
index 0000000000..c5c4959763
--- /dev/null
+++ b/tests/auto/network/access/qdecompresshelper/10K.gz
Binary files differ
diff --git a/tests/auto/network/access/qdecompresshelper/tst_qdecompresshelper.cpp b/tests/auto/network/access/qdecompresshelper/tst_qdecompresshelper.cpp
index c31ab294cc..cfeff188f4 100644
--- a/tests/auto/network/access/qdecompresshelper/tst_qdecompresshelper.cpp
+++ b/tests/auto/network/access/qdecompresshelper/tst_qdecompresshelper.cpp
@@ -64,6 +64,9 @@ private Q_SLOTS:
void decompressBigData_data();
void decompressBigData();
+ void archiveBomb_data();
+ void archiveBomb();
+
#if QT_POINTER_SIZE >= 8
void bigZlib();
#endif
@@ -392,6 +395,43 @@ void tst_QDecompressHelper::decompressBigData()
QTEST(totalSize, "size");
}
+void tst_QDecompressHelper::archiveBomb_data()
+{
+ QTest::addColumn<QByteArray>("encoding");
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("shouldFail");
+
+ QTest::newRow("gzip-10K") << QByteArray("gzip") << (srcDir + "/10K.gz") << false;
+ QTest::newRow("gzip-4G") << QByteArray("gzip") << QString(":/4G.gz") << true;
+}
+
+void tst_QDecompressHelper::archiveBomb()
+{
+ QFETCH(bool, shouldFail);
+ QFETCH(QString, path);
+ QFile file(path);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+
+ QDecompressHelper helper;
+ QFETCH(QByteArray, encoding);
+ helper.setEncoding(encoding);
+ QVERIFY(helper.isValid());
+
+ constexpr qint64 SafeSizeLimit = 10 * 1024 * 1024;
+ constexpr qint64 RatioLimit = 40;
+ qint64 bytesToRead = std::min(SafeSizeLimit / RatioLimit, file.bytesAvailable());
+ QByteArray output(1 + bytesToRead * RatioLimit, Qt::Uninitialized);
+ helper.feed(file.read(bytesToRead));
+ qsizetype bytesRead = helper.read(output.data(), output.size());
+ QVERIFY(bytesRead <= output.size());
+ QVERIFY(helper.isValid());
+
+ if (shouldFail)
+ QCOMPARE(bytesRead, -1);
+ else
+ QVERIFY(bytesRead > 0);
+}
+
#if QT_POINTER_SIZE >= 8
void tst_QDecompressHelper::bigZlib()
{