diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 2fc3d768981..a37ae3b7a6c 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -5384,7 +5384,9 @@ QObjectPrivate::getPropertyAdaptorSlotObject(const QMetaProperty &property) Q_Q(QObject); const QMetaObject *metaObject = q->metaObject(); int signal_index = methodIndexToSignalIndex(&metaObject, property.notifySignalIndex()); - auto connectionList = conns->connectionsForSignal(signal_index); + if (signal_index >= conns->signalVectorCount()) + return nullptr; + const auto connectionList = conns->connectionsForSignal(signal_index); for (auto c = connectionList.first.loadRelaxed(); c; c = c->nextConnectionList.loadRelaxed()) { if (c->isSlotObject) { diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index 5ac7b5fb518..acbeea47301 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -1711,6 +1711,14 @@ class PropertyAdaptorTester : public QObject Q_PROPERTY(int foo1 READ foo WRITE setFoo) signals: + void dummySignal1(); + void dummySignal2(); + void dummySignal3(); + void dummySignal4(); + void dummySignal5(); + void dummySignal6(); + void dummySignal7(); + void dummySignal8(); void fooChanged(int newFoo); public slots: @@ -1739,9 +1747,11 @@ void tst_QProperty::propertyAdaptorBinding() // Check binding of non BINDABLE property PropertyAdaptorTester object; + // set up a dummy connection (needed to verify that the QBindable avoids an out-of-bounds read) + QObject::connect(&object, &PropertyAdaptorTester::dummySignal1, [](){}); + QBindable binding(&object, "foo"); QObject::connect(&object, &PropertyAdaptorTester::fooChanged, &object, &PropertyAdaptorTester::fooHasChanged); - QBindable binding(&object, "foo"); binding.setBinding([&]() { return source + 1; }); QCOMPARE(object.foo(), 6); QCOMPARE(object.fooChangedCount, 1);