From d7996b7637ae0bbc261c32b4f93dd07e66eeda7a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 29 Nov 2012 17:20:34 +0100 Subject: [PATCH] Limit case-sensitivity check in QML to file names. Provide for checking relative paths only; default to file names. Currently, the checking triggers on a drive letters and installation folder names, which is too strict. Task-number: QTBUG-28277 Change-Id: I1174bb0c485eeb1ffee10bb2a523d6629c57728b Reviewed-by: Kai Koehne --- src/qml/qml/qqmlengine.cpp | 19 +++++++++++++++++-- src/qml/qml/qqmlglobal_p.h | 9 ++++++++- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 9 +++++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 9db8927..2a46cdb 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -2078,7 +2078,7 @@ bool QQmlEnginePrivate::isScriptLoaded(const QUrl &url) const return typeLoader.isScriptLoaded(url); } -bool QQml_isFileCaseCorrect(const QString &fileName) +bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) { #if defined(Q_OS_MAC) || defined(Q_OS_WIN) QFileInfo info(fileName); @@ -2100,7 +2100,21 @@ bool QQml_isFileCaseCorrect(const QString &fileName) const int absoluteLength = absolute.length(); const int canonicalLength = canonical.length(); - const int length = qMin(absoluteLength, canonicalLength); + int length = qMin(absoluteLength, canonicalLength); + if (lengthIn >= 0) { + length = qMin(lengthIn, length); + } else { + // No length given: Limit to file name. Do not trigger + // on drive letters or folder names. + int lastSlash = absolute.lastIndexOf(QLatin1Char('/')); + if (lastSlash < 0) + lastSlash = absolute.lastIndexOf(QLatin1Char('\\')); + if (lastSlash >= 0) { + const int fileNameLength = absoluteLength - 1 - lastSlash; + length = qMin(length, fileNameLength); + } + } + for (int ii = 0; ii < length; ++ii) { const QChar &a = absolute.at(absoluteLength - 1 - ii); const QChar &c = canonical.at(canonicalLength - 1 - ii); @@ -2111,6 +2125,7 @@ bool QQml_isFileCaseCorrect(const QString &fileName) return false; } #else + Q_UNUSED(lengthIn) Q_UNUSED(fileName) #endif return true; diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 037323d..9de7e8f 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -204,8 +204,15 @@ struct QQmlGraphics_DerivedObject : public QObject 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). + + Length specifies specifies the number of characters to be checked from + behind. That is, if a file name results from a relative path specification + like "foo/bar.qml" and is made absolute, the original length (11) should + be passed indicating that only the last part of the relative path should + be checked. + */ -bool QQml_isFileCaseCorrect(const QString &fileName); +bool QQml_isFileCaseCorrect(const QString &fileName, int length = -1); /*! Makes the \a object a child of \a parent. Note that when using this method, diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 138a263..cf6c834 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -2482,15 +2482,16 @@ void tst_qqmllanguage::importIncorrectCase() if (engine.importPathList() == defaultImportPathList) engine.addImportPath(testFile("lib")); - QQmlComponent component(&engine, testFileUrl("importIncorrectCase.qml")); + // Load "importIncorrectCase.qml" using wrong case + QQmlComponent component(&engine, testFileUrl("ImportIncorrectCase.qml")); QList errors = component.errors(); QCOMPARE(errors.count(), 1); -#if defined(Q_OS_MAC) || defined(Q_OS_WIN32) - QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testFile("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\""); +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) + QString expectedError = QLatin1String("File name case mismatch"); #else - QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed"); + QString expectedError = QLatin1String("File not found"); #endif QCOMPARE(errors.at(0).description(), expectedError); -- 1.7.2.5