Fix UB in QSplitter::childEvent

The widget might be in the QObject destructor when the event is received,
so we can't static cast.
There is no need to check for isWindow for ChildRemoved because it would
not otherwise be on our list.

Change-Id: Ifc0a2979f1f6720f1963399276a28ac4a3224fff
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
Olivier Goffart 2017-04-19 11:16:14 +02:00 committed by Olivier Goffart (Woboq GmbH)
parent 88b6abcebf
commit 2eee24702b

View File

@ -1298,18 +1298,19 @@ void QSplitter::childEvent(QChildEvent *c)
qWarning("Adding a QLayout to a QSplitter is not supported.");
return;
}
QWidget *w = static_cast<QWidget*>(c->child());
if (w->isWindow())
return;
if (c->added() && !d->blockChildAdd && !d->findWidget(w)) {
d->insertWidget_helper(d->list.count(), w, false);
} else if (c->polished() && !d->blockChildAdd) {
if (d->shouldShowWidget(w))
if (c->added()) {
QWidget *w = static_cast<QWidget*>(c->child());
if (!d->blockChildAdd && !w->isWindow() && !d->findWidget(w))
d->insertWidget_helper(d->list.count(), w, false);
} else if (c->polished()) {
QWidget *w = static_cast<QWidget*>(c->child());
if (!d->blockChildAdd && !w->isWindow() && d->shouldShowWidget(w))
w->show();
} else if (c->type() == QEvent::ChildRemoved) {
} else if (c->removed()) {
QObject *child = c->child();
for (int i = 0; i < d->list.size(); ++i) {
QSplitterLayoutStruct *s = d->list.at(i);
if (s->widget == w) {
if (s->widget == child) {
d->list.removeAt(i);
delete s;
d->recalc(isVisible());