summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2022-03-01 11:25:11 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-03-02 09:43:59 +0000
commita663b0d63ec3a0d27c7da4a34ba27cf9e943e015 (patch)
tree18386800b4106ea6867cc086fd46548785942902
parent7eb6e388da20235116157fd713e3826df622160c (diff)
QMetaObjectBuilder: Always set Data::metatypes
The array of metatypes should always contain at least one entry (for the metatype of the current metaobject itself). This prevents crashes in the case of a metaobject without meta-methods and properties (as observed in Qt for Python). Change-Id: I7a6fb316eea48c4852b6f1c26e0a930aeba4c799 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit ef0e13257ddd57c967000213e3c9812b3c08da91) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp52
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp12
2 files changed, 37 insertions, 27 deletions
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 4f762b5e96..931dcfe2fd 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -1439,41 +1439,39 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
}
- if (d->properties.size() > 0 || d->methods.size() > 0 || d->constructors.size() > 0) {
- ALIGN(size, QtPrivate::QMetaTypeInterface *);
- auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size);
- if constexpr (mode == Construct) {
- meta->d.metaTypes = types;
- for (const auto &prop : d->properties) {
- QMetaType mt = prop.metaType;
+ ALIGN(size, QtPrivate::QMetaTypeInterface *);
+ auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size);
+ if constexpr (mode == Construct) {
+ meta->d.metaTypes = types;
+ for (const auto &prop : d->properties) {
+ QMetaType mt = prop.metaType;
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ }
+ // add metatype interface for this metaobject - must be null
+ // as we can't know our metatype
+ *types = nullptr;
+ types++;
+ for (const auto &method: d->methods) {
+ QMetaType mt(QMetaType::fromName(method.returnType).id());
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ for (const auto &parameterType: method.parameterTypes()) {
+ QMetaType mt = QMetaType::fromName(parameterType);
*types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
types++;
}
- // add metatype interface for this metaobject - must be null
- // as we can't know our metatype
- *types = nullptr;
- types++;
- for (const auto &method: d->methods) {
- QMetaType mt(QMetaType::fromName(method.returnType).id());
+ }
+ for (const auto &constructor : d->constructors) {
+ for (const auto &parameterType : constructor.parameterTypes()) {
+ QMetaType mt = QMetaType::fromName(parameterType);
*types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
types++;
- for (const auto &parameterType: method.parameterTypes()) {
- QMetaType mt = QMetaType::fromName(parameterType);
- *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
- types++;
- }
- }
- for (const auto &constructor : d->constructors) {
- for (const auto &parameterType : constructor.parameterTypes()) {
- QMetaType mt = QMetaType::fromName(parameterType);
- *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
- types++;
- }
}
}
- // parameterMetaTypesIndex is equal to the total number of metatypes
- size += sizeof(QMetaType) * parameterMetaTypesIndex;
}
+ // parameterMetaTypesIndex is equal to the total number of metatypes
+ size += sizeof(QMetaType) * parameterMetaTypesIndex;
// Align the final size and return it.
ALIGN(size, void *);
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 50b49adc34..324efa4787 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -67,6 +67,8 @@ private slots:
void cleanupTestCase();
+ void ownMetaTypeNoProperties();
+
private:
static bool checkForSideEffects
(const QMetaObjectBuilder& builder,
@@ -1660,6 +1662,16 @@ void tst_QMetaObjectBuilder::propertyMetaType()
free(mo);
}
+void tst_QMetaObjectBuilder::ownMetaTypeNoProperties()
+{
+ QMetaObjectBuilder builder;
+ builder.setClassName("NoProperties");
+ auto mo = builder.toMetaObject();
+ auto cleanup = qScopeGuard([&](){ free(mo); });
+ // own metatype should be invalid, as the dynamic metaobject has not been registered
+ QVERIFY(!mo->metaType().isValid());// should not crash
+}
+
void tst_QMetaObjectBuilder::cleanupTestCase()
{
for (QMetaObject *obj: dynamicMetaObjectsPendingFree)