diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-03-01 11:25:11 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-03-02 09:43:59 +0000 |
commit | a663b0d63ec3a0d27c7da4a34ba27cf9e943e015 (patch) | |
tree | 18386800b4106ea6867cc086fd46548785942902 | |
parent | 7eb6e388da20235116157fd713e3826df622160c (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.cpp | 52 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 12 |
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 ¶meterType: 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 ¶meterType : constructor.parameterTypes()) { + QMetaType mt = QMetaType::fromName(parameterType); *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); types++; - for (const auto ¶meterType: method.parameterTypes()) { - QMetaType mt = QMetaType::fromName(parameterType); - *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); - types++; - } - } - for (const auto &constructor : d->constructors) { - for (const auto ¶meterType : 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) |