summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/standalone.rs19
-rw-r--r--cli/tests/integration_tests.rs98
2 files changed, 117 insertions, 0 deletions
diff --git a/cli/standalone.rs b/cli/standalone.rs
index 067fec36a..6559242bd 100644
--- a/cli/standalone.rs
+++ b/cli/standalone.rs
@@ -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)]
{
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index eeffb0097..cb6dfad6d 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -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());
+}