4 ms·
This approach creates an odd mini language, which is incomplete: comptime assert(std.mem.indexOfScalar(u8, cmd, '\'') == null); // Quoting isn't supported
by chubot 2y ago
This approach creates an odd mini language, which is incomplete:
comptime assert(std.mem.indexOfScalar(u8, cmd, '\'') == null); // Quoting isn't supported yet.
comptime assert(std.mem.indexOfScalar(u8, cmd, '"') == null);
But you can do correct interpolation with simple shell variables, rather than generating shell code strings:
$ today='foo; bar' sh -c 'argv git switch --create "release-$today" origin/main'
['git', 'switch', '--create', 'release-foo; bar', 'origin/main']
So that is a test that we can use a plain shell string, without any shell injection bug. (argv is my command to test quoting: python -c 'import sys; print(sys.argv)' "$@" )
Note that there's no escaping function needed, because we're not generating any shell code. We're generating an argv array for `/bin/sh` instead.
---
So by invoking with an env var, you can easily create a correct API that uses plain shell
git switch --create "release-$today"
rather than
git switch --create release-{today} # what language is this? It's not obvious
If you don't want to use the env var, you can also use
git switch --create "release-$1"
And invoke with
['sh', '-c', shell_string, 'unused-arg0', today_string]
With this approach, you don't need
1. any kind of shell escaping
2. any analyzing of pseudo-shell strings, which can't contain quotes
Because you are not generating any shell code. The shell code is constant.