1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 23:34:47 -05:00

fix(upgrade): ensure temp dir cleanup on failure (#17535)

Closes #17533
This commit is contained in:
David Sherret 2023-01-26 09:02:25 -05:00 committed by GitHub
parent 7b6339da6a
commit 21065797f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 12 deletions

View file

@ -111,9 +111,14 @@ async fn get_base_binary(
} }
let archive_data = tokio::fs::read(binary_path).await?; let archive_data = tokio::fs::read(binary_path).await?;
let base_binary_path = let temp_dir = secure_tempfile::TempDir::new()?;
crate::tools::upgrade::unpack(archive_data, target.contains("windows"))?; let base_binary_path = crate::tools::upgrade::unpack_into_dir(
archive_data,
target.contains("windows"),
&temp_dir,
)?;
let base_binary = tokio::fs::read(base_binary_path).await?; let base_binary = tokio::fs::read(base_binary_path).await?;
drop(temp_dir); // delete the temp dir
Ok(base_binary) Ok(base_binary)
} }

View file

@ -377,7 +377,8 @@ pub async fn upgrade(
log::info!("Deno is upgrading to version {}", &install_version); log::info!("Deno is upgrading to version {}", &install_version);
let new_exe_path = unpack(archive_data, cfg!(windows))?; let temp_dir = secure_tempfile::TempDir::new()?;
let new_exe_path = unpack_into_dir(archive_data, cfg!(windows), &temp_dir)?;
fs::set_permissions(&new_exe_path, permissions)?; fs::set_permissions(&new_exe_path, permissions)?;
check_exe(&new_exe_path)?; check_exe(&new_exe_path)?;
@ -423,6 +424,7 @@ pub async fn upgrade(
} }
} }
drop(temp_dir); // delete the temp dir
Ok(()) Ok(())
} }
@ -469,18 +471,16 @@ async fn download_package(
} }
} }
pub fn unpack( pub fn unpack_into_dir(
archive_data: Vec<u8>, archive_data: Vec<u8>,
is_windows: bool, is_windows: bool,
temp_dir: &secure_tempfile::TempDir,
) -> Result<PathBuf, std::io::Error> { ) -> Result<PathBuf, std::io::Error> {
const EXE_NAME: &str = "deno"; const EXE_NAME: &str = "deno";
// We use into_path so that the tempdir is not automatically deleted. This is let temp_dir_path = temp_dir.path();
// useful for debugging upgrade, but also so this function can return a path
// to the newly uncompressed file without fear of the tempdir being deleted.
let temp_dir = secure_tempfile::TempDir::new()?.into_path();
let exe_ext = if is_windows { "exe" } else { "" }; let exe_ext = if is_windows { "exe" } else { "" };
let archive_path = temp_dir.join(EXE_NAME).with_extension("zip"); let archive_path = temp_dir_path.join(EXE_NAME).with_extension("zip");
let exe_path = temp_dir.join(EXE_NAME).with_extension(exe_ext); let exe_path = temp_dir_path.join(EXE_NAME).with_extension(exe_ext);
assert!(!exe_path.exists()); assert!(!exe_path.exists());
let archive_ext = Path::new(&*ARCHIVE_NAME) let archive_ext = Path::new(&*ARCHIVE_NAME)
@ -509,14 +509,14 @@ pub fn unpack(
.arg("-Path") .arg("-Path")
.arg(format!("'{}'", &archive_path.to_str().unwrap())) .arg(format!("'{}'", &archive_path.to_str().unwrap()))
.arg("-DestinationPath") .arg("-DestinationPath")
.arg(format!("'{}'", &temp_dir.to_str().unwrap())) .arg(format!("'{}'", &temp_dir_path.to_str().unwrap()))
.spawn()? .spawn()?
.wait()? .wait()?
} }
"zip" => { "zip" => {
fs::write(&archive_path, &archive_data)?; fs::write(&archive_path, &archive_data)?;
Command::new("unzip") Command::new("unzip")
.current_dir(&temp_dir) .current_dir(temp_dir_path)
.arg(&archive_path) .arg(&archive_path)
.spawn() .spawn()
.map_err(|err| { .map_err(|err| {