mirror of
https://github.com/uutils/coreutils.git
synced 2025-12-23 08:47:37 +00:00
realpath: fix regression with empty string validation
Fixes issue introduced in b965c944837df66b233f57fca7275fbed4e4d311 where switching from NonEmptyStringValueParser to OsString parser removed validation that arguments cannot be empty strings. - Add custom NonEmptyOsStringParser that validates OsString is not empty - Use the parser for FILES, --relative-to, and --relative-base arguments - Add test case to verify empty strings are rejected with exit code 1 - Fixes GNU realpath test failure
This commit is contained in:
parent
1ab3a8df4f
commit
a7f3cb0209
2 changed files with 62 additions and 5 deletions
|
|
@ -5,9 +5,12 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) retcode
|
||||
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use clap::{
|
||||
Arg, ArgAction, ArgMatches, Command,
|
||||
builder::{TypedValueParser, ValueParserFactory},
|
||||
};
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
ffi::{OsStr, OsString},
|
||||
io::{Write, stdout},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
|
@ -34,6 +37,39 @@ const OPT_RELATIVE_BASE: &str = "relative-base";
|
|||
|
||||
const ARG_FILES: &str = "files";
|
||||
|
||||
/// Custom parser that validates `OsString` is not empty
|
||||
#[derive(Clone, Debug)]
|
||||
struct NonEmptyOsStringParser;
|
||||
|
||||
impl TypedValueParser for NonEmptyOsStringParser {
|
||||
type Value = OsString;
|
||||
|
||||
fn parse_ref(
|
||||
&self,
|
||||
_cmd: &Command,
|
||||
_arg: Option<&Arg>,
|
||||
value: &OsStr,
|
||||
) -> Result<Self::Value, clap::Error> {
|
||||
if value.is_empty() {
|
||||
let mut err = clap::Error::new(clap::error::ErrorKind::ValueValidation);
|
||||
err.insert(
|
||||
clap::error::ContextKind::Custom,
|
||||
clap::error::ContextValue::String("invalid operand: empty string".to_string()),
|
||||
);
|
||||
return Err(err);
|
||||
}
|
||||
Ok(value.to_os_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueParserFactory for NonEmptyOsStringParser {
|
||||
type Parser = Self;
|
||||
|
||||
fn value_parser() -> Self::Parser {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uu_app().try_get_matches_from(args).with_exit_code(1)?;
|
||||
|
|
@ -146,21 +182,21 @@ pub fn uu_app() -> Command {
|
|||
Arg::new(OPT_RELATIVE_TO)
|
||||
.long(OPT_RELATIVE_TO)
|
||||
.value_name("DIR")
|
||||
.value_parser(clap::value_parser!(OsString))
|
||||
.value_parser(NonEmptyOsStringParser)
|
||||
.help(translate!("realpath-help-relative-to")),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(OPT_RELATIVE_BASE)
|
||||
.long(OPT_RELATIVE_BASE)
|
||||
.value_name("DIR")
|
||||
.value_parser(clap::value_parser!(OsString))
|
||||
.value_parser(NonEmptyOsStringParser)
|
||||
.help(translate!("realpath-help-relative-base")),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(ARG_FILES)
|
||||
.action(ArgAction::Append)
|
||||
.required(true)
|
||||
.value_parser(clap::value_parser!(OsString))
|
||||
.value_parser(NonEmptyOsStringParser)
|
||||
.value_hint(clap::ValueHint::AnyPath),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -489,3 +489,24 @@ fn test_realpath_non_utf8_paths() {
|
|||
assert!(output.contains("test_"));
|
||||
assert!(output.contains(".txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_realpath_empty_string() {
|
||||
// Test that empty string arguments are rejected with exit code 1
|
||||
new_ucmd!().arg("").fails().code_is(1);
|
||||
|
||||
// Test that empty --relative-base is rejected
|
||||
new_ucmd!()
|
||||
.arg("--relative-base=")
|
||||
.arg("--relative-to=.")
|
||||
.arg(".")
|
||||
.fails()
|
||||
.code_is(1);
|
||||
|
||||
// Test that empty --relative-to is rejected
|
||||
new_ucmd!()
|
||||
.arg("--relative-to=")
|
||||
.arg(".")
|
||||
.fails()
|
||||
.code_is(1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue