From d47036cbd1e181da6eca7f4f125e092bedeb35e0 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sun, 7 Feb 2016 19:31:14 +0100 Subject: Don't let `remove_dir_all` recursively remove a symlink See #29412 --- src/libstd/sys/windows/fs.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/libstd/sys/windows') diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 9f9290b751d..b0decfa463f 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -525,11 +525,22 @@ pub fn rmdir(p: &Path) -> io::Result<()> { } pub fn remove_dir_all(path: &Path) -> io::Result<()> { + let filetype = try!(lstat(path)).file_type(); + if filetype.is_symlink() { + // On Windows symlinks to files and directories are removed differently. + // rmdir only deletes dir symlinks and junctions, not file symlinks. + rmdir(path) + } else { + remove_dir_all_recursive(path) + } +} + +fn remove_dir_all_recursive(path: &Path) -> io::Result<()> { for child in try!(readdir(path)) { let child = try!(child); let child_type = try!(child.file_type()); if child_type.is_dir() { - try!(remove_dir_all(&child.path())); + try!(remove_dir_all_recursive(&child.path())); } else if child_type.is_symlink_dir() { try!(rmdir(&child.path())); } else { -- cgit 1.4.1-3-g733a5