From e95a4ba6bb83161f0fa1af38b23112f2daf25439 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 24 Oct 2024 13:55:05 +0200 Subject: [PATCH] Support builtins.path with disallow-copy-paths --- src/libexpr/eval-settings.hh | 2 ++ src/libexpr/eval.cc | 3 +- src/libexpr/primops.cc | 6 +++- tests/functional/disallow-copy-paths.sh | 48 +++++++++++++++++++++---- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/libexpr/eval-settings.hh b/src/libexpr/eval-settings.hh index ec6b609f422..fdf253c88e7 100644 --- a/src/libexpr/eval-settings.hh +++ b/src/libexpr/eval-settings.hh @@ -255,6 +255,8 @@ struct EvalSettings : Config This is useful for finding expressions which copy sources, which can slow down evaluation. You may find copied sources by running `nix` commands with increased verbosity, such as `nix build -vvvv 2>&1 | grep /nix/store`. After identifying one more more paths, run `nix build --option disallow-copy-paths /nix/store/... --show-trace` to find the expression that copies the path, or add `--debugger`. + + A filtering copy is always allowed, such as `builtins.filterSource` or `builtins.path { filter = ...; }`. )"}; }; diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index fa4661b1102..8ffe69355ba 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2390,7 +2390,8 @@ StorePath EvalState::fetchToStore( PathFilter * filter, RepairFlag repair) { - checkDisallowCopyPath(path); + if (!filter) + checkDisallowCopyPath(path); return ::nix::fetchToStore(*store, path, mode, name, method, filter, repair); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 5f5fb4d8653..9db6a199127 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -2486,8 +2486,12 @@ static void addPath( path ).atPos(pos).debugThrow(); state.allowAndSetStorePathString(dstPath, v); - } else + } else { + if (!filterFun) + state.checkDisallowCopyPath(path); + state.allowAndSetStorePathString(*expectedStorePath, v); + } } catch (Error & e) { e.addTrace(state.positions[pos], "while adding path '%s'", path); throw; diff --git a/tests/functional/disallow-copy-paths.sh b/tests/functional/disallow-copy-paths.sh index 4cd1ff827f1..fb662adb0ea 100755 --- a/tests/functional/disallow-copy-paths.sh +++ b/tests/functional/disallow-copy-paths.sh @@ -7,10 +7,44 @@ clearStoreIfPossible # shellcheck disable=SC2016 path="$(nix eval --raw --impure --expr '"${./disallow-copy-paths.sh}"')" -# shellcheck disable=SC2016 -expectStderr 1 nix-instantiate \ - --disallow-copy-paths "$path" \ - --expr --strict \ - --argstr path "$path" \ - '{ path }: "${/. + path}" + "bla bla"' \ - | grepQuiet "error.*not allowed to copy.*$path.* due to option.*disallow-copy-paths" +all_tests() { + + # shellcheck disable=SC2016 + expectStderr 1 nix-instantiate \ + --disallow-copy-paths "$path" \ + --expr --strict \ + --argstr path "$path" \ + '{ path }: "${/. + path}" + "bla bla"' \ + "$@" \ + | grepQuiet "error.*not allowed to copy.*$path.* due to option.*disallow-copy-paths" + + # shellcheck disable=SC2016 + expectStderr 1 nix-instantiate \ + --disallow-copy-paths "$path" \ + --expr --strict \ + --argstr path "$path" \ + "$@" \ + '{ path }: builtins.path { path = /. + path; name = "source"; } + "bla bla"' \ + | grepQuiet "error.*not allowed to copy.*$path.* due to option.*disallow-copy-paths" + + # shellcheck disable=SC2016 + expectStderr 1 nix-instantiate \ + --disallow-copy-paths "$path" \ + --expr --strict \ + --argstr path "$path" \ + "$@" \ + '{ path }: builtins.path { path = path; name = "source"; } + "bla bla"' \ + | grepQuiet "error.*not allowed to copy.*$path.* due to option.*disallow-copy-paths" + + # shellcheck disable=SC2016 + nix-instantiate \ + --disallow-copy-paths "$path" \ + --expr --eval --strict \ + "$@" \ + --argstr path "$path" \ + '{ path }: builtins.path { path = path; name = "source"; filter = _: _: true; } + "bla bla"' \ + +} + +all_tests +all_tests --readonly-mode