Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traverse symlinked path components in import #4678

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 4 additions & 14 deletions src/libexpr/parser.y
Expand Up @@ -605,23 +605,13 @@ Path resolveExprPath(Path path)
{
assert(path[0] == '/');

unsigned int followCount = 0, maxFollow = 1024;

/* If `path' is a symlink, follow it. This is so that relative
/* Expand all symlinks in `path`. This is so that relative
path references work. */
struct stat st;
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);
st = lstat(path);
if (!S_ISLNK(st.st_mode)) break;
path = absPath(readLink(path), dirOf(path));
}
path = absPath(path, {}, true);

/* If `path' refers to a directory, append `/default.nix'. */
if (S_ISDIR(st.st_mode))
path = canonPath(path + "/default.nix");
if (getFileType(path) == DT_DIR)
path = canonPath(path + "/default.nix", true);

return path;
}
Expand Down
56 changes: 56 additions & 0 deletions tests/check-imports.sh
@@ -0,0 +1,56 @@
source common.sh

rm -rf $TEST_ROOT/example
mkdir -p $TEST_ROOT/example/{,alt-}dir
echo '"good"' > $TEST_ROOT/example/good.nix
echo '"good"' > $TEST_ROOT/example/dir/alt-good.nix
echo 'import ../good.nix' > $TEST_ROOT/example/dir/import-good.nix
echo 'import ./alt-good.nix' > $TEST_ROOT/example/dir/default.nix
ln -s dir/import-good.nix $TEST_ROOT/example/
ln -s . $TEST_ROOT/example/dir/subdir
ln -s good.nix $TEST_ROOT/example/good-link.nix
ln -s good-link.nix $TEST_ROOT/example/good-link-link.nix
ln -s ../good.nix $TEST_ROOT/example/dir/good-link.nix
ln -s ../dir/default.nix $TEST_ROOT/example/alt-dir/

testGoodEval() {
test "`nix eval --impure --raw "$@"`" = "good"
}

testImportFile() {
testGoodEval -f "$1"
testGoodEval --expr "(import $1)"
}

# direct import
testImportFile $TEST_ROOT/example/good.nix

# dir import
testImportFile $TEST_ROOT/example/dir

# two-level relative import
testImportFile $TEST_ROOT/example/dir/import-good.nix

# symlink
testImportFile $TEST_ROOT/example/good-link.nix

# relative symlink
testImportFile $TEST_ROOT/example/dir/good-link.nix

# two-level symlink
testImportFile $TEST_ROOT/example/good-link-link.nix

# symlink dir
testImportFile $TEST_ROOT/example/dir/subdir/alt-good.nix

# symlink dir import
testImportFile $TEST_ROOT/example/dir/subdir

# two-level relative import from path with symlink dir
testImportFile $TEST_ROOT/example/dir/subdir/import-good.nix

# relative traverse of symlink dir
# FIXME: testImportFile $TEST_ROOT/example/dir/subdir/../good.nix

# dir import with symlinked default.nix
testImportFile $TEST_ROOT/example/alt-dir
1 change: 1 addition & 0 deletions tests/local.mk
Expand Up @@ -42,6 +42,7 @@ nix_tests = \
flakes.sh \
build.sh \
compute-levels.sh \
check-imports.sh \
ca/build.sh \
ca/substitute.sh \
ca/signatures.sh \
Expand Down