GitHub

File tree

  • Lib/test

  • Misc/NEWS.d/next/Security

  • Objects

Original file line numberDiff line numberDiff line change

@@ -96,6 +96,19 @@ def imul(a, b): a *= b

9696

self.assertRaises((MemoryError, OverflowError), mul, lst, n)

9797

self.assertRaises((MemoryError, OverflowError), imul, lst, n)

9898
99+

def test_list_resize_overflow(self):

100+

# gh-97616: test new_allocated * sizeof(PyObject*) overflow

101+

# check in list_resize()

102+

lst = [0] * 65

103+

del lst[1:]

104+

self.assertEqual(len(lst), 1)

105+
106+

size = ((2 ** (tuple.__itemsize__ * 8) - 1) // 2)

107+

with self.assertRaises((MemoryError, OverflowError)):

108+

lst * size

109+

with self.assertRaises((MemoryError, OverflowError)):

110+

lst *= size

111+
99112

def test_repr_large(self):

100113

# Check the repr of large list objects

101114

def check(n):

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,3 @@

1+

Fix multiplying a list by an integer (``list *= int``): detect the integer

2+

overflow when the new allocated length is close to the maximum size. Issue

3+

reported by Jordan Limor. Patch by Victor Stinner.

Original file line numberDiff line numberDiff line change

@@ -76,8 +76,14 @@ list_resize(PyListObject *self, Py_ssize_t newsize)

7676
7777

if (newsize == 0)

7878

new_allocated = 0;

79-

num_allocated_bytes = new_allocated * sizeof(PyObject *);

80-

items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);

79+

if (new_allocated <= (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) {

80+

num_allocated_bytes = new_allocated * sizeof(PyObject *);

81+

items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);

82+

}

83+

else {

84+

// integer overflow

85+

items = NULL;

86+

}

8187

if (items == NULL) {

8288

PyErr_NoMemory();

8389

return -1;

Read the original on github.com ↗