Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/walkdir.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-02-02 01:01:08 +0300
committerAndrew Gallant <jamslam@gmail.com>2018-02-02 01:01:08 +0300
commite2b898329f64f71db06a5a0049fed5e22888aa42 (patch)
treed7785d906b164b6fb927cab78428bbbd1daa93ac
parent34857644e6ef90c60e000cba22809b923b79bb9e (diff)
traversal: more robust error handling
This fixes a bug in walkdir that happened on Windows when following symlinks. It was triggered when opening a handle to the symlink failed. In particular, this resulted in the two stacks in the walkdir iterator getting out of sync. At some point, this tripped a panic when popping from one stack would be fine but popping from the other failed because it was empty. We fix this by only pushing to both stacks if and only if both pushes would succeed. This bug was found via ripgrep. See: https://github.com/BurntSushi/ripgrep/issues/633#issuecomment-339076246
-rw-r--r--src/lib.rs4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 8808692..07f7b7a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -851,13 +851,15 @@ impl IntoIter {
});
list = DirList::Closed(entries.into_iter());
}
- self.stack_list.push(list);
if self.opts.follow_links {
let ancestor = Ancestor::new(&dent).map_err(|err| {
Error::from_io(self.depth, err)
})?;
self.stack_path.push(ancestor);
}
+ // We push this after stack_path since creating the Ancestor can fail.
+ // If it fails, then we return the error and won't descend.
+ self.stack_list.push(list);
Ok(())
}