From 0bf5a68c54dfa7616004bf503ed6e0968099330f Mon Sep 17 00:00:00 2001 From: Andrew Liebenow Date: Sat, 12 Oct 2024 01:40:05 -0500 Subject: [PATCH] tr: forbid backwards ranges --- src/uu/tr/src/operation.rs | 27 ++++++++++++++++++++++++++- tests/by-util/test_tr.rs | 12 ++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/uu/tr/src/operation.rs b/src/uu/tr/src/operation.rs index e86768c4f..5c17b7ab4 100644 --- a/src/uu/tr/src/operation.rs +++ b/src/uu/tr/src/operation.rs @@ -36,6 +36,7 @@ pub enum BadSequence { ClassInSet2NotMatchedBySet1, Set1LongerSet2EndsInClass, ComplementMoreThanOneUniqueInSet2, + BackwardsRange { end: u32, start: u32 }, } impl Display for BadSequence { @@ -69,6 +70,23 @@ impl Display for BadSequence { Self::ComplementMoreThanOneUniqueInSet2 => { write!(f, "when translating with complemented character classes,\nstring2 must map all characters in the domain to one") } + Self::BackwardsRange { end, start } => { + fn end_or_start_to_string(ut: &u32) -> String { + match char::from_u32(*ut) { + Some(ch @ '\x20'..='\x7E') => ch.escape_default().to_string(), + _ => { + format!("\\{ut:03o}") + } + } + } + + write!( + f, + "range-endpoints of '{}-{}' are in reverse collating sequence order", + end_or_start_to_string(start), + end_or_start_to_string(end) + ) + } } } } @@ -366,7 +384,14 @@ impl Sequence { .map(|(l, (a, b))| { (l, { let (start, end) = (u32::from(a), u32::from(b)); - Ok(Self::CharRange(start as u8, end as u8)) + + let range = start..=end; + + if range.is_empty() { + Err(BadSequence::BackwardsRange { end, start }) + } else { + Ok(Self::CharRange(start as u8, end as u8)) + } }) }) } diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs index c3b52758c..4cf883bac 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -1500,3 +1500,15 @@ fn test_multibyte_octal_sequence() { // ") .stdout_is("Ł)"); } + +#[test] +fn test_backwards_range() { + new_ucmd!() + .args(&["-d", r"\046-\048"]) + .pipe_in("") + .fails() + .stderr_only( + r"tr: range-endpoints of '&-\004' are in reverse collating sequence order +", + ); +}