diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-10-08 03:47:17 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-10-08 03:50:01 (GMT) |
commit | c4cbd04275906b1bfa1a55147a0a4bb626033a20 (patch) | |
tree | 0689a5f311bc3f6d7d48300cd6a7859b6a166239 /src | |
parent | 5447a9590dc0efa1a79fde6235fdcf76d3ae81fe (diff) | |
download | Qt-c4cbd04275906b1bfa1a55147a0a4bb626033a20.zip Qt-c4cbd04275906b1bfa1a55147a0a4bb626033a20.tar.gz Qt-c4cbd04275906b1bfa1a55147a0a4bb626033a20.tar.bz2 |
Check plugin and QML file case on Mac and Windows
This test should prevent the case where a QML app that is developed on a
case insensitive filesystem (like on Mac or Windows) and then run on
a case sensitive filesystem (like on Linux) fails to find module plugins,
imports and QML files.
Task-number: QTBUG-13517
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/qml/qdeclarativeengine.cpp | 26 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeglobal_p.h | 13 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativeimport.cpp | 11 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativetypeloader.cpp | 8 |
4 files changed, 57 insertions, 1 deletions
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 584c5ec..0749767 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -2159,4 +2159,30 @@ const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const } } +bool QDeclarative_isFileCaseCorrect(const QString &fileName) +{ +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) + QFileInfo info(fileName); + + QString absolute = info.absoluteFilePath(); + QString canonical = info.canonicalFilePath(); + + int absoluteLength = absolute.length(); + int canonicalLength = canonical.length(); + + int length = qMin(absoluteLength, canonicalLength); + for (int ii = 0; ii < length; ++ii) { + const QChar &a = absolute.at(absoluteLength - 1 - ii); + const QChar &c = canonical.at(canonicalLength - 1 - ii); + + if (a.toLower() != c.toLower()) + return true; + if (a != c) + return false; + } +#endif + + return true; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeglobal_p.h b/src/declarative/qml/qdeclarativeglobal_p.h index 1041992..65d9b24 100644 --- a/src/declarative/qml/qdeclarativeglobal_p.h +++ b/src/declarative/qml/qdeclarativeglobal_p.h @@ -75,6 +75,19 @@ struct QDeclarativeGraphics_DerivedObject : public QObject }; /*! + Returns true if the case of \a fileName is equivalent to the file case of + \a fileName on disk, and false otherwise. + + This is used to ensure that the behavior of QML on a case-insensitive file + system is the same as on a case-sensitive file system. This function + performs a "best effort" attempt to determine the real case of the file. + It may have false positives (say the case is correct when it isn't), but it + should never have a false negative (say the case is incorrect when it is + correct). +*/ +bool QDeclarative_isFileCaseCorrect(const QString &fileName); + +/*! Makes the \a object a child of \a parent. Note that when using this method, neither \a parent nor the object's previous parent (if it had one) will receive ChildRemoved or ChildAdded events. diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index fe4ed48..6f5216a 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -351,7 +351,11 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath { QFile file(absoluteFilePath); QString filecontent; - if (file.open(QFile::ReadOnly)) { + if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath); + return false; + } else if (file.open(QFile::ReadOnly)) { filecontent = QString::fromUtf8(file.readAll()); if (qmlImportTrace()) qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: " @@ -913,6 +917,11 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt } if (!engineInitialized || !typesRegistered) { + if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) { + if (errorString) + *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath); + return false; + } QPluginLoader loader(absoluteFilePath); if (!loader.load()) { diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index 061f309..c8e1a07 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -44,6 +44,7 @@ #include <private/qdeclarativeengine_p.h> #include <private/qdeclarativecompiler_p.h> #include <private/qdeclarativecomponent_p.h> +#include <private/qdeclarativeglobal_p.h> #include <QtDeclarative/qdeclarativecomponent.h> #include <QtCore/qdebug.h> @@ -493,6 +494,13 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob) QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(blob->m_url); if (!lf.isEmpty()) { + if (!QDeclarative_isFileCaseCorrect(lf)) { + QDeclarativeError error; + error.setUrl(blob->m_url); + error.setDescription(QLatin1String("File name case mismatch")); + blob->setError(error); + return; + } QFile file(lf); if (file.open(QFile::ReadOnly)) { QByteArray data = file.readAll(); |