tr: fix unescaped trailing backslash warning

This warning is being emitted whenever the input string ends with a
backslash, even if the backslash is escaped.
This commit is contained in:
Andrew Liebenow 2024-09-18 17:29:11 -05:00
parent b8150f5ba5
commit 08992ec6b3
2 changed files with 41 additions and 5 deletions

View file

@ -98,11 +98,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
if let Some(first) = sets.first() {
if let Some(b'\\') = os_str_as_bytes(first)?.last() {
show!(USimpleError::new(
0,
"warning: an unescaped backslash at end of string is not portable"
));
let slice = os_str_as_bytes(first)?;
let mut iter = slice.iter();
if let Some(b'\\') = iter.next_back() {
match iter.next_back() {
Some(b'\\') => {
// The trailing backslash has a backslash preceding it, so it is properly escaped
}
_ => {
// The trailing backslash has a non-backslash character before it OR is the only character in the
// string, so the warning applies
show!(USimpleError::new(
0,
"warning: an unescaped backslash at end of string is not portable"
));
}
}
}
}

View file

@ -1445,3 +1445,26 @@ fn test_truncate_non_utf8_set() {
.succeeds()
.stdout_is_bytes(b"\x010mp12");
}
#[test]
#[cfg(unix)]
fn test_unescaped_backslash_warning_false_positive() {
// Was erroneously printing this warning (even though the backslash was escaped):
// "tr: warning: an unescaped backslash at end of string is not portable"
new_ucmd!()
.args(&["-d", r"\\"])
.pipe_in(r"a\b\c\")
.succeeds()
.stdout_only("abc");
}
#[test]
#[cfg(unix)]
fn test_trailing_backslash_is_only_input_character() {
new_ucmd!()
.args(&["-d", r"\"])
.pipe_in(r"a\b\c\")
.succeeds()
.stderr_is("tr: warning: an unescaped backslash at end of string is not portable\n")
.stdout_is("abc");
}