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 ** 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");