From 1e154840addd127f0625d0e4fdf312059534b1be Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 11 Apr 2024 11:48:41 -0400 Subject: [PATCH] Avoid TOCTOU errors in cache initialization --- crates/ruff/src/cache.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/ruff/src/cache.rs b/crates/ruff/src/cache.rs index dddd8cb64a3aa0..0d3addfef6be44 100644 --- a/crates/ruff/src/cache.rs +++ b/crates/ruff/src/cache.rs @@ -375,15 +375,17 @@ pub(crate) fn init(path: &Path) -> Result<()> { fs::create_dir_all(path.join(VERSION))?; // Add the CACHEDIR.TAG. - if !cachedir::is_tagged(path)? { - cachedir::add_tag(path)?; - } + cachedir::ensure_tag(&path)?; // Add the .gitignore. - let gitignore_path = path.join(".gitignore"); - if !gitignore_path.exists() { - let mut file = fs::File::create(gitignore_path)?; - file.write_all(b"# Automatically created by ruff.\n*\n")?; + match fs::OpenOptions::new() + .write(true) + .create_new(true) + .open(path.join(".gitignore")) + { + Ok(mut file) => file.write_all(b"# Automatically created by ruff.\n*\n")?, + Err(err) if err.kind() == io::ErrorKind::AlreadyExists => (), + Err(err) => return Err(err.into()), } Ok(())