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

Log infinite symlink offender #20985

Merged
merged 9 commits into from
Jan 10, 2025
Merged

Conversation

ndellosa95
Copy link
Contributor

@ndellosa95 ndellosa95 commented May 31, 2024

Gave this a stab since I have infinite free time now, but I have no idea how to see the warning output in tests.

Figured out the (seemingly) only way to see log output in tests is by using the env_logger crate and running with the RUST_LOG=warn env var set. The following command spits out the subsequent log messages in the tests: RUST_LOG=warn ./cargo test -p fs -- --nocapture

[2024-06-04T17:37:12Z WARN  fs::directory] Exceeded the maximum link depth while traversing link `self` to path ".". Stopping traversal.
[2024-06-04T17:37:12Z WARN  fs::directory] Exceeded the maximum link depth while traversing link `self` to path ".". Stopping traversal.

@huonw huonw added category:documentation release-notes:not-required PR doesn't require mention in release notes labels May 31, 2024
@ndellosa95 ndellosa95 changed the title Print infinite symlink offender Log infinite symlink offender Jun 4, 2024
@ndellosa95 ndellosa95 marked this pull request as ready for review June 4, 2024 19:04
Copy link
Contributor

@huonw huonw left a comment

Choose a reason for hiding this comment

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

Looks good in principle, just some minor tweaks/questions

src/rust/engine/fs/src/directory_tests.rs Outdated Show resolved Hide resolved
src/rust/engine/fs/src/directory.rs Outdated Show resolved Hide resolved
src/rust/engine/fs/src/directory.rs Outdated Show resolved Hide resolved
src/rust/engine/fs/src/directory.rs Outdated Show resolved Hide resolved
Comment on lines 650 to 651
let destination_path = if s.target == Component::CurDir.as_os_str() { None } else { Some(path_so_far.join(s.target.clone())) };
let destination_entry = root.entry_helper(root, destination_path.as_ref().unwrap_or(&path), link_depth + 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

@thejcannon you added this code originally. Can you validate that just eliding a . self symlink (and dropping the warning) seems reasonable, rather than repeatedly traversing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it may actually make sense to repeatedly traverse up to the link_depth but it seems like the logic for what gets traversed is inconsistent. If you look at the assertions for walk_too_many_links_rootdir for files we have (0..MAX_LINK_DEPTH).map(|n| ("self/".repeat(n.into()) + "file.txt")).collect::<Vec<_>>() but for directories it's just vec!["".to_string()]. So it seems like the files appear before the symlink and the directory appears afterwards in the traversal. But the reasoning behind this logic is unclear to me, nor is it clear to that this logic always holds (i.e. files always come first, then symlinks, then directories) or is just due to the way the tests are set up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A maybe more illustrative example is if you have a digest with a symlink self -> . and a subdirectory a with a file a/file.txt and a symlink a/self -> . then the contents of that subdirectory will never get traversed because it will just get hung up on the first infinite symlink.

Copy link
Member

Choose a reason for hiding this comment

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

I can't think of reason why that wouldn't be ok. And certainly if it was something we need to support the test/comments should spell that out

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can't think of reason why that wouldn't be ok. And certainly if it was something we need to support the test/comments should spell that out

@thejcannon Sorry do you mean just eliding the self -> . symlink is okay or the potential issue I'm calling out about directory contents potentially never getting traversed due to the self -> . symlink is not actually an issue?

Just eliding actually fails the tests because they expect a file named self/self/self.../file.txt. It also fails the entry_self_referencing_symlink_subdir test because we now have a directory named a/self/self/self... instead of just a.

Copy link
Member

Choose a reason for hiding this comment

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

Ah right. Good thing past josh wrote tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you explain the rationale behind having the file a/self/self.../file.txt but not the directories a/self/self...?

Copy link
Member

Choose a reason for hiding this comment

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

I think it depends on if the capture is symlink aware or not, doesn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right now it seems like it's only oblivious at the file-level though? I don't really get it but I'll trust that the unit testing logic is correct and have reverted to the original implementation except quickly constructing the logical path for better error messaging when self -> . occurs.

@huonw huonw requested a review from thejcannon June 6, 2024 04:26
@ndellosa95 ndellosa95 requested a review from huonw June 11, 2024 17:50
@cburroughs
Copy link
Contributor

Looks good in principle, just some minor tweaks/questions

Gentle status ping; @huonw is this good to land?

Copy link
Contributor

@huonw huonw left a comment

Choose a reason for hiding this comment

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

I reckon so, thanks for iterating and thanks for waiting!!

@huonw huonw merged commit c4da187 into pantsbuild:main Jan 10, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category:documentation release-notes:not-required PR doesn't require mention in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants