diff options
author | Benjamin Peterson <benjamin@python.org> | 2018-09-13 09:47:22 -0700 |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2018-09-19 22:09:14 -0700 |
commit | abc4e5da646cbf502012d24da7f9264085296efc (patch) | |
tree | 64dfa97b708cb4e4090f478f5c9ee01be8c62c9a | |
parent | fd54a45f7987d5b3343c74cb49a12bd39bdad5bc (diff) | |
download | cpython-git-abc4e5da646cbf502012d24da7f9264085296efc.tar.gz |
bpo-34656: Avoid relying on signed overflow in _pickle memos.
-rw-r--r-- | Modules/_pickle.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 2de70f5d94..d731b22e4c 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -650,8 +650,8 @@ typedef struct UnpicklerObject { /* The unpickler memo is just an array of PyObject *s. Using a dict is unnecessary, since the keys are contiguous ints. */ PyObject **memo; - Py_ssize_t memo_size; /* Capacity of the memo array */ - Py_ssize_t memo_len; /* Number of objects in the memo */ + size_t memo_size; /* Capacity of the memo array */ + size_t memo_len; /* Number of objects in the memo */ PyObject *pers_func; /* persistent_load() method, can be NULL. */ PyObject *pers_func_self; /* borrowed reference to self if pers_func @@ -821,22 +821,18 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key) /* Returns -1 on failure, 0 on success. */ static int -_PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size) +_PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size) { PyMemoEntry *oldtable = NULL; PyMemoEntry *oldentry, *newentry; - Py_ssize_t new_size = MT_MINSIZE; + size_t new_size = MT_MINSIZE; Py_ssize_t to_process; assert(min_size > 0); /* Find the smallest valid table size >= min_size. */ - while (new_size < min_size && new_size > 0) + while (new_size < min_size) new_size <<= 1; - if (new_size <= 0) { - PyErr_NoMemory(); - return -1; - } /* new_size needs to be a power of two. */ assert((new_size & (new_size - 1)) == 0); @@ -1376,9 +1372,9 @@ _Unpickler_Readline(UnpicklerObject *self, char **result) /* Returns -1 (with an exception set) on failure, 0 on success. The memo array will be modified in place. */ static int -_Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size) +_Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size) { - Py_ssize_t i; + size_t i; assert(new_size > self->memo_size); @@ -1397,9 +1393,9 @@ _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size) /* Returns NULL if idx is out of bounds. */ static PyObject * -_Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx) +_Unpickler_MemoGet(UnpicklerObject *self, size_t idx) { - if (idx < 0 || idx >= self->memo_size) + if (idx >= self->memo_size) return NULL; return self->memo[idx]; @@ -1408,7 +1404,7 @@ _Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx) /* Returns -1 (with an exception set) on failure, 0 on success. This takes its own reference to `value`. */ static int -_Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value) +_Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value) { PyObject *old_item; @@ -6843,7 +6839,7 @@ static PyObject * _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) /*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/ { - Py_ssize_t i; + size_t i; PyObject *new_memo = PyDict_New(); if (new_memo == NULL) return NULL; @@ -6994,8 +6990,8 @@ static int Unpickler_set_memo(UnpicklerObject *self, PyObject *obj) { PyObject **new_memo; - Py_ssize_t new_memo_size = 0; - Py_ssize_t i; + size_t new_memo_size = 0; + size_t i; if (obj == NULL) { PyErr_SetString(PyExc_TypeError, @@ -7061,7 +7057,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj) error: if (new_memo_size) { i = new_memo_size; - while (--i >= 0) { + for (i = new_memo_size - 1; i != SIZE_MAX; i--) { Py_XDECREF(new_memo[i]); } PyMem_FREE(new_memo); |