1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Merge pull request #3639 from cakebaker/dircolors_quote

dircolors: escape "'" and ":"
This commit is contained in:
Sylvestre Ledru 2022-06-16 10:05:58 +02:00 committed by GitHub
commit e232bb49f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 0 deletions

View file

@ -344,6 +344,8 @@ where
continue;
}
let line = escape(line);
let (key, val) = line.split_two();
if val.is_empty() {
return Err(format!(
@ -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("\\:"));
}
}

View file

@ -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!()