tr: properly determine trailing backslash

Fixes #6729.
This commit is contained in:
Ben Wiederhake 2024-09-24 02:23:58 +02:00
parent 165bbc272a
commit a8b9e042e1
2 changed files with 30 additions and 18 deletions

View file

@ -99,23 +99,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
if let Some(first) = sets.first() { if let Some(first) = sets.first() {
let slice = os_str_as_bytes(first)?; let slice = os_str_as_bytes(first)?;
let trailing_backslashes = slice.iter().rev().take_while(|&&c| c == b'\\').count();
let mut iter = slice.iter(); if trailing_backslashes % 2 == 1 {
// The trailing backslash has a non-backslash character before it.
if let Some(b'\\') = iter.next_back() { show!(USimpleError::new(
match iter.next_back() { 0,
Some(b'\\') => { "warning: an unescaped backslash at end of string is not portable"
// 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

@ -1456,15 +1456,37 @@ fn test_unescaped_backslash_warning_false_positive() {
.pipe_in(r"a\b\c\") .pipe_in(r"a\b\c\")
.succeeds() .succeeds()
.stdout_only("abc"); .stdout_only("abc");
new_ucmd!()
.args(&["-d", r"\\\\"])
.pipe_in(r"a\b\c\")
.succeeds()
.stdout_only("abc");
new_ucmd!()
.args(&["-d", r"\\\\\\"])
.pipe_in(r"a\b\c\")
.succeeds()
.stdout_only("abc");
} }
#[test] #[test]
#[cfg(unix)] #[cfg(unix)]
fn test_trailing_backslash_is_only_input_character() { fn test_trailing_backslash() {
new_ucmd!() new_ucmd!()
.args(&["-d", r"\"]) .args(&["-d", r"\"])
.pipe_in(r"a\b\c\") .pipe_in(r"a\b\c\")
.succeeds() .succeeds()
.stderr_is("tr: warning: an unescaped backslash at end of string is not portable\n") .stderr_is("tr: warning: an unescaped backslash at end of string is not portable\n")
.stdout_is("abc"); .stdout_is("abc");
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");
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");
} }