Skip to content

Commit

Permalink
pythongh-127196: Fix crash in _interpreters, when shared had inva…
Browse files Browse the repository at this point in the history
…lid encodings
  • Loading branch information
sobolevn committed Nov 24, 2024
1 parent f7bb658 commit 72b9e97
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
13 changes: 12 additions & 1 deletion Lib/test/test__interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ def setUp(self):
self.id = _interpreters.create()

def test_signatures(self):
# for method in ['exec', 'run_string', 'run_func']:
# See https://github.com/python/cpython/issues/126654
msg = "expected 'shared' to be a dict"
with self.assertRaisesRegex(TypeError, msg):
_interpreters.exec(self.id, 'a', 1)
Expand All @@ -568,6 +568,17 @@ def test_signatures(self):
with self.assertRaisesRegex(TypeError, msg):
_interpreters.run_func(self.id, lambda: None, shared=1)

def test_invalid_shared_encoding(self):
# See https://github.com/python/cpython/issues/127196
bad_shared = {"\uD82A": 0}
msg = 'surrogates not allowed'
with self.assertRaisesRegex(UnicodeEncodeError, msg):
_interpreters.exec(self.id, 'a', shared=bad_shared)
with self.assertRaisesRegex(UnicodeEncodeError, msg):
_interpreters.run_string(self.id, 'a', shared=bad_shared)
with self.assertRaisesRegex(UnicodeEncodeError, msg):
_interpreters.run_func(self.id, lambda: None, shared=bad_shared)


class RunStringTests(TestBase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix crash when dict with keys in invalid encoding were passed to several
functions in ``_interpreters`` module.
7 changes: 6 additions & 1 deletion Modules/_interpretersmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,12 @@ _run_in_interpreter(PyInterpreterState *interp,

// Prep and switch interpreters.
if (_PyXI_Enter(&session, interp, shareables) < 0) {
assert(!PyErr_Occurred());
if (PyErr_Occurred()) {
// If an error occured at this step, it means that interp
// was not prepared and switched.
return -1;
}
// Now, apply the error from another interpreter:
PyObject *excinfo = _PyXI_ApplyError(session.error);
if (excinfo != NULL) {
*p_excinfo = excinfo;
Expand Down

0 comments on commit 72b9e97

Please sign in to comment.