summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp21
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp52
2 files changed, 54 insertions, 19 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 3cb412e47c..e195afdae9 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Intel Corporation.
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Contact: https://www.qt.io/licensing/
@@ -603,25 +604,7 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
if (!createParents)
return false;
- // we need the cleaned path in order to create the parents
- // and we save errno just in case encodeName needs to load codecs
- int savedErrno = errno;
- bool pathChanged;
- {
- QString cleanName = QDir::cleanPath(dirName);
-
- // Check if the cleaned name is the same or not. If we were given a
- // path with resolvable "../" sections, cleanPath will remove them, but
- // this may change the target dir if one of those segments was a
- // symlink. This operation depends on cleanPath's optimization of
- // returning the original string if it didn't modify anything.
- pathChanged = !dirName.isSharedWith(cleanName);
- if (pathChanged)
- nativeName = QFile::encodeName(cleanName);
- }
-
- errno = savedErrno;
- return createDirectoryWithParents(nativeName, pathChanged);
+ return createDirectoryWithParents(nativeName, false);
}
//static
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 330ff9312d..946620d61f 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Intel Corporation.
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -101,6 +102,7 @@ private slots:
void mkdirRmdir_data();
void mkdirRmdir();
+ void mkdirOnSymlink();
void makedirReturnCode();
@@ -387,6 +389,56 @@ void tst_QDir::mkdirRmdir()
QVERIFY(!fi.exists());
}
+void tst_QDir::mkdirOnSymlink()
+{
+#ifndef Q_OS_UNIX
+ QSKIP("Test only valid on an OS that supports symlinks");
+#else
+ // Create the structure:
+ // .
+ // ├── symlink -> two/three
+ // └── two
+ // └── three
+ // so when we mkdir("symlink/../four/five"), we end up with:
+ // .
+ // ├── symlink -> two/three
+ // └── two
+ // ├── four
+ // │ └── five
+ // └── three
+
+ QDir dir;
+ struct Clean {
+ QDir &dir;
+ Clean(QDir &dir) : dir(dir) {}
+ ~Clean() { doClean(); }
+ void doClean() {
+ dir.rmpath("two/three");
+ dir.rmpath("two/four/five");
+ // in case the test fails, don't leave junk behind
+ dir.rmpath("four/five");
+ QFile::remove("symlink");
+ }
+ };
+ Clean clean(dir);
+ clean.doClean();
+
+ // create our structure:
+ dir.mkpath("two/three");
+ ::symlink("two/three", "symlink");
+
+ // try it:
+ QString path = "symlink/../four/five";
+ QVERIFY(dir.mkpath(path));
+ QFileInfo fi(path);
+ QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
+
+ path = "two/four/five";
+ fi.setFile(path);
+ QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
+#endif
+}
+
void tst_QDir::makedirReturnCode()
{
QString dirName = QString::fromLatin1("makedirReturnCode");