Use a more robust test for absolute paths in QDir
Its filePath() and absoluteFilePath() don't trust its own
isAbsolute(), due to some infelicities on MS-Win; and kludged round a
consequent problem with resource paths; but other virtual file systems
weren't catered for. Replace the convoluted test there with a static
bool function (so that future kludges in this area shall only need to
edit one place; and can document why they're needed) and use a more
robust test that handles all virtual file systems (by asking
QFileInfo) but falls back to QFileSystemEntry to work round the known
infelicities on MS-Win. Add regression test for asset library paths
issue on iOS. Ammends 27f1f84c1c
.
Moved a couple of local variables to after the early return, since it
doesn't need them, in the process.
Task-number: QTBUG-70237
Change-Id: Ib3954826df40ccf816beebe5c3751497e3bf6433
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
parent
69bd238ad8
commit
dd5e7f1a52
@ -748,6 +748,21 @@ static int drivePrefixLength(const QString &path)
|
|||||||
}
|
}
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
|
static bool treatAsAbsolute(const QString &path)
|
||||||
|
{
|
||||||
|
// ### Qt 6: be consistent about absolute paths
|
||||||
|
|
||||||
|
// QFileInfo will use the right FS-engine for virtual file-systems
|
||||||
|
// (e.g. resource paths). Unfortunately, for real file-systems, it relies
|
||||||
|
// on QFileSystemEntry's isRelative(), which is flawed on MS-Win, ignoring
|
||||||
|
// its (correct) isAbsolute(). So only use that isAbsolute() unless there's
|
||||||
|
// a colon in the path.
|
||||||
|
// FIXME: relies on virtual file-systems having colons in their prefixes.
|
||||||
|
// The case of an MS-absolute C:/... path happens to work either way.
|
||||||
|
return (path.contains(QLatin1Char(':')) && QFileInfo(path).isAbsolute())
|
||||||
|
|| QFileSystemEntry(path).isAbsolute();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the path name of a file in the directory. Does \e not
|
Returns the path name of a file in the directory. Does \e not
|
||||||
check if the file actually exists in the directory; but see
|
check if the file actually exists in the directory; but see
|
||||||
@ -759,13 +774,10 @@ static int drivePrefixLength(const QString &path)
|
|||||||
*/
|
*/
|
||||||
QString QDir::filePath(const QString &fileName) const
|
QString QDir::filePath(const QString &fileName) const
|
||||||
{
|
{
|
||||||
const QDirPrivate* d = d_ptr.constData();
|
if (treatAsAbsolute(fileName))
|
||||||
// Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive.
|
|
||||||
if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path
|
|
||||||
? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) {
|
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
|
||||||
|
|
||||||
|
const QDirPrivate* d = d_ptr.constData();
|
||||||
QString ret = d->dirEntry.filePath();
|
QString ret = d->dirEntry.filePath();
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
return ret;
|
return ret;
|
||||||
@ -793,13 +805,10 @@ QString QDir::filePath(const QString &fileName) const
|
|||||||
*/
|
*/
|
||||||
QString QDir::absoluteFilePath(const QString &fileName) const
|
QString QDir::absoluteFilePath(const QString &fileName) const
|
||||||
{
|
{
|
||||||
const QDirPrivate* d = d_ptr.constData();
|
if (treatAsAbsolute(fileName))
|
||||||
// Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive.
|
|
||||||
if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path
|
|
||||||
? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) {
|
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
|
||||||
|
|
||||||
|
const QDirPrivate* d = d_ptr.constData();
|
||||||
d->resolveAbsoluteEntry();
|
d->resolveAbsoluteEntry();
|
||||||
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
|
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
|
41
tests/auto/corelib/io/qdir/Info.plist
Normal file
41
tests/auto/corelib/io/qdir/Info.plist
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>Created by Qt/QMake</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${QMAKE_SHORT_VERSION}</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>${QMAKE_PKGINFO_TYPEINFO}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${QMAKE_FULL_VERSION}</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>${IPHONEOS_DEPLOYMENT_TARGET}</string>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Enables use of assets file engine</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -3,6 +3,7 @@ TARGET = tst_qdir
|
|||||||
QT = core core-private testlib
|
QT = core core-private testlib
|
||||||
SOURCES = tst_qdir.cpp
|
SOURCES = tst_qdir.cpp
|
||||||
RESOURCES += qdir.qrc
|
RESOURCES += qdir.qrc
|
||||||
|
ios: QMAKE_INFO_PLIST = Info.plist
|
||||||
|
|
||||||
TESTDATA += testdir testData searchdir resources entrylist types tst_qdir.cpp
|
TESTDATA += testdir testData searchdir resources entrylist types tst_qdir.cpp
|
||||||
|
|
||||||
|
@ -1523,6 +1523,11 @@ void tst_QDir::filePath_data()
|
|||||||
QTest::newRow("rel-rel") << "relative" << "path" << "relative/path";
|
QTest::newRow("rel-rel") << "relative" << "path" << "relative/path";
|
||||||
QTest::newRow("empty-empty") << "" << "" << ".";
|
QTest::newRow("empty-empty") << "" << "" << ".";
|
||||||
QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
|
QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar";
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
QTest::newRow("assets-rel") << "assets-library:/" << "foo/bar.baz" << "assets-library:/foo/bar.baz";
|
||||||
|
QTest::newRow("assets-abs") << "assets-library:/" << "/foo/bar.baz" << "/foo/bar.baz";
|
||||||
|
QTest::newRow("abs-assets") << "/some/path" << "assets-library:/foo/bar.baz" << "assets-library:/foo/bar.baz";
|
||||||
|
#endif
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QTest::newRow("abs-LTUNC") << "Q:/path" << "\\/leaning\\tooth/pick" << "\\/leaning\\tooth/pick";
|
QTest::newRow("abs-LTUNC") << "Q:/path" << "\\/leaning\\tooth/pick" << "\\/leaning\\tooth/pick";
|
||||||
QTest::newRow("LTUNC-slash") << "\\/leaning\\tooth/pick" << "/path" << "//leaning/tooth/path";
|
QTest::newRow("LTUNC-slash") << "\\/leaning\\tooth/pick" << "/path" << "//leaning/tooth/path";
|
||||||
|
Loading…
Reference in New Issue
Block a user