diff --git a/src/file/mod.rs b/src/file/mod.rs index 1cb238221..5907a79aa 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -1043,16 +1043,11 @@ impl AsRawHandle for NamedTempFile { } pub(crate) fn create_named( - mut path: PathBuf, + path: PathBuf, open_options: &mut OpenOptions, permissions: Option<&std::fs::Permissions>, keep: bool, ) -> io::Result { - // Make the path absolute. Otherwise, changing directories could cause us to - // delete the wrong file. - if !path.is_absolute() { - path = std::env::current_dir()?.join(path) - } imp::create_named(&path, open_options, permissions) .with_err_path(|| path.clone()) .map(|file| NamedTempFile { diff --git a/src/lib.rs b/src/lib.rs index 590bd8418..e0e050005 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -604,17 +604,13 @@ impl<'a, 'b> Builder<'a, 'b> { /// /// [resource-leaking]: struct.TempDir.html#resource-leaking pub fn tempdir_in>(&self, dir: P) -> io::Result { - let storage; - let mut dir = dir.as_ref(); - if !dir.is_absolute() { - let cur_dir = std::env::current_dir()?; - storage = cur_dir.join(dir); - dir = &storage; - } - - util::create_helper(dir, self.prefix, self.suffix, self.random_len, |path| { - dir::create(path, self.permissions.as_ref(), self.keep) - }) + util::create_helper( + dir.as_ref(), + self.prefix, + self.suffix, + self.random_len, + |path| dir::create(path, self.permissions.as_ref(), self.keep), + ) } /// Attempts to create a temporary file (or file-like object) using the diff --git a/src/util.rs b/src/util.rs index 63518b583..98aa36212 100644 --- a/src/util.rs +++ b/src/util.rs @@ -26,6 +26,16 @@ pub fn create_helper( random_len: usize, mut f: impl FnMut(PathBuf) -> io::Result, ) -> io::Result { + // Make the path absolute. Otherwise, changing the current directory can invalidate a stored + // path (causing issues when cleaning up temporary files. + let mut base = &*base; // re-borrow to shrink lifetime + let base_path_storage; // slot to store the absolute path, if necessary. + if !base.is_absolute() { + let cur_dir = std::env::current_dir()?; + base_path_storage = cur_dir.join(base); + base = &base_path_storage; + } + let num_retries = if random_len != 0 { crate::NUM_RETRIES } else { diff --git a/tests/namedtempfile.rs b/tests/namedtempfile.rs index 8ef302697..783ff22c2 100644 --- a/tests/namedtempfile.rs +++ b/tests/namedtempfile.rs @@ -290,6 +290,16 @@ fn test_change_dir() { assert!(!exists(path)) } +#[test] +fn test_change_dir_make() { + std::env::set_current_dir(env::temp_dir()).unwrap(); + let tmpfile = Builder::new().make_in(".", |p| File::create(p)).unwrap(); + let path = std::env::current_dir().unwrap().join(tmpfile.path()); + std::env::set_current_dir("/").unwrap(); + drop(tmpfile); + assert!(!exists(path)) +} + #[test] fn test_into_parts() { let mut file = NamedTempFile::new().unwrap();