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

Skip to content

Commit d4e5be5

Browse files
committed
Closes: #556025 seg fault when doing list(xrange(1e9))
A MemoryError is now raised when the list cannot be created. There is a test, but as the comment says, it really only works for 32 bit systems. I don't know how to improve the test for other systems (ie, 64 bit or systems where the data size != addressable size, e.g. 64 bit data, but 48 bit addressable memory)
1 parent 7779b20 commit d4e5be5

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

Lib/test/test_b1.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,17 @@ class E:
514514
if list('') != []: raise TestFailed, 'list('')'
515515
if list('spam') != ['s', 'p', 'a', 'm']: raise TestFailed, "list('spam')"
516516

517+
try:
518+
# Verify clearing of bug #556025
519+
# this assumes that the max data size (sys.maxint) == max address size
520+
# this also assumes that the address size is at least 4 bytes
521+
# with 8 byte addresses, the bug is not well tested
522+
list(xrange(sys.maxint / 4))
523+
except MemoryError:
524+
pass
525+
else:
526+
raise TestFailed, 'list(xrange(sys.maxint / 4))'
527+
517528
print 'long'
518529
if long(314) != 314L: raise TestFailed, 'long(314)'
519530
if long(3.14) != 3L: raise TestFailed, 'long(3.14)'

Objects/listobject.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ roundupsize(int n)
4444
return ((n >> nbits) + 1) << nbits;
4545
}
4646

47-
#define NRESIZE(var, type, nitems) PyMem_RESIZE(var, type, roundupsize(nitems))
47+
#define NRESIZE(var, type, nitems) \
48+
do { \
49+
size_t _new_size = roundupsize(nitems); \
50+
if (_new_size <= ((~(size_t)0) / sizeof(type))) \
51+
PyMem_RESIZE(var, type, _new_size); \
52+
else \
53+
var = NULL; \
54+
} while (0)
4855

4956
PyObject *
5057
PyList_New(int size)
@@ -1565,8 +1572,10 @@ list_fill(PyListObject *result, PyObject *v)
15651572
if (n < 0)
15661573
n = 8; /* arbitrary */
15671574
NRESIZE(result->ob_item, PyObject*, n);
1568-
if (result->ob_item == NULL)
1575+
if (result->ob_item == NULL) {
1576+
PyErr_NoMemory();
15691577
goto error;
1578+
}
15701579
for (i = 0; i < n; i++)
15711580
result->ob_item[i] = NULL;
15721581
result->ob_size = n;

0 commit comments

Comments
 (0)