diff --git a/src/uucore/src/lib/features/format/mod.rs b/src/uucore/src/lib/features/format/mod.rs index b82b5f62acf..6d7a2ee3079 100644 --- a/src/uucore/src/lib/features/format/mod.rs +++ b/src/uucore/src/lib/features/format/mod.rs @@ -62,6 +62,7 @@ pub enum FormatError { TooManySpecs(Vec), NeedAtLeastOneSpec(Vec), WrongSpecType, + InvalidPrecision(String), } impl Error for FormatError {} @@ -91,6 +92,7 @@ impl Display for FormatError { "format '{}' has no % directive", String::from_utf8_lossy(s) ), + Self::InvalidPrecision(precision) => write!(f, "invalid precision: '{precision}'"), // TODO: Error message below needs some work Self::WrongSpecType => write!(f, "wrong % directive type was given"), Self::IoError(_) => write!(f, "io error"), diff --git a/src/uucore/src/lib/features/format/spec.rs b/src/uucore/src/lib/features/format/spec.rs index 543346bf43d..29e696d3235 100644 --- a/src/uucore/src/lib/features/format/spec.rs +++ b/src/uucore/src/lib/features/format/spec.rs @@ -374,6 +374,10 @@ impl Spec { let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(0); let i = args.get_i64(); + if precision as u64 > i32::MAX as u64 { + return Err(FormatError::InvalidPrecision(precision.to_string())); + } + num_format::SignedInt { width, precision, @@ -393,6 +397,10 @@ impl Spec { let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(0); let i = args.get_u64(); + if precision as u64 > i32::MAX as u64 { + return Err(FormatError::InvalidPrecision(precision.to_string())); + } + num_format::UnsignedInt { variant: *variant, precision, @@ -415,6 +423,10 @@ impl Spec { let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(6); let f = args.get_f64(); + if precision as u64 > i32::MAX as u64 { + return Err(FormatError::InvalidPrecision(precision.to_string())); + } + num_format::Float { width, precision, diff --git a/tests/by-util/test_printf.rs b/tests/by-util/test_printf.rs index 7bf1fcfe5bf..26f556e8e1d 100644 --- a/tests/by-util/test_printf.rs +++ b/tests/by-util/test_printf.rs @@ -774,3 +774,21 @@ fn format_spec_zero_string_fails() { // It is invalid to have the format spec '%0s' new_ucmd!().args(&["%0s", "3"]).fails().code_is(1); } + +#[test] +fn invalid_precision_fails() { + // It is invalid to have length of output string greater than i32::MAX + new_ucmd!() + .args(&["%.*d", "2147483648", "0"]) + .fails() + .stderr_is("printf: invalid precision: '2147483648'\n"); +} + +#[test] +fn float_invalid_precision_fails() { + // It is invalid to have length of output string greater than i32::MAX + new_ucmd!() + .args(&["%.*f", "2147483648", "0"]) + .fails() + .stderr_is("printf: invalid precision: '2147483648'\n"); +}