diff options
| author | Liam Mitchell <[email protected]> | 2026-03-09 18:25:30 -0700 |
|---|---|---|
| committer | Liam Mitchell <[email protected]> | 2026-03-09 18:25:30 -0700 |
| commit | 57c1683b2935c834250b73eb506319ed67946160 (patch) | |
| tree | 1fc8f237010b26e65659b731fe6f6eae30422f5c /src/zenserver/storage/projectstore | |
| parent | Allow external OidcToken executable to be specified unless disabled via comma... (diff) | |
| parent | reduce lock time for project store gc precache and gc validate (#750) (diff) | |
| download | zen-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.cpp | 58 |
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) |