diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2023-11-16 16:45:14 +0100 |
---|---|---|
committer | github-actions[bot] <github-actions[bot]@users.noreply.github.com> | 2024-01-21 20:53:30 +0000 |
commit | bef68e53b9d08c99873a5bc60568b7351934ad51 (patch) | |
tree | 281303b658971f042dd50e0fe9b1fd99bd756616 | |
parent | 60eb80593f3a18aebc7672ad7007cb23c14db061 (diff) |
Fix symlink handling
This restores the symlink handling behaviour prior to
94812cca98fbb157e5f64a15a85a2b852d289feb.
Fixes #9298.
(cherry picked from commit 31ebc6028b3682969d86a7b39ae87131c41cc604)
-rw-r--r-- | src/libexpr/eval.hh | 2 | ||||
-rw-r--r-- | src/libexpr/parser.y | 18 | ||||
-rw-r--r-- | tests/functional/lang/eval-okay-symlink-resolution.exp | 1 | ||||
-rw-r--r-- | tests/functional/lang/eval-okay-symlink-resolution.nix | 1 | ||||
-rw-r--r-- | tests/functional/lang/symlink-resolution/foo/lib/default.nix | 1 | ||||
l--------- | tests/functional/lang/symlink-resolution/foo/overlays | 1 | ||||
-rw-r--r-- | tests/functional/lang/symlink-resolution/overlays/overlay.nix | 1 |
7 files changed, 19 insertions, 6 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index fa8fa462b..553cbe4fd 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -802,7 +802,7 @@ std::string showType(const Value & v); /** * If `path` refers to a directory, then append "/default.nix". */ -SourcePath resolveExprPath(const SourcePath & path); +SourcePath resolveExprPath(SourcePath path); struct InvalidPathError : EvalError { diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 792f51fde..28f6ba41b 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -682,17 +682,25 @@ Expr * EvalState::parse( } -SourcePath resolveExprPath(const SourcePath & path) +SourcePath resolveExprPath(SourcePath path) { + unsigned int followCount = 0, maxFollow = 1024; + /* If `path' is a symlink, follow it. This is so that relative path references work. */ - auto path2 = path.resolveSymlinks(); + while (true) { + // Basic cycle/depth limit to avoid infinite loops. + if (++followCount >= maxFollow) + throw Error("too many symbolic links encountered while traversing the path '%s'", path); + if (path.lstat().type != InputAccessor::tSymlink) break; + path = {path.accessor, CanonPath(path.readLink(), path.path.parent().value_or(CanonPath::root))}; + } /* If `path' refers to a directory, append `/default.nix'. */ - if (path2.lstat().type == InputAccessor::tDirectory) - return path2 + "default.nix"; + if (path.lstat().type == InputAccessor::tDirectory) + return path + "default.nix"; - return path2; + return path; } diff --git a/tests/functional/lang/eval-okay-symlink-resolution.exp b/tests/functional/lang/eval-okay-symlink-resolution.exp new file mode 100644 index 000000000..8b8441b91 --- /dev/null +++ b/tests/functional/lang/eval-okay-symlink-resolution.exp @@ -0,0 +1 @@ +"test" diff --git a/tests/functional/lang/eval-okay-symlink-resolution.nix b/tests/functional/lang/eval-okay-symlink-resolution.nix new file mode 100644 index 000000000..ffb1818bd --- /dev/null +++ b/tests/functional/lang/eval-okay-symlink-resolution.nix @@ -0,0 +1 @@ +import symlink-resolution/foo/overlays/overlay.nix diff --git a/tests/functional/lang/symlink-resolution/foo/lib/default.nix b/tests/functional/lang/symlink-resolution/foo/lib/default.nix new file mode 100644 index 000000000..8b8441b91 --- /dev/null +++ b/tests/functional/lang/symlink-resolution/foo/lib/default.nix @@ -0,0 +1 @@ +"test" diff --git a/tests/functional/lang/symlink-resolution/foo/overlays b/tests/functional/lang/symlink-resolution/foo/overlays new file mode 120000 index 000000000..0d44a21c5 --- /dev/null +++ b/tests/functional/lang/symlink-resolution/foo/overlays @@ -0,0 +1 @@ +../overlays
\ No newline at end of file diff --git a/tests/functional/lang/symlink-resolution/overlays/overlay.nix b/tests/functional/lang/symlink-resolution/overlays/overlay.nix new file mode 100644 index 000000000..b0368308e --- /dev/null +++ b/tests/functional/lang/symlink-resolution/overlays/overlay.nix @@ -0,0 +1 @@ +import ../lib |