Jeff King <peff@xxxxxxxx> writes: > [credential] > helper = cache --socket=/path/to/socket --timeout=123 > > Arguably we could have gotten away with word-splitting ourselves, > sticking the result in child_process.args, and avoided the shell. But > the use of the shell is documented in gitcredentials(7): > > helper > The name of an external credential helper, and any associated > options. If the helper name is not an absolute path, then the string > git credential- is prepended. The resulting string is executed by > the shell (so, for example, setting this to foo --option=bar will > execute git credential-foo --option=bar via the shell. See the > manual of specific helpers for examples of their use. > > So users may be depending on that to do "--socket=$HOME/.foo", or even > more exotic shell constructs. > > Again, it's possible that we could detect that no shell metacharacters > are in play and do the word-splitting ourselves. But at that point I > think it should go into run-command's prepare_shell_cmd(). That is, I I > think it could take space out of the list of metachars that force us to > invoke the shell, and do the word-splitting there. But not having > thought very hard about it, there are probably corner cases where that > optimization is detectable by the user (presumably unusual IFS, but > maybe more?). Well, I strongly object to an approach for us to "parse" anything. But even then it would be sensible to formulate: argv[0] = sh argv[1] = -c argv[2] = git-credential-cache --socket=/path/ --timeout=123 "$@" argv[3] = - argv[4] = NULL and if there is an argument say "get", extend it to argv[0] = sh argv[1] = -c argv[2] = git-credential-cache --socket=/path/ --timeout=123 "$@" argv[3] = - argv[4] = get argv[5] = NULL before passing the array to execv(), no? And with the metacharacter optimization to drop .use_shell we already have, a single-token /bin/myhelper case would then become argv[0] = /bin/myhelper argv[1] = get argv[2] = NULL naturally.