diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 08ec2fac4..3b02e8815 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -472,7 +472,7 @@ EvalState::EvalState( : std::nullopt, [](const CanonPath & path) -> RestrictedPathError { auto modeInformation = evalSettings.pureEval - ? "in pure eval mode (use '--impure' to override)" + ? "in pure evaluation mode (use '--impure' to override)" : "in restricted mode"; throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation); })) diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 96a08ab9b..d395a2220 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -508,8 +508,14 @@ string_parts_interpolated path_start : PATH { - SourcePath path { data->basePath.accessor, CanonPath({$1.p, $1.l}, data->basePath.path) }; - $$ = new ExprPath(std::move(path)); + std::string_view path({$1.p, $1.l}); + $$ = new ExprPath( + /* Absolute paths are always interpreted relative to the + root filesystem accessor, rather than the accessor of the + current Nix expression. */ + hasPrefix(path, "/") + ? SourcePath{data->state.rootFS, CanonPath(path)} + : SourcePath{data->basePath.accessor, CanonPath(path, data->basePath.path)}); } | HPATH { if (evalSettings.pureEval) { diff --git a/tests/flakes/absolute-paths.sh b/tests/flakes/absolute-paths.sh new file mode 100644 index 000000000..e7bfba12d --- /dev/null +++ b/tests/flakes/absolute-paths.sh @@ -0,0 +1,17 @@ +source ./common.sh + +requireGit + +flake1Dir=$TEST_ROOT/flake1 +flake2Dir=$TEST_ROOT/flake2 + +createGitRepo $flake1Dir +cat > $flake1Dir/flake.nix <