mirror of https://github.com/python/cpython
Issue #22193: Fixed integer overflow error in sys.getsizeof().
Fixed an error in _PySys_GetSizeOf declaration.
This commit is contained in:
parent
ed73010319
commit
030e92d1a5
|
@ -34,7 +34,7 @@ PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *);
|
|||
PyAPI_FUNC(PyObject *) PySys_GetXOptions(void);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_DATA(size_t) _PySys_GetSizeOf(PyObject *);
|
||||
PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -723,6 +723,37 @@ class SizeofTest(unittest.TestCase):
|
|||
# but lists are
|
||||
self.assertEqual(sys.getsizeof([]), vsize('Pn') + gc_header_size)
|
||||
|
||||
def test_errors(self):
|
||||
class BadSizeof:
|
||||
def __sizeof__(self):
|
||||
raise ValueError
|
||||
self.assertRaises(ValueError, sys.getsizeof, BadSizeof())
|
||||
|
||||
class InvalidSizeof:
|
||||
def __sizeof__(self):
|
||||
return None
|
||||
self.assertRaises(TypeError, sys.getsizeof, InvalidSizeof())
|
||||
sentinel = ["sentinel"]
|
||||
self.assertIs(sys.getsizeof(InvalidSizeof(), sentinel), sentinel)
|
||||
|
||||
class FloatSizeof:
|
||||
def __sizeof__(self):
|
||||
return 4.5
|
||||
self.assertRaises(TypeError, sys.getsizeof, FloatSizeof())
|
||||
self.assertIs(sys.getsizeof(FloatSizeof(), sentinel), sentinel)
|
||||
|
||||
class OverflowSizeof(int):
|
||||
def __sizeof__(self):
|
||||
return int(self)
|
||||
self.assertEqual(sys.getsizeof(OverflowSizeof(sys.maxsize)),
|
||||
sys.maxsize + self.gc_headsize)
|
||||
with self.assertRaises(OverflowError):
|
||||
sys.getsizeof(OverflowSizeof(sys.maxsize + 1))
|
||||
with self.assertRaises(ValueError):
|
||||
sys.getsizeof(OverflowSizeof(-1))
|
||||
with self.assertRaises((ValueError, OverflowError)):
|
||||
sys.getsizeof(OverflowSizeof(-sys.maxsize - 1))
|
||||
|
||||
def test_default(self):
|
||||
size = test.support.calcvobjsize
|
||||
self.assertEqual(sys.getsizeof(True), size('') + self.longdigit)
|
||||
|
|
|
@ -868,7 +868,7 @@ _PySys_GetSizeOf(PyObject *o)
|
|||
{
|
||||
PyObject *res = NULL;
|
||||
PyObject *method;
|
||||
size_t size;
|
||||
Py_ssize_t size;
|
||||
|
||||
/* Make sure the type is initialized. float gets initialized late */
|
||||
if (PyType_Ready(Py_TYPE(o)) < 0)
|
||||
|
@ -889,15 +889,20 @@ _PySys_GetSizeOf(PyObject *o)
|
|||
if (res == NULL)
|
||||
return (size_t)-1;
|
||||
|
||||
size = PyLong_AsSize_t(res);
|
||||
size = PyLong_AsSsize_t(res);
|
||||
Py_DECREF(res);
|
||||
if (size == (size_t)-1 && PyErr_Occurred())
|
||||
if (size == -1 && PyErr_Occurred())
|
||||
return (size_t)-1;
|
||||
|
||||
if (size < 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0");
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
/* add gc_head size */
|
||||
if (PyObject_IS_GC(o))
|
||||
size += sizeof(PyGC_Head);
|
||||
return size;
|
||||
return ((size_t)size) + sizeof(PyGC_Head);
|
||||
return (size_t)size;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
Loading…
Reference in New Issue