aboutsummaryrefslogtreecommitdiff
path: root/src/libfetchers/path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfetchers/path.cc')
-rw-r--r--src/libfetchers/path.cc23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc
index b6fcdac9e..59e228e97 100644
--- a/src/libfetchers/path.cc
+++ b/src/libfetchers/path.cc
@@ -80,23 +80,31 @@ struct PathInputScheme : InputScheme
// nothing to do
}
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & input) override
{
std::string absPath;
auto path = getStrAttr(input.attrs, "path");
- if (path[0] != '/' && input.parent) {
+ if (path[0] != '/') {
+ if (!input.parent)
+ throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string());
+
auto parent = canonPath(*input.parent);
// the path isn't relative, prefix it
- absPath = canonPath(parent + "/" + path);
+ absPath = nix::absPath(path, parent);
// for security, ensure that if the parent is a store path, it's inside it
- if (!parent.rfind(store->storeDir, 0) && absPath.rfind(store->storeDir, 0))
- throw BadStorePath("relative path '%s' points outside of its parent's store path %s, this is a security violation", path, parent);
+ if (store->isInStore(parent)) {
+ auto storePath = store->printStorePath(store->toStorePath(parent).first);
+ if (!isDirOrInDir(absPath, storePath))
+ throw BadStorePath("relative path '%s' points outside of its parent's store path '%s'", path, storePath);
+ }
} else
absPath = path;
+ Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s'", absPath));
+
// FIXME: check whether access to 'path' is allowed.
auto storePath = store->maybeParseStorePath(absPath);
@@ -107,10 +115,7 @@ struct PathInputScheme : InputScheme
// FIXME: try to substitute storePath.
storePath = store->addToStore("source", absPath);
- return {
- Tree(store->toRealPath(*storePath), std::move(*storePath)),
- input
- };
+ return {std::move(*storePath), input};
}
};