From b8a3795d95adbf4522a76c897ef318065290971a Mon Sep 17 00:00:00 2001 From: DevSabb <97408111+DevSabb@users.noreply.github.com> Date: Fri, 25 Feb 2022 06:11:53 -0500 Subject: [PATCH] tr: fix octal interpretation of repeat count string (#3178) * tr: fix octal interpretation of repeat count string * tr: fix formatting errors * tr: fix formatting issues 2 * tr: attempt to bypass spell check error * tr: fix spell check errors attempt 2 * tr: formatting fixes Co-authored-by: DevSabb --- src/uu/tr/src/operation.rs | 20 +++++++++++++------- tests/by-util/test_tr.rs | 22 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/uu/tr/src/operation.rs b/src/uu/tr/src/operation.rs index 4d00a0af1..afb9a1881 100644 --- a/src/uu/tr/src/operation.rs +++ b/src/uu/tr/src/operation.rs @@ -277,15 +277,21 @@ impl Sequence { separated_pair(Self::parse_backslash_or_char, tag("*"), digit1), tag("]"), )(input) - .map(|(l, (c, str))| { - ( - l, - match usize::from_str_radix(str, 8) { + .map(|(l, (c, cnt_str))| { + let result = if cnt_str.starts_with('0') { + match usize::from_str_radix(cnt_str, 8) { Ok(0) => Ok(Self::CharStar(c)), Ok(count) => Ok(Self::CharRepeat(c, count)), - Err(_) => Err(BadSequence::InvalidRepeatCount(str.to_string())), - }, - ) + Err(_) => Err(BadSequence::InvalidRepeatCount(cnt_str.to_string())), + } + } else { + match cnt_str.parse::() { + Ok(0) => Ok(Self::CharStar(c)), + Ok(count) => Ok(Self::CharRepeat(c, count)), + Err(_) => Err(BadSequence::InvalidRepeatCount(cnt_str.to_string())), + } + }; + (l, result) }) } diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs index ba41a8044..bf550a109 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -1,4 +1,4 @@ -// spell-checker:ignore aabbaa aabbcc aabc abbb abcc abcdefabcdef abcdefghijk abcdefghijklmn abcdefghijklmnop ABCDEFGHIJKLMNOPQRS abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFZZ abcxyz ABCXYZ abcxyzabcxyz ABCXYZABCXYZ acbdef alnum amzamz AMZXAMZ bbbd cclass cefgm cntrl compl dabcdef dncase Gzabcdefg PQRST upcase wxyzz xdigit xycde xyyye xyyz xyzzzzxyzzzz ZABCDEF Zamz +// spell-checker:ignore aabbaa aabbcc aabc abbb abcc abcdefabcdef abcdefghijk abcdefghijklmn abcdefghijklmnop ABCDEFGHIJKLMNOPQRS abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFZZ abcxyz ABCXYZ abcxyzabcxyz ABCXYZABCXYZ acbdef alnum amzamz AMZXAMZ bbbd cclass cefgm cntrl compl dabcdef dncase Gzabcdefg PQRST upcase wxyzz xdigit xycde xyyye xyyz xyzzzzxyzzzz ZABCDEF Zamz Cdefghijkl Cdefghijklmn use crate::common::util::*; #[test] @@ -869,6 +869,26 @@ fn check_against_gnu_tr_tests_o_rep_2() { .stdout_is("BCx"); } +#[test] +fn octal_repeat_count_test() { + //below will result in 8'x' and 4'y' as octal 010 = decimal 8 + new_ucmd!() + .args(&["ABCdefghijkl", "[x*010]Y"]) + .pipe_in("ABCdefghijklmn12") + .succeeds() + .stdout_is("xxxxxxxxYYYYmn12"); +} + +#[test] +fn non_octal_repeat_count_test() { + //below will result in 10'x' and 2'y' as the 10 does not have 0 prefix + new_ucmd!() + .args(&["ABCdefghijkl", "[x*10]Y"]) + .pipe_in("ABCdefghijklmn12") + .succeeds() + .stdout_is("xxxxxxxxxxYYmn12"); +} + #[test] fn check_against_gnu_tr_tests_esc() { // ['esc', qw('a\-z' A-Z), {IN=>'abc-z'}, {OUT=>'AbcBC'}],