Partial fix: Callable alias can provoke Bad file descriptor exception in the internal or external code (#5645)

* fix

* fix

* test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* news

* test

* test

* test

* test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* news

* bump test

* bump test

* test

* test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* news

* test

---------

Co-authored-by: a <1@1.1>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Andy Kipp 2024-08-09 14:46:19 +02:00 committed by GitHub
parent bc8faa4e94
commit 938db85a87
Failed to generate hash of commit
3 changed files with 65 additions and 1 deletions

View file

@ -0,0 +1,23 @@
**Added:**
* <news item>
**Changed:**
* <news item>
**Deprecated:**
* <news item>
**Removed:**
* <news item>
**Fixed:**
* Partial fix for "Bad file descriptor" in case of callable alias with execx invocation inside e.g. ExecAlias (#5645).
**Security:**
* <news item>

View file

@ -1508,3 +1508,41 @@ def test_shebang_cr(tmpdir):
command = f"cd {testdir}; ./{testfile}\n"
out, err, rtn = run_xonsh(command)
assert out == f"{expected_out}\n"
test_code = [
"""
$XONSH_SHOW_TRACEBACK = True
@aliases.register
def _e(a,i,o,e):
echo -n O
echo -n E 1>2
execx("echo -n O")
execx("echo -n E 1>2")
print("o")
print("O", file=o)
print("E", file=e)
import tempfile
for i in range(0, 12):
echo -n e
print($(e), !(e), $[e], ![e])
print($(e > @(tempfile.NamedTemporaryFile(delete=False).name)))
print(!(e > @(tempfile.NamedTemporaryFile(delete=False).name)))
print($[e > @(tempfile.NamedTemporaryFile(delete=False).name)])
print(![e > @(tempfile.NamedTemporaryFile(delete=False).name)])
"""
]
@skip_if_on_windows
@pytest.mark.parametrize("test_code", test_code)
def test_callable_alias_no_bad_file_descriptor(test_code):
"""Test no exceptions during any kind of capturing of callable alias. See also #5631."""
out, err, ret = run_xonsh(
test_code, interactive=True, single_command=True, timeout=60
)
assert ret == 0
assert "Error" not in out
assert "Exception" not in out

View file

@ -511,7 +511,10 @@ class ProcProxyThread(threading.Thread):
# clean up
# scopz: not sure why this is needed, but stdin cannot go here
# and stdout & stderr must.
handles = [self.stdout, self.stderr]
if xp.ON_WINDOWS:
handles = [self.stdout, self.stderr]
else:
handles = [sp_stdout, sp_stderr]
for handle in handles:
safe_fdclose(handle, cache=self._closed_handle_cache)