Merge pull request #2266 from zed-industries/avoid-panic

Avoid panic scanning recursive symlink before gitignore is encountered
This commit is contained in:
Julia 2023-03-10 17:19:55 -05:00 committed by GitHub
commit 09d306df85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2361,7 +2361,7 @@ impl BackgroundScanner {
job: &ScanJob, job: &ScanJob,
) -> Result<()> { ) -> Result<()> {
let mut new_entries: Vec<Entry> = Vec::new(); let mut new_entries: Vec<Entry> = Vec::new();
let mut new_jobs: Vec<ScanJob> = Vec::new(); let mut new_jobs: Vec<Option<ScanJob>> = Vec::new();
let mut ignore_stack = job.ignore_stack.clone(); let mut ignore_stack = job.ignore_stack.clone();
let mut new_ignore = None; let mut new_ignore = None;
@ -2374,6 +2374,7 @@ impl BackgroundScanner {
continue; continue;
} }
}; };
let child_name = child_abs_path.file_name().unwrap(); let child_name = child_abs_path.file_name().unwrap();
let child_path: Arc<Path> = job.path.join(child_name).into(); let child_path: Arc<Path> = job.path.join(child_name).into();
let child_metadata = match self.fs.metadata(&child_abs_path).await { let child_metadata = match self.fs.metadata(&child_abs_path).await {
@ -2412,12 +2413,15 @@ impl BackgroundScanner {
let entry_abs_path = self.abs_path().join(&entry.path); let entry_abs_path = self.abs_path().join(&entry.path);
entry.is_ignored = entry.is_ignored =
ignore_stack.is_abs_path_ignored(&entry_abs_path, entry.is_dir()); ignore_stack.is_abs_path_ignored(&entry_abs_path, entry.is_dir());
if entry.is_dir() { if entry.is_dir() {
new_jobs.next().unwrap().ignore_stack = if entry.is_ignored { if let Some(job) = new_jobs.next().expect("Missing scan job for entry") {
IgnoreStack::all() job.ignore_stack = if entry.is_ignored {
} else { IgnoreStack::all()
ignore_stack.clone() } else {
}; ignore_stack.clone()
};
}
} }
} }
} }
@ -2433,10 +2437,12 @@ impl BackgroundScanner {
let is_ignored = ignore_stack.is_abs_path_ignored(&child_abs_path, true); let is_ignored = ignore_stack.is_abs_path_ignored(&child_abs_path, true);
child_entry.is_ignored = is_ignored; child_entry.is_ignored = is_ignored;
// Avoid recursing until crash in the case of a recursive symlink
if !job.ancestor_inodes.contains(&child_entry.inode) { if !job.ancestor_inodes.contains(&child_entry.inode) {
let mut ancestor_inodes = job.ancestor_inodes.clone(); let mut ancestor_inodes = job.ancestor_inodes.clone();
ancestor_inodes.insert(child_entry.inode); ancestor_inodes.insert(child_entry.inode);
new_jobs.push(ScanJob {
new_jobs.push(Some(ScanJob {
abs_path: child_abs_path, abs_path: child_abs_path,
path: child_path, path: child_path,
ignore_stack: if is_ignored { ignore_stack: if is_ignored {
@ -2446,7 +2452,9 @@ impl BackgroundScanner {
}, },
ancestor_inodes, ancestor_inodes,
scan_queue: job.scan_queue.clone(), scan_queue: job.scan_queue.clone(),
}); }));
} else {
new_jobs.push(None);
} }
} else { } else {
child_entry.is_ignored = ignore_stack.is_abs_path_ignored(&child_abs_path, false); child_entry.is_ignored = ignore_stack.is_abs_path_ignored(&child_abs_path, false);
@ -2461,8 +2469,11 @@ impl BackgroundScanner {
new_ignore, new_ignore,
self.fs.as_ref(), self.fs.as_ref(),
); );
for new_job in new_jobs { for new_job in new_jobs {
job.scan_queue.send(new_job).await.unwrap(); if let Some(new_job) = new_job {
job.scan_queue.send(new_job).await.unwrap();
}
} }
Ok(()) Ok(())