numfmt: respect --invalid mode when rejecting scientific notation (#11945)

* fix #11935

* code style and error message

* cargo fmt

* add test for issue 11935

* Update test_numfmt.rs

* check for the expected output in test
This commit is contained in:
Devel08
2026-04-23 18:29:40 +03:00
committed by GitHub
parent 22bd03668a
commit d836730024
2 changed files with 34 additions and 14 deletions
+23 -14
View File
@@ -33,6 +33,19 @@ pub mod options;
mod numeric;
mod units;
// Returns `true` if the input is in scientific notation
fn is_scientific(input: &[u8]) -> bool {
if let Some(pos) = input.iter().position(|&b| b == b'E' || b == b'e') {
if pos < input.len() - 1 {
if input[pos + 1].is_ascii_digit() {
return true;
}
}
}
false
}
/// Format a single line and write it, handling `--invalid` error modes.
///
/// Returns `true` if the line contained invalid input (only possible in
@@ -49,19 +62,6 @@ fn format_and_write<W: std::io::Write>(
None => input_line,
};
// Return false if the input is in scientific notation
if let Some(pos) = line.iter().position(|&b| b == b'E' || b == b'e') {
if pos < line.len() - 1 {
if line[pos + 1].is_ascii_digit() {
let err = format!(
"invalid suffix in input: '{}'",
String::from_utf8_lossy(line)
);
return Err(Box::new(NumfmtError::FormattingError(err)));
}
}
}
// In non-abort modes we buffer the formatted output so that on error we
// can emit the original line instead.
let buffer_output = !matches!(options.invalid, InvalidModes::Abort);
@@ -72,7 +72,16 @@ fn format_and_write<W: std::io::Write>(
write_formatted_with_delimiter(dest, line, options, eol)
} else {
match std::str::from_utf8(line) {
Ok(s) => write_formatted_with_whitespace(dest, s, options, eol),
Ok(s) => {
if is_scientific(s.as_bytes()) {
Err(format!(
"invalid suffix in input: '{}'",
String::from_utf8_lossy(line)
))
} else {
write_formatted_with_whitespace(dest, s, options, eol)
}
}
Err(_) => Err(translate!(
"numfmt-error-invalid-number",
"input" => escape_line(line).quote()
+11
View File
@@ -1513,3 +1513,14 @@ fn test_locale_c_uses_period() {
.succeeds()
.stdout_is("1.5K\n");
}
// https://github.com/uutils/coreutils/issues/11935
// the rejection path bypasses --invalid=warn/ignore/fail handling
#[test]
fn test_ignores_invalid_mode_issue11935() {
new_ucmd!()
.args(&["--invalid=warn", "100", "1e5", "200"])
.succeeds()
.stderr_is("numfmt: invalid suffix in input: '1e5'\n")
.stdout_is("100\n1e5\n200\n");
}