repo: handle bad programs a bit better

If programs emit non-UTF-8 output, we currently throw a fatal error.
We largely only care about the exit status of programs, and even the
output we do parse is a bit minimal.  Lets make it into a warning and
mangle the invalid bytes into U+FFFD.  This should complain enough to
annoy but not to break when it's not necessary.

Bug: https://crbug.com/gerrit/12337#c2
Change-Id: Idbc94f19ff4d84d2e47e01960dd17d5b492d4a8a
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/255272
Reviewed-by: David Pursehouse <dpursehouse@collab.net>
Tested-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
Mike Frysinger 2020-02-14 23:38:28 -05:00
parent a46bf7dc2a
commit 6a784ff9a6

18
repo
View File

@ -363,15 +363,23 @@ def run_command(cmd, **kwargs):
kwargs.setdefault('stderr', subprocess.PIPE) kwargs.setdefault('stderr', subprocess.PIPE)
cmd_input = kwargs.pop('input', None) cmd_input = kwargs.pop('input', None)
def decode(output):
"""Decode |output| to text."""
if output is None:
return output
try:
return output.decode('utf-8')
except UnicodeError:
print('repo: warning: Invalid UTF-8 output:\ncmd: %r\n%r' % (cmd, output),
file=sys.stderr)
# TODO(vapier): Once we require Python 3, use 'backslashreplace'.
return output.decode('utf-8', 'replace')
# Run & package the results. # Run & package the results.
proc = subprocess.Popen(cmd, **kwargs) proc = subprocess.Popen(cmd, **kwargs)
(stdout, stderr) = proc.communicate(input=cmd_input) (stdout, stderr) = proc.communicate(input=cmd_input)
if stdout is not None:
stdout = stdout.decode('utf-8')
if stderr is not None:
stderr = stderr.decode('utf-8')
trace.print(':', ' '.join(cmd)) trace.print(':', ' '.join(cmd))
ret = RunResult(proc.returncode, stdout, stderr) ret = RunResult(proc.returncode, decode(stdout), decode(stderr))
# If things failed, print useful debugging output. # If things failed, print useful debugging output.
if check and ret.returncode: if check and ret.returncode: