Core/VirtualDirectory: Fix physical path traversal

This commit is contained in:
Jérôme Leclercq 2022-03-12 16:52:39 +01:00
parent 5a9a55ee7e
commit b92a9f8a1c
1 changed files with 9 additions and 5 deletions

View File

@ -84,12 +84,13 @@ namespace Nz
assert(!path.empty()); assert(!path.empty());
VirtualDirectoryPtr currentDir = shared_from_this(); VirtualDirectoryPtr currentDir = shared_from_this();
std::optional<std::filesystem::path> physicalPathBase;
std::vector<std::string> physicalDirectoryParts; std::vector<std::string> physicalDirectoryParts;
return SplitPath(path, [&](std::string_view dirName) return SplitPath(path, [&](std::string_view dirName)
{ {
assert(!dirName.empty()); assert(!dirName.empty());
if (!physicalDirectoryParts.empty()) if (physicalPathBase)
{ {
// Special case when traversing directory // Special case when traversing directory
if (dirName == "..") if (dirName == "..")
@ -97,6 +98,8 @@ namespace Nz
// Don't allow to escape virtual directory // Don't allow to escape virtual directory
if (!physicalDirectoryParts.empty()) if (!physicalDirectoryParts.empty())
physicalDirectoryParts.pop_back(); physicalDirectoryParts.pop_back();
else
physicalPathBase.reset();
} }
else if (dirName != ".") else if (dirName != ".")
physicalDirectoryParts.emplace_back(dirName); physicalDirectoryParts.emplace_back(dirName);
@ -113,8 +116,10 @@ namespace Nz
} }
else if (auto physDirEntry = std::get_if<PhysicalDirectoryEntry>(&entry)) else if (auto physDirEntry = std::get_if<PhysicalDirectoryEntry>(&entry))
{ {
assert(!physicalPathBase);
// We're traversing a physical directory // We're traversing a physical directory
physicalDirectoryParts.emplace_back(dirName); physicalPathBase = physDirEntry->filePath;
return true; return true;
} }
@ -123,10 +128,9 @@ namespace Nz
}, },
[&](std::string_view name) [&](std::string_view name)
{ {
if (!physicalDirectoryParts.empty()) if (physicalPathBase)
{ {
assert(m_physicalPath); std::filesystem::path filePath = *physicalPathBase;
std::filesystem::path filePath = *m_physicalPath;
for (const auto& part : physicalDirectoryParts) for (const auto& part : physicalDirectoryParts)
filePath /= part; filePath /= part;