diff options
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r-- | src/libstore/build.cc | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index cf4218a261fa..676ad5856b13 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -3310,6 +3310,7 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs) struct Checks { + bool ignoreSelfRefs = false; std::experimental::optional<uint64_t> maxSize, maxClosureSize; std::experimental::optional<Strings> allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites; }; @@ -3345,35 +3346,6 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs) return std::make_pair(pathsDone, closureSize); }; - auto checkRefs = [&](const std::experimental::optional<Strings> & value, bool allowed, bool recursive) - { - if (!value) return; - - PathSet spec = parseReferenceSpecifiers(worker.store, *drv, *value); - - PathSet used = recursive ? getClosure(info.path).first : info.references; - - PathSet badPaths; - - for (auto & i : used) - if (allowed) { - if (spec.find(i) == spec.end()) - badPaths.insert(i); - } else { - if (spec.find(i) != spec.end()) - badPaths.insert(i); - } - - if (!badPaths.empty()) { - string badPathsStr; - for (auto & i : badPaths) { - badPathsStr += "\n "; - badPathsStr += i; - } - throw BuildError("output '%s' is not allowed to refer to the following paths:%s", info.path, badPathsStr); - } - }; - auto applyChecks = [&](const Checks & checks) { if (checks.maxSize && info.narSize > *checks.maxSize) @@ -3387,6 +3359,38 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs) info.path, closureSize, *checks.maxClosureSize); } + auto checkRefs = [&](const std::experimental::optional<Strings> & value, bool allowed, bool recursive) + { + if (!value) return; + + PathSet spec = parseReferenceSpecifiers(worker.store, *drv, *value); + + PathSet used = recursive ? getClosure(info.path).first : info.references; + + if (recursive && checks.ignoreSelfRefs) + used.erase(info.path); + + PathSet badPaths; + + for (auto & i : used) + if (allowed) { + if (!spec.count(i)) + badPaths.insert(i); + } else { + if (spec.count(i)) + badPaths.insert(i); + } + + if (!badPaths.empty()) { + string badPathsStr; + for (auto & i : badPaths) { + badPathsStr += "\n "; + badPathsStr += i; + } + throw BuildError("output '%s' is not allowed to refer to the following paths:%s", info.path, badPathsStr); + } + }; + checkRefs(checks.allowedReferences, true, false); checkRefs(checks.allowedRequisites, true, true); checkRefs(checks.disallowedReferences, false, false); @@ -3435,6 +3439,7 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs) } else { // legacy non-structured-attributes case Checks checks; + checks.ignoreSelfRefs = true; checks.allowedReferences = parsedDrv->getStringsAttr("allowedReferences"); checks.allowedRequisites = parsedDrv->getStringsAttr("allowedRequisites"); checks.disallowedReferences = parsedDrv->getStringsAttr("disallowedReferences"); |