-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix: handle invalid working directories gracefully with --full-path #1917
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
Changes from 3 commits
d3a500a
24f7f2b
26756f2
647ced8
807aa11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,9 +15,9 @@ pub struct Config { | |
| /// Whether the search is case-sensitive or case-insensitive. | ||
| pub case_sensitive: bool, | ||
|
|
||
| /// Whether to search within the full file path or just the base name (filename or directory | ||
| /// name). | ||
| pub search_full_path: bool, | ||
| /// Cached current working directory for absolute path construction. | ||
| /// Populated when `--full-path` is set; `None` means search by filename only. | ||
| pub cwd: Option<PathBuf>, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: perhaps |
||
|
|
||
| /// Whether to ignore hidden files and directories (or not). | ||
| pub ignore_hidden: bool, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,17 @@ pub fn path_absolute_form(path: &Path) -> io::Result<PathBuf> { | |||||||||||||||||||||||||||||
| env::current_dir().map(|path_buf| path_buf.join(path)) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /// Construct an absolute path from a potentially relative path and a | ||||||||||||||||||||||||||||||
| /// pre-resolved working directory. Unlike `path_absolute_form`, this | ||||||||||||||||||||||||||||||
| /// does not call `env::current_dir()` and cannot fail. | ||||||||||||||||||||||||||||||
| pub fn make_absolute(path: &Path, cwd: &Path) -> PathBuf { | ||||||||||||||||||||||||||||||
| if path.is_absolute() { | ||||||||||||||||||||||||||||||
| return path.to_path_buf(); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| let path = path.strip_prefix(".").unwrap_or(path); | ||||||||||||||||||||||||||||||
| cwd.join(path) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+32
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: it seems slightly more intuitive to me for the cwd to come first, but that might just be me. |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| pub fn absolute_path(path: &Path) -> io::Result<PathBuf> { | ||||||||||||||||||||||||||||||
| let path_buf = path_absolute_form(path)?; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -153,4 +164,40 @@ mod tests { | |||||||||||||||||||||||||||||
| Path::new("foo/bar/baz") | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||
| fn make_absolute_with_relative_path() { | ||||||||||||||||||||||||||||||
| use super::make_absolute; | ||||||||||||||||||||||||||||||
| use std::path::PathBuf; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let cwd = Path::new("/home/user"); | ||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||
| make_absolute(Path::new("foo/bar"), cwd), | ||||||||||||||||||||||||||||||
| PathBuf::from("/home/user/foo/bar") | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||
| fn make_absolute_strips_dot_prefix() { | ||||||||||||||||||||||||||||||
| use super::make_absolute; | ||||||||||||||||||||||||||||||
| use std::path::PathBuf; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let cwd = Path::new("/home/user"); | ||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||
| make_absolute(Path::new("./foo/bar"), cwd), | ||||||||||||||||||||||||||||||
| PathBuf::from("/home/user/foo/bar") | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||
| fn make_absolute_with_absolute_path() { | ||||||||||||||||||||||||||||||
| use super::make_absolute; | ||||||||||||||||||||||||||||||
| use std::path::PathBuf; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let cwd = Path::new("/home/user"); | ||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||
| make_absolute(Path::new("/absolute/path"), cwd), | ||||||||||||||||||||||||||||||
| PathBuf::from("/absolute/path") | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -524,20 +524,7 @@ impl WorkerState { | |||||||||||||||||||||||||||||||
| // Check the name first, since it doesn't require metadata | ||||||||||||||||||||||||||||||||
| let entry_path = entry.path(); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| let search_str: Cow<OsStr> = if config.search_full_path { | ||||||||||||||||||||||||||||||||
| let path_abs_buf = filesystem::path_absolute_form(entry_path) | ||||||||||||||||||||||||||||||||
| .expect("Retrieving absolute path succeeds"); | ||||||||||||||||||||||||||||||||
| Cow::Owned(path_abs_buf.as_os_str().to_os_string()) | ||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| match entry_path.file_name() { | ||||||||||||||||||||||||||||||||
| Some(filename) => Cow::Borrowed(filename), | ||||||||||||||||||||||||||||||||
| None => unreachable!( | ||||||||||||||||||||||||||||||||
| "Encountered file system entry without a file name. This should only \ | ||||||||||||||||||||||||||||||||
| happen for paths like 'foo/bar/..' or '/' which are not supposed to \ | ||||||||||||||||||||||||||||||||
| appear in a file system traversal." | ||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| let search_str = search_str_for_entry(entry_path, config.cwd.as_deref()); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if !patterns | ||||||||||||||||||||||||||||||||
| .iter() | ||||||||||||||||||||||||||||||||
|
|
@@ -676,6 +663,25 @@ impl WorkerState { | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| fn search_str_for_entry<'a>( | ||||||||||||||||||||||||||||||||
| entry_path: &'a std::path::Path, | ||||||||||||||||||||||||||||||||
| cwd: Option<&std::path::Path>, | ||||||||||||||||||||||||||||||||
| ) -> Cow<'a, OsStr> { | ||||||||||||||||||||||||||||||||
| if let Some(cwd) = cwd { | ||||||||||||||||||||||||||||||||
| let abs_path = filesystem::make_absolute(entry_path, cwd); | ||||||||||||||||||||||||||||||||
| Cow::Owned(abs_path.as_os_str().to_os_string()) | ||||||||||||||||||||||||||||||||
|
Xavrir marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| match entry_path.file_name() { | ||||||||||||||||||||||||||||||||
| Some(filename) => Cow::Borrowed(filename), | ||||||||||||||||||||||||||||||||
| None => unreachable!( | ||||||||||||||||||||||||||||||||
| "Encountered file system entry without a file name. This should only \ | ||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know you cut and pasted this code so no need to fix this in this PR, but we already have a better approach here: Lines 132 to 146 in 7027d45
I think we should expose
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noted, will keep in mind for a follow-up. |
||||||||||||||||||||||||||||||||
| happen for paths like 'foo/bar/..' or '/' which are not supposed to \ | ||||||||||||||||||||||||||||||||
| appear in a file system traversal." | ||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /// Recursively scan the given search path for files / pathnames matching the patterns. | ||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||
| /// If the `--exec` argument was supplied, this will create a thread pool for executing | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.