aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/basics.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp9
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp8
4 files changed, 21 insertions, 0 deletions
diff --git a/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc b/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc
index 1b645a94c0..9eb8f72cf2 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc
@@ -38,6 +38,8 @@ imperative code, in the case where complex custom application behavior is needed
QML source code is generally loaded by the engine through QML \e documents, which are
standalone documents of QML code. These can be used to define \l {QML Object Types}{QML object types} that can then be reused throughout an application.
+Note that type names must begin with an uppercase letter in order
+to be declared as QML object types in a QML file.
\section1 Import Statements
diff --git a/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc
index b74646b7d0..5f089b5ebc 100644
--- a/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc
@@ -45,6 +45,8 @@ type, as discussed in \l {qtqml-documents-definetypes.html}
{Documents as QML object type definitions}, or by defining a QML type from C++
and registering the type with the QML engine, as discussed in
\l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}.
+Note that in both cases, the type name must begin with an uppercase letter in
+order to be declared as a QML object type in a QML file.
\section1 Defining Object Types from QML
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 3a0d5c3daf..89f3ced2d6 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1405,6 +1405,12 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName, int majorVersion = -1)
{
if (!typeName.isEmpty()) {
+ if (typeName.at(0).isLower()) {
+ QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
+ data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName));
+ return false;
+ }
+
int typeNameLen = typeName.length();
for (int ii = 0; ii < typeNameLen; ++ii) {
if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == '_')) {
@@ -1650,6 +1656,9 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
else
return -1;
+ if (!dtype.isValid())
+ return -1;
+
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *typeData = metaTypeData();
typeData->undeletableTypes.insert(dtype);
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 803bf0c468..83151fb6e2 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -271,6 +271,8 @@ private slots:
void accessDeletedObject();
+ void lowercaseTypeNames();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -4596,6 +4598,12 @@ void tst_qqmllanguage::accessDeletedObject()
QVERIFY(!o.isNull());
}
+void tst_qqmllanguage::lowercaseTypeNames()
+{
+ QCOMPARE(qmlRegisterType<QObject>("Test", 1, 0, "lowerCaseTypeName"), -1);
+ QCOMPARE(qmlRegisterSingletonType<QObject>("Test", 1, 0, "lowerCaseTypeName", nullptr), -1);
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"