It is possible to run into an IndexError in the subprocess module's _communicate function.
return run(
File "subprocess.py", line 491, in run
File "subprocess.py", line 1024, in communicate
File "subprocess.py", line 1418, in _communicate
IndexError: list index out of range
The lines in question are:
if stdout is not None:
stdout = stdout[0]
if stderr is not None:
stderr = stderr[0]
I believe this is due to the fact there is no safety checking to make sure that self._stdout_buff and self._stderr_buff have any content in them after being set to empty lists.
The fix I suggest is to change the checks from if stdout is not None to simply if stdout to make sure it is a populated list.
Example fixed code:
if stdout:
stdout = stdout[0]
if stderr:
stderr = stderr[0]
If a more stringent check is required, we could expand that out to check type and length, such as `isinstance(stdout, list) and len(stdout) > 0:` but that is more then necessary currently.
The presumption I suppose is that these statements only execute if self.stdout_thread and/or self.stderr_thread completes successfully. I suppose that the read could fail or get canceled via CancelSynchronousIo(). Of course in that case you have a bigger problem than an IndexError.
On a related note, _communicate() needs significant changes in Windows. See bpo-43346 if you're interested.
The bug is fixed, Thanks Chris! There was a refactoring noted as being nice in my comments on the primary main branch PR that would be nice to have. But isn't critical. If you want to make a PR for that, just reuse this bpo-43423 issue number on the PR and assign it to me.
The backports to 3.9 an 3.8 are approved and should automerge after CI finishes.
Activity
cdgriffith commented on Mar 6, 2021
It is possible to run into an IndexError in the subprocess module's _communicate function.
The lines in question are:
if stdout is not None: stdout = stdout[0] if stderr is not None: stderr = stderr[0]I believe this is due to the fact there is no safety checking to make sure that self._stdout_buff and self._stderr_buff have any content in them after being set to empty lists.
The fix I suggest is to change the checks from if stdout is not None to simply if stdout to make sure it is a populated list.
Example fixed code:
if stdout: stdout = stdout[0] if stderr: stderr = stderr[0]If a more stringent check is required, we could expand that out to check type and length, such as `isinstance(stdout, list) and len(stdout) > 0:` but that is more then necessary currently.
eryksun commented on Mar 6, 2021
The presumption I suppose is that these statements only execute if self.stdout_thread and/or self.stderr_thread completes successfully. I suppose that the read could fail or get canceled via CancelSynchronousIo(). Of course in that case you have a bigger problem than an IndexError.
On a related note, _communicate() needs significant changes in Windows. See bpo-43346 if you're interested.
gpshead commented on Mar 11, 2021
New changeset b4fc44b by Chris Griffith in branch 'master':
bpo-43423 Fix IndexError in subprocess _communicate function (GH-24777)
b4fc44b
gpshead commented on Mar 11, 2021
The bug is fixed, Thanks Chris! There was a refactoring noted as being nice in my comments on the primary main branch PR that would be nice to have. But isn't critical. If you want to make a PR for that, just reuse this bpo-43423 issue number on the PR and assign it to me.
The backports to 3.9 an 3.8 are approved and should automerge after CI finishes.
miss-islington commented on Mar 12, 2021
New changeset 1a5001c by Miss Islington (bot) in branch '3.8':
bpo-43423 Fix IndexError in subprocess _communicate function (GH-24777)
1a5001c
miss-islington commented on Mar 12, 2021
New changeset ad83fde by Miss Islington (bot) in branch '3.9':
bpo-43423 Fix IndexError in subprocess _communicate function (GH-24777)
ad83fde