aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatype.cpp
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-07-25 16:59:17 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-31 00:22:36 +0200
commitc9b7582a2e7ad9fcd03dd999c3b7a16b72803238 (patch)
treed1ffdb193576fef0c243600f46c69b180d2ad2a8 /src/qml/qml/qqmlmetatype.cpp
parent2e6accbbbb9783ff6e5ad171f179d5021b0761af (diff)
Implement strict mode for qmldir modules
Allow a module's qmldir to contain a module directive, which when present specifies 'strict mode' import processing. In strict mode, type registrations are only permitted into the namespace identified in the qmldir file's module directive. In addition, any type registrations to that namespace originating from other modules are treated as error conditions. Task-number: QTBUG-26551 Change-Id: I081bde2d3b83d3f28524440177fb2cd1ccee34ad Reviewed-by: Chris Adams <christopher.adams@nokia.com> Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r--src/qml/qml/qqmlmetatype.cpp74
1 files changed, 71 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index c1147b025b..b3a16b034c 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -108,6 +108,11 @@ struct QQmlMetaTypeData
QBitArray lists;
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
+
+ QSet<QString> protectedNamespaces;
+
+ QString typeRegistrationNamespace;
+ QStringList typeRegistrationFailures;
};
class QQmlTypeModulePrivate
@@ -128,7 +133,7 @@ public:
};
Q_GLOBAL_STATIC(QQmlMetaTypeData, metaTypeData)
-Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
+Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, metaTypeDataLock, (QReadWriteLock::Recursive))
static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
{
@@ -193,7 +198,7 @@ public:
// Avoid multiple fromUtf8(), copies and hashing of the module name.
// This is only called when metaTypeDataLock is locked.
-static QHashedString moduletoUtf8(const char *module)
+static QHashedString moduleFromUtf8(const char *module)
{
if (!module)
return QHashedString();
@@ -241,7 +246,7 @@ QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
QQmlType::QQmlType(int index, const QQmlPrivate::RegisterType &type)
: d(new QQmlTypePrivate)
{
- d->m_module = moduletoUtf8(type.uri);
+ d->m_module = moduleFromUtf8(type.uri);
d->m_elementName = QString::fromUtf8(type.elementName);
d->m_version_maj = type.versionMajor;
@@ -902,6 +907,29 @@ int registerType(const QQmlPrivate::RegisterType &type)
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
+
+ if (type.uri && type.elementName) {
+ QString nameSpace = moduleFromUtf8(type.uri);
+
+ if (!data->typeRegistrationNamespace.isEmpty()) {
+ // We can only install types into the registered namespace
+ if (nameSpace != data->typeRegistrationNamespace) {
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install element '%1' into unregistered namespace '%2'"));
+ data->typeRegistrationFailures.append(failure.arg(QString::fromUtf8(type.elementName)).arg(nameSpace));
+ return -1;
+ }
+ } else if (data->typeRegistrationNamespace != nameSpace) {
+ // Is the target namespace protected against further registrations?
+ if (data->protectedNamespaces.contains(nameSpace)) {
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install element '%1' into protected namespace '%2'"));
+ data->typeRegistrationFailures.append(failure.arg(QString::fromUtf8(type.elementName)).arg(nameSpace));
+ return -1;
+ }
+ }
+ }
+
int index = data->types.count();
QQmlType *dtype = new QQmlType(index, type);
@@ -985,6 +1013,46 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return -1;
}
+bool QQmlMetaType::namespaceContainsRegistrations(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ // Has any type previously been installed to this namespace?
+ QHashedString nameSpace(uri);
+ foreach (const QQmlType *type, data->types)
+ if (type->module() == nameSpace)
+ return true;
+
+ return false;
+}
+
+void QQmlMetaType::protectNamespace(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ data->protectedNamespaces.insert(uri);
+}
+
+void QQmlMetaType::setTypeRegistrationNamespace(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ data->typeRegistrationNamespace = uri;
+ data->typeRegistrationFailures.clear();
+}
+
+QStringList QQmlMetaType::typeRegistrationFailures()
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ return data->typeRegistrationFailures;
+}
+
+QReadWriteLock *QQmlMetaType::typeRegistrationLock()
+{
+ return metaTypeDataLock();
+}
+
/*
Returns true if a module \a uri of any version is installed.
*/