[Python-checkins] cpython (3.3): use safe allocation and reallocation macros

benjamin.peterson python-checkins at python.org
Sat Jun 27 21:18:16 CEST 2015


https://hg.python.org/cpython/rev/acd5c9118931
changeset:   96684:acd5c9118931
branch:      3.3
parent:      96485:035aa81c2ba8
user:        Benjamin Peterson <benjamin at python.org>
date:        Sat Jun 27 13:41:33 2015 -0500
summary:
  use safe allocation and reallocation macros

files:
  Misc/NEWS         |   2 ++
  Modules/_pickle.c |  26 ++++++++++----------------
  2 files changed, 12 insertions(+), 16 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -22,6 +22,8 @@
 Library
 -------
 
+- Fix possible integer overflows in the pickle module.
+
 - Issue #22931: Allow '[' and ']' in cookie values.
 
 - Issue #24094: Fix possible crash in json.encode with poorly behaved dict
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -218,9 +218,7 @@
     if (new_allocated > PY_SSIZE_T_MAX - allocated)
         goto nomemory;
     new_allocated += allocated;
-    if (new_allocated > (PY_SSIZE_T_MAX / sizeof(PyObject *)))
-        goto nomemory;
-    data = PyMem_REALLOC(data, new_allocated * sizeof(PyObject *));
+    PyMem_RESIZE(data, PyObject *, new_allocated);
     if (data == NULL)
         goto nomemory;
 
@@ -433,7 +431,7 @@
     /* The table we get from _New() is probably smaller than we wanted.
        Free it and allocate one that's the right size. */
     PyMem_FREE(new->mt_table);
-    new->mt_table = PyMem_MALLOC(self->mt_allocated * sizeof(PyMemoEntry));
+    new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated);
     if (new->mt_table == NULL) {
         PyMem_FREE(new);
         return NULL;
@@ -527,7 +525,7 @@
 
     /* Allocate new table. */
     oldtable = self->mt_table;
-    self->mt_table = PyMem_MALLOC(new_size * sizeof(PyMemoEntry));
+    self->mt_table = PyMem_NEW(PyMemoEntry, new_size);
     if (self->mt_table == NULL) {
         PyMem_FREE(oldtable);
         PyErr_NoMemory();
@@ -1055,16 +1053,14 @@
 _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
 {
     Py_ssize_t i;
-    PyObject **memo;
 
     assert(new_size > self->memo_size);
 
-    memo = PyMem_REALLOC(self->memo, new_size * sizeof(PyObject *));
-    if (memo == NULL) {
+    PyMem_RESIZE(self->memo, PyObject *, new_size);
+    if (self->memo == NULL) {
         PyErr_NoMemory();
         return -1;
     }
-    self->memo = memo;
     for (i = self->memo_size; i < new_size; i++)
         self->memo[i] = NULL;
     self->memo_size = new_size;
@@ -1103,7 +1099,7 @@
 static PyObject **
 _Unpickler_NewMemo(Py_ssize_t new_size)
 {
-    PyObject **memo = PyMem_MALLOC(new_size * sizeof(PyObject *));
+    PyObject **memo = PyMem_NEW(PyObject *, new_size);
     if (memo == NULL)
         return NULL;
     memset(memo, 0, new_size * sizeof(PyObject *));
@@ -5270,7 +5266,6 @@
 
     if ((self->num_marks + 1) >= self->marks_size) {
         size_t alloc;
-        Py_ssize_t *marks;
 
         /* Use the size_t type to check for overflow. */
         alloc = ((size_t)self->num_marks << 1) + 20;
@@ -5281,15 +5276,14 @@
         }
 
         if (self->marks == NULL)
-            marks = (Py_ssize_t *) PyMem_Malloc(alloc * sizeof(Py_ssize_t));
+            self->marks = PyMem_NEW(Py_ssize_t, alloc);
         else
-            marks = (Py_ssize_t *) PyMem_Realloc(self->marks,
-                                                 alloc * sizeof(Py_ssize_t));
-        if (marks == NULL) {
+            PyMem_RESIZE(self->marks, Py_ssize_t, alloc);
+        if (self->marks == NULL) {
+            self->marks_size = 0;
             PyErr_NoMemory();
             return -1;
         }
-        self->marks = marks;
         self->marks_size = (Py_ssize_t)alloc;
     }
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list