Skip to content

Commit 6240d45

Browse files
committed
Fix ICE caused by at-expanding argument 0 instead of removing it early
1 parent f1b1ed7 commit 6240d45

File tree

4 files changed

+24
-5
lines changed

4 files changed

+24
-5
lines changed

compiler/rustc_driver_impl/src/args.rs

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
1818
}
1919
}
2020

21+
/// **Note:** This function doesn't interpret argument 0 in any special way.
22+
/// If this function is intended to be used with command line arguments,
23+
/// `argv[0]` must be removed prior to calling it manually.
2124
pub fn arg_expand_all(at_args: &[String]) -> Vec<String> {
2225
let mut args = Vec::new();
2326
for arg in at_args {

compiler/rustc_driver_impl/src/lib.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ fn run_compiler(
237237
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
238238
>,
239239
) -> interface::Result<()> {
240+
// Throw away the first argument, the name of the binary.
241+
// In case of at_args being empty, as might be the case by
242+
// passing empty argument array to execve under some platforms,
243+
// just use an empty slice.
244+
//
245+
// This situation was possible before due to arg_expand_all being
246+
// called before removing the argument, enabling a crash by calling
247+
// the compiler with @empty_file as argv[0] and no more arguments.
248+
let at_args = at_args.get(1..).unwrap_or_default();
249+
240250
let args = args::arg_expand_all(at_args);
241251

242252
let Some(matches) = handle_options(&args) else { return Ok(()) };
@@ -993,9 +1003,6 @@ pub fn print_flag_list<T>(
9931003
/// So with all that in mind, the comments below have some more detail about the
9941004
/// contortions done here to get things to work out correctly.
9951005
pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
996-
// Throw away the first argument, the name of the binary
997-
let args = &args[1..];
998-
9991006
if args.is_empty() {
10001007
// user did not write `-v` nor `-Z unstable-options`, so do not
10011008
// include that extra information.

src/librustdoc/config.rs

-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ impl Options {
321321
matches: &getopts::Matches,
322322
args: Vec<String>,
323323
) -> Result<(Options, RenderOptions), i32> {
324-
let args = &args[1..];
325324
// Check for unstable options.
326325
nightly_options::check_nightly_options(matches, &opts());
327326

src/librustdoc/lib.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -703,13 +703,23 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
703703
}
704704

705705
fn main_args(at_args: &[String]) -> MainResult {
706+
// Throw away the first argument, the name of the binary.
707+
// In case of at_args being empty, as might be the case by
708+
// passing empty argument array to execve under some platforms,
709+
// just use an empty slice.
710+
//
711+
// This situation was possible before due to arg_expand_all being
712+
// called before removing the argument, enabling a crash by calling
713+
// the compiler with @empty_file as argv[0] and no more arguments.
714+
let at_args = at_args.get(1..).unwrap_or_default();
715+
706716
let args = rustc_driver::args::arg_expand_all(at_args);
707717

708718
let mut options = getopts::Options::new();
709719
for option in opts() {
710720
(option.apply)(&mut options);
711721
}
712-
let matches = match options.parse(&args[1..]) {
722+
let matches = match options.parse(&args) {
713723
Ok(m) => m,
714724
Err(err) => {
715725
early_error(ErrorOutputType::default(), &err.to_string());

0 commit comments

Comments
 (0)