Fix UB in QLayout::childEvent
We can't just static_cast a child to QLayout, because the child might not be a QLayout, and even if it was, we might be called from the QObject destructor so we would not be a layout anymore. Instead we can just qobject_cast the deleted object to a QLayout and remove it from the layout with removeItem. This would not take in account the case where we would be called because the QLayout gets destroyed, so we handle this case from ~QLayout by removing ourself from the parent. Note that the comment in ~QLayout was wrong, as the layout gets destroyed explicitly from ~QWidget, not from ~QObject. Change-Id: I49c6f17a76f207b9d750b6e5d987469498b96b31 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
parent
f368cd8868
commit
cdb7e81572
@ -641,21 +641,11 @@ void QLayout::childEvent(QChildEvent *e)
|
||||
if (!d->enabled)
|
||||
return;
|
||||
|
||||
if (e->type() == QEvent::ChildRemoved) {
|
||||
QChildEvent *c = (QChildEvent*)e;
|
||||
int i = 0;
|
||||
if (e->type() != QEvent::ChildRemoved)
|
||||
return;
|
||||
|
||||
QLayoutItem *item;
|
||||
while ((item = itemAt(i))) {
|
||||
if (item == static_cast<QLayout*>(c->child())) {
|
||||
takeAt(i);
|
||||
invalidate();
|
||||
break;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (QLayout *childLayout = qobject_cast<QLayout *>(e->child()))
|
||||
removeItem(childLayout);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -766,13 +756,10 @@ QSize QLayout::totalMaximumSize() const
|
||||
QLayout::~QLayout()
|
||||
{
|
||||
Q_D(QLayout);
|
||||
/*
|
||||
This function may be called during the QObject destructor,
|
||||
when the parent no longer is a QWidget.
|
||||
*/
|
||||
if (d->topLevel && parent() && parent()->isWidgetType() &&
|
||||
((QWidget*)parent())->layout() == this)
|
||||
((QWidget*)parent())->d_func()->layout = 0;
|
||||
if (d->topLevel && parent() && parent()->isWidgetType() && parentWidget()->layout() == this)
|
||||
parentWidget()->d_func()->layout = 0;
|
||||
else if (QLayout *parentLayout = qobject_cast<QLayout *>(parent()))
|
||||
parentLayout->removeItem(this);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user