mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Fix stdbuf to handle non-UTF-8 filenames
This commit is contained in:
@@ -6,8 +6,7 @@
|
||||
// spell-checker:ignore (ToDO) COMFOLLOW Chowner RFILE RFILE's derefer dgid nonblank nonprint nonprinting
|
||||
|
||||
use uucore::display::Quotable;
|
||||
pub use uucore::entries;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::entries;
|
||||
use uucore::error::{FromIo, UResult, USimpleError};
|
||||
use uucore::format_usage;
|
||||
use uucore::perms::{GidUidOwnerFilter, IfFrom, chown_base, options};
|
||||
|
||||
@@ -201,12 +201,11 @@ fn find_last_contiguous_block_of_xs(s: &str) -> Option<(usize, usize)> {
|
||||
impl Params {
|
||||
fn from(options: Options) -> Result<Self, MkTempError> {
|
||||
// Convert OsString template to string for processing
|
||||
let template_str = match options.template.to_str() {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
// For non-UTF-8 templates, return an error
|
||||
return Err(MkTempError::InvalidTemplate(options.template.to_string_lossy().into_owned()));
|
||||
}
|
||||
let Some(template_str) = options.template.to_str() else {
|
||||
// For non-UTF-8 templates, return an error
|
||||
return Err(MkTempError::InvalidTemplate(
|
||||
options.template.to_string_lossy().into_owned(),
|
||||
));
|
||||
};
|
||||
|
||||
// The template argument must end in 'X' if a suffix option is given.
|
||||
@@ -241,7 +240,9 @@ impl Params {
|
||||
.display()
|
||||
.to_string();
|
||||
if options.treat_as_template && prefix_from_template.contains(MAIN_SEPARATOR) {
|
||||
return Err(MkTempError::PrefixContainsDirSeparator(template_str.to_string()));
|
||||
return Err(MkTempError::PrefixContainsDirSeparator(
|
||||
template_str.to_string(),
|
||||
));
|
||||
}
|
||||
if tmpdir.is_some() && Path::new(prefix_from_template).is_absolute() {
|
||||
return Err(MkTempError::InvalidTemplate(template_str.to_string()));
|
||||
@@ -465,7 +466,11 @@ pub fn uu_app() -> Command {
|
||||
.help(translate!("mktemp-help-t"))
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(Arg::new(ARG_TEMPLATE).num_args(..=1).value_parser(clap::value_parser!(OsString)))
|
||||
.arg(
|
||||
Arg::new(ARG_TEMPLATE)
|
||||
.num_args(..=1)
|
||||
.value_parser(clap::value_parser!(OsString)),
|
||||
)
|
||||
}
|
||||
|
||||
fn dry_exec(tmpdir: &Path, prefix: &str, rand: usize, suffix: &str) -> UResult<PathBuf> {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// spell-checker:ignore (ToDO) tempdir dyld dylib optgrps libstdbuf
|
||||
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use std::ffi::OsString;
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
@@ -183,9 +184,9 @@ 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::<String>(options::COMMAND).unwrap();
|
||||
let mut command_values = matches.get_many::<OsString>(options::COMMAND).unwrap();
|
||||
let mut command = process::Command::new(command_values.next().unwrap());
|
||||
let command_params: Vec<&str> = command_values.map(|s| s.as_ref()).collect();
|
||||
let command_params: Vec<&OsString> = command_values.collect();
|
||||
|
||||
let tmp_dir = tempdir().unwrap();
|
||||
let (preload_env, libstdbuf) = get_preload_env(&tmp_dir)?;
|
||||
@@ -269,6 +270,7 @@ pub fn uu_app() -> Command {
|
||||
.action(ArgAction::Append)
|
||||
.hide(true)
|
||||
.required(true)
|
||||
.value_hint(clap::ValueHint::CommandName),
|
||||
.value_hint(clap::ValueHint::CommandName)
|
||||
.value_parser(clap::value_parser!(OsString)),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore dyld dylib setvbuf
|
||||
#[cfg(target_os = "linux")]
|
||||
use uutests::at_and_ucmd;
|
||||
use uutests::new_ucmd;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use uutests::util::TestScenario;
|
||||
@@ -216,3 +218,20 @@ fn test_libstdbuf_preload() {
|
||||
"uutils echo should not show architecture mismatch"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_stdbuf_non_utf8_paths() {
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let filename = std::ffi::OsString::from_vec(vec![0xFF, 0xFE]);
|
||||
std::fs::write(at.plus(&filename), b"test content for stdbuf\n").unwrap();
|
||||
|
||||
ucmd.arg("-o0")
|
||||
.arg("cat")
|
||||
.arg(&filename)
|
||||
.succeeds()
|
||||
.stdout_is("test content for stdbuf\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user