commit 7463bfb7677cd4024c3a1c4a47d3b3257016feb7 Author: Jiayi Yin Date: Sun May 18 23:29:18 2025 +0000 转换LFS仓库为普通仓库 diff --git a/10-qt6-check-opengl2.sh b/10-qt6-check-opengl2.sh new file mode 100644 index 0000000..747fa07 --- /dev/null +++ b/10-qt6-check-opengl2.sh @@ -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 diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..671cdb5 --- /dev/null +++ b/README.en.md @@ -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/) diff --git a/README.md b/README.md new file mode 100644 index 0000000..c00fae6 --- /dev/null +++ b/README.md @@ -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/) diff --git a/fix-build-error-of-libxkbcommon-1.6.0.patch b/fix-build-error-of-libxkbcommon-1.6.0.patch new file mode 100644 index 0000000..b2d6ffe --- /dev/null +++ b/fix-build-error-of-libxkbcommon-1.6.0.patch @@ -0,0 +1,31 @@ +From 00b748a08fd27277e4bd8f86b431a1e71423d7ff Mon Sep 17 00:00:00 2001 +From: peijiankang +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, + Xkb2Qt, + Xkb2Qt, ++/* 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, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, ++#endif + + // Special keys from X.org - This include multimedia keys, + // wireless/bluetooth/uwb keys, special launcher keys, etc. +-- +2.41.0 + diff --git a/fix-riscv-configure-tests.patch b/fix-riscv-configure-tests.patch new file mode 100644 index 0000000..a86b454 --- /dev/null +++ b/fix-riscv-configure-tests.patch @@ -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) diff --git a/macros.qt6-qtbase b/macros.qt6-qtbase new file mode 100644 index 0000000..164f760 --- /dev/null +++ b/macros.qt6-qtbase @@ -0,0 +1,4 @@ +%_qt6 @@NAME@@ +%_qt6_epoch @@EPOCH@@ +%_qt6_version @@VERSION@@ +%_qt6_evr @@EVR@@ diff --git a/qconfig-multilib.h b/qconfig-multilib.h new file mode 100644 index 0000000..a104c37 --- /dev/null +++ b/qconfig-multilib.h @@ -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 +#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 + diff --git a/qmake-qt6.sh b/qmake-qt6.sh new file mode 100644 index 0000000..beb29fe --- /dev/null +++ b/qmake-qt6.sh @@ -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 $@ diff --git a/qt6-qtbase-add-sw64-support.patch b/qt6-qtbase-add-sw64-support.patch new file mode 100644 index 0000000..ebba418 --- /dev/null +++ b/qt6-qtbase-add-sw64-support.patch @@ -0,0 +1,188 @@ +From 39e21f564099f9ffe02643f8f02119168263c5dd Mon Sep 17 00:00:00 2001 +From: mahailiang +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 ++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 +-- +2.33.0 + diff --git a/qt6-qtbase.spec b/qt6-qtbase.spec new file mode 100644 index 0000000..e4efec5 --- /dev/null +++ b/qt6-qtbase.spec @@ -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 - 6.5.2-10 +- fix CVE-2025-30348 + +* Tue Mar 11 2025 mahailiang - 6.5.2-9 +- add sw_64 support + +* Tue Dec 17 2024 shenzhongwei - 6.5.2-8 +- include all patches in the source package. + +* Thu Dec 12 2024 Funda Wang - 6.5.2-7 +- fix CVE-2023-45935, CVE-2024-25580 + +* Wed Dec 11 2024 Funda Wang - 6.5.2-5 +- fix CVE-2024-33861, CVE-2024-39936 +- add missing xcb plugin + +* Mon May 20 2024 Wenlong Zhang - 6.5.2-4 +- fix build error for loongarch64 + +* Wed Jan 31 2024 peijiankang - 6.5.2-3 +- add qtbase6.5.2-CVE-2023-51714.patch + +* Mon Jan 29 2024 peijiankang - 6.5.2-2 +- fix build error of libxkbcommon-1.6.0 + +* Wed Nov 29 2023 peijiankang - 6.5.2-1 +- update version to 6.5.2 + +* Fri Nov 24 2023 hua_yadong - 6.5.1-5 +- fix qtbase6.5.1-CVE-2023-43114.patch + +* Fri Nov 24 2023 hua_yadong - 6.5.1-4 +- fix qtbase6.5.1-CVE-2023-37369.patch + +* Thu Nov 23 2023 hua_yadong - 6.5.1-3 +- fix qtbase6.5.1-CVE-2023-38197.patch + +* Thu Nov 02 2023 peijiankang - 6.5.1-2 +- fix qtbase6.5.1-CVE-2023-34410.patch + +* Wed Jul 5 2023 EastDong - 6.5.1-1 +- update package + +* Fri May 19 2023 peijiankang - 6.5.0-2 +- Enable zstd support + +* Tue Apr 25 2023 EastDong - 6.5.0-1 +- update package + +* Thu Nov 10 2022 Jingwiw - 6.4.0-1 +- init package diff --git a/qt6-qtbase.yaml b/qt6-qtbase.yaml new file mode 100644 index 0000000..1dbd3a5 --- /dev/null +++ b/qt6-qtbase.yaml @@ -0,0 +1,4 @@ +version_control: git +src_repo: https://code.qt.io/qt/qtbase.git +tag_prefix: "^v" +separator: "." diff --git a/qtbase-CMake-Install-objects-files-into-ARCHDATADIR.patch b/qtbase-CMake-Install-objects-files-into-ARCHDATADIR.patch new file mode 100644 index 0000000..5d7bc91 --- /dev/null +++ b/qtbase-CMake-Install-objects-files-into-ARCHDATADIR.patch @@ -0,0 +1,51 @@ +From 4e517492a03b6c0b710a2d9a3df05922ac233992 Mon Sep 17 00:00:00 2001 +From: Christophe Marin +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-$/${target}/${rel_obj_file_dir}") ++ "${INSTALL_ARCHDATADIR}/objects-$/${target}/${rel_obj_file_dir}") + endforeach() + endfunction() +-- +2.40.1 diff --git a/qtbase-cxxflag.patch b/qtbase-cxxflag.patch new file mode 100644 index 0000000..321f051 --- /dev/null +++ b/qtbase-cxxflag.patch @@ -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 + diff --git a/qtbase-everywhere-src-6.5.2.tar.xz b/qtbase-everywhere-src-6.5.2.tar.xz new file mode 100644 index 0000000..72ec95a Binary files /dev/null and b/qtbase-everywhere-src-6.5.2.tar.xz differ diff --git a/qtbase-gcc11.patch b/qtbase-gcc11.patch new file mode 100644 index 0000000..dfbd08f --- /dev/null +++ b/qtbase-gcc11.patch @@ -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 + #include + #include + +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 + #include + #include + +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 + #include + #include + #include diff --git a/qtbase-libglvnd.patch b/qtbase-libglvnd.patch new file mode 100644 index 0000000..c5aa7e5 --- /dev/null +++ b/qtbase-libglvnd.patch @@ -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(EGL_DEFAULT_DISPLAY); + EGLNativeDisplayType egldpy = XOpenDisplay(\"\"); +-dpy = egldpy; ++dpy = reinterpret_cast(egldpy); + EGLNativeWindowType w = XCreateWindow(dpy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + XDestroyWindow(dpy, w); + XCloseDisplay(dpy); diff --git a/qtbase-moc-macros.patch b/qtbase-moc-macros.patch new file mode 100644 index 0000000..8f5f4d6 --- /dev/null +++ b/qtbase-moc-macros.patch @@ -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; diff --git a/qtbase-mysql.patch b/qtbase-mysql.patch new file mode 100644 index 0000000..c190ca6 --- /dev/null +++ b/qtbase-mysql.patch @@ -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 ++#include + + #ifdef QT_PLUGIN + #define Q_EXPORT_SQLDRIVER_MYSQL diff --git a/qtbase-tell-truth-about-private-api.patch b/qtbase-tell-truth-about-private-api.patch new file mode 100644 index 0000000..c17e6f6 --- /dev/null +++ b/qtbase-tell-truth-about-private-api.patch @@ -0,0 +1,27 @@ +From c92143a6c6621f680208cd47d91877fd670b1e8f Mon Sep 17 00:00:00 2001 +From: Christophe Marin +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") +-- \ No newline at end of file diff --git a/qtbase-version-check.patch b/qtbase-version-check.patch new file mode 100644 index 0000000..9343ade --- /dev/null +++ b/qtbase-version-check.patch @@ -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, diff --git a/qtbase6.5.1-CVE-2023-43114.patch b/qtbase6.5.1-CVE-2023-43114.patch new file mode 100644 index 0000000..f5cbe01 --- /dev/null +++ b/qtbase6.5.1-CVE-2023-43114.patch @@ -0,0 +1,129 @@ +From 8d7c452d55d55d6d60f3f0112a704968945fdab8 Mon Sep 17 00:00:00 2001 +From: hua_yadong +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 getTrueTypeFontOffsets(const uchar *fontData) ++static QList getTrueTypeFontOffsets(const uchar *fontData, const uchar *fileEndSentinel) + { + QList offsets; +- const quint32 headerTag = *reinterpret_cast(fontData); ++ if (fileEndSentinel - fontData < 12) { ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; ++ return offsets; ++ } ++ ++ const quint32 headerTag = qFromUnaligned(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(fontData + 8); +- for (uint i = 0; i < numFonts; ++i) { +- offsets << qFromBigEndian(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(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(data + 4); +- for (uint i = 0; i < numTables; ++i) { +- const quint32 offset = 12 + 16 * i; +- if (*reinterpret_cast(data + offset) == tag) { +- *table = fileBegin + qFromBigEndian(data + offset + 8); +- *length = qFromBigEndian(data + offset + 12); +- return; ++ if (fileEndSentinel - data >= 6) { ++ const quint16 numTables = qFromBigEndian(data + 4); ++ if (fileEndSentinel - data >= 28 + 16 * (numTables - 1)) { ++ for (quint32 i = 0; i < numTables; ++i) { ++ const quint32 offset = 12 + 16 * i; ++ if (qFromUnaligned(data + offset) == tag) { ++ const quint32 tableOffset = qFromBigEndian(data + offset + 8); ++ if (quintptr(fileEndSentinel - fileBegin) <= tableOffset) { ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; ++ break; ++ } ++ *table = fileBegin + tableOffset; ++ *length = qFromBigEndian(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 *values) + { + const uchar *data = reinterpret_cast(fontData.constData()); ++ const uchar *dataEndSentinel = data + fontData.size(); + +- QList offsets = getTrueTypeFontOffsets(data); ++ QList 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 + diff --git a/qtbase6.5.2-CVE-2023-38197.patch b/qtbase6.5.2-CVE-2023-38197.patch new file mode 100644 index 0000000..e213cf2 --- /dev/null +++ b/qtbase6.5.2-CVE-2023-38197.patch @@ -0,0 +1,371 @@ +From 49a4cf8133eb8d76115fb7827bd76764e1b30d12 Mon Sep 17 00:00:00 2001 +From: peijiankang +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(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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++]> ++ ++ ++ tst_QXmlStream ++ ++ ++ ++ ++ ]> ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++]> ++ ++ ++ ++]> ++ ++ ++ tst_QXmlStream ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++]> ++ ++ ++ tst_QXmlStream ++ ++ ++ +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("fileName"); ++ QTest::addColumn("expectedError"); ++ QTest::addColumn("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("data"); +-- +2.41.0 + diff --git a/qtbase6.5.2-CVE-2023-45935.patch b/qtbase6.5.2-CVE-2023-45935.patch new file mode 100644 index 0000000..7e620cc --- /dev/null +++ b/qtbase6.5.2-CVE-2023-45935.patch @@ -0,0 +1,38 @@ +From 552e3b9b78c136aebedf0a591af04661f0dedbbf Mon Sep 17 00:00:00 2001 +From: Liang Qi +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 +--- + 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 + diff --git a/qtbase6.5.2-CVE-2023-51714.patch b/qtbase6.5.2-CVE-2023-51714.patch new file mode 100644 index 0000000..0efee5e --- /dev/null +++ b/qtbase6.5.2-CVE-2023-51714.patch @@ -0,0 +1,29 @@ +From c1d9a2e1eb0bf78cc33b558a2f78ca49fcb3cb1d Mon Sep 17 00:00:00 2001 +From: peijiankang +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::max() - 32 < sum) ++ size_t sum; ++ if (qAddOverflow(size_t(name.size()), size_t(value.size()), &sum)) ++ return HeaderSize(); ++ if (sum > (std::numeric_limits::max() - 32)) + return HeaderSize(); + return HeaderSize(true, quint32(sum + 32)); + } +-- +2.41.0 + diff --git a/qtbase6.5.2-CVE-2024-25580.patch b/qtbase6.5.2-CVE-2024-25580.patch new file mode 100644 index 0000000..13238af --- /dev/null +++ b/qtbase6.5.2-CVE-2024-25580.patch @@ -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 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::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(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(buf.data() + offset)); +- offset += sizeof(quint32); ++ const quint32 imageSize = decode(qFromUnaligned(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 QKtxHandler::decodeKeyValues(QByteArrayView view) const ++std::optional> QKtxHandler::decodeKeyValues(QByteArrayView view) const + { + QMap 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(view.constData() + offset)); +- offset += sizeof(quint32); ++ decode(qFromUnaligned(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 ++ + QT_BEGIN_NAMESPACE + + struct KTXHeader; +@@ -33,7 +35,7 @@ public: + + private: + bool checkHeader(const KTXHeader &header); +- QMap decodeKeyValues(QByteArrayView view) const; ++ std::optional> decodeKeyValues(QByteArrayView view) const; + quint32 decode(quint32 val) const; + + bool inverseEndian = false; diff --git a/qtbase6.5.2-CVE-2024-33861.patch b/qtbase6.5.2-CVE-2024-33861.patch new file mode 100644 index 0000000..b70ba76 --- /dev/null +++ b/qtbase6.5.2-CVE-2024-33861.patch @@ -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: diff --git a/qtbase6.5.2-CVE-2024-39936.patch b/qtbase6.5.2-CVE-2024-39936.patch new file mode 100644 index 0000000..8dcf842 --- /dev/null +++ b/qtbase6.5.2-CVE-2024-39936.patch @@ -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 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; diff --git a/qtbase6.5.2-CVE-2025-30348.patch b/qtbase6.5.2-CVE-2025-30348.patch new file mode 100644 index 0000000..93a6fcd --- /dev/null +++ b/qtbase6.5.2-CVE-2025-30348.patch @@ -0,0 +1,127 @@ +From 905a5bd421efff6a1d90b6140500d134d32ca745 Mon Sep 17 00:00:00 2001 +From: Christian Ehrlicher +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 +(cherry picked from commit 2ce08e3671b8d18b0284447e5908ce15e6e8f80f) +Reviewed-by: Qt Cherry-pick Bot +(cherry picked from commit 225e235cf966a44af23dbe9aaaa2fd20ab6430ee) +Reviewed-by: Fabian Kosmale +--- + +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, "<"_L1); +- len += 3; +- i += 4; +- } else if (encodeQuotes && (ati == u'"')) { +- retval.replace(i, 1, """_L1); +- len += 5; +- i += 6; +- } else if (ati == u'&') { +- retval.replace(i, 1, "&"_L1); +- len += 4; +- i += 5; +- } else if (ati == u'>' && i >= 2 && retval[i - 1] == u']' && retval[i - 2] == u']') { +- retval.replace(i, 1, ">"_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, " "_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, "<"_L1); ++ break; ++ case u'"': ++ if (encodeQuotes) ++ appendToOutput(cur, """_L1); ++ break; ++ case u'&': ++ appendToOutput(cur, "&"_L1); ++ break; ++ case u'>': ++ if (cur >= 2 && str[cur - 1] == u']' && str[cur - 2] == u']') ++ appendToOutput(cur, ">"_L1); ++ break; ++ case u'\r': ++ if (performAVN || encodeEOLs) ++ appendToOutput(cur, " "_L1); // \r == 0x0d ++ break; ++ case u'\n': ++ if (performAVN) ++ appendToOutput(cur, " "_L1); // \n == 0x0a ++ break; ++ case u'\t': ++ if (performAVN) ++ appendToOutput(cur, " "_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 diff --git a/qtlogging.ini b/qtlogging.ini new file mode 100644 index 0000000..ead33b6 --- /dev/null +++ b/qtlogging.ini @@ -0,0 +1,3 @@ +[Rules] +*.debug=false +qt.qpa.xcb.xcberror.warning=false