diff options
author | Marc Mutz <[email protected]> | 2025-03-22 18:26:46 +0100 |
---|---|---|
committer | Marc Mutz <[email protected]> | 2025-03-25 06:33:52 +0100 |
commit | 41480dbd4abadf13c26e487ae23ce681866b6af3 (patch) | |
tree | 4cac970b25f25de2750938d45cff023b9f6ab768 | |
parent | 0be1ca029cc21e72d9f5408dea99722fba9bc321 (diff) |
QFontDialog: fix UB (invalid cast) in Private::setVisible()
The function can be called from ~QDialog(), in which case a cast of
q_ptr to QFontDialog is UB.
Says UBSan:
qfontdialog_p.h:43:5: runtime error: downcast of address 0x604000026b90 which does not point to an object of type 'QFontDialog'
0x604000026b90: note: object is of type 'QDialog'
00 00 00 00 30 a4 26 31 45 7f 00 00 80 b9 00 00 90 61 00 00 08 a6 26 31 45 7f 00 00 00 00 be be
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QDialog'
#0 0x7f452ecad24d in QFontDialogPrivate::q_func() qfontdialog_p.h:43
#1 0x7f452ecad24d in QFontDialogPrivate::setVisible(bool) qfontdialog.cpp:959
#2 0x7f452ea2b5f5 in QDialog::setVisible(bool) qdialog.cpp:757
#3 0x7f452c26d768 in QWidget::hide() qwidget.cpp:8179
#4 0x7f452ea2ae09 in QDialog::~QDialog() qdialog.cpp:398
Fix by casting at most to QDialog* (QWidget* would actually have
sufficed).
Add a code comment.
Amends e0bb9e81ab1a9d71f2893844ea82430467422e21 (I think; it might
have been present in a different form before that).
Pick-to: 6.9 6.8 6.5
Change-Id: Ic1a63ff02b1a1435499a6980772b1b75236f31f7
Reviewed-by: Volker Hilsheimer <[email protected]>
-rw-r--r-- | src/widgets/dialogs/qfontdialog.cpp | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index ee918992df5..24b91a873dd 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -956,7 +956,9 @@ void QFontDialog::setVisible(bool visible) */ void QFontDialogPrivate::setVisible(bool visible) { - Q_Q(QFontDialog); + // Don't use Q_Q here! This function is called from ~QDialog, + // so Q_Q calling q_func() invokes undefined behavior (invalid cast in q_func()). + const auto q = static_cast<QDialog *>(q_ptr); if (canBeNativeDialog()) setNativeDialogVisible(visible); |