aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmlcppcodegen
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2022-12-12 12:19:36 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2022-12-12 15:33:18 +0100
commitaa4a1e96b8cdc5e6a5ea8e5e1c0406e9f496b92b (patch)
treed4c4af105dae60cfb04bbe2dd53bfb05dc3fc400 /tests/auto/qml/qmlcppcodegen
parentb36864061fb36f2bf8cc30ac0b601f3b3e146c26 (diff)
QQmlJSCodeGenerator: fix nullptr dereference
If we try to lookup the length of a generic QVariant, we fail, and so far crashed. We should ideally detect that we are dealing with an array (and thus length is a known, available property), but for now simply reject compilation to C++. Pick-to: 6.4 Fixes: QTBUG-109164 Change-Id: I9d4149ac09a351754d012dbc829774413d6b32eb Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'tests/auto/qml/qmlcppcodegen')
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/ArraySequenceLengthInterop.qml24
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt2
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.cpp18
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.h29
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp11
5 files changed, 84 insertions, 0 deletions
diff --git a/tests/auto/qml/qmlcppcodegen/data/ArraySequenceLengthInterop.qml b/tests/auto/qml/qmlcppcodegen/data/ArraySequenceLengthInterop.qml
new file mode 100644
index 0000000000..51c9f5fdb1
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/ArraySequenceLengthInterop.qml
@@ -0,0 +1,24 @@
+import QtQml
+import TestTypes
+
+QtObject {
+ property var seq: SequenceTypeExample {
+ id: mySequence
+ }
+
+ property int length: mySequence.qrealListProperty.length
+
+ function goodSequenceWrite() {
+ var someData = [1.1, 2.2, 3.3]
+ someData.length = 100;
+ for (var i = 0; i < 5; ++i) {
+ for (var j = 0; j < 100; ++j) {
+ someData[j] = j;
+ }
+ //Modifies entire sequence at once by copying a temp variable
+ mySequence.qrealListProperty = someData;
+ }
+ }
+
+ Component.onCompleted: goodSequenceWrite()
+}
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index 182c9baac5..2cdbdfbb58 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -13,6 +13,7 @@ set(cpp_sources
multiforeign.h
objectwithmethod.h
person.cpp person.h
+ sequencetypeexample.cpp sequencetypeexample.h
state.h
theme.cpp theme.h
timelinetheme.cpp timelinetheme.h
@@ -21,6 +22,7 @@ set(cpp_sources
set(qml_files
AccessModelMethodsFromOutside.qml
+ ArraySequenceLengthInterop.qml
BadType.qml
BaseMember.qml
BindingExpression.qml
diff --git a/tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.cpp b/tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.cpp
new file mode 100644
index 0000000000..dc74ed9e28
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.cpp
@@ -0,0 +1,18 @@
+#include "sequencetypeexample.h"
+
+SequenceTypeExample::SequenceTypeExample()
+ : QObject()
+{
+ m_list << 1.1 << 2.2 << 3.3;
+}
+
+QList<qreal> SequenceTypeExample::qrealListProperty() const
+{
+ return m_list;
+}
+
+void SequenceTypeExample::setQrealListProperty(const QList<qreal> &list)
+{
+ m_list = list;
+ emit qrealListPropertyChanged();
+}
diff --git a/tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.h b/tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.h
new file mode 100644
index 0000000000..e15306667d
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/sequencetypeexample.h
@@ -0,0 +1,29 @@
+#ifndef SEQENCETYPEEXAMPLE_H
+#define SEQENCETYPEEXAMPLE_H
+
+#include <QDebug>
+#include <QObject>
+#include <QtQml>
+
+class SequenceTypeExample : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY (QList<qreal> qrealListProperty READ qrealListProperty WRITE setQrealListProperty
+ NOTIFY qrealListPropertyChanged)
+
+public:
+ explicit SequenceTypeExample();
+
+ QList<qreal> qrealListProperty() const;
+ void setQrealListProperty(const QList<qreal> &list);
+
+signals:
+ void qrealListPropertyChanged();
+
+private :
+ QList<qreal> m_list;
+
+};
+
+#endif // SEQENCETYPEEXAMPLE_H
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index 2cbf2bc747..a275fff918 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -154,6 +154,7 @@ private slots:
void enumConversion();
void ambiguousSignals();
void fileImportsContainCxxTypes();
+ void lengthAccessArraySequenceCompat();
};
void tst_QmlCppCodegen::initTestCase()
@@ -2944,6 +2945,16 @@ void tst_QmlCppCodegen::fileImportsContainCxxTypes()
QCOMPARE(o->objectName(), u"horst guenther"_s);
}
+void tst_QmlCppCodegen::lengthAccessArraySequenceCompat()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/ArraySequenceLengthInterop.qml"_s));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+ QCOMPARE(o->property("length").toInt(), 100);
+}
+
QTEST_MAIN(tst_QmlCppCodegen)
#include "tst_qmlcppcodegen.moc"