1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-29 05:31:00 +01:00

Fix access control

This commit is contained in:
Eelco Dolstra 2022-05-17 11:53:02 +02:00
parent 65e1e49cf7
commit fdba67d4fa
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 125 additions and 28 deletions

View file

@ -19,6 +19,13 @@ std::optional<CanonPath> CanonPath::parent() const
return CanonPath(unchecked_t(), path.substr(0, path.rfind('/')));
}
void CanonPath::pop()
{
assert(!isRoot());
auto slash = path.rfind('/');
path.resize(std::max((size_t) 1, slash));
}
CanonPath CanonPath::resolveSymlinks() const
{
return CanonPath(unchecked_t(), canonPath(abs(), true));
@ -33,6 +40,14 @@ bool CanonPath::isWithin(const CanonPath & parent) const
&& path[parent.path.size()] != '/'));
}
CanonPath CanonPath::removePrefix(const CanonPath & prefix) const
{
assert(isWithin(prefix));
if (prefix.isRoot()) return *this;
if (path.size() == prefix.path.size()) return root;
return CanonPath(unchecked_t(), path.substr(prefix.path.size()));
}
void CanonPath::extend(const CanonPath & x)
{
if (x.isRoot()) return;
@ -63,6 +78,27 @@ CanonPath CanonPath::operator + (std::string_view c) const
return res;
}
bool CanonPath::isAllowed(const std::set<CanonPath> & allowed) const
{
/* Check if `this` is an exact match or the parent of an
allowed path. */
auto lb = allowed.lower_bound(*this);
if (lb != allowed.end()) {
if (lb->isWithin(*this))
return true;
}
/* Check if a parent of `this` is allowed. */
auto path = *this;
while (!path.isRoot()) {
path.pop();
if (allowed.count(path))
return true;
}
return false;
}
std::ostream & operator << (std::ostream & stream, const CanonPath & path)
{
stream << path.abs();