From e38ad9455099a83e2a8619f19ca949bc64ae6f82 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 28 Mar 2014 15:55:31 +0100 Subject: Fix crash when trying to place toolbar into zero-height window. Change QToolBarAreaLayout::item() to return a pointer and check return values in plug(). Task-number: QTBUG-37183 Change-Id: I7029eb9739cbe603460e87d3e5493f116bdb3a89 Reviewed-by: J-P Nurmi --- src/widgets/widgets/qmainwindowlayout.cpp | 12 ++++++---- src/widgets/widgets/qtoolbararealayout.cpp | 38 ++++++++++++++++++------------ src/widgets/widgets/qtoolbararealayout_p.h | 2 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 92a1274d7c..c026b79103 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -508,8 +508,11 @@ QLayoutItem *QMainWindowLayoutState::item(const QList &path) int i = path.first(); #ifndef QT_NO_TOOLBAR - if (i == 0) - return toolBarAreaLayout.item(path.mid(1)).widgetItem; + if (i == 0) { + const QToolBarAreaLayoutItem *tbItem = toolBarAreaLayout.item(path.mid(1)); + Q_ASSERT(tbItem); + return tbItem->widgetItem; + } #endif #ifndef QT_NO_DOCKWIDGET @@ -1567,9 +1570,10 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) QList previousPath = layoutState.indexOf(widget); - QLayoutItem *it = layoutState.plug(currentGapPos); + const QLayoutItem *it = layoutState.plug(currentGapPos); + if (!it) + return false; Q_ASSERT(it == widgetItem); - Q_UNUSED(it); if (!previousPath.isEmpty()) layoutState.remove(previousPath); diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp index 5ec76569aa..4591c2ac5f 100644 --- a/src/widgets/widgets/qtoolbararealayout.cpp +++ b/src/widgets/widgets/qtoolbararealayout.cpp @@ -1107,16 +1107,19 @@ void QToolBarAreaLayout::clear() rect = QRect(); } -QToolBarAreaLayoutItem &QToolBarAreaLayout::item(const QList &path) +QToolBarAreaLayoutItem *QToolBarAreaLayout::item(const QList &path) { Q_ASSERT(path.count() == 3); - Q_ASSERT(path.at(0) >= 0 && path.at(0) < QInternal::DockCount); + if (path.at(0) < 0 || path.at(0) >= QInternal::DockCount) + return 0; QToolBarAreaLayoutInfo &info = docks[path.at(0)]; - Q_ASSERT(path.at(1) >= 0 && path.at(1) < info.lines.count()); + if (path.at(1) < 0 || path.at(1) >= info.lines.count()) + return 0; QToolBarAreaLayoutLine &line = info.lines[path.at(1)]; - Q_ASSERT(path.at(2) >= 0 && path.at(2) < line.toolBarItems.count()); - return line.toolBarItems[path.at(2)]; + if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.count()) + return 0; + return &(line.toolBarItems[path.at(2)]); } QRect QToolBarAreaLayout::itemRect(const QList &path) const @@ -1132,23 +1135,28 @@ QRect QToolBarAreaLayout::itemRect(const QList &path) const QLayoutItem *QToolBarAreaLayout::plug(const QList &path) { - QToolBarAreaLayoutItem &item = this->item(path); - Q_ASSERT(item.gap); - Q_ASSERT(item.widgetItem != 0); - item.gap = false; - return item.widgetItem; + QToolBarAreaLayoutItem *item = this->item(path); + if (!item) { + qWarning() << Q_FUNC_INFO << "No item at" << path; + return 0; + } + Q_ASSERT(item->gap); + Q_ASSERT(item->widgetItem != 0); + item->gap = false; + return item->widgetItem; } QLayoutItem *QToolBarAreaLayout::unplug(const QList &path, QToolBarAreaLayout *other) { //other needs to be update as well Q_ASSERT(path.count() == 3); - QToolBarAreaLayoutItem &item = this->item(path); + QToolBarAreaLayoutItem *item = this->item(path); + Q_ASSERT(item); //update the leading space here QToolBarAreaLayoutInfo &info = docks[path.at(0)]; QToolBarAreaLayoutLine &line = info.lines[path.at(1)]; - if (item.size != pick(line.o, item.realSizeHint())) { + if (item->size != pick(line.o, item->realSizeHint())) { //the item doesn't have its default size //so we'll give this to the next item int newExtraSpace = 0; @@ -1185,9 +1193,9 @@ QLayoutItem *QToolBarAreaLayout::unplug(const QList &path, QToolBarAreaLayo } } - Q_ASSERT(!item.gap); - item.gap = true; - return item.widgetItem; + Q_ASSERT(!item->gap); + item->gap = true; + return item->widgetItem; } static QRect unpackRect(uint geom0, uint geom1, bool *floating) diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h index ec7d1f26f1..6ba9768467 100644 --- a/src/widgets/widgets/qtoolbararealayout_p.h +++ b/src/widgets/widgets/qtoolbararealayout_p.h @@ -232,7 +232,7 @@ public: void remove(const QList &path); void remove(QLayoutItem *item); void clear(); - QToolBarAreaLayoutItem &item(const QList &path); + QToolBarAreaLayoutItem *item(const QList &path); QRect itemRect(const QList &path) const; QLayoutItem *plug(const QList &path); QLayoutItem *unplug(const QList &path, QToolBarAreaLayout *other); -- cgit v1.2.3