From 0908384e91060c83323581515cfd1cf414cdf1ce Mon Sep 17 00:00:00 2001 From: subotac <73706465+subotac@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:21:02 +0300 Subject: [PATCH 1/2] printf: avoid overflow for minimum dynamic width --- src/uucore/src/lib/features/format/spec.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/format/spec.rs b/src/uucore/src/lib/features/format/spec.rs index 1af75ae94d4..e7fb7406374 100644 --- a/src/uucore/src/lib/features/format/spec.rs +++ b/src/uucore/src/lib/features/format/spec.rs @@ -511,7 +511,7 @@ fn resolve_asterisk_width( Some(CanAsterisk::Asterisk(loc)) => { let nb = args.next_i64(loc); if nb < 0 { - Some((usize::try_from(-(nb as isize)).ok().unwrap_or(0), true)) + Some((usize::try_from(nb.unsigned_abs()).ok().unwrap_or(0), true)) } else { Some((usize::try_from(nb).ok().unwrap_or(0), false)) } @@ -670,6 +670,17 @@ mod tests { ) ); } + + #[test] + fn asterisk_with_i64_min_width() { + assert_eq!( + Some((1usize.checked_shl(63).unwrap_or(0), true)), + resolve_asterisk_width( + Some(CanAsterisk::Asterisk(ArgumentLocation::NextArgument)), + &mut FormatArguments::new(&[FormatArgument::SignedInt(i64::MIN)]), + ) + ); + } } mod resolve_asterisk_precision { From bdbb205337dffd6d8cd582324633b3f4bdb4fac2 Mon Sep 17 00:00:00 2001 From: subotac <73706465+subotac@users.noreply.github.com> Date: Sun, 9 Aug 2026 04:09:34 +0300 Subject: [PATCH 2/2] tests/printf: cover minimum dynamic width --- tests/by-util/test_printf.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/by-util/test_printf.rs b/tests/by-util/test_printf.rs index fda7f7d158e..fda259dbe52 100644 --- a/tests/by-util/test_printf.rs +++ b/tests/by-util/test_printf.rs @@ -590,6 +590,16 @@ fn sub_any_asterisk_first_param_with_integer() { .stdout_only("|0 |"); } +#[test] +#[cfg(target_pointer_width = "64")] +fn sub_any_asterisk_first_param_with_i64_min() { + new_ucmd!() + .args(&["%*d", &i64::MIN.to_string(), "1"]) + .fails_with_code(1) + .stderr_contains("write error") + .stdout_is(""); +} + #[test] fn sub_any_asterisk_second_param_with_integer() { new_ucmd!()