about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2017-05-19 14:16:24 -0600
committerGitHub <noreply@github.com>2017-05-19 14:16:24 -0600
commitfd8ca3ea6d9dbd09336f882ec9a2952a752954b5 (patch)
tree378a1d370dedb584c0f657ad6bc218d9077c92f6
parent7812adf1ee3b410ca367958f0d7275992982b031 (diff)
parente86588e2286ac2c0fb4763bf2d8c3046d0abcc22 (diff)
downloadrust-fd8ca3ea6d9dbd09336f882ec9a2952a752954b5.tar.gz
rust-fd8ca3ea6d9dbd09336f882ec9a2952a752954b5.zip
Rollup merge of #42092 - cuviper:args_os, r=Mark-Simulacrum
Give a nicer error for non-Unicode arguments to rustc and rustdoc

Previously, any non-Unicode argument would panic rustc:

```
$ rustc $'foo\x80bar'
error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report:
https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value:
"foo�bar"', /checkout/src/libcore/result.rs:859 note: Run with
`RUST_BACKTRACE=1` for a backtrace.
```

Now it gives a clean error:

```
$ rustc $'foo\x80bar'
error: Argument 1 is not valid Unicode: "foo�bar"
```

Maybe fixes #15890, although we still can't *compile* arbitrary file names.
-rw-r--r--src/librustc_driver/lib.rs11
-rw-r--r--src/librustdoc/lib.rs11
2 files changed, 19 insertions, 3 deletions
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 34f636d0b9a..18a57f78a50 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1148,9 +1148,18 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
     Registry::new(&all_errors)
 }
 
+fn get_args() -> Vec<String> {
+    env::args_os().enumerate()
+        .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
+             early_error(ErrorOutputType::default(),
+                         &format!("Argument {} is not valid Unicode: {:?}", i, arg))
+         }))
+        .collect()
+}
+
 pub fn main() {
     env_logger::init().unwrap();
-    let result = run(|| run_compiler(&env::args().collect::<Vec<_>>(),
+    let result = run(|| run_compiler(&get_args(),
                                      &mut RustcDefaultCalls,
                                      None,
                                      None));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bbaa7bc2fb6..f682f6aa763 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -107,12 +107,19 @@ pub fn main() {
     const STACK_SIZE: usize = 32_000_000; // 32MB
     env_logger::init().unwrap();
     let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
-        let s = env::args().collect::<Vec<_>>();
-        main_args(&s)
+        get_args().map(|args| main_args(&args)).unwrap_or(1)
     }).unwrap().join().unwrap_or(101);
     process::exit(res as i32);
 }
 
+fn get_args() -> Option<Vec<String>> {
+    env::args_os().enumerate()
+        .map(|(i, arg)| arg.into_string().map_err(|arg| {
+             print_error(format!("Argument {} is not valid Unicode: {:?}", i, arg));
+        }).ok())
+        .collect()
+}
+
 fn stable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::stable(g) }
 fn unstable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::unstable(g) }