diff --git a/src/uucore/src/lib/features/format/argument.rs b/src/uucore/src/lib/features/format/argument.rs index 72f17758a..0441a5796 100644 --- a/src/uucore/src/lib/features/format/argument.rs +++ b/src/uucore/src/lib/features/format/argument.rs @@ -58,7 +58,18 @@ impl<'a, T: Iterator> ArgumentIter<'a> for T { }; match next { FormatArgument::UnsignedInt(n) => *n, - FormatArgument::Unparsed(s) => extract_value(u64::extended_parse(s), s), + FormatArgument::Unparsed(s) => { + // Check if the string is a character literal enclosed in quotes + if s.starts_with(['"', '\'']) && s.len() > 2 { + // Extract the content between the quotes safely + let chars: Vec = + s.trim_matches(|c| c == '"' || c == '\'').chars().collect(); + if chars.len() == 1 { + return chars[0] as u64; // Return the Unicode code point + } + } + extract_value(u64::extended_parse(s), s) + } _ => 0, } } diff --git a/tests/by-util/test_printf.rs b/tests/by-util/test_printf.rs index 2d059c0fa..58f919848 100644 --- a/tests/by-util/test_printf.rs +++ b/tests/by-util/test_printf.rs @@ -1385,3 +1385,13 @@ fn float_arg_with_whitespace() { .fails() .stderr_contains("expected a numeric value"); } + +#[test] +fn mb_input() { + for format in ["\"á", "\'á"] { + new_ucmd!() + .args(&["%04x\n", format]) + .succeeds() + .stdout_only("00e1\n"); + } +}