[Python-checkins] cpython (merge 3.4 -> default): Issue #22193: Fixed integer overflow error in sys.getsizeof().
serhiy.storchaka
python-checkins at python.org
Sat Nov 15 13:05:31 CET 2014
https://hg.python.org/cpython/rev/b7651f9be4a1
changeset: 93495:b7651f9be4a1
parent: 93492:e79c6ea48b83
parent: 93494:df5c6b05238e
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sat Nov 15 13:22:27 2014 +0200
summary:
Issue #22193: Fixed integer overflow error in sys.getsizeof().
Fixed an error in _PySys_GetSizeOf declaration.
files:
Include/sysmodule.h | 2 +-
Lib/test/test_sys.py | 31 +++++++++++++++++++++++++++++++
Python/sysmodule.c | 15 ++++++++++-----
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/Include/sysmodule.h b/Include/sysmodule.h
--- a/Include/sysmodule.h
+++ b/Include/sysmodule.h
@@ -34,7 +34,7 @@
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
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -770,6 +770,37 @@
# 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)
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -868,7 +868,7 @@
{
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 @@
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 *
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list