1 |
commit: b7878373380a080f7a9c7f60e5ae420937f64e94 |
2 |
Author: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Aug 24 14:06:31 2022 +0000 |
4 |
Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Aug 24 14:16:50 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=b7878373 |
7 |
|
8 |
dev-qt/qtcore: Don't access QObjectPrivate::declarativeData unguarded |
9 |
|
10 |
QTBUG: https://bugreports.qt.io/browse/QTBUG-105286 |
11 |
|
12 |
Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org> |
13 |
|
14 |
.../qtcore/files/qtcore-5.15.5-QTBUG-105286.patch | 165 +++++++++++++++++++++ |
15 |
dev-qt/qtcore/qtcore-5.15.5-r3.ebuild | 105 +++++++++++++ |
16 |
2 files changed, 270 insertions(+) |
17 |
|
18 |
diff --git a/dev-qt/qtcore/files/qtcore-5.15.5-QTBUG-105286.patch b/dev-qt/qtcore/files/qtcore-5.15.5-QTBUG-105286.patch |
19 |
new file mode 100644 |
20 |
index 000000000000..985dd283dbd4 |
21 |
--- /dev/null |
22 |
+++ b/dev-qt/qtcore/files/qtcore-5.15.5-QTBUG-105286.patch |
23 |
@@ -0,0 +1,165 @@ |
24 |
+From 7f9253defd2e90f900d963c6d248a2a0bdaca1a8 Mon Sep 17 00:00:00 2001 |
25 |
+From: Volker Hilsheimer <volker.hilsheimer@××.io> |
26 |
+Date: Tue, 16 Aug 2022 15:32:58 +0200 |
27 |
+Subject: [PATCH] Don't access QObjectPrivate::declarativeData unguarded |
28 |
+MIME-Version: 1.0 |
29 |
+Content-Type: text/plain; charset=UTF-8 |
30 |
+Content-Transfer-Encoding: 8bit |
31 |
+ |
32 |
+The QObjectPrivate::declarativeData member is stored in a union with |
33 |
+currentChildBeingDeleted. The QObject destructor always sets the |
34 |
+currentChildBeingDeleted member of the union. It also sets the |
35 |
+isDeletingChildren bool, which is the only way to find out which union |
36 |
+member we can safely access. |
37 |
+ |
38 |
+While the QObject destructor is deleting children and isDeletingChildren |
39 |
+is set, we must not access the declarativeData member of the union. |
40 |
+ |
41 |
+Add a test case that initializes the function pointers for the |
42 |
+declarative handlers and constructs a situation where an object |
43 |
+emits a signal while it is destroying children. |
44 |
+ |
45 |
+Fixes: QTBUG-105286 |
46 |
+Pick-to: 6.4 6.3 6.3.2 6.2 5.15 |
47 |
+Change-Id: Iea5ba2f7843b6926a8d157be166e6044d98d6c02 |
48 |
+Reviewed-by: Qt CI Bot <qt_ci_bot@××××××××××.org> |
49 |
+Reviewed-by: Mårten Nordheim <marten.nordheim@××.io> |
50 |
+(cherry picked from commit 3be99799a675a631c67e05897383af9abbc377b3) |
51 |
+--- |
52 |
+ src/corelib/kernel/qobject.cpp | 4 +- |
53 |
+ src/corelib/kernel/qobject_p.h | 2 +- |
54 |
+ .../corelib/kernel/qobject/tst_qobject.cpp | 77 +++++++++++++++++++ |
55 |
+ 3 files changed, 80 insertions(+), 3 deletions(-) |
56 |
+ |
57 |
+diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp |
58 |
+index 0124f88abd..1f3843669b 100644 |
59 |
+--- a/src/corelib/kernel/qobject.cpp |
60 |
++++ b/src/corelib/kernel/qobject.cpp |
61 |
+@@ -992,7 +992,7 @@ QObject::~QObject() |
62 |
+ emit destroyed(this); |
63 |
+ } |
64 |
+ |
65 |
+- if (d->declarativeData) { |
66 |
++ if (!d->isDeletingChildren && d->declarativeData) { |
67 |
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) { |
68 |
+ if (QAbstractDeclarativeData::destroyed_qml1) |
69 |
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this); |
70 |
+@@ -2583,7 +2583,7 @@ int QObject::receivers(const char *signal) const |
71 |
+ if (!d->isSignalConnected(signal_index)) |
72 |
+ return receivers; |
73 |
+ |
74 |
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) { |
75 |
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) { |
76 |
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this, |
77 |
+ signal_index); |
78 |
+ } |
79 |
+diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h |
80 |
+index 66c19d174e..46dcb93521 100644 |
81 |
+--- a/src/corelib/kernel/qobject_p.h |
82 |
++++ b/src/corelib/kernel/qobject_p.h |
83 |
+@@ -428,7 +428,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons |
84 |
+ |
85 |
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const |
86 |
+ { |
87 |
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected |
88 |
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected |
89 |
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index); |
90 |
+ } |
91 |
+ |
92 |
+diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp |
93 |
+index 9bd66c0835..ed4a0bae5d 100644 |
94 |
+--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp |
95 |
++++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp |
96 |
+@@ -158,6 +158,7 @@ private slots: |
97 |
+ void nullReceiver(); |
98 |
+ void functorReferencesConnection(); |
99 |
+ void disconnectDisconnects(); |
100 |
++ void declarativeData(); |
101 |
+ }; |
102 |
+ |
103 |
+ struct QObjectCreatedOnShutdown |
104 |
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects() |
105 |
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value); |
106 |
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value); |
107 |
+ |
108 |
++#ifdef QT_BUILD_INTERNAL |
109 |
++/* |
110 |
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer |
111 |
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be |
112 |
++ correctly guarded. QTBUG-105286 |
113 |
++*/ |
114 |
++namespace QtDeclarative { |
115 |
++static QAbstractDeclarativeData *theData; |
116 |
++ |
117 |
++static void destroyed(QAbstractDeclarativeData *data, QObject *) |
118 |
++{ |
119 |
++ QCOMPARE(data, theData); |
120 |
++} |
121 |
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **) |
122 |
++{ |
123 |
++ QCOMPARE(data, theData); |
124 |
++} |
125 |
++// we can't use QCOMPARE in the next two functions, as they don't return void |
126 |
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int) |
127 |
++{ |
128 |
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__); |
129 |
++ return 0; |
130 |
++} |
131 |
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int) |
132 |
++{ |
133 |
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__); |
134 |
++ return true; |
135 |
++} |
136 |
++ |
137 |
++class Object : public QObject |
138 |
++{ |
139 |
++ Q_OBJECT |
140 |
++public: |
141 |
++ using QObject::QObject; |
142 |
++ ~Object() |
143 |
++ { |
144 |
++ if (Object *p = static_cast<Object *>(parent())) |
145 |
++ p->emitSignal(); |
146 |
++ } |
147 |
++ |
148 |
++ void emitSignal() |
149 |
++ { |
150 |
++ emit theSignal(); |
151 |
++ } |
152 |
++ |
153 |
++signals: |
154 |
++ void theSignal(); |
155 |
++}; |
156 |
++ |
157 |
++} |
158 |
++#endif |
159 |
++ |
160 |
++void tst_QObject::declarativeData() |
161 |
++{ |
162 |
++#ifdef QT_BUILD_INTERNAL |
163 |
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed, |
164 |
++ QtDeclarative::destroyed); |
165 |
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted, |
166 |
++ QtDeclarative::signalEmitted); |
167 |
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers, |
168 |
++ QtDeclarative::receivers); |
169 |
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected, |
170 |
++ QtDeclarative::isSignalConnected); |
171 |
++ |
172 |
++ QtDeclarative::Object p; |
173 |
++ QObjectPrivate *priv = QObjectPrivate::get(&p); |
174 |
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData; |
175 |
++ |
176 |
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{ |
177 |
++ }); |
178 |
++ |
179 |
++ QtDeclarative::Object *child = new QtDeclarative::Object; |
180 |
++ child->setParent(&p); |
181 |
++#endif |
182 |
++} |
183 |
++ |
184 |
+ QTEST_MAIN(tst_QObject) |
185 |
+ #include "tst_qobject.moc" |
186 |
+-- |
187 |
+GitLab |
188 |
+ |
189 |
|
190 |
diff --git a/dev-qt/qtcore/qtcore-5.15.5-r3.ebuild b/dev-qt/qtcore/qtcore-5.15.5-r3.ebuild |
191 |
new file mode 100644 |
192 |
index 000000000000..521f2c4e0632 |
193 |
--- /dev/null |
194 |
+++ b/dev-qt/qtcore/qtcore-5.15.5-r3.ebuild |
195 |
@@ -0,0 +1,105 @@ |
196 |
+# Copyright 1999-2022 Gentoo Authors |
197 |
+# Distributed under the terms of the GNU General Public License v2 |
198 |
+ |
199 |
+EAPI=8 |
200 |
+ |
201 |
+QT5_KDEPATCHSET_REV=2 |
202 |
+QT5_MODULE="qtbase" |
203 |
+inherit linux-info qt5-build |
204 |
+ |
205 |
+DESCRIPTION="Cross-platform application development framework" |
206 |
+SLOT=5/${QT5_PV} |
207 |
+ |
208 |
+if [[ ${QT5_BUILD_TYPE} == release ]]; then |
209 |
+ KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~loong ~ppc ~ppc64 ~riscv ~sparc ~x86" |
210 |
+fi |
211 |
+ |
212 |
+IUSE="icu old-kernel systemd" |
213 |
+ |
214 |
+DEPEND=" |
215 |
+ dev-libs/double-conversion:= |
216 |
+ dev-libs/glib:2 |
217 |
+ dev-libs/libpcre2[pcre16,unicode] |
218 |
+ sys-libs/zlib:= |
219 |
+ icu? ( dev-libs/icu:= ) |
220 |
+ !icu? ( virtual/libiconv ) |
221 |
+ systemd? ( sys-apps/systemd:= ) |
222 |
+" |
223 |
+RDEPEND="${DEPEND}" |
224 |
+ |
225 |
+PATCHES=( |
226 |
+ "${FILESDIR}/${P}-hack_never_use_execinfo.patch" |
227 |
+ "${FILESDIR}/${P}-QTBUG-105286.patch" |
228 |
+) |
229 |
+ |
230 |
+QT5_TARGET_SUBDIRS=( |
231 |
+ src/tools/bootstrap |
232 |
+ src/tools/moc |
233 |
+ src/tools/rcc |
234 |
+ src/corelib |
235 |
+ src/tools/qlalr |
236 |
+ doc |
237 |
+) |
238 |
+ |
239 |
+QT5_GENTOO_PRIVATE_CONFIG=( |
240 |
+ !:network |
241 |
+ !:sql |
242 |
+ !:testlib |
243 |
+ !:xml |
244 |
+) |
245 |
+ |
246 |
+pkg_pretend() { |
247 |
+ use kernel_linux || return |
248 |
+ get_running_version |
249 |
+ if kernel_is -lt 4 11 && ! use old-kernel; then |
250 |
+ ewarn "The running kernel is older than 4.11. USE=old-kernel is needed for" |
251 |
+ ewarn "dev-qt/qtcore to function on this kernel properly. Bugs #669994, #672856" |
252 |
+ fi |
253 |
+} |
254 |
+ |
255 |
+src_prepare() { |
256 |
+ # don't add -O3 to CXXFLAGS, bug 549140 |
257 |
+ sed -i -e '/CONFIG\s*+=/s/optimize_full//' src/corelib/corelib.pro || die |
258 |
+ |
259 |
+ # fix missing qt_version_tag symbol w/ LTO, bug 674382 |
260 |
+ sed -i -e 's/^gcc:ltcg/gcc/' src/corelib/global/global.pri || die |
261 |
+ |
262 |
+ eapply "${FILESDIR}/${P}-slibtool.patch" # bug 792804, TODO: merge into _QT5_GENTOOPATCHSET_REV |
263 |
+ |
264 |
+ qt5-build_src_prepare |
265 |
+} |
266 |
+ |
267 |
+src_configure() { |
268 |
+ local myconf=( |
269 |
+ $(qt_use icu) |
270 |
+ $(qt_use !icu iconv) |
271 |
+ $(qt_use systemd journald) |
272 |
+ ) |
273 |
+ use old-kernel && myconf+=( |
274 |
+ -no-feature-renameat2 # needs Linux 3.16, bug 669994 |
275 |
+ -no-feature-getentropy # needs Linux 3.17, bug 669994 |
276 |
+ -no-feature-statx # needs Linux 4.11, bug 672856 |
277 |
+ ) |
278 |
+ qt5-build_src_configure |
279 |
+} |
280 |
+ |
281 |
+src_install() { |
282 |
+ qt5-build_src_install |
283 |
+ qt5_symlink_binary_to_path qmake 5 |
284 |
+ |
285 |
+ local flags=( |
286 |
+ DBUS FREETYPE IMAGEFORMAT_JPEG IMAGEFORMAT_PNG |
287 |
+ OPENGL OPENSSL SSL WIDGETS |
288 |
+ ) |
289 |
+ |
290 |
+ for flag in ${flags[@]}; do |
291 |
+ cat >> "${D}"/${QT5_HEADERDIR}/QtCore/qconfig.h <<- _EOF_ || die |
292 |
+ |
293 |
+ #if defined(QT_NO_${flag}) && defined(QT_${flag}) |
294 |
+ # undef QT_NO_${flag} |
295 |
+ #elif !defined(QT_NO_${flag}) && !defined(QT_${flag}) |
296 |
+ # define QT_NO_${flag} |
297 |
+ #endif |
298 |
+ _EOF_ |
299 |
+ done |
300 |
+} |