Package: git-buildpackage Version: 0.8.9 Severity: normal Tags: patch I'm currently using git-buildpackage with a custom --builder command (vectis, https://github.com/smcv/vectis) that among other things accepts a command-line option of the form:
--extra-repository='deb [trusted=yes] http://localhost/path suite component' With git-buildpackage, I have to backslash-escape the spaces: --extra-repository='deb\ [trusted=yes]\ ...' or it will treat "--extra-repository=deb", "[trusted=yes]", etc. as separate command-line arguments for vectis. This is because gbp.command_wrappers.Command(..., shell=True) just joins the command to the arguments with " ".join() rather than doing proper shell quoting. That's correct for the --builder as currently documented, but not for its arguments. It would be easy to run into this with debuild if you're using something like gbp buildpackage --set-envvar=DEBFULLNAME="Simon McVittie" (a debuild option) or gbp buildpackage --check-command="lintian -Ii" (a dpkg-buildpackage option). Doing proper shell quoting in Python 3 is trival (shlex.quote, which I use a lot in vectis) but Python 2 doesn't have that function. However, there is another way to get the --builder interpreted as a shell one-liner and still pass it arguments: you can invoke ["sh", "-c", ('%s "$@"' % builder), "sh"] + arguments with shell=False, and it will do the right thing. The first "sh" in that monster is argv[0] for the subprocess, and the second is $0 for the shell one-liner. I attach a possible patch. S
>From a088aef91ffa9de60c6d7ac3278360ce0ee571e1 Mon Sep 17 00:00:00 2001 From: Simon McVittie <s...@debian.org> Date: Tue, 10 Jan 2017 19:49:08 +0000 Subject: [PATCH] buildpackage: don't treat dpkg arguments as shell input If one of gbp buildpackage's command-line arguments (after processing by the calling shell if applicable) includes spaces or shell metacharacters, it's unexpected to subject it to a layer of shell interpretation. Conversely, the builder option is documented to be a shell command and so must go through one layer of shell interpretation. This makes an invocation like gbp buildpackage --check-command="lintian -Ii" work the way it was presumably intended. --- gbp/scripts/buildpackage.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 6524f01..c7ad903 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -727,7 +727,11 @@ def main(argv): )(dir=build_dir) # Finally build the package: - RunAtCommand(options.builder, dpkg_args, shell=True, + RunAtCommand('sh', + ['-c', options.builder + ' "$@"', + 'sh'] + # $0 for the shell one-liner + dpkg_args, # $@ for the shell one-liner + shell=False, # we start the shell explicitly extra_env=Hook.md(build_env, {'GBP_BUILD_DIR': build_dir}) )(dir=build_dir) -- 2.11.0