Details
-
Bug
-
Resolution: Done
-
Not Evaluated
-
None
-
4.8.6, 4.8.7
-
None
-
Tested on OS X 10.6.8 and 10.9.4 with Qt 4.8.6
Description
QWidgetPrivate::setGeometry_sys_helper() assumes it is always called with a parented widget, and it turns out this assumption isn't always true. The symptom is an immediate crash on OS X when attempting to open a menu in the global menubar containing items that respond to certain criteria.
Every application running unpatched Qt4 and KDE libs 4.14.1 and earlier can provoke this bug simply by using `KMenu::addTitle` to add a distinctive "title" menu item to a menu that will be attached to the global menubar.
This function contains pure Qt4 code, and it should therefore be possible to reproduce the crash on OS X without having KDE installed:
class KMenu : public QMenu;
QAction* KMenu::addTitle(const QIcon &icon, const QString &text, QAction* before)
{
QAction *buttonAction = new QAction(this);
QFont font = buttonAction->font();
font.setBold(true);
buttonAction->setFont(font);
buttonAction->setText(text);
buttonAction->setIcon(icon);
QWidgetAction *action = new QWidgetAction(this);
action->setObjectName(KMENU_TITLE);
QToolButton *titleButton = new QToolButton(this);
titleButton->installEventFilter(d); // prevent clicks on the title of the menu
titleButton->setDefaultAction(buttonAction);
titleButton->setDown(true); // prevent hover style changes in some styles
titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
action->setDefaultWidget(titleButton);
insertAction(before, action);
return action;
}
The crash occurs during the call to insertAction() (= QMenu::insertAction()).
Discussion about this bug on KDE's reviewboard:
https://git.reviewboard.kde.org/r/120355/
The attached patch has been conceived with feedback from the above review request, and simply introduces a check on q->parentWidget() in the offending function, setGeometry_sys_helper().
The patch goes one step further: isResize is set to False when there is no parentWidget and a resize operation could thus not be prepared by invalidating a buffer.
Is this an unnecessary or possibly even unwanted step?