aboutsummaryrefslogtreecommitdiff
path: root/src/common/fs/path_util.cpp
diff options
context:
space:
mode:
authorMaufeat <sahyno1996@gmail.com>2026-07-25 00:31:22 +0200
committercrueter <crueter@eden-emu.dev>2026-07-25 00:31:22 +0200
commit5b4c29b12393f9da26a55408ea179d4813ca2c45 (patch)
tree82afbe9754a661d527d3ff4c4443686b26ec719a /src/common/fs/path_util.cpp
parent5b4dc32c1ad528972f3073b7ac3d7ec01cfbec02 (diff)
[file_sys] Quick sandbox escape fix (#4223)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4223 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Diffstat (limited to 'src/common/fs/path_util.cpp')
-rw-r--r--src/common/fs/path_util.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index 3844cca06b..4105855866 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -476,6 +476,29 @@ std::string SanitizePath(std::string_view path_, DirectorySeparator directory_se
path.erase(std::unique(start, path.end(),
[type2](char c1, char c2) { return c1 == type2 && c2 == type2; }),
path.end());
+
+ const bool absolute = !path.empty() && path[0] == type2;
+ std::vector<std::string_view> parts;
+
+ for (const auto part : SplitPathComponents(path))
+ {
+ if (part.empty() || part == ".")
+ continue;
+ if (part == ".." && !parts.empty() && parts.back() != "..")
+ parts.pop_back();
+ else if (part != "..") parts.push_back(part);
+ }
+
+ std::string resolved = absolute ? std::string(1, type2) : std::string{};
+ for (std::size_t i = 0; i < parts.size(); ++i)
+ {
+ if (i != 0)
+ resolved += type2;
+ resolved.append(parts[i].data(), parts[i].size());
+ }
+
+ path = std::move(resolved);
+
return std::string(RemoveTrailingSlash(path));
}