From 07d6056ef070de8bccf856540da1125db656625a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 7 Dec 2024 10:54:25 +0100 Subject: [PATCH] stat: handle error better. should make tests/stat/stat-printf.pl pass --- src/uu/stat/src/stat.rs | 9 +++++++++ tests/by-util/test_stat.rs | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index 0a6a4a6c4ef..2a61f9b7b34 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -563,6 +563,15 @@ impl Stater { if let Some((field_width, offset)) = format_str[j..].scan_num::() { width = field_width; j += offset; + + // Reject directives like `%` by checking if width has been parsed. + if j >= bound || chars[j] == '%' { + let invalid_directive: String = chars[old..=j.min(bound - 1)].iter().collect(); + return Err(USimpleError::new( + 1, + format!("{}: invalid directive", invalid_directive.quote()), + )); + } } check_bound(format_str, bound, old, j)?; diff --git a/tests/by-util/test_stat.rs b/tests/by-util/test_stat.rs index cb52f19e055..161efd061f9 100644 --- a/tests/by-util/test_stat.rs +++ b/tests/by-util/test_stat.rs @@ -412,3 +412,20 @@ fn test_printf_bel_etc() { .succeeds() .stdout_is_bytes(expected_stdout); } + +#[test] +fn test_printf_invalid_directive() { + let ts = TestScenario::new(util_name!()); + + ts.ucmd() + .args(&["--printf=%9", "."]) + .fails() + .code_is(1) + .stderr_contains("'%9': invalid directive"); + + ts.ucmd() + .args(&["--printf=%9%", "."]) + .fails() + .code_is(1) + .stderr_contains("'%9%': invalid directive"); +}