aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/storage/projectstore
diff options
context:
space:
mode:
authorLiam Mitchell <[email protected]>2026-03-09 18:25:30 -0700
committerLiam Mitchell <[email protected]>2026-03-09 18:25:30 -0700
commit57c1683b2935c834250b73eb506319ed67946160 (patch)
tree1fc8f237010b26e65659b731fe6f6eae30422f5c /src/zenserver/storage/projectstore
parentAllow external OidcToken executable to be specified unless disabled via comma... (diff)
parentreduce lock time for project store gc precache and gc validate (#750) (diff)
downloadzen-57c1683b2935c834250b73eb506319ed67946160.tar.xz
zen-57c1683b2935c834250b73eb506319ed67946160.zip
Merge branch 'main' into lm/oidctoken-exe-path
Diffstat (limited to 'src/zenserver/storage/projectstore')
-rw-r--r--src/zenserver/storage/projectstore/httpprojectstore.cpp58
1 files changed, 49 insertions, 9 deletions
diff --git a/src/zenserver/storage/projectstore/httpprojectstore.cpp b/src/zenserver/storage/projectstore/httpprojectstore.cpp
index 91c0a8af1..e3dd52ca7 100644
--- a/src/zenserver/storage/projectstore/httpprojectstore.cpp
+++ b/src/zenserver/storage/projectstore/httpprojectstore.cpp
@@ -565,11 +565,23 @@ HttpProjectService::HttpProjectService(CidStore& Store,
using namespace std::literals;
- m_Router.AddPattern("project", "([[:alnum:]_.]+)");
- m_Router.AddPattern("log", "([[:alnum:]_.]+)");
- m_Router.AddPattern("op", "([[:digit:]]+?)");
- m_Router.AddPattern("chunk", "([[:xdigit:]]{24})");
- m_Router.AddPattern("hash", "([[:xdigit:]]{40})");
+ static constexpr AsciiSet ValidProjectCharactersSet{"abcdefghijklmnopqrstuvwxyz0123456789_.ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
+ static constexpr AsciiSet ValidOplogCharactersSet{"abcdefghijklmnopqrstuvwxyz0123456789_.ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
+ static constexpr AsciiSet ValidNumberCharactersSet{"0123456789"};
+ static constexpr AsciiSet ValidHexCharactersSet{"0123456789abcdefABCDEF"};
+
+ m_Router.AddMatcher("project",
+ [](std::string_view Str) -> bool { return !Str.empty() && AsciiSet::HasOnly(Str, ValidProjectCharactersSet); });
+ m_Router.AddMatcher("log",
+ [](std::string_view Str) -> bool { return !Str.empty() && AsciiSet::HasOnly(Str, ValidOplogCharactersSet); });
+ m_Router.AddMatcher("op",
+ [](std::string_view Str) -> bool { return !Str.empty() && AsciiSet::HasOnly(Str, ValidNumberCharactersSet); });
+ m_Router.AddMatcher("chunk", [](std::string_view Str) -> bool {
+ return Str.length() == Oid::StringLength && AsciiSet::HasOnly(Str, ValidHexCharactersSet);
+ });
+ m_Router.AddMatcher("hash", [](std::string_view Str) -> bool {
+ return Str.length() == IoHash::StringLength && AsciiSet::HasOnly(Str, ValidHexCharactersSet);
+ });
m_Router.RegisterRoute(
"",
@@ -2900,6 +2912,8 @@ HttpProjectService::HandleRpcRequest(HttpRouterRequest& Req)
};
tsl::robin_map<IoHash, AddedChunk, IoHash::Hasher> AddedChunks;
+ const std::filesystem::path CanonicalRoot = std::filesystem::canonical(Project->RootDir);
+
Oplog->IterateOplog(
[&](CbObjectView Op) {
bool OpRewritten = false;
@@ -2918,10 +2932,36 @@ HttpProjectService::HandleRpcRequest(HttpRouterRequest& Req)
if (DataHash == IoHash::Zero)
{
- std::string_view ServerPath = View["serverpath"sv].AsString();
- std::filesystem::path FilePath = Project->RootDir / ServerPath;
- BasicFile DataFile;
- std::error_code Ec;
+ std::string_view ServerPath = View["serverpath"sv].AsString();
+ if (CanonicalRoot.empty())
+ {
+ ZEN_WARN("Attempting to load file '{}' from project with unset project root", ServerPath);
+ AllOk = false;
+ continue;
+ }
+
+ std::error_code Ec;
+ const std::filesystem::path FilePath = std::filesystem::canonical(Project->RootDir / ServerPath, Ec);
+
+ if (Ec)
+ {
+ ZEN_WARN("Failed to find file '{}' in project root '{}' for 'snapshot'. Reason: '{}'",
+ ServerPath,
+ Project->RootDir,
+ Ec.message());
+ AllOk = false;
+ continue;
+ }
+
+ if (std::mismatch(CanonicalRoot.begin(), CanonicalRoot.end(), FilePath.begin()).first !=
+ CanonicalRoot.end())
+ {
+ ZEN_WARN("Unable to read file '{}' outside of project root '{}'", FilePath, CanonicalRoot);
+ AllOk = false;
+ continue;
+ }
+
+ BasicFile DataFile;
DataFile.Open(FilePath, BasicFile::Mode::kRead, Ec);
if (Ec)