From b92a9f8a1cb2579cd228ece8c06a8b6923f4e59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 12 Mar 2022 16:52:39 +0100 Subject: [PATCH] Core/VirtualDirectory: Fix physical path traversal --- include/Nazara/Core/VirtualDirectory.inl | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/VirtualDirectory.inl b/include/Nazara/Core/VirtualDirectory.inl index cede180cb..f37f9f163 100644 --- a/include/Nazara/Core/VirtualDirectory.inl +++ b/include/Nazara/Core/VirtualDirectory.inl @@ -84,12 +84,13 @@ namespace Nz assert(!path.empty()); VirtualDirectoryPtr currentDir = shared_from_this(); + std::optional physicalPathBase; std::vector physicalDirectoryParts; return SplitPath(path, [&](std::string_view dirName) { assert(!dirName.empty()); - if (!physicalDirectoryParts.empty()) + if (physicalPathBase) { // Special case when traversing directory if (dirName == "..") @@ -97,6 +98,8 @@ namespace Nz // Don't allow to escape virtual directory if (!physicalDirectoryParts.empty()) physicalDirectoryParts.pop_back(); + else + physicalPathBase.reset(); } else if (dirName != ".") physicalDirectoryParts.emplace_back(dirName); @@ -113,8 +116,10 @@ namespace Nz } else if (auto physDirEntry = std::get_if(&entry)) { + assert(!physicalPathBase); + // We're traversing a physical directory - physicalDirectoryParts.emplace_back(dirName); + physicalPathBase = physDirEntry->filePath; return true; } @@ -123,10 +128,9 @@ namespace Nz }, [&](std::string_view name) { - if (!physicalDirectoryParts.empty()) + if (physicalPathBase) { - assert(m_physicalPath); - std::filesystem::path filePath = *m_physicalPath; + std::filesystem::path filePath = *physicalPathBase; for (const auto& part : physicalDirectoryParts) filePath /= part;