mirror of
https://github.com/uutils/findutils.git
synced 2026-06-10 15:48:30 -07:00
find: -name: don't panic on a malformed POSIX bracket class
A `-name` glob with a `[.`/`[=`/`[:` introducer whose closing delimiter is missing — only a lone `]` (or the delimiter) before a multibyte char, e.g. `'[[:]é'` — panicked (exit 101). `extract_bracket_expr` searched for *either* the delimiter or `]` and then added a blind `+ 2`, which overshot into the following character and sliced off a UTF-8 boundary. Search for the actual two-byte closing sequence `<delim>]` instead. A valid class (`[:alpha:]`) is unchanged; a malformed one returns None, so the caller treats `[` literally and accepts the pattern like GNU find (exit 0). Reachable via -name/-iname/-path/-ipath/-lname/-ilname. Adds a regression test.
This commit is contained in:
@@ -83,7 +83,10 @@ fn extract_bracket_expr(pattern: &str) -> Option<(String, &str)> {
|
||||
|
||||
if matches!(delim, '.' | '=' | ':') {
|
||||
let rest = chars.as_str();
|
||||
let end = rest.find([delim, ']'])? + 2;
|
||||
// Search for the two-byte closer `<delim>]` (e.g. `:]`);
|
||||
// matching either byte alone let `+ 2` overshoot a char boundary.
|
||||
let closer = format!("{delim}]");
|
||||
let end = rest.find(closer.as_str())? + 2;
|
||||
expr.push_str(&rest[..end]);
|
||||
chars = rest[end..].chars();
|
||||
}
|
||||
@@ -222,6 +225,16 @@ mod tests {
|
||||
assert_glob_regex(r"foo[bar[!baz", r"foo\[bar\[!baz");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn malformed_posix_class_with_multibyte_char() {
|
||||
for pat in ["[[:]é", "[[:a]é", "[[.]é", "[[:é]", "[[=]😀"] {
|
||||
assert!(
|
||||
glob_to_regex(pat).is_some(),
|
||||
"panicked or rejected: {pat:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn incomplete_escape() {
|
||||
assert_eq!(glob_to_regex(r"foo\"), None);
|
||||
|
||||
Reference in New Issue
Block a user