diff options
Diffstat (limited to 'src/libfetchers/path.cc')
-rw-r--r-- | src/libfetchers/path.cc | 23 |
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}; } }; |