about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2017-12-18 15:35:45 +0000
committervarkor <github@varkor.com>2017-12-18 15:35:45 +0000
commitc76cdce3d953759a53d4990af0f5fb472cbc04de (patch)
treedcbcbc14b7064b3da433a12cc9bba35969e1ea03
parent53a6d14e5bb8b1915a5f0b9371bbf0da934ed052 (diff)
downloadrust-c76cdce3d953759a53d4990af0f5fb472cbc04de.tar.gz
rust-c76cdce3d953759a53d4990af0f5fb472cbc04de.zip
Prevent rustc overwriting input files
If rustc is invoked on a file that would be overwritten by the
compilation, the compilation now fails, to avoid accidental loss. This
resolves #13019.
-rw-r--r--src/librustc/session/config.rs25
-rw-r--r--src/librustc_driver/lib.rs16
-rw-r--r--src/test/run-make/output-filename-overwrites-input/Makefile10
-rw-r--r--src/test/run-make/output-filename-overwrites-input/foo.rs11
-rw-r--r--src/test/run-make/weird-output-filenames/Makefile4
5 files changed, 63 insertions, 3 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 009fb619846..ef05c9b0779 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -528,6 +528,25 @@ impl OutputFilenames {
     pub fn filestem(&self) -> String {
         format!("{}{}", self.out_filestem, self.extra)
     }
+
+    pub fn contains_path(&self, input_path: &PathBuf) -> bool {
+        let input_path = input_path.canonicalize().ok();
+        if input_path.is_none() {
+            return false
+        }
+        match self.single_output_file {
+            Some(ref output_path) => output_path.canonicalize().ok() == input_path,
+            None => {
+                for k in self.outputs.keys() {
+                    let output_path = self.path(k.to_owned());
+                    if output_path.canonicalize().ok() == input_path {
+                        return true;
+                    }
+                }
+                false
+            }
+        }
+    }
 }
 
 pub fn host_triple() -> &'static str {
@@ -596,6 +615,12 @@ impl Options {
             ).map(|(src, dst)| (src.clone(), dst.clone())).collect()
         )
     }
+
+    /// True if there will be an output file generated
+    pub fn will_create_output_file(&self) -> bool {
+        !self.debugging_opts.parse_only && // The file is just being parsed
+            !self.debugging_opts.ls // The file is just being queried
+    }
 }
 
 // The type of entry function, so
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 29d3d31e451..2bc0b39dd0d 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -232,11 +232,25 @@ pub fn run_compiler<'a>(args: &[String],
     let loader = file_loader.unwrap_or(box RealFileLoader);
     let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
     let mut sess = session::build_session_with_codemap(
-        sopts, input_file_path, descriptions, codemap, emitter_dest,
+        sopts, input_file_path.clone(), descriptions, codemap, emitter_dest,
     );
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
+    // Ensure the source file isn't accidentally overwritten during compilation.
+    match input_file_path {
+        Some(input_file_path) => {
+            if driver::build_output_filenames(&input, &odir, &ofile, &[], &sess)
+                .contains_path(&input_file_path) && sess.opts.will_create_output_file() {
+                sess.err(&format!(
+                    "the input file \"{}\" would be overwritten by the generated executable",
+                    input_file_path.display()));
+                return (Err(CompileIncomplete::Stopped), Some(sess));
+            }
+        },
+        None => {}
+    }
+
     let mut cfg = config::build_configuration(&sess, cfg);
     target_features::add_configuration(&mut cfg, &sess);
     sess.parse_sess.config = cfg;
diff --git a/src/test/run-make/output-filename-overwrites-input/Makefile b/src/test/run-make/output-filename-overwrites-input/Makefile
new file mode 100644
index 00000000000..0554627d677
--- /dev/null
+++ b/src/test/run-make/output-filename-overwrites-input/Makefile
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+	cp foo.rs $(TMPDIR)/foo
+	$(RUSTC) $(TMPDIR)/foo 2>&1 \
+		| $(CGREP) -e "the input file \".*foo\" would be overwritten by the generated executable"
+	$(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls $(TMPDIR)/foo 2>&1
+	cp foo.rs $(TMPDIR)/foo.rs
+	$(RUSTC) $(TMPDIR)/foo.rs -o $(TMPDIR)/foo.rs 2>&1 \
+		| $(CGREP) -e "the input file \".*foo.rs\" would be overwritten by the generated executable"
diff --git a/src/test/run-make/output-filename-overwrites-input/foo.rs b/src/test/run-make/output-filename-overwrites-input/foo.rs
new file mode 100644
index 00000000000..046d27a9f0f
--- /dev/null
+++ b/src/test/run-make/output-filename-overwrites-input/foo.rs
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {}
diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make/weird-output-filenames/Makefile
index a5543e3b2c4..f161fe9f8e8 100644
--- a/src/test/run-make/weird-output-filenames/Makefile
+++ b/src/test/run-make/weird-output-filenames/Makefile
@@ -7,8 +7,8 @@ all:
 	cp foo.rs $(TMPDIR)/.foo.bar
 	$(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \
 		| $(CGREP) -e "invalid character.*in crate name:"
-	cp foo.rs $(TMPDIR)/+foo+bar
-	$(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \
+	cp foo.rs $(TMPDIR)/+foo+bar.rs
+	$(RUSTC) $(TMPDIR)/+foo+bar.rs 2>&1 \
 		| $(CGREP) -e "invalid character.*in crate name:"
 	cp foo.rs $(TMPDIR)/-foo.rs
 	$(RUSTC) $(TMPDIR)/-foo.rs 2>&1 \