diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2021-04-23 12:16:26 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2021-04-26 11:46:09 +0200 |
commit | 16d946701d7fc38fce264ffdb4d5443ffcb50514 (patch) | |
tree | 98e663f754bf2cd76fd4c1f2580a59d2b1e8d517 | |
parent | 470abc3566ead79a5c0b14b3dea4b40418cc1029 (diff) |
ScrollView: fix crash when scrolling with zero-sized item
Check if a Flickable type was actually set as the contentItem before
accessing the pointer. Also warn that using a type other than Flickable
is not supported.
Fixes: QTBUG-93039
Change-Id: I1470766c6de02b7b601edf1375791d3147f26ab5
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit e7df2279bf5519703fd0b853abaa23947a599920)
-rw-r--r-- | src/quicktemplates2/qquickscrollbar.cpp | 6 | ||||
-rw-r--r-- | src/quicktemplates2/qquickscrollview.cpp | 6 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_scrollview.qml | 24 |
3 files changed, 35 insertions, 1 deletions
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp index fdbd4b31..1ac4b42d 100644 --- a/src/quicktemplates2/qquickscrollbar.cpp +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -869,6 +869,9 @@ class QQuickFriendlyFlickable : public QQuickFlickable void QQuickScrollBarAttachedPrivate::scrollHorizontal() { + if (!flickable) + return; + QQuickFriendlyFlickable *f = reinterpret_cast<QQuickFriendlyFlickable *>(flickable); const qreal viewwidth = f->width(); @@ -881,6 +884,9 @@ void QQuickScrollBarAttachedPrivate::scrollHorizontal() void QQuickScrollBarAttachedPrivate::scrollVertical() { + if (!flickable) + return; + QQuickFriendlyFlickable *f = reinterpret_cast<QQuickFriendlyFlickable *>(flickable); const qreal viewheight = f->height(); diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp index 387c30a5..0c9d8f3e 100644 --- a/src/quicktemplates2/qquickscrollview.cpp +++ b/src/quicktemplates2/qquickscrollview.cpp @@ -38,6 +38,7 @@ #include "qquickpane_p_p.h" #include "qquickscrollbar_p_p.h" +#include <QtQml/qqmlinfo.h> #include <QtQuick/private/qquickflickable_p.h> QT_BEGIN_NAMESPACE @@ -575,7 +576,10 @@ void QQuickScrollView::contentItemChange(QQuickItem *newItem, QQuickItem *oldIte // assume/require that it has an explicit content size assigned. d->flickableHasExplicitContentWidth = true; d->flickableHasExplicitContentHeight = true; - d->setFlickable(qobject_cast<QQuickFlickable *>(newItem), false); + auto newItemAsFlickable = qobject_cast<QQuickFlickable *>(newItem); + if (newItem && !newItemAsFlickable) + qmlWarning(this) << "ScrollView only supports Flickable types as its contentItem"; + d->setFlickable(newItemAsFlickable, false); } QQuickPane::contentItemChange(newItem, oldItem); } diff --git a/tests/auto/controls/data/tst_scrollview.qml b/tests/auto/controls/data/tst_scrollview.qml index 87c39509..453f7753 100644 --- a/tests/auto/controls/data/tst_scrollview.qml +++ b/tests/auto/controls/data/tst_scrollview.qml @@ -502,4 +502,28 @@ TestCase { compare(control.contentWidth, flickable.contentWidth) compare(control.contentHeight, flickable.contentHeight) } + + Component { + id: zeroSizedContentItemComponent + ScrollView { + width: 100 + height: 100 + contentItem: Item {} + } + } + + function test_zeroSizedContentItem() { + ignoreWarning(/ScrollView only supports Flickable types as its contentItem/) + let control = createTemporaryObject(zeroSizedContentItemComponent, testCase) + verify(control) + + let verticalScrollBar = control.ScrollBar.vertical + verify(verticalScrollBar) + // Scrolling a ScrollView with a zero-sized contentItem shouldn't crash. + mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50) + + let horizontalScrollBar = control.ScrollBar.horizontal + verify(verticalScrollBar) + mouseDrag(horizontalScrollBar, horizontalScrollBar.width / 2, horizontalScrollBar.height / 2, 50, 0) + } } |