Skip to content

Commit 6b8a9a1

Browse files
authored
[3.12] gh-122334: Fix crash when importing ssl after re-initialization (GH-122481) (#122495)
Fix crash when importing ssl after re-initialization The current METH_FASTCALL|METH_KEYWORDS functions in a non-builtin module can cause segfaults after restarting the main interpreter, invoking _PyArg_UnpackKeywords() with an insufficiently cleared _PyArg_Parser struct. This patch fixes the invalidation of the static argument parsers.
1 parent 372df19 commit 6b8a9a1

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

Lib/test/test_embed.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,21 @@ def add(cls, slot, own):
434434
self.assertEqual(result, {})
435435
self.assertEqual(out, '')
436436

437+
def test_getargs_reset_static_parser(self):
438+
# Test _PyArg_Parser initializations via _PyArg_UnpackKeywords()
439+
# https://github.com/python/cpython/issues/122334
440+
code = textwrap.dedent("""
441+
import _ssl
442+
_ssl.txt2obj(txt='1.3')
443+
print('1')
444+
445+
import _queue
446+
_queue.SimpleQueue().put_nowait(item=None)
447+
print('2')
448+
""")
449+
out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
450+
self.assertEqual(out, '1\n2\n' * INIT_LOOPS)
451+
437452

438453
class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
439454
maxDiff = 4096
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix crash when importing :mod:`ssl` after the main interpreter restarts.

Python/getargs.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,6 +2071,18 @@ parser_clear(struct _PyArg_Parser *parser)
20712071
if (parser->initialized == 1) {
20722072
Py_CLEAR(parser->kwtuple);
20732073
}
2074+
2075+
if (parser->format) {
2076+
parser->fname = NULL;
2077+
}
2078+
else {
2079+
assert(parser->fname != NULL);
2080+
}
2081+
parser->custom_msg = NULL;
2082+
parser->pos = 0;
2083+
parser->min = 0;
2084+
parser->max = 0;
2085+
parser->initialized = 0;
20742086
}
20752087

20762088
static PyObject*

0 commit comments

Comments
 (0)