Protect against decoding errors with subprocess text mode

All these are calling subprocess in 'text mode', where it will
try to decode stdout/stderr using the default encoding (utf-8
for us). If it doesn't decode, subprocess will raise an exception
and kobo doesn't handle it, it just passes it along to us, so
things blow up - see https://pagure.io/releng/issue/12474 . To
avoid this, let's set `errors="replace"`, which tells the decoder
to replace invalid data with ? characters. This way we should get
as much of the output as can be read, and no crashes.

We also replace `universal_newlines=True` with `text=True` as
the latter is shorter, clearer, and what Python 3 subprocess
wants us to use, it considers `universal_newlines` to just be
a backwards-compatibility thing - "The universal_newlines argument
is equivalent to text and is provided for backwards compatibility"

Signed-off-by: Adam Williamson <awilliam@redhat.com>
Merges: https://pagure.io/pungi/pull-request/1812
This commit is contained in:
Adam Williamson 2025-01-15 11:00:33 -08:00 committed by Lubomír Sedlář
parent 98e3b3f8c4
commit 2d16a3af00
17 changed files with 132 additions and 70 deletions

View file

@ -652,7 +652,11 @@ def run_unmount_cmd(cmd, max_retries=10, path=None, logger=None):
"""
for i in range(max_retries):
proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
errors="replace",
)
out, err = proc.communicate()
if proc.returncode == 0:
@ -674,7 +678,8 @@ def run_unmount_cmd(cmd, max_retries=10, path=None, logger=None):
c,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
text=True,
errors="replace",
)
out, _ = proc.communicate()
logger.debug(
@ -879,7 +884,7 @@ def git_ls_remote(baseurl, ref, credential_helper=None):
if credential_helper:
cmd.extend(["-c", "credential.useHttpPath=true"])
cmd.extend(["-c", "credential.helper=%s" % credential_helper])
return run(cmd + ["ls-remote", baseurl, ref], universal_newlines=True)
return run(cmd + ["ls-remote", baseurl, ref], text=True, errors="replace")
def get_tz_offset():