diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 612e639846d..4d931f8d3c6 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -67,6 +67,14 @@ def __len__(self): return 1 self.assertRaises(TypeError, _posixsubprocess.fork_exec, 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17) + # Issue #15736: overflow in _PySequence_BytesToCharpArray() + class Z(object): + def __len__(self): + return sys.maxsize + def __getitem__(self, i): + return b'x' + self.assertRaises(MemoryError, _posixsubprocess.fork_exec, + 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17) @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') def test_subprocess_fork_exec(self): diff --git a/Objects/abstract.c b/Objects/abstract.c index 299daf549ef..7705d05d71e 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2728,6 +2728,13 @@ _PySequence_BytesToCharpArray(PyObject* self) if (argc == -1) return NULL; + assert(argc >= 0); + + if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) { + PyErr_NoMemory(); + return NULL; + } + array = malloc((argc + 1) * sizeof(char *)); if (array == NULL) { PyErr_NoMemory();