mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
fix(numfmt): format output on error messages
This commit is contained in:
committed by
Daniel Hofstetter
parent
30434cb789
commit
dd6b88b264
@@ -452,6 +452,20 @@ fn format_string(
|
||||
))
|
||||
}
|
||||
|
||||
/// Encodes a byte slice as a string, representing non-UTF-8 bytes as octal escapes.
|
||||
/// Used to safely format invalid input in error messages.
|
||||
pub(crate) fn escape_line(line: &[u8]) -> String {
|
||||
line.iter()
|
||||
.map(|&b| {
|
||||
if b.is_ascii_graphic() || b.is_ascii_whitespace() {
|
||||
(b as char).to_string()
|
||||
} else {
|
||||
format!("\\{b:03o}")
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn split_bytes<'a>(input: &'a [u8], delim: &'a [u8]) -> impl Iterator<Item = &'a [u8]> {
|
||||
let mut remainder = Some(input);
|
||||
std::iter::from_fn(move || {
|
||||
@@ -488,7 +502,7 @@ pub fn write_formatted_with_delimiter<W: std::io::Write>(
|
||||
if field_selected {
|
||||
// Field must be valid UTF-8 for numeric conversion
|
||||
let field_str = std::str::from_utf8(field)
|
||||
.map_err(|_| translate!("numfmt-error-invalid-number", "input" => String::from_utf8_lossy(field).into_owned().quote()))?
|
||||
.map_err(|_| translate!("numfmt-error-invalid-number", "input" => escape_line(field).quote()))?
|
||||
.trim_start();
|
||||
let formatted = format_string(field_str, options, None)?;
|
||||
writer.write_all(formatted.as_bytes()).unwrap();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::errors::NumfmtError;
|
||||
use crate::format::{write_formatted_with_delimiter, write_formatted_with_whitespace};
|
||||
use crate::format::{escape_line, write_formatted_with_delimiter, write_formatted_with_whitespace};
|
||||
use crate::options::{
|
||||
DEBUG, DELIMITER, FIELD, FIELD_DEFAULT, FORMAT, FROM, FROM_DEFAULT, FROM_UNIT,
|
||||
FROM_UNIT_DEFAULT, FormatOptions, HEADER, HEADER_DEFAULT, INVALID, InvalidModes, NUMBER,
|
||||
@@ -99,7 +99,9 @@ fn write_line<W: std::io::Write>(
|
||||
// Whitespace mode requires valid UTF-8
|
||||
match std::str::from_utf8(&line) {
|
||||
Ok(s) => write_formatted_with_whitespace(writer, s, options, eol),
|
||||
Err(_) => Err(translate!("numfmt-error-invalid-input")),
|
||||
Err(_) => Err(
|
||||
translate!("numfmt-error-invalid-number", "input" => escape_line(&line).quote()),
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1272,3 +1272,13 @@ fn test_null_byte_input_multiline() {
|
||||
.succeeds()
|
||||
.stdout_is("1000\n3000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_utf8_input() {
|
||||
// 0xFF is invalid UTF-8
|
||||
new_ucmd!()
|
||||
.pipe_in([b'1', b'0', b'\n', b'\xFF'])
|
||||
.fails_with_code(2)
|
||||
.stdout_is("10\n")
|
||||
.stderr_is("numfmt: invalid number: '\\377'\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user