From 1113544b6bb098cb84606991a7e771007e4543dd Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Mon, 15 Feb 2016 10:49:24 +0100 Subject: [PATCH] src: fixed canonical paths * reimplemented FilePath::canonical method to work for symbolic links. --- src/lib/utility/file/FilePath.cpp | 33 ++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/lib/utility/file/FilePath.cpp b/src/lib/utility/file/FilePath.cpp index a393826c..9e4ba345 100644 --- a/src/lib/utility/file/FilePath.cpp +++ b/src/lib/utility/file/FilePath.cpp @@ -63,12 +63,39 @@ FilePath FilePath::absolute() const FilePath FilePath::canonical() const { - if (m_exists) + if (!m_exists) { - return boost::filesystem::canonical(m_path); + return FilePath(m_path); } - return FilePath(m_path); + boost::filesystem::path abs_p = boost::filesystem::absolute(m_path); + boost::filesystem::path result; + for (boost::filesystem::path::iterator it = abs_p.begin(); it != abs_p.end(); ++it) + { + if (*it == "..") + { + // /a/b/.. is not necessarily /a if b is a symbolic link + if (boost::filesystem::is_symlink(result)) + result /= *it; + // /a/b/../.. is not /a/b/.. under most circumstances + // We can end up with ..s in our result because of symbolic links + else if (result.filename() == "..") + result /= *it; + // Otherwise it should be safe to resolve the parent + else + result = result.parent_path(); + } + else if (*it == ".") + { + // Ignore + } + else + { + // Just cat other path entries + result /= *it; + } + } + return result; } FilePath FilePath::relativeTo(const FilePath& other) const