diff --git a/src/uu/tr/src/operation.rs b/src/uu/tr/src/operation.rs index ae857ef865b..e6eb087486c 100644 --- a/src/uu/tr/src/operation.rs +++ b/src/uu/tr/src/operation.rs @@ -238,12 +238,14 @@ impl Sequence { set2_uniques.sort(); set2_uniques.dedup(); - //If the complement flag is used in translate mode, only one unique character may appear in - //set2. Validate this with the set of uniques in set2 that we just generated. + // If the complement flag is used in translate mode, only one unique + // character may appear in set2. Validate this with the set of uniques + // in set2 that we just generated. + // Also, set2 must not overgrow set1, otherwise the mapping can't be 1:1. if set1.iter().any(|x| matches!(x, Self::Class(_))) && translating && complement_flag - && set2_uniques.len() > 1 + && (set2_uniques.len() > 1 || set2_solved.len() > set1_len) { return Err(BadSequence::ComplementMoreThanOneUniqueInSet2); } diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs index 8fe6aab00e6..5d800af947c 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -1413,3 +1413,14 @@ fn check_complement_1_unique_in_set2() { .args(&["-c", "[:upper:]", arg.as_str()]) .succeeds(); } + +#[test] +fn check_complement_set2_too_big() { + let x231 = "x".repeat(231); + + // [:upper:] expands to 230 characters, putting more characters in set2 + // should fail. + new_ucmd!() + .args(&["-c", "[:upper:]", x231.as_str()]) + .fails(); +}