Sync from SUSE:SLFO:Main qt6-base revision dc82084911ba0fe423f6301c8defbc95

This commit is contained in:
Adrian Schröter 2024-09-11 10:39:30 +02:00
parent 613c024f03
commit a07d6d9a62
7 changed files with 373 additions and 54 deletions

View File

@ -0,0 +1,244 @@
From 2b1e36e183ce75c224305c7a94457b92f7a5cf58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= <marten.nordheim@qt.io>
Date: Tue, 25 Jun 2024 17:09:35 +0200
Subject: [PATCH] HTTP2: Delay any communication until encrypted() can be
responded to
We have the encrypted() signal that lets users do extra checks on the
established connection. It is emitted as BlockingQueued, so the HTTP
thread stalls until it is done emitting. Users can potentially call
abort() on the QNetworkReply at that point, which is passed as a Queued
call back to the HTTP thread. That means that any currently queued
signal emission will be processed before the abort() call is processed.
In the case of HTTP2 it is a little special since it is multiplexed and
the code is built to start requests as they are available. This means
that, while the code worked fine for HTTP1, since one connection only
has one request, it is not working for HTTP2, since we try to send more
requests in-between the encrypted() signal and the abort() call.
This patch changes the code to delay any communication until the
encrypted() signal has been emitted and processed, for HTTP2 only.
It's done by adding a few booleans, both to know that we have to return
early and so we can keep track of what events arose and what we need to
resume once enough time has passed that any abort() call must have been
processed.
Fixes: QTBUG-126610
Pick-to: 6.5 6.2 5.15 5.12
Change-Id: Ic25a600c278203256e35f541026f34a8783235ae
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit b1e75376cc3adfc7da5502a277dfe9711f3e0536)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 0fb43e4395da34d561814242a0186999e4956e28)
---
src/network/access/qhttp2protocolhandler.cpp | 6 +--
.../access/qhttpnetworkconnectionchannel.cpp | 48 ++++++++++++++++++-
.../access/qhttpnetworkconnectionchannel_p.h | 6 +++
tests/auto/network/access/http2/tst_http2.cpp | 44 +++++++++++++++++
4 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 0abd99b9bc..3631b13dc8 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -303,12 +303,12 @@ bool QHttp2ProtocolHandler::sendRequest()
}
}
- if (!prefaceSent && !sendClientPreface())
- return false;
-
if (!requests.size())
return true;
+ if (!prefaceSent && !sendClientPreface())
+ return false;
+
m_channel->state = QHttpNetworkConnectionChannel::WritingState;
// Check what was promised/pushed, maybe we do not have to send a request
// and have a response already?
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 6766989690..1e4161d1fd 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -209,6 +209,10 @@ void QHttpNetworkConnectionChannel::abort()
bool QHttpNetworkConnectionChannel::sendRequest()
{
Q_ASSERT(protocolHandler);
+ if (waitingForPotentialAbort) {
+ needInvokeSendRequest = true;
+ return false; // this return value is unused
+ }
return protocolHandler->sendRequest();
}
@@ -221,21 +225,28 @@ bool QHttpNetworkConnectionChannel::sendRequest()
void QHttpNetworkConnectionChannel::sendRequestDelayed()
{
QMetaObject::invokeMethod(this, [this] {
- Q_ASSERT(protocolHandler);
if (reply)
- protocolHandler->sendRequest();
+ sendRequest();
}, Qt::ConnectionType::QueuedConnection);
}
void QHttpNetworkConnectionChannel::_q_receiveReply()
{
Q_ASSERT(protocolHandler);
+ if (waitingForPotentialAbort) {
+ needInvokeReceiveReply = true;
+ return;
+ }
protocolHandler->_q_receiveReply();
}
void QHttpNetworkConnectionChannel::_q_readyRead()
{
Q_ASSERT(protocolHandler);
+ if (waitingForPotentialAbort) {
+ needInvokeReadyRead = true;
+ return;
+ }
protocolHandler->_q_readyRead();
}
@@ -1239,7 +1250,18 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
if (!h2RequestsToSend.isEmpty()) {
// Similar to HTTP/1.1 counterpart below:
const auto &pair = std::as_const(h2RequestsToSend).first();
+ waitingForPotentialAbort = true;
emit pair.second->encrypted();
+
+ // We don't send or handle any received data until any effects from
+ // emitting encrypted() have been processed. This is necessary
+ // because the user may have called abort(). We may also abort the
+ // whole connection if the request has been aborted and there is
+ // no more requests to send.
+ QMetaObject::invokeMethod(this,
+ &QHttpNetworkConnectionChannel::checkAndResumeCommunication,
+ Qt::QueuedConnection);
+
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
}
@@ -1257,6 +1279,28 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
+
+void QHttpNetworkConnectionChannel::checkAndResumeCommunication()
+{
+ Q_ASSERT(connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct);
+
+ // Because HTTP/2 requires that we send a SETTINGS frame as the first thing we do, and respond
+ // to a SETTINGS frame with an ACK, we need to delay any handling until we can ensure that any
+ // effects from emitting encrypted() have been processed.
+ // This function is called after encrypted() was emitted, so check for changes.
+
+ if (!reply && h2RequestsToSend.isEmpty())
+ abort();
+ waitingForPotentialAbort = false;
+ if (needInvokeReadyRead)
+ _q_readyRead();
+ if (needInvokeReceiveReply)
+ _q_receiveReply();
+ if (needInvokeSendRequest)
+ sendRequest();
+}
+
void QHttpNetworkConnectionChannel::requeueHttp2Requests()
{
const auto h2RequestsToSendCopy = std::exchange(h2RequestsToSend, {});
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index c42290feca..061f20fd42 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -74,6 +74,10 @@ public:
QAbstractSocket *socket;
bool ssl;
bool isInitialized;
+ bool waitingForPotentialAbort = false;
+ bool needInvokeReceiveReply = false;
+ bool needInvokeReadyRead = false;
+ bool needInvokeSendRequest = false;
ChannelState state;
QHttpNetworkRequest request; // current request, only used for HTTP
QHttpNetworkReply *reply; // current reply for this request, only used for HTTP
@@ -146,6 +150,8 @@ public:
void closeAndResendCurrentRequest();
void resendCurrentRequest();
+ void checkAndResumeCommunication();
+
bool isSocketBusy() const;
bool isSocketWriting() const;
bool isSocketWaiting() const;
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
index 00efbc9832..c02e7b7b5b 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -106,6 +106,8 @@ private slots:
void duplicateRequestsWithAborts();
+ void abortOnEncrypted();
+
protected slots:
// Slots to listen to our in-process server:
void serverStarted(quint16 port);
@@ -1479,6 +1481,48 @@ void tst_Http2::duplicateRequestsWithAborts()
QCOMPARE(finishedCount, ExpectedSuccessfulRequests);
}
+void tst_Http2::abortOnEncrypted()
+{
+#if !QT_CONFIG(ssl)
+ QSKIP("TLS support is needed for this test");
+#else
+ clearHTTP2State();
+ serverPort = 0;
+
+ ServerPtr targetServer(newServer(defaultServerSettings, H2Type::h2Direct));
+
+ QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection);
+ runEventLoop();
+
+ nRequests = 1;
+ nSentRequests = 0;
+
+ const auto url = requestUrl(H2Type::h2Direct);
+ QNetworkRequest request(url);
+ request.setAttribute(QNetworkRequest::Http2DirectAttribute, true);
+
+ std::unique_ptr<QNetworkReply> reply{manager->get(request)};
+ reply->ignoreSslErrors();
+ connect(reply.get(), &QNetworkReply::encrypted, reply.get(), [reply = reply.get()](){
+ reply->abort();
+ });
+ connect(reply.get(), &QNetworkReply::errorOccurred, this, &tst_Http2::replyFinishedWithError);
+
+ runEventLoop();
+ STOP_ON_FAILURE
+
+ QCOMPARE(nRequests, 0);
+ QCOMPARE(reply->error(), QNetworkReply::OperationCanceledError);
+
+ const bool res = QTest::qWaitFor(
+ [this, server = targetServer.get()]() {
+ return serverGotSettingsACK || prefaceOK || nSentRequests > 0;
+ },
+ 500);
+ QVERIFY(!res);
+#endif // QT_CONFIG(ssl)
+}
+
void tst_Http2::serverStarted(quint16 port)
{
serverPort = port;
--
2.45.2

View File

@ -1,29 +0,0 @@
From 25e78cce15fdf737cc48ed5d7683ad1d01b55621 Mon Sep 17 00:00:00 2001
From: Christophe Giboudeaux <christophe@krop.fr>
Date: Sun, 20 Sep 2020 09:57:22 +0200
Subject: [PATCH] Tell the truth about private API
Mark private API with symbols only for the current patch release
This change is a port of the libqt5-qtbase patch which was
added during the Qt 5.6 cycle.
---
cmake/QtFlagHandlingHelpers.cmake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake
index d8597326cc..f9da7b2171 100644
--- a/cmake/QtFlagHandlingHelpers.cmake
+++ b/cmake/QtFlagHandlingHelpers.cmake
@@ -23,7 +23,7 @@ function(qt_internal_add_linker_version_script target)
endif()
if(TEST_ld_version_script)
- set(contents "Qt_${PROJECT_VERSION_MAJOR}_PRIVATE_API {\n qt_private_api_tag*;\n")
+ set(contents "Qt_${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}_PRIVATE_API {\n qt_private_api_tag*;\n")
if(arg_PRIVATE_HEADERS)
foreach(ph ${arg_PRIVATE_HEADERS})
string(APPEND contents " @FILE:${ph}@\n")
--
2.40.0

48
gcc14.patch Normal file
View File

@ -0,0 +1,48 @@
From 39fa7e7bef90be2940c5f736935f963e3969e0bd Mon Sep 17 00:00:00 2001
From: Dmitry Shachnev <mitya57@gmail.com>
Date: Sat, 27 Jul 2024 23:03:07 +0300
Subject: [PATCH] Use _Float16 only when SSE2 is enabled
The GCC documentation [1] says: “On x86 targets with SSE2 enabled, GCC
supports half-precision (16-bit) floating point via the _Float16 type”.
On non-SSE2 x86 (such as Debian i386 baseline [2]), __FLT16_MAX__ is
defined starting with GCC 14 [3], however any non-trivial use of the
_Float16 type results in an error:
error: operation not permitted on type _Float16 without option -msse2
which makes some packages fail to build on i386 architecture [4].
[1]: https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html
[2]: https://wiki.debian.org/ArchitectureSpecificsMemo#i386-1
[3]: https://gcc.gnu.org/g:9a19fa8b616f83474c35cc5b34a3865073ced829
[4]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1076986
Pick-to: 6.8 6.7 6.5
Change-Id: I393ee83eb8e8888f5fc9e3b349dc8b063eef6f5a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
---
diff --git a/src/corelib/global/qtypes.h b/src/corelib/global/qtypes.h
index db9ba38..28458f6 100644
--- a/src/corelib/global/qtypes.h
+++ b/src/corelib/global/qtypes.h
@@ -263,13 +263,12 @@
// disabled due to https://github.com/llvm/llvm-project/issues/56963
# define QFLOAT16_IS_NATIVE 1
using NativeFloat16Type = decltype(__FLT16_MAX__);
-#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__)
+#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__ARM_FP16_FORMAT_IEEE)
# define QFLOAT16_IS_NATIVE 1
-# ifdef __ARM_FP16_FORMAT_IEEE
using NativeFloat16Type = __fp16;
-# else
+#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__SSE2__)
+# define QFLOAT16_IS_NATIVE 1
using NativeFloat16Type = _Float16;
-# endif
#else
# define QFLOAT16_IS_NATIVE 0
using NativeFloat16Type = void;

View File

@ -1,3 +1,48 @@
-------------------------------------------------------------------
Wed Aug 7 12:46:16 UTC 2024 - Filip Kastl <filip.kastl@suse.com>
- Add gcc14.patch so that the package builds for 32bit with GCC 14.
-------------------------------------------------------------------
Sat Jul 6 11:22:52 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Add upstream change (boo#1227426, CVE-2024-39936)
* 0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch
-------------------------------------------------------------------
Wed Jun 19 07:25:37 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Update to 6.7.2:
* https://www.qt.io/blog/qt-6.7.2-released
-------------------------------------------------------------------
Tue May 21 08:31:24 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Update to 6.7.1:
* https://www.qt.io/blog/qt-6.7.1-released
- Build with system md4c when possible
- Drop patches, merged upstream:
* fix_builds_with_Werror.patch
* 0001-QStringConverterICU-Pass-correct-pointer-to-callback.patch
* 0001-CMake-ELF-allow-using-Qt-s-full-version-number-in-th.patch
-------------------------------------------------------------------
Fri May 3 07:15:23 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Add upstream security fix (CVE-2024-33861, boo#1223917):
* 0001-QStringConverterICU-Pass-correct-pointer-to-callback.patch
-------------------------------------------------------------------
Tue Apr 2 13:39:34 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Update to 6.7.0:
* https://www.qt.io/blog/qt-6.7-released
- Replace 0001-Tell-the-truth-about-private-API.patch with
upstream change:
* 0001-CMake-ELF-allow-using-Qt-s-full-version-number-in-th.patch
- Add upstream fix (QTBUG-123937):
* fix_builds_with_Werror.patch
-------------------------------------------------------------------
Tue Mar 26 14:25:22 UTC 2024 - Christophe Marin <christophe@krop.fr>

View File

@ -16,8 +16,8 @@
#
%define real_version 6.6.3
%define short_version 6.6
%define real_version 6.7.2
%define short_version 6.7
%define tar_name qtbase-everywhere-src
%define tar_suffix %{nil}
#
@ -29,24 +29,28 @@
%ifarch %{arm} aarch64
%global with_gles 1
%endif
%if 0%{?suse_version} > 1500
%bcond_without system_md4c
%endif
Name: qt6-base%{?pkg_suffix}
Version: 6.6.3
Version: 6.7.2
Release: 0
Summary: Qt 6 core components (Core, Gui, Widgets, Network...)
# Legal: qtpaths is BSD-3-Clause
License: LGPL-2.1-with-Qt-Company-Qt-exception-1.1 OR LGPL-3.0-only
URL: https://www.qt.io
Source: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz
Source0: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz
Source99: qt6-base-rpmlintrc
# Patches 0-100 are upstream patches #
Patch0: gcc14.patch
# Patches 100-200 are openSUSE and/or non-upstream(able) patches #
Patch100: 0001-Tell-the-truth-about-private-API.patch
# No need to pollute the library dir with object files, install them in the qt6 subfolder
Patch101: 0001-CMake-Install-objects-files-into-ARCHDATADIR.patch
Patch100: 0001-CMake-Install-objects-files-into-ARCHDATADIR.patch
%if 0%{?suse_version} == 1500
Patch102: 0001-Use-newer-GCC-on-Leap.patch
Patch101: 0001-Use-newer-GCC-on-Leap.patch
%endif
Patch103: 0001-Don-t-strip-binaries-when-building-with-qmake.patch
Patch102: 0001-Don-t-strip-binaries-when-building-with-qmake.patch
Patch103: 0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch
##
BuildRequires: cmake >= 3.18.3
BuildRequires: cups-devel
@ -68,6 +72,9 @@ BuildRequires: pkgconfig
BuildRequires: qt6-macros
BuildRequires: xmlstarlet
BuildRequires: cmake(double-conversion)
%if %{with system_md4c}
BuildRequires: cmake(md4c)
%endif
BuildRequires: pkgconfig(atspi-2)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(egl)
@ -737,6 +744,9 @@ sed -i 's#../../3rdparty/freetype/LICENSE.txt#FREETYPE_LICENSE.txt#' src/gui/pai
# We don't want to use these 3rdparty libraries
rm -r src/3rdparty/{blake2,double-conversion,freetype,harfbuzz-ng,libjpeg,libpng,pcre2,sqlite,xcb,zlib}
%if %{with system_md4c}
rm -r src/3rdparty/md4c
%endif
# Empty file used for the meta packages
cat >> meta_package << EOF
@ -771,24 +781,25 @@ sed -i '/zstd CONFIG/d' cmake/FindWrapZSTD.cmake
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \
-DQT_BUILD_EXAMPLES:BOOL=TRUE \
-DQT_BUILD_TESTS:BOOL=FALSE \
-DQT_CREATE_VERSIONED_HARD_LINK:BOOL=OFF \
-DQT_DISABLE_RPATH:BOOL=OFF \
-DQT_CREATE_VERSIONED_HARD_LINK:BOOL=FALSE \
-DQT_DISABLE_RPATH:BOOL=FALSE \
%ifnarch ppc64
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=ON \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=TRUE \
%endif
-DFEATURE_enable_new_dtags:BOOL=ON \
-DFEATURE_journald:BOOL=ON \
-DFEATURE_libproxy:BOOL=ON \
-DFEATURE_reduce_relocations:BOOL=OFF \
-DFEATURE_relocatable:BOOL=OFF \
-DFEATURE_system_sqlite:BOOL=ON \
-DFEATURE_system_xcb_xinput:BOOL=ON \
-DFEATURE_xcb_native_painting:BOOL=ON \
-DFEATURE_elf_private_full_version=TRUE \
-DFEATURE_enable_new_dtags:BOOL=TRUE \
-DFEATURE_journald:BOOL=TRUE \
-DFEATURE_libproxy:BOOL=TRUE \
-DFEATURE_reduce_relocations:BOOL=FALSE \
-DFEATURE_relocatable:BOOL=FALSE \
-DFEATURE_system_sqlite:BOOL=TRUE \
-DFEATURE_system_xcb_xinput:BOOL=TRUE \
-DFEATURE_xcb_native_painting:BOOL=TRUE \
-DINPUT_openssl:STRING=linked \
-DFEATURE_forkfd_pidfd:BOOL=OFF \
-DFEATURE_forkfd_pidfd:BOOL=FALSE \
%if 0%{?with_gles}
-DINPUT_opengl:STRING=es2 \
-DFEATURE_opengles3:BOOL=ON
-DFEATURE_opengles3:BOOL=TRUE
%endif
%{qt6_build}
@ -816,7 +827,6 @@ rm %{buildroot}%{_qt6_mkspecsdir}/modules/qt_lib_concurrent_private.pri
rm %{buildroot}%{_qt6_mkspecsdir}/modules/qt_lib_openglwidgets_private.pri
# These files are only useful for the Qt continuous integration
rm %{buildroot}%{_qt6_libexecdir}/android_*.sh
rm %{buildroot}%{_qt6_libexecdir}/ensure_pro_file.cmake
rm %{buildroot}%{_qt6_libexecdir}/qt-testrunner.py
rm %{buildroot}%{_qt6_libexecdir}/sanitizer-testrunner.py
@ -885,6 +895,7 @@ rm -r %{buildroot}%{_qt6_mkspecsdir}/features/uikit
%{_qt6_libexecdir}/qt-cmake-private
%{_qt6_libexecdir}/qt-cmake-private-install.cmake
%{_qt6_libexecdir}/qt-cmake-standalone-test
%{_qt6_libexecdir}/qt-internal-configure-examples
%{_qt6_libexecdir}/qt-internal-configure-tests
%{_qt6_libexecdir}/qvkgen
%{_qt6_libexecdir}/rcc

BIN
qtbase-everywhere-src-6.6.3.tar.xz (Stored with Git LFS)

Binary file not shown.

BIN
qtbase-everywhere-src-6.7.2.tar.xz (Stored with Git LFS) Normal file

Binary file not shown.