Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 087bb48

Browse files
authored
gh-127196: Fix crash in _interpreters, when shared had invalid encodings (#127220)
1 parent 8af5781 commit 087bb48

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

Lib/test/test__interpreters.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ def setUp(self):
557557
self.id = _interpreters.create()
558558

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

571+
def test_invalid_shared_encoding(self):
572+
# See https://github.com/python/cpython/issues/127196
573+
bad_shared = {"\uD82A": 0}
574+
msg = 'surrogates not allowed'
575+
with self.assertRaisesRegex(UnicodeEncodeError, msg):
576+
_interpreters.exec(self.id, 'a', shared=bad_shared)
577+
with self.assertRaisesRegex(UnicodeEncodeError, msg):
578+
_interpreters.run_string(self.id, 'a', shared=bad_shared)
579+
with self.assertRaisesRegex(UnicodeEncodeError, msg):
580+
_interpreters.run_func(self.id, lambda: None, shared=bad_shared)
581+
571582

572583
class RunStringTests(TestBase):
573584

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when dict with keys in invalid encoding were passed to several
2+
functions in ``_interpreters`` module.

Modules/_interpretersmodule.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,12 @@ _run_in_interpreter(PyInterpreterState *interp,
459459

460460
// Prep and switch interpreters.
461461
if (_PyXI_Enter(&session, interp, shareables) < 0) {
462-
assert(!PyErr_Occurred());
462+
if (PyErr_Occurred()) {
463+
// If an error occured at this step, it means that interp
464+
// was not prepared and switched.
465+
return -1;
466+
}
467+
// Now, apply the error from another interpreter:
463468
PyObject *excinfo = _PyXI_ApplyError(session.error);
464469
if (excinfo != NULL) {
465470
*p_excinfo = excinfo;

0 commit comments

Comments
 (0)