From 0f11fab6f75dec78d3721280971448cc2edd6e72 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sat, 26 Aug 2017 23:02:07 +0300 Subject: [PATCH] Fix resolution of relative symlinks from relative path on unix Consider the following: /root/target - a file /root/path/link -> ../target /root/path/other/exe - executable Running from /root/path/other. exe is: #include #include int main() { qDebug() << QFileInfo("../link").symLinkTarget() return 0; } The link references /root/target, but the current output is /root/path/target. The link doesn't depend on the PWD. It depends on its own directory. Change-Id: I61e95018154a75e0e0d795ee801068e18870a5df Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 12 +++++------- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index ac0c43d055..7600c9a613 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -187,13 +187,11 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, #endif if (!ret.startsWith(QLatin1Char('/'))) { - const QString linkFilePath = link.filePath(); - if (linkFilePath.startsWith(QLatin1Char('/'))) { - ret.prepend(linkFilePath.leftRef(linkFilePath.lastIndexOf(QLatin1Char('/'))) - + QLatin1Char('/')); - } else { - ret.prepend(QDir::currentPath() + QLatin1Char('/')); - } + const QString linkPath = link.path(); + if (linkPath.startsWith(QLatin1Char('/'))) + ret.prepend(linkPath + QLatin1Char('/')); + else + ret.prepend(QDir::currentPath() + QLatin1Char('/') + linkPath + QLatin1Char('/')); } ret = QDir::cleanPath(ret); if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 87b579bb2b..17f41cba2b 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1261,6 +1261,7 @@ void tst_QFileInfo::isSymLink_data() QFile::remove("link.lnk"); QFile::remove("brokenlink.lnk"); QFile::remove("dummyfile"); + QFile::remove("relative/link.lnk"); QFile file1(m_sourceFile); QVERIFY(file1.link("link.lnk")); @@ -1277,6 +1278,12 @@ void tst_QFileInfo::isSymLink_data() QTest::newRow("existent file") << m_sourceFile << false << ""; QTest::newRow("link") << "link.lnk" << true << QFileInfo(m_sourceFile).absoluteFilePath(); QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath(); + +#ifndef Q_OS_WIN + QDir::current().mkdir("relative"); + QFile::link("../dummyfile", "relative/link.lnk"); + QTest::newRow("relative link") << "relative/link.lnk" << true << QFileInfo("dummyfile").absoluteFilePath(); +#endif #endif }