mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
pr: reject a non-positive expand-tab width (-e0)
`pr -e0` on input containing a tab aborted with a remainder-by-zero panic (`chunk.len() % expand_options.width` in `apply_expand_tab`). The `-e[char][width]` parser accepted a width of `0` — and a negative width via e.g. `-eX-5` — without validation, so the zero/negative reached the chunk arithmetic. Reject `width <= 0` while parsing `-e`, emitting the same invalid-argument error GNU produces (`pr: '-e' extra characters or invalid number in the argument: '0'`, exit 1) instead of crashing.
This commit is contained in:
+37
-16
@@ -582,22 +582,43 @@ fn build_options(
|
||||
let expand_tabs = matches
|
||||
.get_one::<String>(options::EXPAND_TABS)
|
||||
.map(|s| {
|
||||
s.chars().next().map_or(Ok(ExpandTabsOptions::default()), |c| {
|
||||
if c.is_ascii_digit() {
|
||||
s
|
||||
.parse()
|
||||
.map_err(|_e| PrError::EncounteredErrors { msg: format!("{}\n{}", translate!("pr-error-invalid-expand-tab-argument", "arg" => s), translate!("pr-try-help-message")) })
|
||||
.map(|width| ExpandTabsOptions{input_char: TAB, width})
|
||||
} else if s.len() > 1 {
|
||||
s[1..]
|
||||
.parse()
|
||||
.map_err(|_e| PrError::EncounteredErrors { msg: format!("{}\n{}", translate!("pr-error-invalid-expand-tab-argument", "arg" => &s[1..]), translate!("pr-try-help-message")) })
|
||||
.map(|width| ExpandTabsOptions{input_char: c, width})
|
||||
} else {
|
||||
Ok(ExpandTabsOptions{input_char: c, width: 8})
|
||||
}
|
||||
})
|
||||
}).transpose()?;
|
||||
s.chars()
|
||||
.next()
|
||||
.map_or(Ok(ExpandTabsOptions::default()), |c| {
|
||||
let invalid = |arg: &str| PrError::EncounteredErrors {
|
||||
msg: format!(
|
||||
"{}\n{}",
|
||||
translate!("pr-error-invalid-expand-tab-argument", "arg" => arg),
|
||||
translate!("pr-try-help-message")
|
||||
),
|
||||
};
|
||||
if c.is_ascii_digit() {
|
||||
let width: i32 = s.parse().map_err(|_e| invalid(s))?;
|
||||
if width <= 0 {
|
||||
return Err(invalid(s));
|
||||
}
|
||||
Ok(ExpandTabsOptions {
|
||||
input_char: TAB,
|
||||
width,
|
||||
})
|
||||
} else if s.len() > 1 {
|
||||
let width: i32 = s[1..].parse().map_err(|_e| invalid(&s[1..]))?;
|
||||
if width <= 0 {
|
||||
return Err(invalid(&s[1..]));
|
||||
}
|
||||
Ok(ExpandTabsOptions {
|
||||
input_char: c,
|
||||
width,
|
||||
})
|
||||
} else {
|
||||
Ok(ExpandTabsOptions {
|
||||
input_char: c,
|
||||
width: 8,
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let double_space = matches.get_flag(options::DOUBLE_SPACE);
|
||||
|
||||
|
||||
@@ -889,3 +889,16 @@ fn test_zero_columns_shortcut() {
|
||||
.fails_with_code(1)
|
||||
.stderr_contains("pr: invalid --column argument '0'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_expand_tab_width() {
|
||||
let expected = "pr: '-e' extra characters or invalid number in the argument: ‘0’\nTry 'pr --help' for more information.\n";
|
||||
new_ucmd!()
|
||||
.arg("-e0")
|
||||
.fails_with_code(1)
|
||||
.stderr_only(expected);
|
||||
new_ucmd!()
|
||||
.arg("-eX0")
|
||||
.fails_with_code(1)
|
||||
.stderr_only(expected);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user