fix(parser): Don't panic on invalid UTF-8 values

Fixes #4473
This commit is contained in:
Ed Page 2022-11-11 12:25:56 -06:00
parent 45d26e0013
commit e9cbed34cd
4 changed files with 5 additions and 9 deletions

View file

@ -156,4 +156,3 @@ mod util;
const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \ const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \
report at https://github.com/clap-rs/clap/issues"; report at https://github.com/clap-rs/clap/issues";
const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point";

View file

@ -35,7 +35,7 @@ where
/// Returns a suffix that can be empty, or is the standard 'did you mean' phrase /// Returns a suffix that can be empty, or is the standard 'did you mean' phrase
pub(crate) fn did_you_mean_flag<'a, 'help, I, T>( pub(crate) fn did_you_mean_flag<'a, 'help, I, T>(
arg: &str, arg: &str,
remaining_args: &[&str], remaining_args: &[&std::ffi::OsStr],
longs: I, longs: I,
subcommands: impl IntoIterator<Item = &'a mut Command>, subcommands: impl IntoIterator<Item = &'a mut Command>,
) -> Option<(String, Option<String>)> ) -> Option<(String, Option<String>)>

View file

@ -20,7 +20,7 @@ use crate::parser::{ArgMatcher, SubCommand};
use crate::parser::{Validator, ValueSource}; use crate::parser::{Validator, ValueSource};
use crate::util::Id; use crate::util::Id;
use crate::ArgAction; use crate::ArgAction;
use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8}; use crate::INTERNAL_ERROR_MSG;
pub(crate) struct Parser<'cmd> { pub(crate) struct Parser<'cmd> {
cmd: &'cmd mut Command, cmd: &'cmd mut Command,
@ -171,10 +171,8 @@ impl<'cmd> Parser<'cmd> {
} }
ParseResult::NoMatchingArg { arg } => { ParseResult::NoMatchingArg { arg } => {
let _ = self.resolve_pending(matcher); let _ = self.resolve_pending(matcher);
let remaining_args: Vec<_> = raw_args let remaining_args: Vec<_> =
.remaining(&mut args_cursor) raw_args.remaining(&mut args_cursor).collect();
.map(|x| x.to_str().expect(INVALID_UTF8))
.collect();
return Err(self.did_you_mean_error( return Err(self.did_you_mean_error(
&arg, &arg,
matcher, matcher,
@ -1523,7 +1521,7 @@ impl<'cmd> Parser<'cmd> {
&mut self, &mut self,
arg: &str, arg: &str,
matcher: &mut ArgMatcher, matcher: &mut ArgMatcher,
remaining_args: &[&str], remaining_args: &[&OsStr],
trailing_values: bool, trailing_values: bool,
) -> ClapError { ) -> ClapError {
debug!("Parser::did_you_mean_error: arg={}", arg); debug!("Parser::did_you_mean_error: arg={}", arg);

View file

@ -112,7 +112,6 @@ fn invalid_utf8_strict_invalid_short() {
} }
#[test] #[test]
#[should_panic]
fn invalid_utf8_strict_invalid_long() { fn invalid_utf8_strict_invalid_long() {
let m = Command::new("bad_utf8").try_get_matches_from(vec![ let m = Command::new("bad_utf8").try_get_matches_from(vec![
OsString::from(""), OsString::from(""),