Merge pull request #9429 from naoNao89/fix/stdbuf-remove-unwrap

Remove unsafe unwrap() calls in stdbuf error handling
This commit is contained in:
Sylvestre Ledru 2025-11-21 06:13:46 +01:00 committed by GitHub
commit 7c1a25a8f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 8 deletions

View file

@ -7,7 +7,6 @@
use clap::{Arg, ArgAction, ArgMatches, Command};
use std::ffi::OsString;
use std::os::unix::process::ExitStatusExt;
use std::path::PathBuf;
use std::process;
use tempfile::TempDir;
@ -188,11 +187,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let options =
ProgramOptions::try_from(&matches).map_err(|e| UUsageError::new(125, e.to_string()))?;
let mut command_values = matches.get_many::<OsString>(options::COMMAND).unwrap();
let mut command = process::Command::new(command_values.next().unwrap());
let mut command_values = matches
.get_many::<OsString>(options::COMMAND)
.ok_or_else(|| UUsageError::new(125, "no command specified".to_string()))?;
let Some(first_command) = command_values.next() else {
return Err(UUsageError::new(125, "no command specified".to_string()));
};
let mut command = process::Command::new(first_command);
let command_params: Vec<&OsString> = command_values.collect();
let tmp_dir = tempdir().unwrap();
let tmp_dir = tempdir()
.map_err(|e| UUsageError::new(125, format!("failed to create temp directory: {e}")))?;
let (preload_env, libstdbuf) = get_preload_env(&tmp_dir)?;
command.env(preload_env, libstdbuf);
set_command_env(&mut command, "_STDBUF_I", &options.stdin);
@ -229,10 +234,27 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Err(i.into())
}
}
None => Err(USimpleError::new(
1,
translate!("stdbuf-error-killed-by-signal", "signal" => status.signal().unwrap()),
)),
None => {
#[cfg(unix)]
{
use std::os::unix::process::ExitStatusExt;
let signal_msg = status
.signal()
.map(|s| s.to_string())
.unwrap_or_else(|| "unknown".to_string());
Err(USimpleError::new(
1,
translate!("stdbuf-error-killed-by-signal", "signal" => signal_msg),
))
}
#[cfg(not(unix))]
{
Err(USimpleError::new(
1,
"process terminated abnormally".to_string(),
))
}
}
}
}

View file

@ -87,6 +87,17 @@ fn test_stdbuf_no_buffer_option_fails() {
.stderr_contains("the following required arguments were not provided:");
}
#[cfg(not(target_os = "windows"))]
#[test]
fn test_stdbuf_no_command_fails_with_125() {
// Test that missing command fails with exit code 125 (stdbuf error)
// This verifies proper error handling without unwrap panic
new_ucmd!()
.args(&["-o1"])
.fails_with_code(125)
.stderr_contains("the following required arguments were not provided:");
}
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
// does not provide musl-compiled system utilities (like tail), leading to dynamic linker errors
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.