aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/primops.cc29
-rw-r--r--tests/pure-eval.sh3
2 files changed, 25 insertions, 7 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index aff8f951e..62c21c7c5 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -89,18 +89,28 @@ StringMap EvalState::realiseContext(const PathSet & context)
return res;
}
-static Path realisePath(EvalState & state, const Pos & pos, Value & v, bool requireAbsolutePath = true)
+struct RealisePathFlags {
+ // Whether to check whether the path is a valid absolute path
+ bool requireAbsolutePath = true;
+ // Whether to check that the path is allowed in pure eval mode
+ bool checkForPureEval = true;
+};
+
+static Path realisePath(EvalState & state, const Pos & pos, Value & v, const RealisePathFlags flags = {})
{
PathSet context;
- Path path = requireAbsolutePath
+ Path path = flags.requireAbsolutePath
? state.coerceToPath(pos, v, context)
: state.coerceToString(pos, v, context, false, false);
StringMap rewrites = state.realiseContext(context);
- return state.checkSourcePath(
- state.toRealPath(rewriteStrings(path, rewrites), context));
+ auto realPath = state.toRealPath(rewriteStrings(path, rewrites), context);
+
+ return flags.checkForPureEval
+ ? state.checkSourcePath(realPath)
+ : realPath;
}
/* Add and attribute to the given attribute map from the output name to
@@ -1371,7 +1381,12 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args,
{
Path path;
try {
- path = realisePath(state, pos, *args[0]);
+ // We don’t check the path right now, because we don’t want to throw if
+ // the path isn’t allowed, but just return false
+ // (and we can’t just catch the exception here because we still want to
+ // throw if something in the evaluation of `*args[0]` tries to access an
+ // unauthorized path)
+ path = realisePath(state, pos, *args[0], { .checkForPureEval = false });
} catch (InvalidPathError & e) {
throw EvalError({
.msg = hintfmt(
@@ -1382,7 +1397,7 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args,
}
try {
- mkBool(v, pathExists(path));
+ mkBool(v, pathExists(state.checkSourcePath(path)));
} catch (SysError & e) {
/* Don't give away info from errors while canonicalising
‘path’ in restricted mode. */
@@ -1496,7 +1511,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
Path path;
try {
- path = realisePath(state, pos, *i->value, false);
+ path = realisePath(state, pos, *i->value, { .requireAbsolutePath = false });
} catch (InvalidPathError & e) {
throw EvalError({
.msg = hintfmt("cannot find '%1%', since path '%2%' is not valid", path, e.path),
diff --git a/tests/pure-eval.sh b/tests/pure-eval.sh
index cb4b5c5fc..1a4568ea6 100644
--- a/tests/pure-eval.sh
+++ b/tests/pure-eval.sh
@@ -11,6 +11,9 @@ missingImpureErrorMsg=$(! nix eval --expr 'builtins.readFile ./pure-eval.sh' 2>&
echo "$missingImpureErrorMsg" | grep -q -- --impure || \
fail "The error message should mention the “--impure” flag to unblock users"
+[[ $(nix eval --expr 'builtins.pathExists ./pure-eval.sh') == false ]] || \
+ fail "Calling 'pathExists' on a non-authorised path should return false"
+
(! nix eval --expr builtins.currentTime)
(! nix eval --expr builtins.currentSystem)