Skip to content

Commit d836730

Browse files
authored
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
1 parent 22bd036 commit d836730

2 files changed

Lines changed: 34 additions & 14 deletions

File tree

src/uu/numfmt/src/numfmt.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ pub mod options;
3333
mod numeric;
3434
mod units;
3535

36+
// Returns `true` if the input is in scientific notation
37+
fn is_scientific(input: &[u8]) -> bool {
38+
if let Some(pos) = input.iter().position(|&b| b == b'E' || b == b'e') {
39+
if pos < input.len() - 1 {
40+
if input[pos + 1].is_ascii_digit() {
41+
return true;
42+
}
43+
}
44+
}
45+
46+
false
47+
}
48+
3649
/// Format a single line and write it, handling `--invalid` error modes.
3750
///
3851
/// Returns `true` if the line contained invalid input (only possible in
@@ -49,19 +62,6 @@ fn format_and_write<W: std::io::Write>(
4962
None => input_line,
5063
};
5164

52-
// Return false if the input is in scientific notation
53-
if let Some(pos) = line.iter().position(|&b| b == b'E' || b == b'e') {
54-
if pos < line.len() - 1 {
55-
if line[pos + 1].is_ascii_digit() {
56-
let err = format!(
57-
"invalid suffix in input: '{}'",
58-
String::from_utf8_lossy(line)
59-
);
60-
return Err(Box::new(NumfmtError::FormattingError(err)));
61-
}
62-
}
63-
}
64-
6565
// In non-abort modes we buffer the formatted output so that on error we
6666
// can emit the original line instead.
6767
let buffer_output = !matches!(options.invalid, InvalidModes::Abort);
@@ -72,7 +72,16 @@ fn format_and_write<W: std::io::Write>(
7272
write_formatted_with_delimiter(dest, line, options, eol)
7373
} else {
7474
match std::str::from_utf8(line) {
75-
Ok(s) => write_formatted_with_whitespace(dest, s, options, eol),
75+
Ok(s) => {
76+
if is_scientific(s.as_bytes()) {
77+
Err(format!(
78+
"invalid suffix in input: '{}'",
79+
String::from_utf8_lossy(line)
80+
))
81+
} else {
82+
write_formatted_with_whitespace(dest, s, options, eol)
83+
}
84+
}
7685
Err(_) => Err(translate!(
7786
"numfmt-error-invalid-number",
7887
"input" => escape_line(line).quote()

tests/by-util/test_numfmt.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,3 +1513,14 @@ fn test_locale_c_uses_period() {
15131513
.succeeds()
15141514
.stdout_is("1.5K\n");
15151515
}
1516+
1517+
// https://github.com/uutils/coreutils/issues/11935
1518+
// the rejection path bypasses --invalid=warn/ignore/fail handling
1519+
#[test]
1520+
fn test_ignores_invalid_mode_issue11935() {
1521+
new_ucmd!()
1522+
.args(&["--invalid=warn", "100", "1e5", "200"])
1523+
.succeeds()
1524+
.stderr_is("numfmt: invalid suffix in input: '1e5'\n")
1525+
.stdout_is("100\n1e5\n200\n");
1526+
}

0 commit comments

Comments
 (0)