mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
printf: Check precision before writing into stdout (#6511)
* Add a new error type InvalidPrecision * check if the precision is valid before writing to stdout when it is signedInt, unsigned, or float * add tests for invalid precision check * add tests for invalid precision check * fix possible cross-platform issue that code failing to pass on some tests * uucore/format: inline var in format string --------- Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
parent
ff389491cc
commit
e6b6b2761b
3 changed files with 32 additions and 0 deletions
|
@ -62,6 +62,7 @@ pub enum FormatError {
|
||||||
TooManySpecs(Vec<u8>),
|
TooManySpecs(Vec<u8>),
|
||||||
NeedAtLeastOneSpec(Vec<u8>),
|
NeedAtLeastOneSpec(Vec<u8>),
|
||||||
WrongSpecType,
|
WrongSpecType,
|
||||||
|
InvalidPrecision(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for FormatError {}
|
impl Error for FormatError {}
|
||||||
|
@ -91,6 +92,7 @@ impl Display for FormatError {
|
||||||
"format '{}' has no % directive",
|
"format '{}' has no % directive",
|
||||||
String::from_utf8_lossy(s)
|
String::from_utf8_lossy(s)
|
||||||
),
|
),
|
||||||
|
Self::InvalidPrecision(precision) => write!(f, "invalid precision: '{precision}'"),
|
||||||
// TODO: Error message below needs some work
|
// TODO: Error message below needs some work
|
||||||
Self::WrongSpecType => write!(f, "wrong % directive type was given"),
|
Self::WrongSpecType => write!(f, "wrong % directive type was given"),
|
||||||
Self::IoError(_) => write!(f, "io error"),
|
Self::IoError(_) => write!(f, "io error"),
|
||||||
|
|
|
@ -374,6 +374,10 @@ impl Spec {
|
||||||
let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(0);
|
let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(0);
|
||||||
let i = args.get_i64();
|
let i = args.get_i64();
|
||||||
|
|
||||||
|
if precision as u64 > i32::MAX as u64 {
|
||||||
|
return Err(FormatError::InvalidPrecision(precision.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
num_format::SignedInt {
|
num_format::SignedInt {
|
||||||
width,
|
width,
|
||||||
precision,
|
precision,
|
||||||
|
@ -393,6 +397,10 @@ impl Spec {
|
||||||
let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(0);
|
let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(0);
|
||||||
let i = args.get_u64();
|
let i = args.get_u64();
|
||||||
|
|
||||||
|
if precision as u64 > i32::MAX as u64 {
|
||||||
|
return Err(FormatError::InvalidPrecision(precision.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
num_format::UnsignedInt {
|
num_format::UnsignedInt {
|
||||||
variant: *variant,
|
variant: *variant,
|
||||||
precision,
|
precision,
|
||||||
|
@ -415,6 +423,10 @@ impl Spec {
|
||||||
let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(6);
|
let precision = resolve_asterisk(*precision, &mut args)?.unwrap_or(6);
|
||||||
let f = args.get_f64();
|
let f = args.get_f64();
|
||||||
|
|
||||||
|
if precision as u64 > i32::MAX as u64 {
|
||||||
|
return Err(FormatError::InvalidPrecision(precision.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
num_format::Float {
|
num_format::Float {
|
||||||
width,
|
width,
|
||||||
precision,
|
precision,
|
||||||
|
|
|
@ -774,3 +774,21 @@ fn format_spec_zero_string_fails() {
|
||||||
// It is invalid to have the format spec '%0s'
|
// It is invalid to have the format spec '%0s'
|
||||||
new_ucmd!().args(&["%0s", "3"]).fails().code_is(1);
|
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");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue