Skip to content

Commit 46ddc72

Browse files
authored
Properly handle path with trailing slash in file matching (#2817)
* Properly handle path with trailing slash in file matching Today if a path has a trailing slash, the glob pattern will look like "/path-to-folder//**" (note the double slash). Glob doesn't work with double slash actually (it doesn't match anything). As a result, the permission management for fs_read and fs_write is broken when allowed or denied path has trailing slash. The fix is to just manually remove the trailing slash. * format change
1 parent f1a7d5b commit 46ddc72

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

crates/chat-cli/src/util/directories.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,11 @@ pub fn canonicalizes_path(os: &Os, path_as_str: &str) -> Result<String> {
193193
/// patterns to exist in a globset.
194194
pub fn add_gitignore_globs(builder: &mut GlobSetBuilder, path: &str) -> Result<()> {
195195
let glob_for_file = Glob::new(path)?;
196-
let glob_for_dir = Glob::new(&format!("{path}/**"))?;
196+
197+
// remove existing slash in path so we don't end up with double slash
198+
// Glob doesn't normalize the path so it doesn't work with double slash
199+
let dir_pattern: String = format!("{}/**", path.trim_end_matches('/'));
200+
let glob_for_dir = Glob::new(&dir_pattern)?;
197201

198202
builder.add(glob_for_file);
199203
builder.add(glob_for_dir);
@@ -278,6 +282,40 @@ mod linux_tests {
278282
assert!(logs_dir().is_ok());
279283
assert!(settings_path().is_ok());
280284
}
285+
286+
#[test]
287+
fn test_add_gitignore_globs() {
288+
let direct_file = "/home/user/a.txt";
289+
let nested_file = "/home/user/folder/a.txt";
290+
let other_file = "/home/admin/a.txt";
291+
292+
// Case 1: Path with trailing slash
293+
let mut builder1 = GlobSetBuilder::new();
294+
add_gitignore_globs(&mut builder1, "/home/user/").unwrap();
295+
let globset1 = builder1.build().unwrap();
296+
297+
assert!(globset1.is_match(direct_file));
298+
assert!(globset1.is_match(nested_file));
299+
assert!(!globset1.is_match(other_file));
300+
301+
// Case 2: Path without trailing slash - should behave same as case 1
302+
let mut builder2 = GlobSetBuilder::new();
303+
add_gitignore_globs(&mut builder2, "/home/user").unwrap();
304+
let globset2 = builder2.build().unwrap();
305+
306+
assert!(globset2.is_match(direct_file));
307+
assert!(globset2.is_match(nested_file));
308+
assert!(!globset1.is_match(other_file));
309+
310+
// Case 3: File path - should only match exact file
311+
let mut builder3 = GlobSetBuilder::new();
312+
add_gitignore_globs(&mut builder3, "/home/user/a.txt").unwrap();
313+
let globset3 = builder3.build().unwrap();
314+
315+
assert!(globset3.is_match(direct_file));
316+
assert!(!globset3.is_match(nested_file));
317+
assert!(!globset1.is_match(other_file));
318+
}
281319
}
282320

283321
// TODO(grant): Add back path tests on linux

0 commit comments

Comments
 (0)