Skip to content

Commit

Permalink
dircolors: escape "'" and ":"
Browse files Browse the repository at this point in the history
  • Loading branch information
cakebaker committed Jun 15, 2022
1 parent 029e0dc commit 42c35bc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/uu/dircolors/src/dircolors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ where
continue;
}

let line = escape(line);

let (key, val) = line.split_two();
if val.is_empty() {
return Err(format!(
Expand Down Expand Up @@ -411,3 +413,37 @@ where

Ok(result)
}

/// Escape single quotes because they are not allowed between single quotes in shell code, and code
/// enclosed by single quotes is what is returned by `parse()`.
///
/// We also escape ":" to make the "quote" test pass in the GNU test suite:
/// https://github.com/coreutils/coreutils/blob/master/tests/misc/dircolors.pl
fn escape(s: &str) -> String {
let mut result = String::new();
let mut previous = ' ';

for c in s.chars() {
match c {
'\'' => result.push_str("'\\''"),
':' if previous != '\\' => result.push_str("\\:"),
_ => result.push_str(&c.to_string()),
}
previous = c;
}

result
}

#[cfg(test)]
mod tests {
use super::escape;

#[test]
fn test_escape() {
assert_eq!("", escape(""));
assert_eq!("'\\''", escape("'"));
assert_eq!("\\:", escape(":"));
assert_eq!("\\:", escape("\\:"));
}
}
10 changes: 10 additions & 0 deletions tests/by-util/test_dircolors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ fn test_stdin() {
.no_stderr();
}

#[test]
fn test_quoting() {
new_ucmd!()
.pipe_in("exec 'echo Hello;:'\n")
.args(&["-b", "-"])
.succeeds()
.stdout_is("LS_COLORS='ex='\\''echo Hello;\\:'\\'':';\nexport LS_COLORS\n")
.no_stderr();
}

#[test]
fn test_extra_operand() {
new_ucmd!()
Expand Down

0 comments on commit 42c35bc

Please sign in to comment.