Issue #22193: Fixed integer overflow error in sys.getsizeof().

Fixed an error in _PySys_GetSizeOf declaration.
This commit is contained in:
Serhiy Storchaka 2014-11-15 13:21:37 +02:00
parent ed73010319
commit 030e92d1a5
3 changed files with 42 additions and 6 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 *