Conversation
This restores the symlink handling behaviour prior to 94812cc. Fixes NixOS#9298.
|
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); |
There was a problem hiding this comment.
We may want to say what limit it ran into?
| 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); |
There was a problem hiding this comment.
Nah, if you have more than 1024 symlinks, it's almost certainly a cycle.
There was a problem hiding this comment.
Then let's be explicit about intent, then users will know what to do with the error:
| 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); |
There was a problem hiding this comment.
coreutils:
$ ln -s bar foo
$ ln -s foo bar
$ cat foo
cat: foo: Too many levels of symbolic linksOf course coreutils is kinda bad with error messages, but we can align with it for a consistent user experience and improve on it.
| 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.
| SourcePath resolveExprPath(const SourcePath & path) | ||
| SourcePath resolveExprPath(SourcePath path) | ||
| { | ||
| unsigned int followCount = 0, maxFollow = 1024; |
There was a problem hiding this comment.
| 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))}; | ||
| } |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
coreutils:
$ ln -s bar foo
$ ln -s foo bar
$ cat foo
cat: foo: Too many levels of symbolic linksOf course coreutils is kinda bad with error messages, but we can align with it for a consistent user experience and improve on it.
| 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.
|
Backport failed for 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 |
|
Backport failed for 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 |
|
Backport failed for 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 |
|
Backport failed for 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 |
|
Backport failed for 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 |
|
Successfully created backport PR for |
Motivation
This restores the symlink handling behaviour prior to 94812cc.
Fixes #9298.
Context
Priorities
Add 👍 to pull requests you find important.