转换LFS仓库为普通仓库

This commit is contained in:
Jiayi Yin 2025-05-18 23:29:18 +00:00
commit 7463bfb767
29 changed files with 2588 additions and 0 deletions

14
10-qt6-check-opengl2.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
if [ -z "$QT_XCB_FORCE_SOFTWARE_OPENGL" ]; then
QT6_CHECK_OPENGL_VERSION=`LANG=C glxinfo 2> /dev/null | grep '^OpenGL version string: ' | head -n 1 | sed -e 's/^OpenGL version string: \([0-9]\).*$/\1/g'` ||:
if [ "$QT6_CHECK_OPENGL_VERSION" == "1" ]; then
QT_XCB_FORCE_SOFTWARE_OPENGL=1
export QT_XCB_FORCE_SOFTWARE_OPENGL
fi
unset QT6_CHECK_OPENGL_VERSION
fi

36
README.en.md Normal file
View File

@ -0,0 +1,36 @@
# qt6-qtbase
#### Description
Qt6 - QtBase components
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

37
README.md Normal file
View File

@ -0,0 +1,37 @@
# qt6-qtbase
#### 介绍
Qt6 - QtBase components
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -0,0 +1,31 @@
From 00b748a08fd27277e4bd8f86b431a1e71423d7ff Mon Sep 17 00:00:00 2001
From: peijiankang <peijiankang@kylinos.cn>
Date: Mon, 29 Jan 2024 11:04:27 +0800
Subject: [PATCH] fix build error of libxkbcommon 1.6.0
---
src/gui/platform/unix/qxkbcommon.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/gui/platform/unix/qxkbcommon.cpp b/src/gui/platform/unix/qxkbcommon.cpp
index fc014b38..0de9e98f 100644
--- a/src/gui/platform/unix/qxkbcommon.cpp
+++ b/src/gui/platform/unix/qxkbcommon.cpp
@@ -239,10 +239,14 @@ static constexpr const auto KeyTbl = qMakeArray(
Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
+/* The following four XKB_KEY_dead keys got removed in libxkbcommon 1.6.0
+ The define check is kind of version check here. */
+#ifdef XKB_KEY_dead_lowline
Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
+#endif
// Special keys from X.org - This include multimedia keys,
// wireless/bluetooth/uwb keys, special launcher keys, etc.
--
2.41.0

View File

@ -0,0 +1,14 @@
diff --git a/cmake/QtBaseConfigureTests.cmake b/cmake/QtBaseConfigureTests.cmake
index e337a431..3244922e 100644
--- a/cmake/QtBaseConfigureTests.cmake
+++ b/cmake/QtBaseConfigureTests.cmake
@@ -77,7 +76,8 @@ function(qt_run_config_test_architecture)
string(SUBSTRING "${_line}" ${_pos} -1 _build_abi)
endif()
endforeach()
-
+ set(_architecture "riscv64")
+ set(_build_abi "riscv64-little_endian-lp64")
if (NOT _architecture OR NOT _build_abi)
list(SUBLIST _arch_lines 0 5 arch_lines_fewer)
list(JOIN arch_lines_fewer "\n" arch_lines_output)

4
macros.qt6-qtbase Normal file
View File

@ -0,0 +1,4 @@
%_qt6 @@NAME@@
%_qt6_epoch @@EPOCH@@
%_qt6_version @@VERSION@@
%_qt6_evr @@EVR@@

23
qconfig-multilib.h Normal file
View File

@ -0,0 +1,23 @@
/* qconfig.h */
/* This file is here to prevent a file conflict on multiarch systems. A
* conflict will occur because qconfig.h has arch-specific definitions.
*
* DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */
#ifndef QCONFIG_MULTILIB_H
#define QCONFIG_MULTILIB_H
#ifndef __WORDSIZE
#include <bits/wordsize.h>
#endif
#if __WORDSIZE == 32
#include "QtCore/qconfig-32.h"
#elif __WORDSIZE == 64
#include "QtCore/qconfig-64.h"
#else
#error "unexpected value for __WORDSIZE macro"
#endif
#endif

10
qmake-qt6.sh Normal file
View File

@ -0,0 +1,10 @@
#!/bin/sh
# An attempt at providing a qmake wrapper for projects that
# lack native qmake support (ie, qmake is run by buildsystem
# instead of developer or fedora packager).
QMAKE="$(rpm --eval %{_qt6_qmake})"
QMAKE_FLAGS="$(rpm --eval %{?_qt6_qmake_flags})"
eval $QMAKE $QMAKE_FLAGS $@

View File

@ -0,0 +1,188 @@
From 39e21f564099f9ffe02643f8f02119168263c5dd Mon Sep 17 00:00:00 2001
From: mahailiang <mahailiang@uniontech.com>
Date: Tue, 12 Nov 2024 09:53:31 +0800
Subject: [PATCH] add sw64 support
---
.../double-conversion/utils.h | 2 +-
src/3rdparty/forkfd/forkfd_linux.c | 2 +-
src/3rdparty/sha3/brg_endian.h | 1 +
src/corelib/global/archdetect.cpp | 2 ++
src/corelib/global/qprocessordetection.h | 2 ++
src/corelib/io/qfilesystemwatcher_inotify.cpp | 4 +++
src/corelib/plugin/qelfparser_p.cpp | 3 ++
src/gui/image/qimage.cpp | 4 +++
src/testlib/3rdparty/cycle_p.h | 35 +++++++++++++++++++
9 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/src/3rdparty/double-conversion/double-conversion/utils.h b/src/3rdparty/double-conversion/double-conversion/utils.h
index 4f4dd71b..4c4fdde7 100644
--- a/src/3rdparty/double-conversion/double-conversion/utils.h
+++ b/src/3rdparty/double-conversion/double-conversion/utils.h
@@ -139,7 +139,7 @@ int main(int argc, char** argv) {
defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
defined(__hppa__) || defined(__ia64__) || \
defined(__mips__) || \
- defined(__loongarch__) || \
+ defined(__loongarch__) || defined(__sw_64__) \
defined(__nios2__) || defined(__ghs) || \
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
diff --git a/src/3rdparty/forkfd/forkfd_linux.c b/src/3rdparty/forkfd/forkfd_linux.c
index cc7af6cb..cd86496b 100644
--- a/src/3rdparty/forkfd/forkfd_linux.c
+++ b/src/3rdparty/forkfd/forkfd_linux.c
@@ -85,7 +85,7 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
#elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
- defined(__loongarch__)
+ defined(__loongarch__) || defined(__sw_64__)
/* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
* but since both values are 0, there's no harm. */
return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
diff --git a/src/3rdparty/sha3/brg_endian.h b/src/3rdparty/sha3/brg_endian.h
index 9bb306e6..e3907596 100644
--- a/src/3rdparty/sha3/brg_endian.h
+++ b/src/3rdparty/sha3/brg_endian.h
@@ -105,6 +105,7 @@ Changes for ARM 9/9/2010 [Downstream relative to Gladman's GitHub, upstream to Q
#if !defined(PLATFORM_BYTE_ORDER)
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
+#if defined( __sw_64__ ) || defined( __sw_64 ) || \
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
defined( vax ) || defined( vms ) || defined( VMS ) || \
diff --git a/src/corelib/global/archdetect.cpp b/src/corelib/global/archdetect.cpp
index 6a1e110a..5e16e1fe 100644
--- a/src/corelib/global/archdetect.cpp
+++ b/src/corelib/global/archdetect.cpp
@@ -7,6 +7,8 @@
// main part: processor type
#if defined(Q_PROCESSOR_ALPHA)
# define ARCH_PROCESSOR "alpha"
+#elif defined(Q_PROCESSOR_SW_64)
+# define ARCH_PROCESSOR "sw_64"
#elif defined(Q_PROCESSOR_ARM_32)
# define ARCH_PROCESSOR "arm"
#elif defined(Q_PROCESSOR_ARM_64)
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index f7298bbb..781476a1 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -55,6 +55,8 @@
# define Q_PROCESSOR_ALPHA
// Q_BYTE_ORDER not defined, use endianness auto-detection
+#elif defined(__sw_64__) || defined(_M_SW_64)
+# define Q_PROCESSOR_SW_64
/*
ARM family, known revisions: V5, V6, V7, V8
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 3b53b490..493bc5c8 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -55,6 +55,10 @@
# define __NR_inotify_add_watch 285
# define __NR_inotify_rm_watch 286
# define __NR_inotify_init1 324
+#elif defined (__sw_64__)
+# define __NR_inotify_init 444
+# define __NR_inotify_add_watch 445
+# define __NR_inotify_rm_watch 446
#elif defined (__alpha__)
# define __NR_inotify_init 444
# define __NR_inotify_add_watch 445
diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp
index ffc4a14b..7b8749eb 100644
--- a/src/corelib/plugin/qelfparser_p.cpp
+++ b/src/corelib/plugin/qelfparser_p.cpp
@@ -109,6 +109,8 @@ struct ElfMachineCheck
// nothing
#elif defined(Q_PROCESSOR_ALPHA)
EM_ALPHA
+#elif defined(Q_PROCESSOR_SW_64)
+ EM_SW_64
#elif defined(Q_PROCESSOR_ARM_32)
EM_ARM
#elif defined(Q_PROCESSOR_ARM_64)
@@ -380,6 +382,7 @@ Q_DECL_UNUSED Q_DECL_COLD_FUNCTION static QDebug &operator<<(QDebug &d, ElfHeade
// list definitely not exhaustive!
case EM_NONE: d << ", no machine"; break;
case EM_ALPHA: d << ", Alpha"; break;
+ case EM_SW_64: d << ", SW_64"; break;
case EM_68K: d << ", MC68000"; break;
case EM_ARM: d << ", ARM"; break;
case EM_AARCH64: d << ", AArch64"; break;
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 71367f6d..bc8c84df 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -53,6 +53,10 @@ using namespace Qt::StringLiterals;
// for valid QImage's, where height() cannot be 0. Therefore disable the warning.
QT_WARNING_DISABLE_MSVC(4723)
+#if defined(Q_CC_DEC) && defined(__sw_64) && (__DECCXX_VER-0 >= 50190001)
+#pragma message disable narrowptr
+#endif
+
#if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
#pragma message disable narrowptr
#endif
diff --git a/src/testlib/3rdparty/cycle_p.h b/src/testlib/3rdparty/cycle_p.h
index 95e741a8..4d933e10 100644
--- a/src/testlib/3rdparty/cycle_p.h
+++ b/src/testlib/3rdparty/cycle_p.h
@@ -405,6 +405,26 @@ INLINE_ELAPSED(__inline__)
#define HAVE_TICK_COUNTER
#endif
+/*----------------------------------------------------------------*/
+#if defined(__GNUC__) && defined(__sw_64__) && !defined(HAVE_TICK_COUNTER)
+/*
+ * The 32-bit cycle counter on sw_64 overflows pretty quickly,
+ * unfortunately. A 1GHz machine overflows in 4 seconds.
+ */
+typedef unsigned int CycleCounterTicks;
+
+static __inline__ CycleCounterTicks getticks(void)
+{
+ unsigned long cc;
+ __asm__ __volatile__ ("rtc %0" : "=r"(cc));
+ return (cc & 0xFFFFFFFF);
+}
+
+INLINE_ELAPSED(__inline__)
+
+#define HAVE_TICK_COUNTER
+#endif
+
/*----------------------------------------------------------------*/
#if defined(__GNUC__) && defined(__alpha__) && !defined(HAVE_TICK_COUNTER)
/*
@@ -441,6 +461,21 @@ INLINE_ELAPSED(__inline__)
#define HAVE_TICK_COUNTER
#endif
+#if (defined(__DECC) || defined(__DECCXX)) && defined(__sw_64) && defined(HAVE_C_ASM_H) && !defined(HAVE_TICK_COUNTER)
+# include <c_asm.h>
+typedef unsigned int CycleCounterTicks;
+
+static __inline CycleCounterTicks getticks(void)
+{
+ unsigned long cc;
+ cc = asm("rtc %v0");
+ return (cc & 0xFFFFFFFF);
+}
+
+INLINE_ELAPSED(__inline)
+
+#define HAVE_TICK_COUNTER
+#endif
/*----------------------------------------------------------------*/
#if (defined(__DECC) || defined(__DECCXX)) && defined(__alpha) && defined(HAVE_C_ASM_H) && !defined(HAVE_TICK_COUNTER)
# include <c_asm.h>
--
2.33.0

861
qt6-qtbase.spec Normal file
View File

@ -0,0 +1,861 @@
# See http://bugzilla.redhat.com/223663
%global multilib_archs x86_64 %{ix86} %{?mips} ppc64 ppc s390x s390 sparc64 sparcv9 riscv64 loongarch64
%global multilib_basearchs x86_64 %{?mips64} ppc64 s390x sparc64 riscv64 loongarch64
%define short_version 6.5
%ifarch s390x ppc64le aarch64 armv7hl riscv64 loongarch64
%global no_sse2 1
%endif
%global platform linux-g++
%global use_clang 0
%if 0%{?use_clang}
%global platform linux-clang
%endif
%global qt_module qtbase
%global journald 1
BuildRequires: pkgconfig(libsystemd)
%global examples 1
## skip for now, until we're better at it --rex
#global tests 1
Name: qt6-qtbase
Summary: Qt6 - QtBase components
Version: 6.5.2
Release: 10
License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0
Url: http://qt-project.org/
Source0: https://download.qt.io/official_releases/qt/%{short_version}/%{version}/submodules/%{qt_module}-everywhere-src-%{version}.tar.xz
# https://bugzilla.redhat.com/show_bug.cgi?id=1227295
Source1: qtlogging.ini
# header file to workaround multilib issue
# https://bugzilla.redhat.com/show_bug.cgi?id=1036956
Source5: qconfig-multilib.h
# xinitrc script to check for OpenGL 1 only drivers and automatically set
# QT_XCB_FORCE_SOFTWARE_OPENGL for them
Source6: 10-qt6-check-opengl2.sh
# macros
Source10: macros.qt6-qtbase
# borrowed from opensuse
# track private api via properly versioned symbols
# downside: binaries produced with these differently-versioned symbols are no longer
# compatible with qt-project.org's Qt binary releases.
Patch1: qtbase-tell-truth-about-private-api.patch
Patch2: qtbase-CMake-Install-objects-files-into-ARCHDATADIR.patch
# upstreamable patches
# namespace QT_VERSION_CHECK to workaround major/minor being pre-defined (#1396755)
Patch50: qtbase-version-check.patch
# 1. Workaround moc/multilib issues
# https://bugzilla.redhat.com/show_bug.cgi?id=1290020
# https://bugreports.qt.io/browse/QTBUG-49972
# 2. Workaround sysmacros.h (pre)defining major/minor a breaking stuff
Patch51: qtbase-moc-macros.patch
# drop -O3 and make -O2 by default
Patch54: qtbase-cxxflag.patch
# fix for new mariadb
Patch56: qtbase-mysql.patch
# fix FTBFS against libglvnd-1.3.4+
Patch58: qtbase-libglvnd.patch
# gcc-11
Patch90: qtbase-gcc11.patch
# fix riscv test
Patch100: fix-riscv-configure-tests.patch
Patch102: fix-build-error-of-libxkbcommon-1.6.0.patch
Patch103: qt6-qtbase-add-sw64-support.patch
#fix CVE
Patch6001:qtbase6.5.2-CVE-2023-38197.patch
Patch6003:qtbase6.5.1-CVE-2023-43114.patch
Patch6004:qtbase6.5.2-CVE-2023-51714.patch
Patch6005:qtbase6.5.2-CVE-2024-33861.patch
Patch6006:qtbase6.5.2-CVE-2024-39936.patch
Patch6007:qtbase6.5.2-CVE-2023-45935.patch
Patch6008:qtbase6.5.2-CVE-2024-25580.patch
Patch6009:qtbase6.5.2-CVE-2025-30348.patch
# Do not check any files in %%{_qt6_plugindir}/platformthemes/ for requires.
# Those themes are there for platform integration. If the required libraries are
# not there, the platform to integrate with isn't either. Then Qt will just
# silently ignore the plugin that fails to load. Thus, there is no need to let
# RPM drag in gtk3 as a dependency for the GTK+3 dialog support.
%global __requires_exclude_from ^%{_qt6_plugindir}/platformthemes/.*$
# filter plugin provides
%global __provides_exclude_from ^%{_qt6_plugindir}/.*\\.so$
%if 0%{?use_clang}
BuildRequires: clang >= 6.0.0
%else
BuildRequires: gcc-c++
%endif
BuildRequires: cmake
BuildRequires: ninja-build
BuildRequires: cups-devel
BuildRequires: desktop-file-utils
BuildRequires: findutils
BuildRequires: double-conversion-devel
BuildRequires: libb2-devel
BuildRequires: libjpeg-devel
BuildRequires: libmng-devel
BuildRequires: libtiff-devel
BuildRequires: libzstd-devel
BuildRequires: mtdev-devel
BuildRequires: tslib-devel
BuildRequires: pkgconfig(alsa)
# required for -accessibility
BuildRequires: pkgconfig(atspi-2)
# http://bugzilla.redhat.com/1196359
%global dbus_linked 1
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(fontconfig)
BuildRequires: pkgconfig(gl)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gtk+-3.0)
BuildRequires: pkgconfig(libproxy-1.0)
BuildRequires: pkgconfig(libsctp)
# xcb-sm
BuildRequires: pkgconfig(ice) pkgconfig(sm)
BuildRequires: pkgconfig(libpng)
BuildRequires: pkgconfig(libudev)
BuildRequires: openssl-devel
BuildRequires: pkgconfig(libpulse) pkgconfig(libpulse-mainloop-glib)
BuildRequires: pkgconfig(libinput)
BuildRequires: pkgconfig(xcb-xkb) >= 1.10
BuildRequires: pkgconfig(xcb-util)
BuildRequires: pkgconfig(xkbcommon) >= 0.4.1
BuildRequires: pkgconfig(xkbcommon-x11) >= 0.4.1
BuildRequires: pkgconfig(xkeyboard-config)
%global vulkan 1
BuildRequires: pkgconfig(vulkan)
%global egl 1
BuildRequires: mesa-libEGL-devel
BuildRequires: pkgconfig(egl)
BuildRequires: pkgconfig(gbm)
BuildRequires: pkgconfig(libglvnd)
BuildRequires: pkgconfig(x11)
%global sqlite 1
BuildRequires: pkgconfig(sqlite3) >= 3.7
BuildRequires: pkgconfig(harfbuzz) >= 0.9.42
BuildRequires: pkgconfig(icu-i18n)
BuildRequires: pkgconfig(libpcre2-16) >= 10.20
%global pcre 1
BuildRequires: pkgconfig(xcb-xkb)
BuildRequires: pkgconfig(xcb) pkgconfig(xcb-glx) pkgconfig(xcb-icccm) pkgconfig(xcb-image) pkgconfig(xcb-keysyms) pkgconfig(xcb-renderutil) pkgconfig(xcb-cursor)
BuildRequires: pkgconfig(zlib)
BuildRequires: perl
BuildRequires: perl-generators
BuildRequires: python3
BuildRequires: qt6-rpm-macros
%if 0%{?tests}
BuildRequires: dbus-x11
BuildRequires: mesa-dri-drivers
BuildRequires: time
BuildRequires: xorg-x11-server-Xvfb
%endif
Requires: %{name}-common = %{version}-%{release}
## Sql drivers
%global ibase 1
%description
Qt is a software toolkit for developing applications.
This package contains base tools, like string, xml, and network
handling.
%package common
Summary: Common files for Qt6
Requires: %{name} = %{version}-%{release}
BuildArch: noarch
%description common
%{summary}.
%package devel
Summary: Development files for %{name}
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: %{name}-gui%{?_isa}
%if 0%{?egl}
Requires: libEGL-devel
%endif
Requires: pkgconfig(gl)
%if 0%{?vulkan}
Requires: pkgconfig(vulkan)
%endif
Requires: qt6-rpm-macros
%if 0%{?use_clang}
Requires: clang >= 3.7.0
%endif
%if 0%{?ibase}
Requires: %{name}-ibase%{?_isa} = %{version}-%{release}
%endif
Requires: %{name}-mysql%{?_isa} = %{version}-%{release}
Requires: %{name}-odbc%{?_isa} = %{version}-%{release}
Requires: %{name}-postgresql%{?_isa} = %{version}-%{release}
%description devel
%{summary}.
%package private-devel
Summary: Development files for %{name} private APIs
Requires: %{name}-devel%{?_isa} = %{version}-%{release}
# QtPrintSupport/private requires cups/ppd.h
Requires: cups-devel
%description private-devel
%{summary}.
%package examples
Summary: Programming examples for %{name}
Requires: %{name}%{?_isa} = %{version}-%{release}
%description examples
%{summary}.
%package static
Summary: Static library files for %{name}
Requires: %{name}-devel%{?_isa} = %{version}-%{release}
Requires: pkgconfig(fontconfig)
Requires: pkgconfig(glib-2.0)
Requires: pkgconfig(libinput)
Requires: pkgconfig(xkbcommon)
Requires: pkgconfig(zlib)
%description static
%{summary}.
%if 0%{?ibase}
%package ibase
Summary: IBase driver for Qt6's SQL classes
BuildRequires: firebird-devel
Requires: %{name}%{?_isa} = %{version}-%{release}
%description ibase
%{summary}.
%endif
%package mysql
Summary: MySQL driver for Qt6's SQL classes
BuildRequires: mariadb-connector-c-devel
Requires: %{name}%{?_isa} = %{version}-%{release}
%description mysql
%{summary}.
%package odbc
Summary: ODBC driver for Qt6's SQL classes
BuildRequires: unixODBC-devel
Requires: %{name}%{?_isa} = %{version}-%{release}
%description odbc
%{summary}.
%package postgresql
Summary: PostgreSQL driver for Qt6's SQL classes
BuildRequires: libpq-devel
Requires: %{name}%{?_isa} = %{version}-%{release}
%description postgresql
%{summary}.
# debating whether to do 1 subpkg per library or not -- rex
%package gui
Summary: Qt6 GUI-related libraries
Requires: %{name}%{?_isa} = %{version}-%{release}
Recommends: mesa-dri-drivers
# for Source6: 10-qt6-check-opengl2.sh:
# glxinfo
Requires: glx-utils
%description gui
Qt6 libraries used for drawing widgets and OpenGL items.
%prep
%setup -qn %{qt_module}-everywhere-src-%{version}
%autopatch -M99 -p1
%ifarch riscv64
%patch -P 100 -p1
%endif
%autopatch -m101 -p1
# move some bundled libs to ensure they're not accidentally used
pushd src/3rdparty
mkdir UNUSED
mv harfbuzz-ng freetype libjpeg libpng sqlite zlib UNUSED/
popd
# builds failing mysteriously on f20
# ./configure: Permission denied
# check to ensure that can't happen -- rex
test -x configure || chmod +x configure
%build
# QT is known not to work properly with LTO at this point. Some of the issues
# are being worked on upstream and disabling LTO should be re-evaluated as
# we update this change. Until such time...
# Disable LTO
# https://bugzilla.redhat.com/1900527
%define _lto_cflags %{nil}
## FIXME/TODO:
# * for %%ix86, add sse2 enabled builds for Qt6Gui, Qt6Core, QtNetwork, see also:
# http://anonscm.debian.org/cgit/pkg-kde/qt/qtbase.git/tree/debian/rules (234-249)
## adjust $RPM_OPT_FLAGS
# remove -fexceptions
RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'`
RPM_OPT_FLAGS="$RPM_OPT_FLAGS %{?qt6_arm_flag} %{?qt6_deprecated_flag} %{?qt6_null_flag}"
%if 0%{?use_clang}
RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fno-delete-null-pointer-checks||g'`
export CC=clang
export CXX=clang++
%endif
export CFLAGS="$CFLAGS $RPM_OPT_FLAGS"
export CXXFLAGS="$CXXFLAGS $RPM_OPT_FLAGS"
export LDFLAGS="$LDFLAGS $RPM_LD_FLAGS"
export MAKEFLAGS="%{?_smp_mflags}"
%cmake_qt6 \
-DQT_FEATURE_accessibility=ON \
-DQT_FEATURE_fontconfig=ON \
-DQT_FEATURE_glib=ON \
-DQT_FEATURE_sse2=%{?no_sse2:OFF}%{!?no_sse2:ON} \
-DQT_FEATURE_icu=ON \
-DQT_FEATURE_enable_new_dtags=ON \
-DQT_FEATURE_journald=%{?journald:ON}%{!?journald:OFF} \
-DQT_FEATURE_openssl_linked=ON \
-DQT_FEATURE_libproxy=ON \
-DQT_FEATURE_sctp=ON \
-DQT_FEATURE_separate_debug_info=OFF \
-DQT_FEATURE_reduce_relocations=OFF \
-DQT_FEATURE_relocatable=OFF \
-DQT_FEATURE_system_jpeg=ON \
-DQT_FEATURE_system_png=ON \
-DQT_FEATURE_system_zlib=ON \
%{?ibase:-DQT_FEATURE_sql_ibase=ON} \
-DQT_FEATURE_sql_odbc=ON \
-DQT_FEATURE_sql_mysql=ON \
-DQT_FEATURE_sql_psql=ON \
-DQT_FEATURE_sql_sqlite=ON \
-DQT_FEATURE_rpath=OFF \
-DQT_FEATURE_zstd=ON \
%{?dbus_linked:-DQT_FEATURE_dbus_linked=ON} \
%{?pcre:-DQT_FEATURE_system_pcre2=ON} \
%{?sqlite:-DQT_FEATURE_system_sqlite=ON} \
-DBUILD_SHARED_LIBS=ON \
-DQT_BUILD_EXAMPLES=%{?examples:ON}%{!?examples:OFF} \
-DQT_BUILD_TESTS=%{?tests:ON}%{!?tests:OFF} \
-DQT_QMAKE_TARGET_MKSPEC=%{platform}
# FIXME
# -DQT_FEATURE_directfb=ON \
cmake --build . %{?_smp_mflags} --verbose
%install
DESTDIR="%{buildroot}" cmake --install .
install -m644 -p -D %{SOURCE1} %{buildroot}%{_qt6_datadir}/qtlogging.ini
# Qt6.pc
mkdir -p %{buildroot}%{_libdir}/pkgconfig
cat << EOF > %{buildroot}%{_libdir}/pkgconfig/Qt6.pc
prefix=%{_qt6_prefix}
archdatadir=%{_qt6_archdatadir}
bindir=%{_qt6_bindir}
datadir=%{_qt6_datadir}
docdir=%{_qt6_docdir}
examplesdir=%{_qt6_examplesdir}
headerdir=%{_qt6_headerdir}
importdir=%{_qt6_importdir}
libdir=%{_qt6_libdir}
libexecdir=%{_qt6_libexecdir}
moc=%{_qt6_libexecdir}/moc
plugindir=%{_qt6_plugindir}
qmake=%{_qt6_bindir}/qmake
settingsdir=%{_qt6_settingsdir}
sysconfdir=%{_qt6_sysconfdir}
translationdir=%{_qt6_translationdir}
Name: Qt6
Description: Qt6 Configuration
Version: 6.5.2
EOF
# rpm macros
install -p -m644 -D %{SOURCE10} \
%{buildroot}%{_rpmmacrodir}/macros.qt6-qtbase
sed -i \
-e "s|@@NAME@@|%{name}|g" \
-e "s|@@EPOCH@@|%{?epoch}%{!?epoch:0}|g" \
-e "s|@@VERSION@@|%{version}|g" \
-e "s|@@EVR@@|%{?epoch:%{epoch:}}%{version}-%{release}|g" \
%{buildroot}%{_rpmmacrodir}/macros.qt6-qtbase
# create/own dirs
mkdir -p %{buildroot}{%{_qt6_archdatadir}/mkspecs/modules,%{_qt6_importdir},%{_qt6_libexecdir},%{_qt6_plugindir}/{designer,iconengines,script,styles},%{_qt6_translationdir}}
mkdir -p %{buildroot}%{_sysconfdir}/xdg/QtProject
# hardlink files to {_bindir}, add -qt6 postfix to not conflict
mkdir %{buildroot}%{_bindir}
pushd %{buildroot}%{_qt6_bindir}
for i in * ; do
case "${i}" in
qdbuscpp2xml|qdbusxml2cpp|qtpaths)
ln -v ${i} %{buildroot}%{_bindir}/${i}-qt6
;;
*)
ln -v ${i} %{buildroot}%{_bindir}/${i}
;;
esac
done
popd
%ifarch %{multilib_archs}
# multilib: qconfig.h
mv %{buildroot}%{_qt6_headerdir}/QtCore/qconfig.h %{buildroot}%{_qt6_headerdir}/QtCore/qconfig-%{__isa_bits}.h
install -p -m644 -D %{SOURCE5} %{buildroot}%{_qt6_headerdir}/QtCore/qconfig.h
%endif
## .prl/.la file love
# nuke .prl reference(s) to %%buildroot, excessive (.la-like) libs
pushd %{buildroot}%{_qt6_libdir}
for prl_file in libQt6*.prl ; do
sed -i -e "/^QMAKE_PRL_BUILD_DIR/d" ${prl_file}
if [ -f "$(basename ${prl_file} .prl).so" ]; then
rm -fv "$(basename ${prl_file} .prl).la"
sed -i -e "/^QMAKE_PRL_LIBS/d" ${prl_file}
fi
done
popd
install -p -m755 -D %{SOURCE6} %{buildroot}%{_sysconfdir}/X11/xinit/xinitrc.d/10-qt6-check-opengl2.sh
# install privat headers for qtxcb
mkdir -p %{buildroot}%{_qt6_headerdir}/QtXcb
install -m 644 src/plugins/platforms/xcb/*.h %{buildroot}%{_qt6_headerdir}/QtXcb/
rm %{buildroot}/%{_qt6_libexecdir}/qt-cmake-private-install.cmake
# Use better location for some new scripts in qtbase-6.0.1
mv %{buildroot}/%{_qt6_libexecdir}/ensure_pro_file.cmake %{buildroot}/%{_qt6_libdir}/cmake/Qt6/ensure_pro_file.cmake
%check
# verify Qt6.pc
export PKG_CONFIG_PATH=%{buildroot}%{_libdir}/pkgconfig
test "$(pkg-config --modversion Qt6)" = "%{version}"
%if 0%{?tests}
## see tests/README for expected environment (running a plasma session essentially)
## we are not quite there yet
export CTEST_OUTPUT_ON_FAILURE=1
export PATH=%{buildroot}%{_qt6_bindir}:$PATH
export LD_LIBRARY_PATH=%{buildroot}%{_qt6_libdir}
# dbus tests error out when building if session bus is not available
dbus-launch --exit-with-session \
%make_build sub-tests -k ||:
xvfb-run -a --server-args="-screen 0 1280x1024x32" \
dbus-launch --exit-with-session \
time \
make check -k ||:
%endif
%ldconfig_scriptlets
%files
%license LICENSES/GPL*
%license LICENSES/LGPL*
%dir %{_sysconfdir}/xdg/QtProject/
%{_qt6_libdir}/libQt6Concurrent.so.6*
%{_qt6_libdir}/libQt6Core.so.6*
%{_qt6_libdir}/libQt6DBus.so.6*
%{_qt6_libdir}/libQt6Network.so.6*
%{_qt6_libdir}/libQt6Sql.so.6*
%{_qt6_libdir}/libQt6Test.so.6*
%{_qt6_libdir}/libQt6Xml.so.6*
%dir %{_qt6_docdir}/
%{_qt6_docdir}/global/
%{_qt6_docdir}/config/
%{_qt6_importdir}/
%{_qt6_translationdir}/
%if "%{_qt6_prefix}" != "%{_prefix}"
%dir %{_qt6_prefix}/
%endif
%dir %{_qt6_archdatadir}/
%dir %{_qt6_datadir}/
%{_qt6_datadir}/qtlogging.ini
%dir %{_qt6_libexecdir}/
%dir %{_qt6_plugindir}/
%dir %{_qt6_plugindir}/designer/
%dir %{_qt6_plugindir}/generic/
%dir %{_qt6_plugindir}/iconengines/
%dir %{_qt6_plugindir}/imageformats/
%dir %{_qt6_plugindir}/platforminputcontexts/
%dir %{_qt6_plugindir}/platforms/
%dir %{_qt6_plugindir}/platformthemes/
%dir %{_qt6_plugindir}/printsupport/
%dir %{_qt6_plugindir}/script/
%dir %{_qt6_plugindir}/sqldrivers/
%dir %{_qt6_plugindir}/styles/
%{_qt6_plugindir}/networkinformation/libqglib.so
%{_qt6_plugindir}/networkinformation/libqnetworkmanager.so
%{_qt6_plugindir}/sqldrivers/libqsqlite.so
%{_qt6_plugindir}/tls/libqcertonlybackend.so
%{_qt6_plugindir}/tls/libqopensslbackend.so
%files common
# mostly empty for now, consider: filesystem/dir ownership, licenses
%{_rpmmacrodir}/macros.qt6-qtbase
%files devel
%dir %{_qt6_libdir}/qt6/modules
%dir %{_qt6_libdir}/qt6/metatypes
%dir %{_qt6_libdir}/cmake/Qt6
%dir %{_qt6_libdir}/cmake/Qt6/platforms
%dir %{_qt6_libdir}/cmake/Qt6/platforms/Platform
%dir %{_qt6_libdir}/cmake/Qt6/config.tests
%dir %{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules
%dir %{_qt6_libdir}/cmake/Qt6/3rdparty/kwin
%dir %{_qt6_libdir}/cmake/Qt6BuildInternals
%dir %{_qt6_libdir}/cmake/Qt6BuildInternals/StandaloneTests
%dir %{_qt6_libdir}/cmake/Qt6Concurrent
%dir %{_qt6_libdir}/cmake/Qt6Core
%dir %{_qt6_libdir}/cmake/Qt6CoreTools
%dir %{_qt6_libdir}/cmake/Qt6DBus
%dir %{_qt6_libdir}/cmake/Qt6DBusTools
%dir %{_qt6_libdir}/cmake/Qt6DeviceDiscoverySupportPrivate
%dir %{_qt6_libdir}/cmake/Qt6EglFSDeviceIntegrationPrivate
%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate
%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate
%dir %{_qt6_libdir}/cmake/Qt6ExampleIconsPrivate
%dir %{_qt6_libdir}/cmake/Qt6FbSupportPrivate
%dir %{_qt6_libdir}/cmake/Qt6Gui
%dir %{_qt6_libdir}/cmake/Qt6GuiTools
%dir %{_qt6_libdir}/cmake/Qt6HostInfo
%dir %{_qt6_libdir}/cmake/Qt6KmsSupportPrivate
%dir %{_qt6_libdir}/cmake/Qt6Network
%dir %{_qt6_libdir}/cmake/Qt6OpenGL
%dir %{_qt6_libdir}/cmake/Qt6OpenGLWidgets
%dir %{_qt6_libdir}/cmake/Qt6PrintSupport
%dir %{_qt6_libdir}/cmake/Qt6Sql
%dir %{_qt6_libdir}/cmake/Qt6Test
%dir %{_qt6_libdir}/cmake/Qt6Widgets
%dir %{_qt6_libdir}/cmake/Qt6WidgetsTools
%dir %{_qt6_libdir}/cmake/Qt6Xml
%if "%{_qt6_bindir}" != "%{_bindir}"
%dir %{_qt6_bindir}
%endif
%{_bindir}/androiddeployqt
%{_bindir}/androiddeployqt6
%{_bindir}/androidtestrunner
%{_bindir}/qdbuscpp2xml*
%{_bindir}/qdbusxml2cpp*
%{_bindir}/qmake*
%{_bindir}/qtpaths*
%{_bindir}/qt-cmake
%{_bindir}/qt-configure-module
%{_libdir}/qt6/bin/qmake6
%{_qt6_bindir}/androiddeployqt
%{_qt6_bindir}/androiddeployqt6
%{_qt6_bindir}/androidtestrunner
%{_qt6_bindir}/qdbuscpp2xml
%{_qt6_bindir}/qdbusxml2cpp
%{_qt6_bindir}/qmake
%{_qt6_bindir}/qtpaths*
%{_qt6_bindir}/qt-cmake
%{_qt6_bindir}/qt-configure-module
%{_qt6_libexecdir}/qt-cmake-private
%{_qt6_libexecdir}/qt-cmake-standalone-test
%{_qt6_libexecdir}/cmake_automoc_parser
%{_qt6_libexecdir}/qt-internal-configure-tests
%{_qt6_libexecdir}/sanitizer-testrunner.py
%{_qt6_libexecdir}/syncqt
%{_qt6_libexecdir}/android_emulator_launcher.sh
%{_qt6_libexecdir}/moc
%{_qt6_libexecdir}/tracegen
%{_qt6_libexecdir}/tracepointgen
%{_qt6_libexecdir}/qlalr
%{_qt6_libexecdir}/qvkgen
%{_qt6_libexecdir}/rcc
%{_qt6_libexecdir}/uic
%{_qt6_libexecdir}/qt-testrunner.py
%{_qt6_libdir}/qt6/modules/*.json
%if "%{_qt6_headerdir}" != "%{_includedir}"
%dir %{_qt6_headerdir}
%endif
%{_qt6_headerdir}/QtConcurrent/
%{_qt6_headerdir}/QtCore/
%{_qt6_headerdir}/QtDBus/
%{_qt6_headerdir}/QtInputSupport
%{_qt6_headerdir}/QtExampleIcons
%{_qt6_headerdir}/QtGui/
%{_qt6_headerdir}/QtNetwork/
%{_qt6_headerdir}/QtOpenGL/
%{_qt6_headerdir}/QtOpenGLWidgets
%{_qt6_headerdir}/QtPrintSupport/
%{_qt6_headerdir}/QtSql/
%{_qt6_headerdir}/QtTest/
%{_qt6_headerdir}/QtWidgets/
%{_qt6_headerdir}/QtXcb/
%{_qt6_headerdir}/QtXml/
%{_qt6_headerdir}/QtEglFSDeviceIntegration
%{_qt6_headerdir}/QtEglFsKmsGbmSupport
%{_qt6_headerdir}/QtEglFsKmsSupport
%{_qt6_mkspecsdir}/
%{_qt6_libdir}/libQt6Concurrent.prl
%{_qt6_libdir}/libQt6Concurrent.so
%{_qt6_libdir}/libQt6Core.prl
%{_qt6_libdir}/libQt6Core.so
%{_qt6_libdir}/libQt6DBus.prl
%{_qt6_libdir}/libQt6DBus.so
%{_qt6_libdir}/libQt6Gui.prl
%{_qt6_libdir}/libQt6Gui.so
%{_qt6_libdir}/libQt6Network.prl
%{_qt6_libdir}/libQt6Network.so
%{_qt6_libdir}/libQt6OpenGL.prl
%{_qt6_libdir}/libQt6OpenGL.so
%{_qt6_libdir}/libQt6OpenGLWidgets.prl
%{_qt6_libdir}/libQt6OpenGLWidgets.so
%{_qt6_libdir}/libQt6PrintSupport.prl
%{_qt6_libdir}/libQt6PrintSupport.so
%{_qt6_libdir}/libQt6Sql.prl
%{_qt6_libdir}/libQt6Sql.so
%{_qt6_libdir}/libQt6Test.prl
%{_qt6_libdir}/libQt6Test.so
%{_qt6_libdir}/libQt6Widgets.prl
%{_qt6_libdir}/libQt6Widgets.so
%{_qt6_libdir}/libQt6XcbQpa.prl
%{_qt6_libdir}/libQt6XcbQpa.so
%{_qt6_libdir}/libQt6Xml.prl
%{_qt6_libdir}/libQt6Xml.so
%{_qt6_libdir}/libQt6EglFSDeviceIntegration.prl
%{_qt6_libdir}/libQt6EglFSDeviceIntegration.so
%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.prl
%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.so
%{_qt6_libdir}/cmake/Qt6/*.h.in
%{_qt6_libdir}/cmake/Qt6/*.cmake
%{_qt6_libdir}/cmake/Qt6/*.cmake.in
%{_qt6_libdir}/cmake/Qt6/PkgConfigLibrary.pc.in
%{_qt6_libdir}/cmake/Qt6/config.tests/*
%{_qt6_libdir}/cmake/Qt6/libexec/*
%{_qt6_libdir}/cmake/Qt6/platforms/*.cmake
%{_qt6_libdir}/cmake/Qt6/platforms/Platform/*.cmake
%{_qt6_libdir}/cmake/Qt6/qbatchedtestrunner.in.cpp
%{_qt6_libdir}/cmake/Qt6/ModuleDescription.json.in
%{_qt6_libdir}/cmake/Qt6/QtFileConfigure.txt.in
%{_qt6_libdir}/cmake/Qt6/QtConfigureTimeExecutableCMakeLists.txt.in
%{_qt6_libdir}/cmake/Qt6/QtSeparateDebugInfo.Info.plist.in
%{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/COPYING-CMAKE-SCRIPTS
%{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/find-modules/*.cmake
%{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/modules/*.cmake
%{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/qt_attribution.json
%{_qt6_libdir}/cmake/Qt6/3rdparty/kwin/COPYING-CMAKE-SCRIPTS
%{_qt6_libdir}/cmake/Qt6/3rdparty/kwin/*.cmake
%{_qt6_libdir}/cmake/Qt6/3rdparty/kwin/qt_attribution.json
%{_qt6_libdir}/cmake/Qt6BuildInternals/*.cmake
%{_qt6_libdir}/cmake/Qt6BuildInternals/QtStandaloneTestTemplateProject/CMakeLists.txt
%{_qt6_libdir}/cmake/Qt6BuildInternals/StandaloneTests/QtBaseTestsConfig.cmake
%{_qt6_libdir}/cmake/Qt6BuildInternals/QtStandaloneTestTemplateProject/Main.cmake
%{_qt6_libdir}/cmake/Qt6Concurrent/*.cmake
%{_qt6_libdir}/cmake/Qt6Core/*.cmake
%{_qt6_libdir}/cmake/Qt6Core/Qt6CoreConfigureFileTemplate.in
%{_qt6_libdir}/cmake/Qt6CoreTools/*.cmake
%{_qt6_libdir}/cmake/Qt6DBus/*.cmake
%{_qt6_libdir}/cmake/Qt6DBusTools/*.cmake
%{_qt6_libdir}/cmake/Qt6DeviceDiscoverySupportPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6EglFSDeviceIntegrationPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6ExampleIconsPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6FbSupportPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6Gui/*.cmake
%{_qt6_libdir}/cmake/Qt6GuiTools/*.cmake
%{_qt6_libdir}/cmake/Qt6HostInfo/*.cmake
%{_qt6_libdir}/cmake/Qt6InputSupportPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6KmsSupportPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6Network/*.cmake
%{_qt6_libdir}/cmake/Qt6OpenGL/*.cmake
%{_qt6_libdir}/cmake/Qt6OpenGLWidgets/*.cmake
%{_qt6_libdir}/cmake/Qt6PrintSupport/*.cmake
%{_qt6_libdir}/cmake/Qt6Sql/Qt6Sql*.cmake
%{_qt6_libdir}/cmake/Qt6Sql/Qt6QSQLiteDriverPlugin*.cmake
%{_qt6_libdir}/cmake/Qt6Test/*.cmake
%{_qt6_libdir}/cmake/Qt6Widgets/*.cmake
%{_qt6_libdir}/cmake/Qt6WidgetsTools/*.cmake
%{_qt6_libdir}/cmake/Qt6XcbQpaPrivate/*.cmake
%{_qt6_libdir}/cmake/Qt6Xml/*.cmake
%{_qt6_libdir}/qt6/metatypes/*.json
%{_qt6_libdir}/qt6/objects-RelWithDebInfo/ExampleIconsPrivate_resources_1/.rcc/qrc_example_icons.cpp.o
%{_qt6_libdir}/pkgconfig/*.pc
%if 0%{?egl}
%{_qt6_libdir}/libQt6EglFsKmsSupport.prl
%{_qt6_libdir}/libQt6EglFsKmsSupport.so
%endif
## private-devel globs
%exclude %{_qt6_headerdir}/*/%{version}/
%files private-devel
%{_qt6_headerdir}/*/%{version}/
%files static
%{_qt6_headerdir}/QtDeviceDiscoverySupport
%{_qt6_libdir}/libQt6DeviceDiscoverySupport.*a
%{_qt6_libdir}/libQt6DeviceDiscoverySupport.prl
%{_qt6_libdir}/libQt6ExampleIcons.a
%{_qt6_libdir}/libQt6ExampleIcons.prl
%{_qt6_headerdir}/QtFbSupport
%{_qt6_libdir}/libQt6FbSupport.*a
%{_qt6_libdir}/libQt6FbSupport.prl
%{_qt6_libdir}/libQt6InputSupport.*a
%{_qt6_libdir}/libQt6InputSupport.prl
%{_qt6_headerdir}/QtKmsSupport
%{_qt6_libdir}/libQt6KmsSupport.*a
%{_qt6_libdir}/libQt6KmsSupport.prl
%if 0%{?examples}
%files examples
%{_qt6_examplesdir}/
%endif
%if 0%{?ibase}
%files ibase
%{_qt6_plugindir}/sqldrivers/libqsqlibase.so
%{_qt6_libdir}/cmake/Qt6Sql/Qt6QIBaseDriverPlugin*.cmake
%endif
%files mysql
%{_qt6_plugindir}/sqldrivers/libqsqlmysql.so
%{_qt6_libdir}/cmake/Qt6Sql/Qt6QMYSQLDriverPlugin*.cmake
%files odbc
%{_qt6_plugindir}/sqldrivers/libqsqlodbc.so
%{_qt6_libdir}/cmake/Qt6Sql/Qt6QODBCDriverPlugin*.cmake
%files postgresql
%{_qt6_plugindir}/sqldrivers/libqsqlpsql.so
%{_qt6_libdir}/cmake/Qt6Sql/Qt6QPSQLDriverPlugin*.cmake
%files gui
%dir %{_sysconfdir}/X11/xinit
%dir %{_sysconfdir}/X11/xinit/xinitrc.d/
%{_sysconfdir}/X11/xinit/xinitrc.d/10-qt6-check-opengl2.sh
%{_qt6_libdir}/libQt6Gui.so.6*
%{_qt6_libdir}/libQt6OpenGL.so.6*
%{_qt6_libdir}/libQt6OpenGLWidgets.so.6*
%{_qt6_libdir}/libQt6PrintSupport.so.6*
%{_qt6_libdir}/libQt6Widgets.so.6*
%{_qt6_libdir}/libQt6XcbQpa.so.6*
# Generic
%{_qt6_plugindir}/generic/libqevdevkeyboardplugin.so
%{_qt6_plugindir}/generic/libqevdevmouseplugin.so
%{_qt6_plugindir}/generic/libqevdevtabletplugin.so
%{_qt6_plugindir}/generic/libqevdevtouchplugin.so
%{_qt6_plugindir}/generic/libqlibinputplugin.so
%{_qt6_plugindir}/generic/libqtslibplugin.so
%{_qt6_plugindir}/generic/libqtuiotouchplugin.so
# Imageformats
%{_qt6_plugindir}/imageformats/libqico.so
%{_qt6_plugindir}/imageformats/libqjpeg.so
%{_qt6_plugindir}/imageformats/libqgif.so
# Platforminputcontexts
%{_qt6_plugindir}/platforminputcontexts/libcomposeplatforminputcontextplugin.so
%{_qt6_plugindir}/platforminputcontexts/libibusplatforminputcontextplugin.so
# EGL
%if 0%{?egl}
%{_qt6_libdir}/libQt6EglFSDeviceIntegration.so.6*
%{_qt6_libdir}/libQt6EglFsKmsSupport.so.6*
%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.so.6*
%{_qt6_plugindir}/platforms/libqeglfs.so
%{_qt6_plugindir}/platforms/libqminimalegl.so
%dir %{_qt6_plugindir}/egldeviceintegrations/
%{_qt6_plugindir}/egldeviceintegrations/libqeglfs-kms-integration.so
%{_qt6_plugindir}/egldeviceintegrations/libqeglfs-x11-integration.so
%{_qt6_plugindir}/egldeviceintegrations/libqeglfs-kms-egldevice-integration.so
%{_qt6_plugindir}/egldeviceintegrations/libqeglfs-emu-integration.so
%{_qt6_plugindir}/xcbglintegrations/libqxcb-egl-integration.so
%endif
# Platforms
%{_qt6_plugindir}/platforms/libqlinuxfb.so
%{_qt6_plugindir}/platforms/libqminimal.so
%{_qt6_plugindir}/platforms/libqoffscreen.so
%{_qt6_plugindir}/platforms/libqxcb.so
%{_qt6_plugindir}/platforms/libqvnc.so
%{_qt6_plugindir}/platforms/libqvkkhrdisplay.so
%{_qt6_plugindir}/xcbglintegrations/libqxcb-glx-integration.so
# Platformthemes
%{_qt6_plugindir}/platformthemes/libqxdgdesktopportal.so
%{_qt6_plugindir}/platformthemes/libqgtk3.so
%{_qt6_plugindir}/printsupport/libcupsprintersupport.so
%changelog
* Wed Apr 02 2025 Funda Wang <fundawang@yeah.net> - 6.5.2-10
- fix CVE-2025-30348
* Tue Mar 11 2025 mahailiang <mahailiang@uniontech.com> - 6.5.2-9
- add sw_64 support
* Tue Dec 17 2024 shenzhongwei <shenzhongwei@kylinos.cn> - 6.5.2-8
- include all patches in the source package.
* Thu Dec 12 2024 Funda Wang <fundawang@yeah.net> - 6.5.2-7
- fix CVE-2023-45935, CVE-2024-25580
* Wed Dec 11 2024 Funda Wang <fundawang@yeah.net> - 6.5.2-5
- fix CVE-2024-33861, CVE-2024-39936
- add missing xcb plugin
* Mon May 20 2024 Wenlong Zhang <zhangwenlong@loongson.cn> - 6.5.2-4
- fix build error for loongarch64
* Wed Jan 31 2024 peijiankang <peijiankang@kylinos.cn> - 6.5.2-3
- add qtbase6.5.2-CVE-2023-51714.patch
* Mon Jan 29 2024 peijiankang <peijiankang@kylinos.cn> - 6.5.2-2
- fix build error of libxkbcommon-1.6.0
* Wed Nov 29 2023 peijiankang <peijiankang@kylinos.cn> - 6.5.2-1
- update version to 6.5.2
* Fri Nov 24 2023 hua_yadong<huayadong@kylinos.cn> - 6.5.1-5
- fix qtbase6.5.1-CVE-2023-43114.patch
* Fri Nov 24 2023 hua_yadong<huayadong@kylinos.cn> - 6.5.1-4
- fix qtbase6.5.1-CVE-2023-37369.patch
* Thu Nov 23 2023 hua_yadong<huayadong@kylinos.cn> - 6.5.1-3
- fix qtbase6.5.1-CVE-2023-38197.patch
* Thu Nov 02 2023 peijiankang<peijiankang@kylinos.cn> - 6.5.1-2
- fix qtbase6.5.1-CVE-2023-34410.patch
* Wed Jul 5 2023 EastDong <xudong23@iscas.ac.cn> - 6.5.1-1
- update package
* Fri May 19 2023 peijiankang <peijiankang@kylinos.cn> - 6.5.0-2
- Enable zstd support
* Tue Apr 25 2023 EastDong <xudong23@iscas.ac.cn> - 6.5.0-1
- update package
* Thu Nov 10 2022 Jingwiw <wangjingwei@iscas.ac.cn> - 6.4.0-1
- init package

4
qt6-qtbase.yaml Normal file
View File

@ -0,0 +1,4 @@
version_control: git
src_repo: https://code.qt.io/qt/qtbase.git
tag_prefix: "^v"
separator: "."

View File

@ -0,0 +1,51 @@
From 4e517492a03b6c0b710a2d9a3df05922ac233992 Mon Sep 17 00:00:00 2001
From: Christophe Marin <christophe@krop.fr>
Date: Wed, 24 May 2023 11:23:39 +0200
Subject: [PATCH] CMake: Install objects files into 'ARCHDATADIR'
Change-Id: I917a9ef4d83f93eb5c3e47964bf1814d1b53fdab
---
cmake/QtResourceHelpers.cmake | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/cmake/QtResourceHelpers.cmake b/cmake/QtResourceHelpers.cmake
index 2df1fed50f..e4f34b5ff1 100644
--- a/cmake/QtResourceHelpers.cmake
+++ b/cmake/QtResourceHelpers.cmake
@@ -38,7 +38,7 @@ function(qt_internal_add_resource target resourceName)
if (out_targets)
qt_install(TARGETS ${out_targets}
EXPORT "${INSTALL_CMAKE_NAMESPACE}${target}Targets"
- DESTINATION "${INSTALL_LIBDIR}"
+ DESTINATION "${INSTALL_ARCHDATADIR}"
)
qt_internal_add_targets_to_additional_targets_export_file(
TARGETS ${out_targets}
@@ -47,7 +47,7 @@ function(qt_internal_add_resource target resourceName)
qt_internal_install_resource_pdb_files("${out_targets}")
qt_internal_record_rcc_object_files("${target}" "${out_targets}"
- INSTALL_DIRECTORY "${INSTALL_LIBDIR}")
+ INSTALL_DIRECTORY "${INSTALL_ARCHDATADIR}")
endif()
if (arg_OUTPUT_TARGETS)
@@ -77,7 +77,7 @@ function(qt_internal_record_rcc_object_files target resource_targets)
# It's comprised of thee following path parts:
#
# part (1) INSTALL_DIRECTORY.
- # A usual value is '${INSTALL_LIBDIR}/' for libraries
+ # A usual value is '${INSTALL_ARCHDATADIR}/' for libraries
# and '${INSTALL_QMLDIR}/foo/bar/' for qml plugin resources.
#
# part (2) the value computed by CMake's computeInstallObjectDir comprised of an
@@ -128,6 +128,6 @@ function(qt_internal_install_resource_pdb_files objlib_targets)
_qt_resource_generated_cpp_relative_path)
get_filename_component(rel_obj_file_dir "${generated_cpp_file_relative_path}" DIRECTORY)
qt_internal_install_pdb_files(${target}
- "${INSTALL_LIBDIR}/objects-$<CONFIG>/${target}/${rel_obj_file_dir}")
+ "${INSTALL_ARCHDATADIR}/objects-$<CONFIG>/${target}/${rel_obj_file_dir}")
endforeach()
endfunction()
--
2.40.1

13
qtbase-cxxflag.patch Normal file
View File

@ -0,0 +1,13 @@
diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf
index e7e6ee1..ff2a939 100644
--- a/mkspecs/common/gcc-base.conf
+++ b/mkspecs/common/gcc-base.conf
@@ -32,7 +32,7 @@
#
QMAKE_CFLAGS_OPTIMIZE = -O2
-QMAKE_CFLAGS_OPTIMIZE_FULL = -O3
+QMAKE_CFLAGS_OPTIMIZE_FULL = -O2
QMAKE_CFLAGS_OPTIMIZE_DEBUG = -Og
QMAKE_CFLAGS_OPTIMIZE_SIZE = -Os

Binary file not shown.

36
qtbase-gcc11.patch Normal file
View File

@ -0,0 +1,36 @@
diff --git a/examples/corelib/tools/contiguouscache/randomlistmodel.h b/examples/corelib/tools/contiguouscache/randomlistmodel.h
index 1fabb0d9..393ebaa3 100644
--- a/examples/corelib/tools/contiguouscache/randomlistmodel.h
+++ b/examples/corelib/tools/contiguouscache/randomlistmodel.h
@@ -50,6 +50,7 @@
#ifndef RANDOMLISTMODEL_H
#define RANDOMLISTMODEL_H
+#include <limits>
#include <QContiguousCache>
#include <QAbstractListModel>
diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h
index a7606253..60747cf0 100644
--- a/src/corelib/text/qanystringview.h
+++ b/src/corelib/text/qanystringview.h
@@ -39,6 +39,7 @@
#ifndef QANYSTRINGVIEW_H
#define QANYSTRINGVIEW_H
+#include <limits>
#include <QtCore/qstringview.h>
#include <QtCore/qutf8stringview.h>
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h
index 9f646aaa..a5af793c 100644
--- a/src/corelib/text/qbytearray.h
+++ b/src/corelib/text/qbytearray.h
@@ -41,6 +41,7 @@
#ifndef QBYTEARRAY_H
#define QBYTEARRAY_H
+#include <limits>
#include <QtCore/qrefcount.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qarraydata.h>

16
qtbase-libglvnd.patch Normal file
View File

@ -0,0 +1,16 @@
diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake
index 0bf250ea..2d1bb645 100644
--- a/src/gui/configure.cmake
+++ b/src/gui/configure.cmake
@@ -174,9 +174,9 @@ qt_config_compile_test(egl_x11
int main(void)
{
/* BEGIN TEST: */
-Display *dpy = EGL_DEFAULT_DISPLAY;
+Display *dpy = reinterpret_cast<Display *>(EGL_DEFAULT_DISPLAY);
EGLNativeDisplayType egldpy = XOpenDisplay(\"\");
-dpy = egldpy;
+dpy = reinterpret_cast<Display *>(egldpy);
EGLNativeWindowType w = XCreateWindow(dpy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
XDestroyWindow(dpy, w);
XCloseDisplay(dpy);

16
qtbase-moc-macros.patch Normal file
View File

@ -0,0 +1,16 @@
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index 1cb383c9..6bfdee55 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -230,6 +230,11 @@ int runMoc(int argc, char **argv)
Moc moc;
pp.macros["Q_MOC_RUN"];
pp.macros["__cplusplus"];
+ pp.macros["_SYS_SYSMACROS_H_OUTER"];
+ Macro macro;
+ macro.symbols = Preprocessor::tokenize(QByteArray::number(Q_PROCESSOR_WORDSIZE*8), 1, Preprocessor::TokenizeDefine);
+ macro.symbols.removeLast(); // remove the EOF symbol
+ pp.macros.insert("__WORDSIZE", macro);
// Don't stumble over GCC extensions
Macro dummyVariadicFunctionMacro;

12
qtbase-mysql.patch Normal file
View File

@ -0,0 +1,12 @@
diff -up qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql.cpp.than qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
diff -up qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h.than qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h
--- qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h.than 2017-07-14 13:43:50.831203768 +0200
+++ qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h 2017-07-14 13:44:24.364948006 +0200
@@ -58,6 +58,7 @@
#endif
#include <mysql.h>
+#include <mysql_version.h>
#ifdef QT_PLUGIN
#define Q_EXPORT_SQLDRIVER_MYSQL

View File

@ -0,0 +1,27 @@
From c92143a6c6621f680208cd47d91877fd670b1e8f Mon Sep 17 00:00:00 2001
From: Christophe Marin <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")
--

View File

@ -0,0 +1,13 @@
diff --git a/src/corelib/global/qtversionchecks.h b/src/corelib/global/qtversionchecks.h
index d3b7a7b0..a8b9c6f3 100644
--- a/src/corelib/global/qtversionchecks.h
+++ b/src/corelib/global/qtversionchecks.h
@@ -26,7 +26,7 @@
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
*/
-#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+#define QT_VERSION_CHECK(qt_version_check_major, qt_version_check_minor, qt_version_check_patch) ((qt_version_check_major<<16)|(qt_version_check_minor<<8)|(qt_version_check_patch))
/*
Helper macros to make some simple code active in Qt 6 or Qt 7 only,

View File

@ -0,0 +1,129 @@
From 8d7c452d55d55d6d60f3f0112a704968945fdab8 Mon Sep 17 00:00:00 2001
From: hua_yadong <huayadong@kylinos.cn>
Date: Thu, 23 Nov 2023 17:55:06 +0800
Subject: [PATCH] qtbase6.5.1-CVE-2023-43114
---
src/gui/text/windows/qwindowsfontdatabase.cpp | 67 ++++++++++++++-----
1 file changed, 51 insertions(+), 16 deletions(-)
diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp
index 2de53be6..3f27466d 100644
--- a/src/gui/text/windows/qwindowsfontdatabase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabase.cpp
@@ -868,36 +868,70 @@ QT_WARNING_POP
return fontEngine;
}
-static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData)
+static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData, const uchar *fileEndSentinel)
{
QList<quint32> offsets;
- const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData);
+ if (fileEndSentinel - fontData < 12) {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ return offsets;
+ }
+
+ const quint32 headerTag = qFromUnaligned<quint32>(fontData);
if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) {
if (headerTag != MAKE_TAG(0, 1, 0, 0)
&& headerTag != MAKE_TAG('O', 'T', 'T', 'O')
&& headerTag != MAKE_TAG('t', 'r', 'u', 'e')
- && headerTag != MAKE_TAG('t', 'y', 'p', '1'))
+ && headerTag != MAKE_TAG('t', 'y', 'p', '1')) {
return offsets;
+ }
offsets << 0;
return offsets;
}
+
+ const quint32 maximumNumFonts = 0xffff;
const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8);
- for (uint i = 0; i < numFonts; ++i) {
- offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
+ if (numFonts > maximumNumFonts) {
+ qCWarning(lcQpaFonts) << "Font collection of" << numFonts << "fonts is too large. Aborting.";
+ return offsets;
+ }
+
+ if (quintptr(fileEndSentinel - fontData) > 12 + (numFonts - 1) * 4) {
+ for (quint32 i = 0; i < numFonts; ++i)
+ offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
+ } else {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
}
+
return offsets;
}
-static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
+static void getFontTable(const uchar *fileBegin, const uchar *fileEndSentinel, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
{
- const quint16 numTables = qFromBigEndian<quint16>(data + 4);
- for (uint i = 0; i < numTables; ++i) {
- const quint32 offset = 12 + 16 * i;
- if (*reinterpret_cast<const quint32 *>(data + offset) == tag) {
- *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8);
- *length = qFromBigEndian<quint32>(data + offset + 12);
- return;
+ if (fileEndSentinel - data >= 6) {
+ const quint16 numTables = qFromBigEndian<quint16>(data + 4);
+ if (fileEndSentinel - data >= 28 + 16 * (numTables - 1)) {
+ for (quint32 i = 0; i < numTables; ++i) {
+ const quint32 offset = 12 + 16 * i;
+ if (qFromUnaligned<quint32>(data + offset) == tag) {
+ const quint32 tableOffset = qFromBigEndian<quint32>(data + offset + 8);
+ if (quintptr(fileEndSentinel - fileBegin) <= tableOffset) {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ break;
+ }
+ *table = fileBegin + tableOffset;
+ *length = qFromBigEndian<quint32>(data + offset + 12);
+ if (quintptr(fileEndSentinel - *table) < *length) {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ break;
+ }
+ return;
+ }
+ }
+ } else {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
}
+ } else {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
}
*table = 0;
*length = 0;
@@ -910,8 +944,9 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
QList<QFontValues> *values)
{
const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
+ const uchar *dataEndSentinel = data + fontData.size();
- QList<quint32> offsets = getTrueTypeFontOffsets(data);
+ QList<quint32> offsets = getTrueTypeFontOffsets(data, dataEndSentinel);
if (offsets.isEmpty())
return;
@@ -919,7 +954,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
const uchar *font = data + offsets.at(i);
const uchar *table;
quint32 length;
- getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
+ getFontTable(data, dataEndSentinel, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
if (!table)
continue;
QFontNames names = qt_getCanonicalFontNames(table, length);
@@ -929,7 +964,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
families->append(std::move(names));
if (values || signatures)
- getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
+ getFontTable(data, dataEndSentinel, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
if (values) {
QFontValues fontValues;
--
2.41.0

View File

@ -0,0 +1,371 @@
From 49a4cf8133eb8d76115fb7827bd76764e1b30d12 Mon Sep 17 00:00:00 2001
From: peijiankang <peijiankang@kylinos.cn>
Date: Wed, 29 Nov 2023 20:51:35 +0800
Subject: [PATCH] CVE-2023-38197
---
src/corelib/serialization/qxmlstream.cpp | 144 +++++++++++++++++-
src/corelib/serialization/qxmlstream_p.h | 11 ++
.../qxmlstream/tokenError/dtdInBody.xml | 21 +++
.../qxmlstream/tokenError/multipleDtd.xml | 21 +++
.../qxmlstream/tokenError/wellFormed.xml | 16 ++
.../qxmlstream/tst_qxmlstream.cpp | 38 +++++
6 files changed, 243 insertions(+), 8 deletions(-)
create mode 100644 tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
create mode 100644 tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
create mode 100644 tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index 3175517a..7dcf80c3 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -185,7 +185,7 @@ WRAP(indexOf, QLatin1StringView)
addData() or by waiting for it to arrive on the device().
\value UnexpectedElementError The parser encountered an element
- that was different to those it expected.
+ or token that was different to those it expected.
*/
@@ -322,13 +322,34 @@ QXmlStreamEntityResolver *QXmlStreamReader::entityResolver() const
QXmlStreamReader is a well-formed XML 1.0 parser that does \e not
include external parsed entities. As long as no error occurs, the
- application code can thus be assured that the data provided by the
- stream reader satisfies the W3C's criteria for well-formed XML. For
- example, you can be certain that all tags are indeed nested and
- closed properly, that references to internal entities have been
- replaced with the correct replacement text, and that attributes have
- been normalized or added according to the internal subset of the
- DTD.
+ application code can thus be assured, that
+ \list
+ \li the data provided by the stream reader satisfies the W3C's
+ criteria for well-formed XML,
+ \li tokens are provided in a valid order.
+ \endlist
+
+ Unless QXmlStreamReader raises an error, it guarantees the following:
+ \list
+ \li All tags are nested and closed properly.
+ \li References to internal entities have been replaced with the
+ correct replacement text.
+ \li Attributes have been normalized or added according to the
+ internal subset of the \l DTD.
+ \li Tokens of type \l StartDocument happen before all others,
+ aside from comments and processing instructions.
+ \li At most one DOCTYPE element (a token of type \l DTD) is present.
+ \li If present, the DOCTYPE appears before all other elements,
+ aside from StartDocument, comments and processing instructions.
+ \endlist
+
+ In particular, once any token of type \l StartElement, \l EndElement,
+ \l Characters, \l EntityReference or \l EndDocument is seen, no
+ tokens of type StartDocument or DTD will be seen. If one is present in
+ the input stream, out of order, an error is raised.
+
+ \note The token types \l Comment and \l ProcessingInstruction may appear
+ anywhere in the stream.
If an error occurs while parsing, atEnd() and hasError() return
true, and error() returns the error that occurred. The functions
@@ -659,6 +680,7 @@ QXmlStreamReader::TokenType QXmlStreamReader::readNext()
d->token = -1;
return readNext();
}
+ d->checkToken();
return d->type;
}
@@ -743,6 +765,11 @@ static constexpr auto QXmlStreamReader_tokenTypeString = qOffsetStringArray(
"ProcessingInstruction"
);
+static constexpr auto QXmlStreamReader_XmlContextString = qOffsetStringArray(
+ "Prolog",
+ "Body"
+);
+
/*!
\property QXmlStreamReader::namespaceProcessing
\brief the namespace-processing flag of the stream reader.
@@ -777,6 +804,15 @@ QString QXmlStreamReader::tokenString() const
return QLatin1StringView(QXmlStreamReader_tokenTypeString.at(d->type));
}
+/*!
+ \internal
+ \return \param loc (Prolog/Body) as a string.
+ */
+static constexpr QLatin1StringView contextString(QXmlStreamReaderPrivate::XmlContext ctxt)
+{
+ return QLatin1StringView(QXmlStreamReader_XmlContextString.at(static_cast<int>(ctxt)));
+}
+
#endif // QT_NO_XMLSTREAMREADER
QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack()
@@ -864,6 +900,8 @@ void QXmlStreamReaderPrivate::init()
type = QXmlStreamReader::NoToken;
error = QXmlStreamReader::NoError;
+ currentContext = XmlContext::Prolog;
+ foundDTD = false;
}
/*
@@ -3838,6 +3876,96 @@ void QXmlStreamWriter::writeCurrentToken(const QXmlStreamReader &reader)
break;
}
}
+static constexpr bool isTokenAllowedInContext(QXmlStreamReader::TokenType type,
+ QXmlStreamReaderPrivate::XmlContext loc)
+{
+ switch (type) {
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::DTD:
+ return loc == QXmlStreamReaderPrivate::XmlContext::Prolog;
+
+ case QXmlStreamReader::StartElement:
+ case QXmlStreamReader::EndElement:
+ case QXmlStreamReader::Characters:
+ case QXmlStreamReader::EntityReference:
+ case QXmlStreamReader::EndDocument:
+ return loc == QXmlStreamReaderPrivate::XmlContext::Body;
+
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::ProcessingInstruction:
+ return true;
+
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ return false;
+ }
+
+ // GCC 8.x does not treat __builtin_unreachable() as constexpr
+#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
+ Q_UNREACHABLE_RETURN(false);
+#else
+ return false;
+#endif
+}
+
+/*!
+ \internal
+ \brief QXmlStreamReader::isValidToken
+ \return \c true if \param type is a valid token type.
+ \return \c false if \param type is an unexpected token,
+ which indicates a non-well-formed or invalid XML stream.
+ */
+bool QXmlStreamReaderPrivate::isValidToken(QXmlStreamReader::TokenType type)
+{
+ // Don't change currentContext, if Invalid or NoToken occur in the prolog
+ if (type == QXmlStreamReader::Invalid || type == QXmlStreamReader::NoToken)
+ return false;
+
+ // If a token type gets rejected in the body, there is no recovery
+ const bool result = isTokenAllowedInContext(type, currentContext);
+ if (result || currentContext == XmlContext::Body)
+ return result;
+
+ // First non-Prolog token observed => switch context to body and check again.
+ currentContext = XmlContext::Body;
+ return isTokenAllowedInContext(type, currentContext);
+}
+
+/*!
+ \internal
+ Checks token type and raises an error, if it is invalid
+ in the current context (prolog/body).
+ */
+void QXmlStreamReaderPrivate::checkToken()
+{
+ Q_Q(QXmlStreamReader);
+
+ // The token type must be consumed, to keep track if the body has been reached.
+ const XmlContext context = currentContext;
+ const bool ok = isValidToken(type);
+
+ // Do nothing if an error has been raised already (going along with an unexpected token)
+ if (error != QXmlStreamReader::Error::NoError)
+ return;
+
+ if (!ok) {
+ raiseError(QXmlStreamReader::UnexpectedElementError,
+ QObject::tr("Unexpected token type %1 in %2.")
+ .arg(q->tokenString(), contextString(context)));
+ return;
+ }
+
+ if (type != QXmlStreamReader::DTD)
+ return;
+
+ // Raise error on multiple DTD tokens
+ if (foundDTD) {
+ raiseError(QXmlStreamReader::UnexpectedElementError,
+ QObject::tr("Found second DTD token in %1.").arg(contextString(context)));
+ } else {
+ foundDTD = true;
+ }
+}
/*!
\fn bool QXmlStreamAttributes::hasAttribute(QAnyStringView qualifiedName) const
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 7c46d187..f805cedb 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -296,6 +296,17 @@ public:
QStringDecoder decoder;
bool atEnd;
+ enum class XmlContext
+ {
+ Prolog,
+ Body,
+ };
+
+ XmlContext currentContext = XmlContext::Prolog;
+ bool foundDTD = false;
+ bool isValidToken(QXmlStreamReader::TokenType type);
+ void checkToken();
+
/*!
\sa setType()
*/
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
new file mode 100644
index 00000000..68ef2962
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statement, as this is typical DTD content -->
+ <!ENTITY unite "&#x222a;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+ <!-- invalid DTD in XML body follows -->
+ <!DOCTYPE DTDTEST [
+ <!ELEMENT RESULT (CASE+)>
+ <!ATTLIST RESULT OUTPUT CDATA #REQUIRED>
+ ]>
+</TEST>
+
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
new file mode 100644
index 00000000..1dbe75c4
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION, DATASET, COMMENTS)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statements, as this is typical DTD content -->
+ <!ENTITY iff "&hArr;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<!-- invalid second DTD follows -->
+<!DOCTYPE SECOND [
+ <!ELEMENT SECONDATTRIBUTE (#PCDATA)>
+ <!ENTITY on "&#8728;">
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+</TEST>
+
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
new file mode 100644
index 00000000..9dfbc0f9
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
@@ -0,0 +1,16 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION, DATASET, COMMENTS)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statements, as this is typical DTD content -->
+ <!ENTITY unite "&#x222a;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+</TEST>
+
diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
index b7f603c7..839d9edc 100644
--- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
@@ -590,6 +590,8 @@ private slots:
void entityExpansionLimit() const;
+ void tokenErrorHandling_data() const;
+ void tokenErrorHandling() const;
private:
static QByteArray readFile(const QString &filename);
@@ -1818,6 +1820,42 @@ void tst_QXmlStream::roundTrip() const
QCOMPARE(out, in);
}
+void tst_QXmlStream::tokenErrorHandling_data() const
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QXmlStreamReader::Error>("expectedError");
+ QTest::addColumn<QString>("errorKeyWord");
+
+ constexpr auto invalid = QXmlStreamReader::Error::UnexpectedElementError;
+ constexpr auto valid = QXmlStreamReader::Error::NoError;
+ QTest::newRow("DtdInBody") << "dtdInBody.xml" << invalid << "DTD";
+ QTest::newRow("multipleDTD") << "multipleDtd.xml" << invalid << "second DTD";
+ QTest::newRow("wellFormed") << "wellFormed.xml" << valid << "";
+}
+
+void tst_QXmlStream::tokenErrorHandling() const
+{
+ QFETCH(const QString, fileName);
+ QFETCH(const QXmlStreamReader::Error, expectedError);
+ QFETCH(const QString, errorKeyWord);
+
+ const QDir dir(QFINDTESTDATA("tokenError"));
+ QFile file(dir.absoluteFilePath(fileName));
+
+ // Cross-compiling: File will be on host only
+ if (!file.exists())
+ QSKIP("Testfile not found.");
+
+ file.open(QIODevice::ReadOnly);
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QCOMPARE(reader.error(), expectedError);
+ if (expectedError != QXmlStreamReader::Error::NoError)
+ QVERIFY(reader.errorString().contains(errorKeyWord));
+}
+
void tst_QXmlStream::test_fastScanName_data() const
{
QTest::addColumn<QByteArray>("data");
--
2.41.0

View File

@ -0,0 +1,38 @@
From 552e3b9b78c136aebedf0a591af04661f0dedbbf Mon Sep 17 00:00:00 2001
From: Liang Qi <liang.qi@qt.io>
Date: Mon, 31 Jul 2023 05:35:11 +0200
Subject: xcb: guard a pointer before usage
in QXcbAtom::initializeAllAtoms().
See also the example in
https://manpages.debian.org/testing/libxcb-doc/xcb_intern_atom_reply.3.en.html
Fixes: QTBUG-115599
Pick-to: 6.6 6.5 6.2
Change-Id: I6590fe1aa11deec7fef7ce6d8f5c49a71d636648
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
---
src/plugins/platforms/xcb/qxcbatom.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index 09b1fe8a9d..a456c19490 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -230,8 +230,10 @@ void QXcbAtom::initializeAllAtoms(xcb_connection_t *connection) {
for (i = 0; i < QXcbAtom::NAtoms; ++i) {
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookies[i], nullptr);
- m_allAtoms[i] = reply->atom;
- free(reply);
+ if (reply) {
+ m_allAtoms[i] = reply->atom;
+ free(reply);
+ }
}
}
--
cgit v1.2.3

View File

@ -0,0 +1,29 @@
From c1d9a2e1eb0bf78cc33b558a2f78ca49fcb3cb1d Mon Sep 17 00:00:00 2001
From: peijiankang <peijiankang@kylinos.cn>
Date: Wed, 31 Jan 2024 11:31:35 +0800
Subject: [PATCH] qtbase-6.5.2-CVE-2023-51714
---
src/network/access/http2/hpacktable.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp
index 74a09a20..2c728b37 100644
--- a/src/network/access/http2/hpacktable.cpp
+++ b/src/network/access/http2/hpacktable.cpp
@@ -26,8 +26,10 @@ HeaderSize entry_size(QByteArrayView name, QByteArrayView value)
// for counting the number of references to the name and value would have
// 32 octets of overhead."
- const unsigned sum = unsigned(name.size() + value.size());
- if (std::numeric_limits<unsigned>::max() - 32 < sum)
+ size_t sum;
+ if (qAddOverflow(size_t(name.size()), size_t(value.size()), &sum))
+ return HeaderSize();
+ if (sum > (std::numeric_limits<unsigned>::max() - 32))
return HeaderSize();
return HeaderSize(true, quint32(sum + 32));
}
--
2.41.0

View File

@ -0,0 +1,325 @@
diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
index ee5e879516..d52d6a8a3c 100644
--- a/src/gui/util/qktxhandler.cpp
+++ b/src/gui/util/qktxhandler.cpp
@@ -41,7 +41,7 @@ struct KTXHeader {
quint32 bytesOfKeyValueData;
};
-static const quint32 qktxh_headerSize = sizeof(KTXHeader);
+static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader);
// Currently unused, declared for future reference
struct KTXKeyValuePairItem {
@@ -71,11 +71,24 @@ struct KTXMipmapLevel {
*/
};
-// Returns the nearest multiple of 'rounding' greater than or equal to 'value'
-constexpr quint32 withPadding(quint32 value, quint32 rounding)
+// Returns the nearest multiple of 4 greater than or equal to 'value'
+static const std::optional<quint32> nearestMultipleOf4(quint32 value)
{
- Q_ASSERT(rounding > 1);
- return value + (rounding - 1) - ((value + (rounding - 1)) % rounding);
+ constexpr quint32 rounding = 4;
+ quint32 result = 0;
+ if (qAddOverflow(value, rounding - 1, &result))
+ return std::nullopt;
+ result &= ~(rounding - 1);
+ return result;
+}
+
+// Returns a view with prechecked bounds
+static QByteArrayView safeView(QByteArrayView view, quint32 start, quint32 length)
+{
+ quint32 end = 0;
+ if (qAddOverflow(start, length, &end) || end > quint32(view.length()))
+ return {};
+ return view.sliced(start, length);
}
QKtxHandler::~QKtxHandler() = default;
@@ -83,8 +96,7 @@ QKtxHandler::~QKtxHandler() = default;
bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
{
Q_UNUSED(suffix);
-
- return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0);
+ return block.startsWith(ktxIdentifier);
}
QTextureFileData QKtxHandler::read()
@@ -93,55 +105,122 @@ QTextureFileData QKtxHandler::read()
return QTextureFileData();
const QByteArray buf = device()->readAll();
- const quint32 dataSize = quint32(buf.size());
- if (dataSize < qktxh_headerSize || !canRead(QByteArray(), buf)) {
- qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
+ if (buf.size() > std::numeric_limits<quint32>::max()) {
+ qWarning(lcQtGuiTextureIO, "Too big KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ if (!canRead(QByteArray(), buf)) {
+ qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
return QTextureFileData();
}
- const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.data());
- if (!checkHeader(*header)) {
- qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
+ if (buf.size() < qsizetype(qktxh_headerSize)) {
+ qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ KTXHeader header;
+ memcpy(&header, buf.data(), qktxh_headerSize);
+ if (!checkHeader(header)) {
+ qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
return QTextureFileData();
}
QTextureFileData texData;
texData.setData(buf);
- texData.setSize(QSize(decode(header->pixelWidth), decode(header->pixelHeight)));
- texData.setGLFormat(decode(header->glFormat));
- texData.setGLInternalFormat(decode(header->glInternalFormat));
- texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
+ texData.setSize(QSize(decode(header.pixelWidth), decode(header.pixelHeight)));
+ texData.setGLFormat(decode(header.glFormat));
+ texData.setGLInternalFormat(decode(header.glInternalFormat));
+ texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat));
- texData.setNumLevels(decode(header->numberOfMipmapLevels));
- texData.setNumFaces(decode(header->numberOfFaces));
+ texData.setNumLevels(decode(header.numberOfMipmapLevels));
+ texData.setNumFaces(decode(header.numberOfFaces));
+
+ const quint32 bytesOfKeyValueData = decode(header.bytesOfKeyValueData);
+ quint32 headerKeyValueSize;
+ if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, &headerKeyValueSize)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in header of KTX file %s",
+ logName().constData());
+ return QTextureFileData();
+ }
- const quint32 bytesOfKeyValueData = decode(header->bytesOfKeyValueData);
- if (qktxh_headerSize + bytesOfKeyValueData < quint64(buf.size())) // oob check
- texData.setKeyValueMetadata(decodeKeyValues(
- QByteArrayView(buf.data() + qktxh_headerSize, bytesOfKeyValueData)));
- quint32 offset = qktxh_headerSize + bytesOfKeyValueData;
+ if (headerKeyValueSize >= quint32(buf.size())) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ // File contains key/values
+ if (bytesOfKeyValueData > 0) {
+ auto keyValueDataView = safeView(buf, qktxh_headerSize, bytesOfKeyValueData);
+ if (keyValueDataView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ auto keyValues = decodeKeyValues(keyValueDataView);
+ if (!keyValues) {
+ qWarning(lcQtGuiTextureIO, "Could not parse key values in KTX file %s",
+ logName().constData());
+ return QTextureFileData();
+ }
+
+ texData.setKeyValueMetadata(*keyValues);
+ }
+
+ // Technically, any number of levels is allowed but if the value is bigger than
+ // what is possible in KTX V2 (and what makes sense) we return an error.
+ // maxLevels = log2(max(width, height, depth))
+ const int maxLevels = (sizeof(quint32) * 8)
+ - qCountLeadingZeroBits(std::max(
+ { header.pixelWidth, header.pixelHeight, header.pixelDepth }));
+
+ if (texData.numLevels() > maxLevels) {
+ qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
- constexpr int MAX_ITERATIONS = 32; // cap iterations in case of corrupt data
+ if (texData.numFaces() != 1 && texData.numFaces() != 6) {
+ qWarning(lcQtGuiTextureIO, "Invalid number of faces in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
- for (int level = 0; level < qMin(texData.numLevels(), MAX_ITERATIONS); level++) {
- if (offset + sizeof(quint32) > dataSize) // Corrupt file; avoid oob read
- break;
+ quint32 offset = headerKeyValueSize;
+ for (int level = 0; level < texData.numLevels(); level++) {
+ const auto imageSizeView = safeView(buf, offset, sizeof(quint32));
+ if (imageSizeView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
- const quint32 imageSize = decode(qFromUnaligned<quint32>(buf.data() + offset));
- offset += sizeof(quint32);
+ const quint32 imageSize = decode(qFromUnaligned<quint32>(imageSizeView.data()));
+ offset += sizeof(quint32); // overflow checked indirectly above
- for (int face = 0; face < qMin(texData.numFaces(), MAX_ITERATIONS); face++) {
+ for (int face = 0; face < texData.numFaces(); face++) {
texData.setDataOffset(offset, level, face);
texData.setDataLength(imageSize, level, face);
// Add image data and padding to offset
- offset += withPadding(imageSize, 4);
+ const auto padded = nearestMultipleOf4(imageSize);
+ if (!padded) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ quint32 offsetNext;
+ if (qAddOverflow(offset, *padded, &offsetNext)) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ offset = offsetNext;
}
}
if (!texData.isValid()) {
- qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData());
+ qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s",
+ logName().constData());
return QTextureFileData();
}
@@ -187,33 +266,83 @@ bool QKtxHandler::checkHeader(const KTXHeader &header)
return is2D && (isCubeMap || isCompressedImage);
}
-QMap<QByteArray, QByteArray> QKtxHandler::decodeKeyValues(QByteArrayView view) const
+std::optional<QMap<QByteArray, QByteArray>> QKtxHandler::decodeKeyValues(QByteArrayView view) const
{
QMap<QByteArray, QByteArray> output;
quint32 offset = 0;
- while (offset < view.size() + sizeof(quint32)) {
+ while (offset < quint32(view.size())) {
+ const auto keyAndValueByteSizeView = safeView(view, offset, sizeof(quint32));
+ if (keyAndValueByteSizeView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value");
+ return std::nullopt;
+ }
+
const quint32 keyAndValueByteSize =
- decode(qFromUnaligned<quint32>(view.constData() + offset));
- offset += sizeof(quint32);
+ decode(qFromUnaligned<quint32>(keyAndValueByteSizeView.data()));
- if (offset + keyAndValueByteSize > quint64(view.size()))
- break; // oob read
+ quint32 offsetKeyAndValueStart;
+ if (qAddOverflow(offset, quint32(sizeof(quint32)), &offsetKeyAndValueStart)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ quint32 offsetKeyAndValueEnd;
+ if (qAddOverflow(offsetKeyAndValueStart, keyAndValueByteSize, &offsetKeyAndValueEnd)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ const auto keyValueView = safeView(view, offsetKeyAndValueStart, keyAndValueByteSize);
+ if (keyValueView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value");
+ return std::nullopt;
+ }
// 'key' is a UTF-8 string ending with a null terminator, 'value' is the rest.
// To separate the key and value we convert the complete data to utf-8 and find the first
// null terminator from the left, here we split the data into two.
- const auto str = QString::fromUtf8(view.constData() + offset, keyAndValueByteSize);
- const int idx = str.indexOf('\0'_L1);
- if (idx == -1)
- continue;
-
- const QByteArray key = str.left(idx).toUtf8();
- const size_t keySize = key.size() + 1; // Actual data size
- const QByteArray value = QByteArray::fromRawData(view.constData() + offset + keySize,
- keyAndValueByteSize - keySize);
-
- offset = withPadding(offset + keyAndValueByteSize, 4);
- output.insert(key, value);
+
+ const int idx = keyValueView.indexOf('\0');
+ if (idx == -1) {
+ qWarning(lcQtGuiTextureIO, "Invalid key in KTX key-value");
+ return std::nullopt;
+ }
+
+ const QByteArrayView keyView = safeView(view, offsetKeyAndValueStart, idx);
+ if (keyView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ const quint32 keySize = idx + 1; // Actual data size
+
+ quint32 offsetValueStart;
+ if (qAddOverflow(offsetKeyAndValueStart, keySize, &offsetValueStart)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ quint32 valueSize;
+ if (qSubOverflow(keyAndValueByteSize, keySize, &valueSize)) {
+ qWarning(lcQtGuiTextureIO, "Underflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ const QByteArrayView valueView = safeView(view, offsetValueStart, valueSize);
+ if (valueView.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value");
+ return std::nullopt;
+ }
+
+ output.insert(keyView.toByteArray(), valueView.toByteArray());
+
+ const auto offsetNext = nearestMultipleOf4(offsetKeyAndValueEnd);
+ if (!offsetNext) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value");
+ return std::nullopt;
+ }
+
+ offset = *offsetNext;
}
return output;
diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h
index 0fd2487393..1142aa8dc0 100644
--- a/src/gui/util/qktxhandler_p.h
+++ b/src/gui/util/qktxhandler_p.h
@@ -17,6 +17,8 @@
#include "qtexturefilehandler_p.h"
+#include <optional>
+
QT_BEGIN_NAMESPACE
struct KTXHeader;
@@ -33,7 +35,7 @@ public:
private:
bool checkHeader(const KTXHeader &header);
- QMap<QByteArray, QByteArray> decodeKeyValues(QByteArrayView view) const;
+ std::optional<QMap<QByteArray, QByteArray>> decodeKeyValues(QByteArrayView view) const;
quint32 decode(quint32 val) const;
bool inverseEndian = false;

View File

@ -0,0 +1,22 @@
diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp
index 6ca65ba6ad8..043b8f54151 100644
--- a/src/corelib/text/qstringconverter.cpp
+++ b/src/corelib/text/qstringconverter.cpp
@@ -1966,7 +1966,7 @@ struct QStringConverterICU : QStringConverter
const void *context;
ucnv_getToUCallBack(icu_conv, &action, &context);
if (context != state)
- ucnv_setToUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
+ ucnv_setToUCallBack(icu_conv, action, state, nullptr, nullptr, &err);
ucnv_toUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
// We did reserve enough space:
@@ -1999,7 +1999,7 @@ struct QStringConverterICU : QStringConverter
const void *context;
ucnv_getFromUCallBack(icu_conv, &action, &context);
if (context != state)
- ucnv_setFromUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
+ ucnv_setFromUCallBack(icu_conv, action, state, nullptr, nullptr, &err);
ucnv_fromUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
// We did reserve enough space:

View File

@ -0,0 +1,138 @@
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index ec100708600..80819105201 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -339,12 +339,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 b9e1ae403cd..3cbe1b16f9e 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -209,6 +209,10 @@
bool QHttpNetworkConnectionChannel::sendRequest()
{
Q_ASSERT(protocolHandler);
+ if (waitingForPotentialAbort) {
+ needInvokeSendRequest = true;
+ return false; // this return value is unused
+ }
return protocolHandler->sendRequest();
}
@@ -221,21 +225,28 @@
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();
}
@@ -1232,7 +1243,18 @@
// Similar to HTTP/1.1 counterpart below:
const auto &h2Pairs = h2RequestsToSend.values(); // (request, reply)
const auto &pair = h2Pairs.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).
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
@@ -1250,6 +1272,28 @@
}
}
+
+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()
{
QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values();
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index e38e56df160..76d5baef2e3 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -73,6 +73,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
@@ -145,6 +149,8 @@ public:
void closeAndResendCurrentRequest();
void resendCurrentRequest();
+ void checkAndResumeCommunication();
+
bool isSocketBusy() const;
bool isSocketWriting() const;
bool isSocketWaiting() const;

View File

@ -0,0 +1,127 @@
From 905a5bd421efff6a1d90b6140500d134d32ca745 Mon Sep 17 00:00:00 2001
From: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Date: Tue, 06 Aug 2024 22:39:44 +0200
Subject: [PATCH] XML/QDom: speedup encodeText()
The code copied the whole string, then replaced parts inline, at
the cost of relocating everything beyond, at each replacement.
Instead, copy character by character (in chunks where possible)
and append replacements as we skip what they replace.
Manual conflict resolution for 6.5:
- This is a manual cherry-pick. The original change was only
picked to 6.8, but the quadratic behavior is present in Qt 5, too.
- Changed Task-number to Fixes: because this is the real fix;
the QString change, 315210de916d060c044c01e53ff249d676122b1b,
was unrelated to the original QTBUG-127549.
Pick-to: 5.15
Fixes: QTBUG-127549
Change-Id: I368482859ed0c4127f1eec2919183711b5488ada
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 2ce08e3671b8d18b0284447e5908ce15e6e8f80f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 225e235cf966a44af23dbe9aaaa2fd20ab6430ee)
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
---
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 7b45237..45cde91 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -3607,47 +3607,57 @@
const bool performAVN = false,
const bool encodeEOLs = false)
{
- QString retval(str);
- int len = retval.size();
- int i = 0;
+ QString retval;
+ qsizetype start = 0;
+ auto appendToOutput = [&](qsizetype cur, const auto &replacement)
+ {
+ if (start < cur) {
+ retval.reserve(str.size() + replacement.size());
+ retval.append(QStringView(str).first(cur).sliced(start));
+ }
+ // Skip over str[cur], replaced by replacement
+ start = cur + 1;
+ retval.append(replacement);
+ };
- while (i < len) {
- const QChar ati(retval.at(i));
-
- if (ati == u'<') {
- retval.replace(i, 1, "&lt;"_L1);
- len += 3;
- i += 4;
- } else if (encodeQuotes && (ati == u'"')) {
- retval.replace(i, 1, "&quot;"_L1);
- len += 5;
- i += 6;
- } else if (ati == u'&') {
- retval.replace(i, 1, "&amp;"_L1);
- len += 4;
- i += 5;
- } else if (ati == u'>' && i >= 2 && retval[i - 1] == u']' && retval[i - 2] == u']') {
- retval.replace(i, 1, "&gt;"_L1);
- len += 3;
- i += 4;
- } else if (performAVN &&
- (ati == QChar(0xA) ||
- ati == QChar(0xD) ||
- ati == QChar(0x9))) {
- const QString replacement(u"&#x"_s + QString::number(ati.unicode(), 16) + u';');
- retval.replace(i, 1, replacement);
- i += replacement.size();
- len += replacement.size() - 1;
- } else if (encodeEOLs && ati == QChar(0xD)) {
- retval.replace(i, 1, "&#xd;"_L1); // Replace a single 0xD with a ref for 0xD
- len += 4;
- i += 5;
- } else {
- ++i;
+ const qsizetype len = str.size();
+ for (qsizetype cur = 0; cur < len; ++cur) {
+ switch (str[cur].unicode()) {
+ case u'<':
+ appendToOutput(cur, "&lt;"_L1);
+ break;
+ case u'"':
+ if (encodeQuotes)
+ appendToOutput(cur, "&quot;"_L1);
+ break;
+ case u'&':
+ appendToOutput(cur, "&amp;"_L1);
+ break;
+ case u'>':
+ if (cur >= 2 && str[cur - 1] == u']' && str[cur - 2] == u']')
+ appendToOutput(cur, "&gt;"_L1);
+ break;
+ case u'\r':
+ if (performAVN || encodeEOLs)
+ appendToOutput(cur, "&#xd;"_L1); // \r == 0x0d
+ break;
+ case u'\n':
+ if (performAVN)
+ appendToOutput(cur, "&#xa;"_L1); // \n == 0x0a
+ break;
+ case u'\t':
+ if (performAVN)
+ appendToOutput(cur, "&#x9;"_L1); // \t == 0x09
+ break;
+ default:
+ break;
}
}
-
- return retval;
+ if (start > 0) {
+ retval.append(QStringView(str).first(len).sliced(start));
+ return retval;
+ }
+ return str;
}
void QDomAttrPrivate::save(QTextStream& s, int, int) const

3
qtlogging.ini Normal file
View File

@ -0,0 +1,3 @@
[Rules]
*.debug=false
qt.qpa.xcb.xcberror.warning=false