summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qdir.cpp')
-rw-r--r--src/corelib/io/qdir.cpp36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index d043b3aea5..06eacf5455 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -750,13 +750,47 @@ QString QDir::filePath(const QString &fileName) const
QString QDir::absoluteFilePath(const QString &fileName) const
{
const QDirPrivate* d = d_ptr.constData();
- if (isAbsolutePath(fileName))
+ // Don't trust our own isAbsolutePath(); Q_OS_WIN needs a drive.
+ if (QFileSystemEntry(fileName).isAbsolute())
return fileName;
d->resolveAbsoluteEntry();
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
if (fileName.isEmpty())
return absoluteDirPath;
+#ifdef Q_OS_WIN
+ // Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
+ int size = absoluteDirPath.length();
+ if ((fileName.startsWith(QLatin1Char('/'))
+ || fileName.startsWith(QLatin1Char('\\')))
+ && size > 1) {
+ // Combine absoluteDirPath's drive with fileName
+ int drive = 2; // length of drive prefix
+ if (Q_UNLIKELY(absoluteDirPath.at(1).unicode() != ':')) {
+ // Presumably, absoluteDirPath is an UNC path; use its //server/share
+ // part as "drive" - it's as sane a thing as we can do.
+ for (int i = 2; i-- > 0; ) { // Scan two "path fragments":
+ while (drive < size && absoluteDirPath.at(drive).unicode() == '/')
+ drive++;
+ if (drive >= size) {
+ qWarning("Base directory starts with neither a drive nor a UNC share: %s",
+ qPrintable(QDir::toNativeSeparators(absoluteDirPath)));
+ return QString();
+ }
+ while (drive < size && absoluteDirPath.at(drive).unicode() != '/')
+ drive++;
+ }
+ // We'll append fileName, which starts with a slash; so omit trailing slash:
+ if (absoluteDirPath.at(drive).unicode() == '/')
+ drive--;
+ } else if (!absoluteDirPath.at(0).isLetter()) {
+ qWarning("Base directory's drive is not a letter: %s",
+ qPrintable(QDir::toNativeSeparators(absoluteDirPath)));
+ return QString();
+ }
+ return absoluteDirPath.leftRef(drive) % fileName;
+ }
+#endif // Q_OS_WIN
if (!absoluteDirPath.endsWith(QLatin1Char('/')))
return absoluteDirPath % QLatin1Char('/') % fileName;
return absoluteDirPath % fileName;