Skip to content

Commit fa8d19c

Browse files
committed
Implement handling of unicode decode error from incomplete code bytes
1 parent c7e5bba commit fa8d19c

1 file changed

Lines changed: 31 additions & 3 deletions

File tree

‎Lib/subprocess.py‎

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,11 +1245,39 @@ def _check_timeout(self, endtime, orig_timeout, stdout_seq, stderr_seq,
12451245
"""Convenience for checking if a timeout has expired."""
12461246
if endtime is None:
12471247
return
1248+
1249+
def translate_newlines_partial_output(data, encoding, errors):
1250+
# Handle decoding the data considering it may be truncated
1251+
# mid-codepoint (ignore the trailing partial codepoint).
1252+
# See https://github.com/python/cpython/issues/87597
1253+
try:
1254+
output = self._translate_newlines(data, encoding, errors)
1255+
except UnicodeDecodeError as exc:
1256+
if exc.end == len(data):
1257+
output = self._translate_newlines(data[:exc.start],
1258+
encoding,
1259+
errors)
1260+
else:
1261+
raise
1262+
return output
1263+
12481264
if skip_check_and_raise or _time() > endtime:
1265+
if stdout_seq:
1266+
stdout = b''.join(stdout_seq)
1267+
if self.text_mode:
1268+
stdout = translate_newlines_partial_output(
1269+
stdout, self.stdout.encoding, self.stdout.errors)
1270+
else:
1271+
stdout = None
1272+
if stderr_seq:
1273+
stderr = b''.join(stderr_seq)
1274+
if self.text_mode:
1275+
stderr = translate_newlines_partial_output(
1276+
stderr, self.stderr.encoding, self.stderr.errors)
1277+
else:
1278+
stderr = None
12491279
raise TimeoutExpired(
1250-
self.args, orig_timeout,
1251-
output=b''.join(stdout_seq) if stdout_seq else None,
1252-
stderr=b''.join(stderr_seq) if stderr_seq else None)
1280+
self.args, orig_timeout, output=stdout, stderr=stderr)
12531281

12541282

12551283
def wait(self, timeout=None):

0 commit comments

Comments
 (0)