cptree doesn't check for symlink loops, loops forever
mberndt123 opened this issue · comments
Hi,
imagine the following directory structure:
mkdir /tmp/foo
ln -s /tmp/foo /tmp/foo/foo
Now when you run cptree "/tmp/foo" "/tmp/bar"
, it treats the symlink as a directory and recurses, and you end up with a directory structure like /tmp/bar/foo/foo/foo/foo/foo/foo/...
.
So before recursing it should probably check whether the file is a symlink and if so, create a new symlink in the target directory.
Note: I haven't checked how rmtree behaves, but if it does the same (i. e. recurse into symlinked directories), the results may be catastrophic. Just imagine trying to delete a symlink to $HOME
😱
Fix up here: #344
Wow, thanks for taking care of this so quickly! I left some minor stylistic comments, but the code looks good to me.
Hm, now that I think about it: Maybe it makes sense to create a new version of lstree
that implements this behaviour? Because the current implementation of lstree
crashes whenever it encounters a symlink loop, and I don't think anyone ever wants that behaviour.
@mberndt123: How common are symlink loops in the wild?
Also, rather than create a new version of lstree
it might be better to instead promote isNotSymbolicLink
to a top-level utility that can be used by lsif
(possibly in conjunction with other predicates) or used in isolation
I don't have any data regarding how common this is. I found such a loop when I was compiling a Linux kernel for an embedded device. The build system creates a link to the source directory in the build directory, so when the build directory is inside the source directory, you'll get a loop.
I also found a bug report in the Jenkins bug tracker that describes problems with such symlinks. So I don't know how common this is, but it does happen in the wild.
Anyway, I don't think the current behaviour of lstree is safe. Users should be able to call such a function without having to worry about crashes and endless loops, don't you agree?
Another way to deal with this would be to simply change the behaviour of lstree to not recurse into directory symlinks. The question is whether somebody currently relies on that behaviour.
@mberndt123: What I'll do for right now is export isNotSymbolicLink
so that people can use lsif isNotSymbolicLink
to avoid descending into symlinks. If more people complain about the default behavior of lstree
then I'll change it