summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Thiel <sebastian.thiel@icloud.com>2020-03-01 02:20:55 +0800
committerGitHub <noreply@github.com>2020-02-29 19:20:55 +0100
commitd7a2b29f065fbb10007649aabcc4ddf66b7ca2ff (patch)
treed2f156d02fc50803aa927fbfbb9d55ff13d7cfec
parent4039c72fd350e4d91eb49d1e3e9b22155e9debaf (diff)
Assure copy_files_except_ext(..) won't copy directories into itself (#1135)
This prevents recursive copy-loops when the destination directory is contained in the source directory. Now it bails out with a descriptive error message.
-rw-r--r--src/utils/fs.rs59
1 files changed, 43 insertions, 16 deletions
diff --git a/src/utils/fs.rs b/src/utils/fs.rs
index 99456c0f..9b427384 100644
--- a/src/utils/fs.rs
+++ b/src/utils/fs.rs
@@ -109,6 +109,15 @@ pub fn copy_files_except_ext(
return Ok(());
}
+ // Is the destination inside of the source?
+ if to.canonicalize()?.starts_with(from.canonicalize()?) {
+ return Err(Error::from(format!(
+ "Destination directory cannot be contained in source directory: '{}' is in '{}'",
+ to.display(),
+ from.display()
+ )));
+ }
+
for entry in fs::read_dir(from)? {
let entry = entry?;
let metadata = entry.metadata()?;
@@ -177,63 +186,81 @@ mod tests {
use std::fs;
#[test]
- fn copy_files_except_ext_test() {
+ fn it_fails_when_destination_is_in_source() {
let tmp = match tempfile::TempDir::new() {
Ok(t) => t,
Err(e) => panic!("Could not create a temp dir: {}", e),
};
+ let dst = tmp.path().join("destination");
+ fs::create_dir(&dst).unwrap();
+ assert!(
+ format!("{:?}", copy_files_except_ext(tmp.path(), &dst, true, &[]))
+ .contains("Destination directory cannot be contained in source directory: ")
+ );
+ }
+
+ #[test]
+ fn copy_files_except_ext_test() {
+ let src = match tempfile::TempDir::new() {
+ Ok(t) => t,
+ Err(e) => panic!("Could not create a temp dir: {}", e),
+ };
// Create a couple of files
- if let Err(err) = fs::File::create(&tmp.path().join("file.txt")) {
+ if let Err(err) = fs::File::create(&src.path().join("file.txt")) {
panic!("Could not create file.txt: {}", err);
}
- if let Err(err) = fs::File::create(&tmp.path().join("file.md")) {
+ if let Err(err) = fs::File::create(&src.path().join("file.md")) {
panic!("Could not create file.md: {}", err);
}
- if let Err(err) = fs::File::create(&tmp.path().join("file.png")) {
+ if let Err(err) = fs::File::create(&src.path().join("file.png")) {
panic!("Could not create file.png: {}", err);
}
- if let Err(err) = fs::create_dir(&tmp.path().join("sub_dir")) {
+ if let Err(err) = fs::create_dir(&src.path().join("sub_dir")) {
panic!("Could not create sub_dir: {}", err);
}
- if let Err(err) = fs::File::create(&tmp.path().join("sub_dir/file.png")) {
+ if let Err(err) = fs::File::create(&src.path().join("sub_dir/file.png")) {
panic!("Could not create sub_dir/file.png: {}", err);
}
- if let Err(err) = fs::create_dir(&tmp.path().join("sub_dir_exists")) {
+ if let Err(err) = fs::create_dir(&src.path().join("sub_dir_exists")) {
panic!("Could not create sub_dir_exists: {}", err);
}
- if let Err(err) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
+ if let Err(err) = fs::File::create(&src.path().join("sub_dir_exists/file.txt")) {
panic!("Could not create sub_dir_exists/file.txt: {}", err);
}
// Create output dir
- if let Err(err) = fs::create_dir(&tmp.path().join("output")) {
+ let dst = match tempfile::TempDir::new() {
+ Ok(t) => t,
+ Err(e) => panic!("Could not create a temp dir: {}", e),
+ };
+ if let Err(err) = fs::create_dir(&dst.path().join("output")) {
panic!("Could not create output: {}", err);
}
- if let Err(err) = fs::create_dir(&tmp.path().join("output/sub_dir_exists")) {
+ if let Err(err) = fs::create_dir(&dst.path().join("output/sub_dir_exists")) {
panic!("Could not create output/sub_dir_exists: {}", err);
}
if let Err(e) =
- copy_files_except_ext(&tmp.path(), &tmp.path().join("output"), true, &["md"])
+ copy_files_except_ext(&src.path(), &dst.path().join("output"), true, &["md"])
{
panic!("Error while executing the function:\n{:?}", e);
}
// Check if the correct files where created
- if !(&tmp.path().join("output/file.txt")).exists() {
+ if !(&dst.path().join("output/file.txt")).exists() {
panic!("output/file.txt should exist")
}
- if (&tmp.path().join("output/file.md")).exists() {
+ if (&dst.path().join("output/file.md")).exists() {
panic!("output/file.md should not exist")
}
- if !(&tmp.path().join("output/file.png")).exists() {
+ if !(&dst.path().join("output/file.png")).exists() {
panic!("output/file.png should exist")
}
- if !(&tmp.path().join("output/sub_dir/file.png")).exists() {
+ if !(&dst.path().join("output/sub_dir/file.png")).exists() {
panic!("output/sub_dir/file.png should exist")
}
- if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
+ if !(&dst.path().join("output/sub_dir_exists/file.txt")).exists() {
panic!("output/sub_dir/file.png should exist")
}
}