-
-
Notifications
You must be signed in to change notification settings - Fork 31.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-43423 Fix IndexError in subprocess _communicate function #24777
bpo-43423 Fix IndexError in subprocess _communicate function #24777
Conversation
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). CLA MissingOur records indicate the following people have not signed the CLA: For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
stdout = stdout[0] | ||
if stderr is not None: | ||
if stderr: | ||
stderr = stderr[0] | ||
|
||
return (stdout, stderr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an additional bug exposed by the above fix. This line could now return ([], []) instead of (None, None).
Changing the above translation logic to
stdout = stdout[0] if stdout else None
stderr = stderr[0] if stdout else None
would work. call this option [A[.
though nicer code all around would be to not use _stdXXX_buff = []
at all but instead refactor _readerthread
to take an attribute name to assign to instead of passing it a list to shove a single element in.
something similar to:
def _readerthread(self, fh, attr_name):
try:
setattr(self, attr_name, fh.read())
finally:
fh.close()
that larger refactoring makes sense in the context of 3.10. call this option [B].
as a bugfix for 3.9 and earlier i'd stick with the modification of the stdout and stderr assignments. The time when this case even happens looks to be only when the timeout has expired on the joins() above. So what's broken is timeout logic on Windows during a timeout when collecting stdout and stderr.
lets go ahead with [A] in this PR and a followup PR can do [B].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to option A
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The time when this case even happens looks to be only when the timeout has expired on the joins() above. So what's broken is timeout logic on Windows during a timeout when collecting stdout and stderr.
If either thread is still alive, then a TimeoutExpired
will be raised. The only time there is a problem is if one or more reader threads has failed, either by being forcibly terminated via TerminateThread
(not exposed to Python code, except via ctypes) or if the fh.read()
call fails, which is most likely due to another thread calling CancelSynchronousIo
(also only exposed to Python code via ctypes).
Looks good. Can you add a NEWS entry? https://blurb-it.herokuapp.com/ should be able to do it if you don't have blurb installed. |
Thanks @cdgriffith for the PR, and @gpshead for merging it 🌮🎉.. I'm working now to backport this PR to: 3.8, 3.9. |
GH-24823 is a backport of this pull request to the 3.9 branch. |
GH-24824 is a backport of this pull request to the 3.8 branch. |
bpo-43423 Fix IndexError in subprocess _communicate function (pythonGH-24777)
|
Thanks @cdgriffith for the PR, and @gpshead for merging it 🌮🎉.. I'm working now to backport this PR to: 3.9. |
Thanks @cdgriffith for the PR, and @gpshead for merging it 🌮🎉.. I'm working now to backport this PR to: 3.8. |
GH-24830 is a backport of this pull request to the 3.8 branch. |
GH-24831 is a backport of this pull request to the 3.9 branch. |
Check to make sure stdout and stderr are not empty before selecting an item from them in Windows subprocess._communicate. Co-authored-by: Gregory P. Smith <greg@krypto.org> (cherry picked from commit b4fc44b) Co-authored-by: Chris Griffith <chris@cdgriffith.com>
Check to make sure stdout and stderr are not empty before selecting an item from them in Windows subprocess._communicate. Co-authored-by: Gregory P. Smith <greg@krypto.org> (cherry picked from commit b4fc44b) Co-authored-by: Chris Griffith <chris@cdgriffith.com>
|
It is possible to run into an IndexError in the subprocess module's _communicate function.
The lines in question are:
I believe this is due to the fact there is no safety checking to make sure that
self._stdout_buff
andself._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 simplyif stdout
to make sure it is a populated list, as well as forstderr
.Example fixed code:
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.https://bugs.python.org/issue43423