mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-11 00:36:20 +02:00
FSInputAccessor: Implement filtering
This commit is contained in:
parent
3ec83565b1
commit
38c665847a
2 changed files with 37 additions and 6 deletions
|
@ -90,10 +90,19 @@ void InputAccessor::dumpPath(
|
||||||
struct FSInputAccessor : InputAccessor
|
struct FSInputAccessor : InputAccessor
|
||||||
{
|
{
|
||||||
Path root;
|
Path root;
|
||||||
|
std::optional<PathSet> allowedPaths;
|
||||||
|
|
||||||
FSInputAccessor(const Path & root)
|
FSInputAccessor(const Path & root, std::optional<PathSet> && allowedPaths)
|
||||||
: root(root)
|
: root(root)
|
||||||
{ }
|
, allowedPaths(allowedPaths)
|
||||||
|
{
|
||||||
|
if (allowedPaths) {
|
||||||
|
for (auto & p : *allowedPaths) {
|
||||||
|
assert(!hasPrefix(p, "/"));
|
||||||
|
assert(!hasSuffix(p, "/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string readFile(PathView path) override
|
std::string readFile(PathView path) override
|
||||||
{
|
{
|
||||||
|
@ -139,6 +148,7 @@ struct FSInputAccessor : InputAccessor
|
||||||
case DT_LNK: type = Type::tSymlink; break;
|
case DT_LNK: type = Type::tSymlink; break;
|
||||||
case DT_DIR: type = Type::tDirectory; break;
|
case DT_DIR: type = Type::tDirectory; break;
|
||||||
}
|
}
|
||||||
|
if (isAllowed(absPath + "/" + entry.name))
|
||||||
res.emplace(entry.name, type);
|
res.emplace(entry.name, type);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -161,6 +171,8 @@ struct FSInputAccessor : InputAccessor
|
||||||
void checkAllowed(PathView absPath)
|
void checkAllowed(PathView absPath)
|
||||||
{
|
{
|
||||||
if (!isAllowed(absPath))
|
if (!isAllowed(absPath))
|
||||||
|
// FIXME: for Git trees, show a custom error message like
|
||||||
|
// "file is not under version control or does not exist"
|
||||||
throw Error("access to path '%s' is not allowed", absPath);
|
throw Error("access to path '%s' is not allowed", absPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,13 +180,30 @@ struct FSInputAccessor : InputAccessor
|
||||||
{
|
{
|
||||||
if (!isDirOrInDir(absPath, root))
|
if (!isDirOrInDir(absPath, root))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (allowedPaths) {
|
||||||
|
// FIXME: make isDirOrInDir return subPath
|
||||||
|
auto subPath = absPath.substr(root.size());
|
||||||
|
if (hasPrefix(subPath, "/"))
|
||||||
|
subPath = subPath.substr(1);
|
||||||
|
|
||||||
|
if (subPath != "") {
|
||||||
|
auto lb = allowedPaths->lower_bound((std::string) subPath);
|
||||||
|
if (lb == allowedPaths->end()
|
||||||
|
|| !isDirOrInDir("/" + *lb, "/" + (std::string) subPath))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ref<InputAccessor> makeFSInputAccessor(const Path & root)
|
ref<InputAccessor> makeFSInputAccessor(
|
||||||
|
const Path & root,
|
||||||
|
std::optional<PathSet> && allowedPaths)
|
||||||
{
|
{
|
||||||
return make_ref<FSInputAccessor>(root);
|
return make_ref<FSInputAccessor>(root, std::move(allowedPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
||||||
|
|
|
@ -44,7 +44,9 @@ struct InputAccessor
|
||||||
PathFilter & filter = defaultPathFilter);
|
PathFilter & filter = defaultPathFilter);
|
||||||
};
|
};
|
||||||
|
|
||||||
ref<InputAccessor> makeFSInputAccessor(const Path & root);
|
ref<InputAccessor> makeFSInputAccessor(
|
||||||
|
const Path & root,
|
||||||
|
std::optional<PathSet> && allowedPaths = {});
|
||||||
|
|
||||||
struct MemoryInputAccessor : InputAccessor
|
struct MemoryInputAccessor : InputAccessor
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue