Skip to content

Comments

Fix symlink handling#9363

Merged
edolstra merged 1 commit intoNixOS:masterfrom
edolstra:symlink-regression
Nov 17, 2023
Merged

Fix symlink handling#9363
edolstra merged 1 commit intoNixOS:masterfrom
edolstra:symlink-regression

Conversation

@edolstra
Copy link
Member

Motivation

This restores the symlink handling behaviour prior to 94812cc.

Fixes #9298.

Context

Priorities

Add 👍 to pull requests you find important.

This restores the symlink handling behaviour prior to
94812cc.

Fixes NixOS#9298.
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Nov 16, 2023
@Ericson2314
Copy link
Member

Do you think this will fix #9306 ?

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to say what limit it ran into?

Suggested change
throw Error("too many symbolic links encountered while traversing the path '%s'", path);
throw Error("too many symbolic links encountered while traversing the path '%s' (limit is %d)", path, maxFollow);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, if you have more than 1024 symlinks, it's almost certainly a cycle.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then let's be explicit about intent, then users will know what to do with the error:

Suggested change
throw Error("too many symbolic links encountered while traversing the path '%s'", path);
throw Error("more than %d symbolic links encountered while traversing the path '%s' (there is probably a cycle)", path, maxFollow);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coreutils:

$ ln -s bar foo
$ ln -s foo bar
$ cat foo
cat: foo: Too many levels of symbolic links

Of course coreutils is kinda bad with error messages, but we can align with it for a consistent user experience and improve on it.

Suggested change
throw Error("too many symbolic links encountered while traversing the path '%s'", path);
throw Error("too many levels of symbolic links while traversing the path '%s'; assuming it's part of a cycle after %d indirections", originalPath, maxFollows);

It would also be slightly more helpful to show the original path instead of an arbitrary path within the cycle, in case it's not the cycle that's the mistake, but rather the use of the cycle. Also note that the original symlink does not even have to be part of the cycle; it only has to lead to it.

@fricklerhandwerk fricklerhandwerk added the regression Something doesn't work anymore label Nov 16, 2023
SourcePath resolveExprPath(const SourcePath & path)
SourcePath resolveExprPath(SourcePath path)
{
unsigned int followCount = 0, maxFollow = 1024;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsigned int followCount = 0, maxFollow = 1024;
unsigned int followCount = 0, maxFollow = 1000;

1024 would suggest some base-2 exponential behavior.

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))};
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if I understand correctly, this is a "shallow" version of resolveSymlinks that only resolves the final path component?

In any case, this code should have a name and not be in the parser. Could you put this in a method like SourcePath::followSymlink perhaps?

I haven't had enough coffee yet to really understand the subtlety between the two methods yet, so if you could describe that in the doc comments, that will probably even help those who aren't caffeine deprived.

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coreutils:

$ ln -s bar foo
$ ln -s foo bar
$ cat foo
cat: foo: Too many levels of symbolic links

Of course coreutils is kinda bad with error messages, but we can align with it for a consistent user experience and improve on it.

Suggested change
throw Error("too many symbolic links encountered while traversing the path '%s'", path);
throw Error("too many levels of symbolic links while traversing the path '%s'; assuming it's part of a cycle after %d indirections", originalPath, maxFollows);

It would also be slightly more helpful to show the original path instead of an arbitrary path within the cycle, in case it's not the cycle that's the mistake, but rather the use of the cycle. Also note that the original symlink does not even have to be part of the cycle; it only has to lead to it.

@edolstra edolstra merged commit 3a7f024 into NixOS:master Nov 17, 2023
@edolstra edolstra deleted the symlink-regression branch November 17, 2023 13:11
@github-actions
Copy link

Backport failed for 2.16-maintenance, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 2.16-maintenance
git worktree add -d .worktree/backport-9363-to-2.16-maintenance origin/2.16-maintenance
cd .worktree/backport-9363-to-2.16-maintenance
git switch --create backport-9363-to-2.16-maintenance
git cherry-pick -x 31ebc6028b3682969d86a7b39ae87131c41cc604

@github-actions
Copy link

Backport failed for 2.17-maintenance, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 2.17-maintenance
git worktree add -d .worktree/backport-9363-to-2.17-maintenance origin/2.17-maintenance
cd .worktree/backport-9363-to-2.17-maintenance
git switch --create backport-9363-to-2.17-maintenance
git cherry-pick -x 31ebc6028b3682969d86a7b39ae87131c41cc604

@github-actions
Copy link

Backport failed for 2.18-maintenance, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 2.18-maintenance
git worktree add -d .worktree/backport-9363-to-2.18-maintenance origin/2.18-maintenance
cd .worktree/backport-9363-to-2.18-maintenance
git switch --create backport-9363-to-2.18-maintenance
git cherry-pick -x 31ebc6028b3682969d86a7b39ae87131c41cc604

@github-actions
Copy link

Backport failed for 2.16-maintenance, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 2.16-maintenance
git worktree add -d .worktree/backport-9363-to-2.16-maintenance origin/2.16-maintenance
cd .worktree/backport-9363-to-2.16-maintenance
git switch --create backport-9363-to-2.16-maintenance
git cherry-pick -x 31ebc6028b3682969d86a7b39ae87131c41cc604

@github-actions
Copy link

Backport failed for 2.17-maintenance, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin 2.17-maintenance
git worktree add -d .worktree/backport-9363-to-2.17-maintenance origin/2.17-maintenance
cd .worktree/backport-9363-to-2.17-maintenance
git switch --create backport-9363-to-2.17-maintenance
git cherry-pick -x 31ebc6028b3682969d86a7b39ae87131c41cc604

@github-actions
Copy link

Successfully created backport PR for 2.18-maintenance:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug regression Something doesn't work anymore with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression in symlink handling in 2.16

4 participants