diff options
| author | varkor <github@varkor.com> | 2017-12-18 15:35:45 +0000 |
|---|---|---|
| committer | varkor <github@varkor.com> | 2017-12-18 15:35:45 +0000 |
| commit | c76cdce3d953759a53d4990af0f5fb472cbc04de (patch) | |
| tree | dcbcbc14b7064b3da433a12cc9bba35969e1ea03 | |
| parent | 53a6d14e5bb8b1915a5f0b9371bbf0da934ed052 (diff) | |
| download | rust-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.rs | 25 | ||||
| -rw-r--r-- | src/librustc_driver/lib.rs | 16 | ||||
| -rw-r--r-- | src/test/run-make/output-filename-overwrites-input/Makefile | 10 | ||||
| -rw-r--r-- | src/test/run-make/output-filename-overwrites-input/foo.rs | 11 | ||||
| -rw-r--r-- | src/test/run-make/weird-output-filenames/Makefile | 4 |
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 \ |
