Skip to content

Commit 86795c8

Browse files
[3.14] gh-159739: Fix crash in _PyTuple_Resize() with an invalid size (GH-159804) (#159977)
gh-159739: Fix crash in _PyTuple_Resize() with an invalid size (GH-159804) _PyTuple_Resize() did not validate newsize for non-empty tuples. Raise SystemError for a negative size and MemoryError for a too-large size, like PyTuple_New() already does for the empty-tuple path. (cherry picked from commit c360884) Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
1 parent a3f95bb commit 86795c8

3 files changed

Lines changed: 16 additions & 1 deletion

File tree

‎Lib/test/test_capi/test_tuple.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ def test__tuple_resize(self):
261261
self.assertRaises(MemoryError, resize, a, PY_SSIZE_T_MAX)
262262
self.assertRaises(SystemError, resize, a, -1)
263263
self.assertRaises(SystemError, resize, a, PY_SSIZE_T_MIN)
264+
a = ([1], [2], [3])
265+
self.assertRaises(MemoryError, resize, a, PY_SSIZE_T_MAX)
266+
self.assertRaises(SystemError, resize, a, -1)
267+
self.assertRaises(SystemError, resize, a, PY_SSIZE_T_MIN)
264268
# refcount > 1
265269
a = (1, 2, 3)
266270
self.assertRaises(SystemError, resize, a, 3, False)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a crash in :c:func:`_PyTuple_Resize` when resizing a non-empty tuple to a
2+
negative or too large size. It now raises :exc:`SystemError` or
3+
:exc:`MemoryError` respectively.

‎Objects/tupleobject.c‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
961961
Py_ssize_t oldsize;
962962

963963
v = (PyTupleObject *) *pv;
964-
if (v == NULL || !Py_IS_TYPE(v, &PyTuple_Type) ||
964+
if (v == NULL || !Py_IS_TYPE(v, &PyTuple_Type) || newsize < 0 ||
965965
(Py_SIZE(v) != 0 && !_PyObject_IsUniquelyReferenced(*pv))) {
966966
*pv = 0;
967967
Py_XDECREF(v);
@@ -988,6 +988,14 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
988988
*pv = PyTuple_New(newsize);
989989
return *pv == NULL ? -1 : 0;
990990
}
991+
/* Check for overflow */
992+
if ((size_t)newsize > ((size_t)PY_SSIZE_T_MAX - (sizeof(PyTupleObject) -
993+
sizeof(PyObject *))) / sizeof(PyObject *)) {
994+
*pv = NULL;
995+
Py_DECREF(v);
996+
PyErr_NoMemory();
997+
return -1;
998+
}
991999

9921000
if (_PyObject_GC_IS_TRACKED(v)) {
9931001
_PyObject_GC_UNTRACK(v);

0 commit comments

Comments
 (0)