"This projects aims at gathering/developing new completion scripts that
are not available in Zsh yet. The scripts are meant to be contributed to
the Zsh project when stable enough."
Quoting various characters that the shell *may* interpret specially is a
very fragile thing to do.
I've used something more robust all over the place in various Nix
expression I've written just because I didn't trust escapeShellArg.
Here is a proof of concept showing that I was indeed right in
distrusting escapeShellArg:
with import <nixpkgs> {};
let
payload = runCommand "payload" {} ''
# \x00 is not allowed for Nix strings, so let's begin at 1
for i in $(seq 1 255); do
echo -en "\\x$(printf %02x $i)"
done > "$out"
'';
escapers = with lib; {
current = escapeShellArg;
better = arg: let
backslashEscapes = stringToCharacters "\"\\ ';$`()|<>\r\t*[]&!~#";
search = backslashEscapes ++ [ "\n" ];
replace = map (c: "\\${c}") backslashEscapes ++ [ "'\n'" ];
in replaceStrings search replace (toString arg);
best = arg: "'${replaceStrings ["'"] ["'\\''"] (toString arg)}'";
};
testWith = escaper: let
escaped = escaper (builtins.readFile payload);
in runCommand "test" {} ''
if ! r="$(bash -c ${escapers.best "echo -nE ${escaped}"} 2> /dev/null)"
then
echo bash eval error > "$out"
exit 0
fi
if echo -n "$r" | cmp -s "${payload}"; then
echo success > "$out"
else
echo failed > "$out"
fi
'';
in runCommand "results" {} ''
echo "Test results:"
${lib.concatStrings (lib.mapAttrsToList (name: impl: ''
echo " ${name}: $(< "${testWith impl}")"
'') escapers)}
exit 1
''
The resulting output is the following:
Test results:
best: success
better: success
current: bash eval error
I did the "better" implementation just to illustrate that the method of
quoting only "harmful" characters results in madness in terms of
implementation and performance.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @edolstra, @zimbatm
If an option value is not a list, you now get
The option value `bla' in `file.nix' is not a list.
rather than
value is a string while a list was expected, at .../nixpkgs/lib/lists.nix:49:56