1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-26 16:09:27 -05:00

fix(cli/compile): error when the output path already exists (#8681)

This commit is contained in:
Yosi Pramajaya 2020-12-13 02:41:43 +07:00 committed by GitHub
parent 623bc22ad0
commit 84ef9bd21f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 0 deletions

View file

@ -5,6 +5,7 @@ use crate::tokio_util;
use crate::version;
use crate::worker::MainWorker;
use crate::worker::WorkerOptions;
use deno_core::error::bail;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
@ -169,6 +170,24 @@ pub async fn create_standalone_binary(
} else {
output
};
if output.exists() {
// If the output is a directory, throw error
if output.is_dir() {
bail!("Could not compile: {:?} is a directory.", &output);
}
// Make sure we don't overwrite any file not created by Deno compiler.
// Check for magic trailer in last 16 bytes
let mut output_file = File::open(&output)?;
output_file.seek(SeekFrom::End(-16))?;
let mut trailer = [0; 16];
output_file.read_exact(&mut trailer)?;
let (magic_trailer, _) = trailer.split_at(8);
if magic_trailer != MAGIC_TRAILER {
bail!("Could not compile: cannot overwrite {:?}.", &output);
}
}
tokio::fs::write(&output, final_bin).await?;
#[cfg(unix)]
{

View file

@ -4650,3 +4650,101 @@ fn standalone_no_module_load() {
assert!(util::strip_ansi_codes(&stderr_str)
.contains("Self-contained binaries don't support module loading"));
}
#[test]
fn compile_with_directory_exists_error() {
let dir = TempDir::new().expect("tempdir fail");
let exe = if cfg!(windows) {
dir.path().join("args.exe")
} else {
dir.path().join("args")
};
std::fs::create_dir(&exe).expect("cannot create directory");
let output = util::deno_cmd()
.current_dir(util::root_path())
.arg("compile")
.arg("--unstable")
.arg("./cli/tests/028_args.ts")
.arg("--output")
.arg(&exe)
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(!output.status.success());
let expected_stderr =
format!("Could not compile: {:?} is a directory.\n", &exe);
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains(&expected_stderr));
}
#[test]
fn compile_with_conflict_file_exists_error() {
let dir = TempDir::new().expect("tempdir fail");
let exe = if cfg!(windows) {
dir.path().join("args.exe")
} else {
dir.path().join("args")
};
std::fs::write(&exe, b"SHOULD NOT BE OVERWRITTEN")
.expect("cannot create file");
let output = util::deno_cmd()
.current_dir(util::root_path())
.arg("compile")
.arg("--unstable")
.arg("./cli/tests/028_args.ts")
.arg("--output")
.arg(&exe)
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(!output.status.success());
let expected_stderr =
format!("Could not compile: cannot overwrite {:?}.\n", &exe);
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains(&expected_stderr));
assert!(std::fs::read(&exe)
.expect("cannot read file")
.eq(b"SHOULD NOT BE OVERWRITTEN"));
}
#[test]
fn compile_and_overwrite_file() {
let dir = TempDir::new().expect("tempdir fail");
let exe = if cfg!(windows) {
dir.path().join("args.exe")
} else {
dir.path().join("args")
};
let output = util::deno_cmd()
.current_dir(util::root_path())
.arg("compile")
.arg("--unstable")
.arg("./cli/tests/028_args.ts")
.arg("--output")
.arg(&exe)
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
assert!(&exe.exists());
let recompile_output = util::deno_cmd()
.current_dir(util::root_path())
.arg("compile")
.arg("--unstable")
.arg("./cli/tests/028_args.ts")
.arg("--output")
.arg(&exe)
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(recompile_output.status.success());
}