diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-01-12 16:25:31 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-01-13 14:38:16 +0100 |
commit | c3a5fe2fd7a1b8a6b6133c938ffe6b3f30181bf0 (patch) | |
tree | d02d98633c4ce910a8653c6a4aefbe6a719e292a /src | |
parent | 4e4cd7416af3f84e6a7c7dee03a2e50864e9cacc (diff) |
QFormLayout: don't access out-of-bounds layout data
When rows are hidden (implicitly or explicitly), then their layout data
does not get fully updated. If rows get hidden after the layout data has
been calculated once, then we must make sure that their indices are
reset. Otherwise we might access array indices that are out of bounds
when the layout data structure gets resized to fit only visible rows.
For good measure, skip entirely over hidden rows when accessing the
layout data when arranging the widget.
Fixes: QTBUG-109237
Pick-to: 6.5 6.4
Change-Id: I4d6943b6a110edb61f60ce78d31f0fc64b5cc03d
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/kernel/qformlayout.cpp | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index e924c71997..991b1429d7 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -480,6 +480,7 @@ void QFormLayoutPrivate::recalcHFW(int w) void QFormLayoutPrivate::setupHfwLayoutData() { + Q_Q(QFormLayout); // setupVerticalLayoutData must be called before this // setupHorizontalLayoutData must also be called before this // copies non hfw data into hfw @@ -504,6 +505,10 @@ void QFormLayoutPrivate::setupHfwLayoutData() QFormLayoutItem *label = m_matrix(i, 0); QFormLayoutItem *field = m_matrix(i, 1); + // ignore rows with only hidden items + if (!q->isRowVisible(i)) + continue; + if (label && label->vLayoutIndex > -1) { if (label->isHfw) { // We don't check sideBySide here, since a label is only @@ -681,9 +686,15 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) QFormLayoutItem *label = m_matrix(i, 0); QFormLayoutItem *field = m_matrix(i, 1); - // Totally ignore empty rows or rows with only hidden items - if (!q->isRowVisible(i)) + // Ignore empty rows or rows with only hidden items, + // and invalidate their position in the layout. + if (!q->isRowVisible(i)) { + if (label) + label->vLayoutIndex = -1; + if (field) + field->vLayoutIndex = -1; continue; + } QSize min1; QSize min2; @@ -2190,6 +2201,9 @@ void QFormLayoutPrivate::arrangeWidgets(const QList<QLayoutStruct> &layouts, QRe QFormLayoutItem *label = m_matrix(i, 0); QFormLayoutItem *field = m_matrix(i, 1); + if (!q->isRowVisible(i)) + continue; + if (label && label->vLayoutIndex > -1) { int height = layouts.at(label->vLayoutIndex).size; if ((label->expandingDirections() & Qt::Vertical) == 0) { |