diff --git a/src/uu/expand/src/expand.rs b/src/uu/expand/src/expand.rs index 48a965fa0ea..d81d2d313d0 100644 --- a/src/uu/expand/src/expand.rs +++ b/src/uu/expand/src/expand.rs @@ -17,6 +17,7 @@ use std::error::Error; use std::fmt; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; +use std::num::IntErrorKind; use std::str::from_utf8; use unicode_width::UnicodeWidthChar; use uucore::display::Quotable; @@ -65,6 +66,7 @@ enum ParseError { InvalidCharacter(String), SpecifierNotAtStartOfNumber(String, String), TabSizeCannotBeZero, + TabSizeTooLarge(String), TabSizesMustBeAscending, } @@ -84,6 +86,7 @@ impl fmt::Display for ParseError { s.quote(), ), Self::TabSizeCannotBeZero => write!(f, "tab size cannot be 0"), + Self::TabSizeTooLarge(s) => write!(f, "tab stop is too large {}", s.quote()), Self::TabSizesMustBeAscending => write!(f, "tab sizes must be ascending"), } } @@ -122,31 +125,38 @@ fn tabstops_parse(s: &str) -> Result<(RemainingMode, Vec), ParseError> { _ => { // Parse a number from the byte sequence. let s = from_utf8(&bytes[i..]).unwrap(); - if let Ok(num) = s.parse::() { - // Tab size must be positive. - if num == 0 { - return Err(ParseError::TabSizeCannotBeZero); - } + match s.parse::() { + Ok(num) => { + // Tab size must be positive. + if num == 0 { + return Err(ParseError::TabSizeCannotBeZero); + } - // Tab sizes must be ascending. - if let Some(last_stop) = nums.last() { - if *last_stop >= num { - return Err(ParseError::TabSizesMustBeAscending); + // Tab sizes must be ascending. + if let Some(last_stop) = nums.last() { + if *last_stop >= num { + return Err(ParseError::TabSizesMustBeAscending); + } } + + // Append this tab stop to the list of all tabstops. + nums.push(num); + break; } + Err(e) => { + if *e.kind() == IntErrorKind::PosOverflow { + return Err(ParseError::TabSizeTooLarge(s.to_string())); + } - // Append this tab stop to the list of all tabstops. - nums.push(num); - break; - } else { - let s = s.trim_start_matches(char::is_numeric); - if s.starts_with('/') || s.starts_with('+') { - return Err(ParseError::SpecifierNotAtStartOfNumber( - s[0..1].to_string(), - s.to_string(), - )); - } else { - return Err(ParseError::InvalidCharacter(s.to_string())); + let s = s.trim_start_matches(char::is_numeric); + if s.starts_with('/') || s.starts_with('+') { + return Err(ParseError::SpecifierNotAtStartOfNumber( + s[0..1].to_string(), + s.to_string(), + )); + } else { + return Err(ParseError::InvalidCharacter(s.to_string())); + } } } } diff --git a/tests/by-util/test_expand.rs b/tests/by-util/test_expand.rs index 6a8084ec574..289743ce8dd 100644 --- a/tests/by-util/test_expand.rs +++ b/tests/by-util/test_expand.rs @@ -237,3 +237,11 @@ fn test_tabs_with_invalid_chars() { .fails() .stderr_contains("tab size contains invalid character(s): 'x2'"); } + +#[test] +fn test_tabs_with_too_large_size() { + let arg = format!("--tabs={}", u128::MAX); + let expected_error = format!("tab stop is too large '{}'", u128::MAX); + + new_ucmd!().arg(arg).fails().stderr_contains(expected_error); +}