mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-08-27 18:33:54 -07:00
globset: fix bug where trailing .
in file name was incorrectly handled
I'm not sure why I did this, but I think I was trying to imitate the contract of [`std::path::Path::file_name`]: > Returns None if the path terminates in `..`. But the status quo clearly did not implement this. And as a result, if you have a glob that ends in a `.`, it was instead treated as the empty string (which only matches the empty string). We fix this by implementing the semantic from the standard library correctly. Fixes #2990 [`std::path::Path::file_name`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.file_name
This commit is contained in:
@@ -4,21 +4,25 @@ use bstr::{ByteSlice, ByteVec};
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in `.`, `..`, or consists solely of a root of
|
||||
/// prefix, file_name will return None.
|
||||
/// If the path terminates in `..`, or consists solely of a root of prefix,
|
||||
/// file_name will return `None`.
|
||||
pub(crate) fn file_name<'a>(path: &Cow<'a, [u8]>) -> Option<Cow<'a, [u8]>> {
|
||||
if path.last_byte().map_or(true, |b| b == b'.') {
|
||||
if path.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let last_slash = path.rfind_byte(b'/').map(|i| i + 1).unwrap_or(0);
|
||||
Some(match *path {
|
||||
let got = match *path {
|
||||
Cow::Borrowed(path) => Cow::Borrowed(&path[last_slash..]),
|
||||
Cow::Owned(ref path) => {
|
||||
let mut path = path.clone();
|
||||
path.drain_bytes(..last_slash);
|
||||
Cow::Owned(path)
|
||||
}
|
||||
})
|
||||
};
|
||||
if got == &b".."[..] {
|
||||
return None;
|
||||
}
|
||||
Some(got)
|
||||
}
|
||||
|
||||
/// Return a file extension given a path's file name.
|
||||
|
Reference in New Issue
Block a user