Skip to content

Only delete last commands in the undostack if the new command in not obsolete#32

Closed
rolivav wants to merge 1 commit intoqt:devfrom
rolivav:patch-1
Closed

Only delete last commands in the undostack if the new command in not obsolete#32
rolivav wants to merge 1 commit intoqt:devfrom
rolivav:patch-1

Conversation

@rolivav
Copy link

@rolivav rolivav commented Nov 27, 2019

No description provided.

@rolivav
Copy link
Author

rolivav commented Nov 27, 2019

Will need to do it through gerrit someday!

@rolivav rolivav closed this Nov 27, 2019
@rolivav rolivav deleted the patch-1 branch November 27, 2019 16:34
qtprojectorg pushed a commit that referenced this pull request Apr 4, 2025
…howAndHide()

The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.

Says UBSan:

  qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
  0x7fffefab47e0: note: object is of type 'QWidget'
   00 00 00 00  28 c1 5b 6e 6d 7f 00 00  80 22 10 00 90 61 00 00  d8 c2 5b 6e 6d 7f 00 00  00 00 00 00
                ^~~~~~~~~~~~~~~~~~~~~~~
                vptr for 'QWidget'
     #0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
     #1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
     #2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
     #3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
     #4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
     #5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
     #6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
     #7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
     #8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
     #9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
     #10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
     #11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
     #12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
     #13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
     #14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
     #15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
     #16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
     #17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
     #18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
     #19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
     #20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
     #21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
     #22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
     #23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
     #24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
     #25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
     #26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
     #27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
     #28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
     #29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
     #30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
     #31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
     #32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
     #33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496

To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.

Amends aff0915. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.

Pick-to: 6.9 6.8 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
qtprojectorg pushed a commit that referenced this pull request Apr 12, 2025
…howAndHide()

The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.

Says UBSan:

  qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
  0x7fffefab47e0: note: object is of type 'QWidget'
   00 00 00 00  28 c1 5b 6e 6d 7f 00 00  80 22 10 00 90 61 00 00  d8 c2 5b 6e 6d 7f 00 00  00 00 00 00
                ^~~~~~~~~~~~~~~~~~~~~~~
                vptr for 'QWidget'
     #0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
     #1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
     #2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
     #3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
     #4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
     #5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
     #6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
     #7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
     #8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
     #9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
     #10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
     #11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
     #12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
     #13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
     #14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
     #15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
     #16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
     #17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
     #18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
     #19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
     #20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
     #21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
     #22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
     #23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
     #24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
     #25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
     #26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
     #27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
     #28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
     #29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
     #30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
     #31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
     #32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
     #33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496

To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.

Amends aff0915. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.

Pick-to: 6.8 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit dceff0a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
qtprojectorg pushed a commit that referenced this pull request Apr 12, 2025
…howAndHide()

The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.

Says UBSan:

  qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
  0x7fffefab47e0: note: object is of type 'QWidget'
   00 00 00 00  28 c1 5b 6e 6d 7f 00 00  80 22 10 00 90 61 00 00  d8 c2 5b 6e 6d 7f 00 00  00 00 00 00
                ^~~~~~~~~~~~~~~~~~~~~~~
                vptr for 'QWidget'
     #0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
     #1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
     #2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
     #3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
     #4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
     #5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
     #6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
     #7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
     #8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
     #9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
     #10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
     #11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
     #12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
     #13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
     #14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
     #15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
     #16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
     #17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
     #18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
     #19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
     #20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
     #21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
     #22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
     #23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
     #24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
     #25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
     #26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
     #27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
     #28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
     #29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
     #30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
     #31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
     #32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
     #33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496

To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.

Amends aff0915. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.

Pick-to: 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit dceff0a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 6753ab4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant