Skip to content

Commit

Permalink
paste: handle list ending with unescaped backslash
Browse files Browse the repository at this point in the history
  • Loading branch information
cakebaker authored and sylvestre committed Mar 27, 2023
1 parent 97f8e9d commit 62e3303
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/uu/paste/src/paste.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

static ABOUT: &str = "Write lines consisting of the sequentially corresponding lines from each
FILE, separated by TABs, to standard output.";
Expand Down Expand Up @@ -127,6 +127,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<char> = unescape(delimiters).chars().collect();
let mut delim_count = 0;
let mut delim_length = 1;
Expand Down Expand Up @@ -220,10 +230,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('\\', "")
}
31 changes: 31 additions & 0 deletions tests/by-util/test_paste.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 62e3303

Please sign in to comment.