Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
safe_relative_path.hpp
Go to the documentation of this file.
1#pragma once
2
14
15#include <filesystem>
16#include <iterator>
17#include <string>
18
19namespace pulp::runtime {
20
25inline bool is_safe_relative_path(const std::filesystem::path& path) {
26 if (path.empty() || path.is_absolute() || path.has_root_name() || path.has_root_directory())
27 return false;
28 for (const auto& part : path) {
29 const std::u8string text = part.u8string();
30 if (text.empty() || text == u8"." || text == u8"..")
31 return false;
32 for (const char8_t c : text)
33 if (c == u8'\\' || c == u8':' || c == u8'\0')
34 return false;
35 }
36 return true;
37}
38
43inline bool is_within_directory(const std::filesystem::path& directory,
44 const std::filesystem::path& candidate) {
45 const auto root = directory.lexically_normal();
46 const auto path = candidate.lexically_normal();
47 // An empty directory constrains nothing, so it cannot vouch for anything.
48 if (root.empty())
49 return false;
50 // `.` (or `a/..`) is the current directory: any relative candidate that
51 // does not climb out of it lies within it.
52 if (root == ".") {
53 if (path.has_root_name() || path.has_root_directory())
54 return false;
55 return path.empty() || *path.begin() != "..";
56 }
57 auto r = root.begin();
58 auto p = path.begin();
59 for (; r != root.end(); ++r) {
60 // A trailing separator on the directory normalizes to an empty final
61 // element; it does not constrain the candidate.
62 if (r->empty() && std::next(r) == root.end())
63 break;
64 if (p == path.end() || *p != *r)
65 return false;
66 ++p;
67 }
68 return true;
69}
70
71} // namespace pulp::runtime
Definition generated_event_source.hpp:33
bool is_safe_relative_path(const std::filesystem::path &path)
True only if path is safe to join beneath a destination directory: a non-empty relative path with no ...
Definition safe_relative_path.hpp:25
bool is_within_directory(const std::filesystem::path &directory, const std::filesystem::path &candidate)
True if candidate, compared lexically after normalization, is directory itself or lies beneath it.
Definition safe_relative_path.hpp:43