diff --git a/src/uu/paste/src/paste.rs b/src/uu/paste/src/paste.rs index d7a4d325c..c8d807635 100644 --- a/src/uu/paste/src/paste.rs +++ b/src/uu/paste/src/paste.rs @@ -12,7 +12,7 @@ use std::fmt::Display; use std::fs::File; use std::io::{stdin, stdout, BufRead, BufReader, Read, Write}; use std::path::Path; -use uucore::error::{FromIo, UResult}; +use uucore::error::{FromIo, UResult, USimpleError}; use uucore::{format_usage, help_about, help_usage}; const ABOUT: &str = help_about!("paste.md"); @@ -129,6 +129,16 @@ fn paste( files.push(file); } + if delimiters.ends_with('\\') && !delimiters.ends_with("\\\\") { + return Err(USimpleError::new( + 1, + format!( + "delimiter list ends with an unescaped backslash: {}", + delimiters + ), + )); + } + let delimiters: Vec = unescape(delimiters).chars().collect(); let mut delim_count = 0; let mut delim_length = 1; @@ -222,10 +232,8 @@ fn paste( } // Unescape all special characters -// TODO: this will need work to conform to GNU implementation fn unescape(s: &str) -> String { s.replace("\\n", "\n") .replace("\\t", "\t") .replace("\\\\", "\\") - .replace('\\', "") } diff --git a/tests/by-util/test_paste.rs b/tests/by-util/test_paste.rs index 2e119846e..fa7ead335 100644 --- a/tests/by-util/test_paste.rs +++ b/tests/by-util/test_paste.rs @@ -156,6 +156,37 @@ fn test_multi_stdin() { } } +#[test] +fn test_delimiter_list_ending_with_escaped_backslash() { + for d in ["-d", "--delimiters"] { + let (at, mut ucmd) = at_and_ucmd!(); + let mut ins = vec![]; + for (i, _in) in ["a\n", "b\n"].iter().enumerate() { + let file = format!("in{}", i); + at.write(&file, _in); + ins.push(file); + } + ucmd.args(&[d, "\\\\"]) + .args(&ins) + .succeeds() + .stdout_is("a\\b\n"); + } +} + +#[test] +fn test_delimiter_list_ending_with_unescaped_backslash() { + for d in ["-d", "--delimiters"] { + new_ucmd!() + .args(&[d, "\\"]) + .fails() + .stderr_contains("delimiter list ends with an unescaped backslash: \\"); + new_ucmd!() + .args(&[d, "_\\"]) + .fails() + .stderr_contains("delimiter list ends with an unescaped backslash: _\\"); + } +} + #[test] fn test_data() { for example in EXAMPLE_DATA {