From cc1112660a48de0ce372ca5e0f6fb65d50f75bcc Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Fri, 11 Apr 2025 22:01:49 -0400 Subject: [PATCH] head: return to parse:: and switch to parse_size_u64_max --- src/uu/head/src/parse.rs | 17 +++++++++-------- tests/by-util/test_head.rs | 28 ++++++++++------------------ 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/uu/head/src/parse.rs b/src/uu/head/src/parse.rs index 0dbac6fe2..a4ce6e710 100644 --- a/src/uu/head/src/parse.rs +++ b/src/uu/head/src/parse.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. use std::ffi::OsString; -use uucore::parser::parse_size::{ParseSizeError, parse_size_u64}; +use uucore::parser::parse_size::{ParseSizeError, parse_size_u64_max}; #[derive(PartialEq, Eq, Debug)] pub struct ParseError; @@ -49,10 +49,11 @@ fn process_num_block( last_char: char, chars: &mut std::str::CharIndices, ) -> Option, ParseError>> { - let num = src.chars().fold(0u32, |acc, ch| { - acc.saturating_mul(10) - .saturating_add(ch.to_digit(10).unwrap()) - }); + let num = match src.parse::() { + Ok(n) => n, + Err(e) if *e.kind() == std::num::IntErrorKind::PosOverflow => usize::MAX, + _ => return Some(Err(ParseError)), + }; let mut quiet = false; let mut verbose = false; let mut zero_terminated = false; @@ -129,7 +130,7 @@ pub fn parse_num(src: &str) -> Result<(u64, bool), ParseSizeError> { if trimmed_string.is_empty() { Ok((0, all_but_last)) } else { - parse_size_u64(trimmed_string).map(|n| (n, all_but_last)) + parse_size_u64_max(trimmed_string).map(|n| (n, all_but_last)) } } @@ -193,11 +194,11 @@ mod tests { fn test_parse_obsolete_overflow_x64() { assert_eq!( obsolete("-1000000000000000m"), - obsolete_result(&["-c", "4294967295"]) + obsolete_result(&["-c", "18446744073709551615"]) ); assert_eq!( obsolete("-10000000000000000000000"), - obsolete_result(&["-n", "4294967295"]) + obsolete_result(&["-n", "18446744073709551615"]) ); } diff --git a/tests/by-util/test_head.rs b/tests/by-util/test_head.rs index 6c73936f3..9cd690c73 100644 --- a/tests/by-util/test_head.rs +++ b/tests/by-util/test_head.rs @@ -321,24 +321,20 @@ fn test_bad_utf8_lines() { fn test_head_invalid_num() { new_ucmd!() .args(&["-c", "1024R", "emptyfile.txt"]) - .fails() - .stderr_is( - "head: invalid number of bytes: '1024R': Value too large for defined data type\n", - ); + .succeeds() + .no_output(); new_ucmd!() .args(&["-n", "1024R", "emptyfile.txt"]) - .fails() - .stderr_is( - "head: invalid number of lines: '1024R': Value too large for defined data type\n", - ); + .succeeds() + .no_output(); new_ucmd!() .args(&["-c", "1Y", "emptyfile.txt"]) - .fails() - .stderr_is("head: invalid number of bytes: '1Y': Value too large for defined data type\n"); + .succeeds() + .no_output(); new_ucmd!() .args(&["-n", "1Y", "emptyfile.txt"]) - .fails() - .stderr_is("head: invalid number of lines: '1Y': Value too large for defined data type\n"); + .succeeds() + .no_output(); #[cfg(target_pointer_width = "32")] { let sizes = ["1000G", "10T"]; @@ -350,10 +346,7 @@ fn test_head_invalid_num() { { let sizes = ["-1000G", "-10T"]; for size in &sizes { - new_ucmd!() - .args(&["-c", size]) - .fails() - .stderr_is("head: out of range integral type conversion attempted: number of -bytes or -lines is too large\n"); + new_ucmd!().args(&["-c", size]).succeeds().no_output(); } } new_ucmd!() @@ -778,8 +771,7 @@ fn test_value_too_large() { new_ucmd!() .args(&["-n", format!("{MAX}0").as_str(), "lorem_ipsum.txt"]) - .fails() - .stderr_contains("Value too large for defined data type"); + .succeeds(); } #[test]