about summary refs log tree commit diff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc63
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");