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);
|
PyAPI_FUNC(PyObject *) PySys_GetXOptions(void);
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_DATA(size_t) _PySys_GetSizeOf(PyObject *);
|
PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -723,6 +723,37 @@ class SizeofTest(unittest.TestCase):
|
||||||
# but lists are
|
# but lists are
|
||||||
self.assertEqual(sys.getsizeof([]), vsize('Pn') + gc_header_size)
|
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):
|
def test_default(self):
|
||||||
size = test.support.calcvobjsize
|
size = test.support.calcvobjsize
|
||||||
self.assertEqual(sys.getsizeof(True), size('') + self.longdigit)
|
self.assertEqual(sys.getsizeof(True), size('') + self.longdigit)
|
||||||
|
|
|
@ -868,7 +868,7 @@ _PySys_GetSizeOf(PyObject *o)
|
||||||
{
|
{
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
PyObject *method;
|
PyObject *method;
|
||||||
size_t size;
|
Py_ssize_t size;
|
||||||
|
|
||||||
/* Make sure the type is initialized. float gets initialized late */
|
/* Make sure the type is initialized. float gets initialized late */
|
||||||
if (PyType_Ready(Py_TYPE(o)) < 0)
|
if (PyType_Ready(Py_TYPE(o)) < 0)
|
||||||
|
@ -889,15 +889,20 @@ _PySys_GetSizeOf(PyObject *o)
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
return (size_t)-1;
|
return (size_t)-1;
|
||||||
|
|
||||||
size = PyLong_AsSize_t(res);
|
size = PyLong_AsSsize_t(res);
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
if (size == (size_t)-1 && PyErr_Occurred())
|
if (size == -1 && PyErr_Occurred())
|
||||||
return (size_t)-1;
|
return (size_t)-1;
|
||||||
|
|
||||||
|
if (size < 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0");
|
||||||
|
return (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
/* add gc_head size */
|
/* add gc_head size */
|
||||||
if (PyObject_IS_GC(o))
|
if (PyObject_IS_GC(o))
|
||||||
size += sizeof(PyGC_Head);
|
return ((size_t)size) + sizeof(PyGC_Head);
|
||||||
return size;
|
return (size_t)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Reference in New Issue