about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-10-27T13·40+0200
committerEelco Dolstra <edolstra@gmail.com>2018-10-27T13·41+0200
commit18b4c53f71dfc626f5f5ffa0282afd1b9faad6a4 (patch)
tree011f81c17e77bd269f36a0b0f7f74342c1fa3b9e
parent1427958b3cf4a8d5c7e46169c00039f6b75317d2 (diff)
Restore old (dis)allowedRequisites behaviour for self-references
stdenv relies on this. So ignore self-references (but only in legacy non-structured attributes mode).
-rw-r--r--src/libstore/build.cc63
-rw-r--r--tests/check-refs.sh2
-rw-r--r--tests/check-reqs.nix2
-rw-r--r--tests/check-reqs.sh2
4 files changed, 39 insertions, 30 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");
diff --git a/tests/check-refs.sh b/tests/check-refs.sh
index 34ee22cfc8f7..16bbabc40985 100644
--- a/tests/check-refs.sh
+++ b/tests/check-refs.sh
@@ -1,5 +1,7 @@
 source common.sh
 
+clearStore
+
 RESULT=$TEST_ROOT/result
 
 dep=$(nix-build -o $RESULT check-refs.nix -A dep)
diff --git a/tests/check-reqs.nix b/tests/check-reqs.nix
index 47b5b3d9c723..41436cb48e08 100644
--- a/tests/check-reqs.nix
+++ b/tests/check-reqs.nix
@@ -33,7 +33,7 @@ rec {
   };
 
   # When specifying all the requisites, the build succeeds.
-  test1 = makeTest 1 [ "out" dep1 dep2 deps ];
+  test1 = makeTest 1 [ dep1 dep2 deps ];
 
   # But missing anything it fails.
   test2 = makeTest 2 [ dep2 deps ];
diff --git a/tests/check-reqs.sh b/tests/check-reqs.sh
index 77689215def1..e9f65fc2a6d3 100644
--- a/tests/check-reqs.sh
+++ b/tests/check-reqs.sh
@@ -1,5 +1,7 @@
 source common.sh
 
+clearStore
+
 RESULT=$TEST_ROOT/result
 
 nix-build -o $RESULT check-reqs.nix -A test1