From 128335a24bc65948afd34af98067976092cad139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Fri, 12 Jul 2024 16:12:35 +0200 Subject: [PATCH] tr: Raise error if set2 is too big on complemented class --- src/uu/tr/src/operation.rs | 8 +++++--- tests/by-util/test_tr.rs | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/uu/tr/src/operation.rs b/src/uu/tr/src/operation.rs index ae857ef86..e6eb08748 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 8fe6aab00..209c4f284 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -1413,3 +1413,17 @@ 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); + let x230 = &x231[..230]; + + // The complement of [:upper:] expands to 230 characters, + // putting more characters in set2 should fail. + new_ucmd!().args(&["-c", "[:upper:]", x230]).succeeds(); + new_ucmd!() + .args(&["-c", "[:upper:]", x231.as_str()]) + .fails() + .stderr_contains("when translating with complemented character classes,\nstring2 must map all characters in the domain to one"); +}