[Python-checkins] cpython (2.7): 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/3537994fa43b
changeset:   93493:3537994fa43b
branch:      2.7
parent:      93491:33d68c79d601
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat Nov 15 13:21:01 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 |  25 +++++++++++++++++++++++++
  Python/sysmodule.c   |  13 +++++++++----
  3 files changed, 35 insertions(+), 5 deletions(-)


diff --git a/Include/sysmodule.h b/Include/sysmodule.h
--- a/Include/sysmodule.h
+++ b/Include/sysmodule.h
@@ -23,7 +23,7 @@
 PyAPI_FUNC(void) PySys_AddWarnOption(char *);
 PyAPI_FUNC(int) PySys_HasWarnOptions(void);
 
-PyAPI_DATA(size_t) _PySys_GetSizeOf(PyObject *);
+PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
 
 #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
@@ -494,6 +494,31 @@
         # but lists are
         self.assertEqual(sys.getsizeof([]), size('P PP') + gc_header_size)
 
+    def test_errors(self):
+        class BadSizeof(object):
+            def __sizeof__(self):
+                raise ValueError
+        self.assertRaises(ValueError, sys.getsizeof, BadSizeof())
+
+        class InvalidSizeof(object):
+            def __sizeof__(self):
+                return None
+        self.assertRaises(TypeError, sys.getsizeof, InvalidSizeof())
+        sentinel = ["sentinel"]
+        self.assertIs(sys.getsizeof(InvalidSizeof(), 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.test_support.calcobjsize
         self.assertEqual(sys.getsizeof(True, -1), size('l'))
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -689,7 +689,7 @@
 {
     static PyObject *str__sizeof__ = NULL;
     PyObject *res = NULL;
-    size_t size;
+    Py_ssize_t size;
 
     /* Make sure the type is initialized. float gets initialized late */
     if (PyType_Ready(Py_TYPE(o)) < 0)
@@ -718,14 +718,19 @@
 
         size = (size_t)PyInt_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