1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

expand: handle too large tab size

This commit is contained in:
Daniel Hofstetter 2022-06-05 13:49:11 +02:00
parent 69c2871336
commit c14ff14e99
2 changed files with 41 additions and 23 deletions

View file

@ -17,6 +17,7 @@ use std::error::Error;
use std::fmt; use std::fmt;
use std::fs::File; use std::fs::File;
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write}; use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
use std::num::IntErrorKind;
use std::str::from_utf8; use std::str::from_utf8;
use unicode_width::UnicodeWidthChar; use unicode_width::UnicodeWidthChar;
use uucore::display::Quotable; use uucore::display::Quotable;
@ -65,6 +66,7 @@ enum ParseError {
InvalidCharacter(String), InvalidCharacter(String),
SpecifierNotAtStartOfNumber(String, String), SpecifierNotAtStartOfNumber(String, String),
TabSizeCannotBeZero, TabSizeCannotBeZero,
TabSizeTooLarge(String),
TabSizesMustBeAscending, TabSizesMustBeAscending,
} }
@ -84,6 +86,7 @@ impl fmt::Display for ParseError {
s.quote(), s.quote(),
), ),
Self::TabSizeCannotBeZero => write!(f, "tab size cannot be 0"), 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"), Self::TabSizesMustBeAscending => write!(f, "tab sizes must be ascending"),
} }
} }
@ -122,31 +125,38 @@ fn tabstops_parse(s: &str) -> Result<(RemainingMode, Vec<usize>), ParseError> {
_ => { _ => {
// Parse a number from the byte sequence. // Parse a number from the byte sequence.
let s = from_utf8(&bytes[i..]).unwrap(); let s = from_utf8(&bytes[i..]).unwrap();
if let Ok(num) = s.parse::<usize>() { match s.parse::<usize>() {
// Tab size must be positive. Ok(num) => {
if num == 0 { // Tab size must be positive.
return Err(ParseError::TabSizeCannotBeZero); 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);
} }
}
// Append this tab stop to the list of all tabstops. // Tab sizes must be ascending.
nums.push(num); if let Some(last_stop) = nums.last() {
break; if *last_stop >= num {
} else { return Err(ParseError::TabSizesMustBeAscending);
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(), // Append this tab stop to the list of all tabstops.
s.to_string(), nums.push(num);
)); break;
} else { }
return Err(ParseError::InvalidCharacter(s.to_string())); Err(e) => {
if *e.kind() == IntErrorKind::PosOverflow {
return Err(ParseError::TabSizeTooLarge(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()));
}
} }
} }
} }

View file

@ -237,3 +237,11 @@ fn test_tabs_with_invalid_chars() {
.fails() .fails()
.stderr_contains("tab size contains invalid character(s): 'x2'"); .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);
}