From 6c3fc7b214d974397548bbbc6f7fd7dea960b09a Mon Sep 17 00:00:00 2001 From: ndd7xv Date: Tue, 15 Feb 2022 01:35:28 -0500 Subject: [PATCH] split: throw error when # chunks > # filenames from suffix length --- src/uu/split/src/filenames.rs | 2 +- src/uu/split/src/split.rs | 28 +++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/uu/split/src/filenames.rs b/src/uu/split/src/filenames.rs index 0121ba87f..426c76226 100644 --- a/src/uu/split/src/filenames.rs +++ b/src/uu/split/src/filenames.rs @@ -44,7 +44,7 @@ pub enum SuffixType { impl SuffixType { /// The radix to use when representing the suffix string as digits. - fn radix(&self) -> u8 { + pub fn radix(&self) -> u8 { match self { SuffixType::Alphabetic => 26, SuffixType::NumericDecimal => 10, diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 70de45ce2..a7a49af00 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -293,11 +293,14 @@ enum SettingsError { Strategy(StrategyError), /// Invalid suffix length parameter. - SuffixLength(String), + SuffixNotParsable(String), /// Suffix contains a directory separator, which is not allowed. SuffixContainsSeparator(String), + /// Suffix is not large enough to split into specified chunks + SuffixTooSmall(usize), + /// The `--filter` option is not supported on Windows. #[cfg(windows)] NotSupported, @@ -317,7 +320,8 @@ impl fmt::Display for SettingsError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Strategy(e) => e.fmt(f), - Self::SuffixLength(s) => write!(f, "invalid suffix length: {}", s.quote()), + Self::SuffixNotParsable(s) => write!(f, "invalid suffix length: {}", s.quote()), + Self::SuffixTooSmall(i) => write!(f, "the suffix length needs to be at least {}", i), Self::SuffixContainsSeparator(s) => write!( f, "invalid suffix {}, contains directory separator", @@ -340,15 +344,29 @@ impl Settings { if additional_suffix.contains('/') { return Err(SettingsError::SuffixContainsSeparator(additional_suffix)); } + let strategy = Strategy::from(matches).map_err(SettingsError::Strategy)?; + let suffix_type = suffix_type_from(matches); let suffix_length_str = matches.value_of(OPT_SUFFIX_LENGTH).unwrap(); + let suffix_length: usize = suffix_length_str + .parse() + .map_err(|_| SettingsError::SuffixNotParsable(suffix_length_str.to_string()))?; + if let Strategy::Number(chunks) = strategy { + if suffix_length != 0 { + let required_suffix_length = + (chunks as f64).log(suffix_type.radix() as f64).ceil() as usize; + if suffix_length < required_suffix_length { + return Err(SettingsError::SuffixTooSmall(required_suffix_length)); + } + } + } let result = Self { suffix_length: suffix_length_str .parse() - .map_err(|_| SettingsError::SuffixLength(suffix_length_str.to_string()))?, - suffix_type: suffix_type_from(matches), + .map_err(|_| SettingsError::SuffixNotParsable(suffix_length_str.to_string()))?, + suffix_type, additional_suffix, verbose: matches.occurrences_of("verbose") > 0, - strategy: Strategy::from(matches).map_err(SettingsError::Strategy)?, + strategy, input: matches.value_of(ARG_INPUT).unwrap().to_owned(), prefix: matches.value_of(ARG_PREFIX).unwrap().to_owned(), filter: matches.value_of(OPT_FILTER).map(|s| s.to_owned()),