10000 bpo-34656: Avoid relying on signed overflow in _pickle memos. · python/cpython@59c974e · GitHub
[go: up one dir, main page]

Skip to content

Commit 59c974e

Browse files
committed
bpo-34656: Avoid relying on signed overflow in _pickle memos.
1 parent ed709d5 commit 59c974e

File tree

1 file changed

+14
-18
lines changed

1 file changed

+14
-18
lines changed

Modules/_pickle.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,8 @@ typedef struct UnpicklerObject {
650650
/* The unpickler memo is just an array of PyObject *s. Using a dict
651651
is unnecessary, since the keys are contiguous ints. */
652652
PyObject **memo;
653-
Py_ssize_t memo_size; /* Capacity of the memo array */
654-
Py_ssize_t memo_len; /* Number of objects in the memo */
653+
size_t memo_size; /* Capacity of the memo array */
654+
size_t memo_len; /* Number of objects in the memo */
655655

656656
PyObject *pers_func; /* persistent_load() method, can be NULL. */
657657
PyObject *pers_func_self; /* borrowed reference to self if pers_func
@@ -821,22 +821,18 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
821821

822822
/* Returns -1 on failure, 0 on success. */
823823
static int
824-
_PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size)
824+
_PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size)
825825
{
826826
PyMemoEntry *oldtable = NULL;
827827
PyMemoEntry *oldentry, *newentry;
828-
Py_ssize_t new_size = MT_MINSIZE;
828+
size_t new_size = MT_MINSIZE;
829829
Py_ssize_t to_process;
830830

831831
assert(min_size > 0);
832832

833833
/* Find the smallest valid table size >= min_size. */
834-
while (new_size < min_size && new_size > 0)
834+
while (new_size < min_size)
835835
new_size <<= 1;
836-
if (new_size <= 0) {
837-
PyErr_NoMemory();
838-
return -1;
839-
}
840836
/* new_size needs to be a power of two. */
841837
assert((new_size & (new_size - 1)) == 0);
842838

@@ -1376,9 +1372,9 @@ _Unpickler_Readline(UnpicklerObject *self, char **result)
13761372
/* Returns -1 (with an exception set) on failure, 0 on success. The memo array
13771373
will be modified in place. */
13781374
static int
1379-
_Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
1375+
_Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size)
13801376
{
1381-
Py_ssize_t i;
1377+
size_t i;
13821378

13831379
assert(new_size > self->memo_size);
13841380

@@ -1397,9 +1393,9 @@ _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
13971393

13981394
/* Returns NULL if idx is out of bounds. */
13991395
static PyObject *
1400-
_Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx)
1396+
_Unpickler_MemoGet(UnpicklerObject *self, size_t idx)
14011397
{
1402-
if (idx < 0 || idx >= self->memo_size)
1398+
if (idx >= self->memo_size)
14031399
return NULL;
14041400

14051401
return self->memo[idx];
@@ -1408,7 +1404,7 @@ _Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx)
14081404
/* Returns -1 (with an exception set) on failure, 0 on success.
14091405
This takes its own reference to `value`. */
14101406
static int
1411-
_Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value)
1407+
_Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value)
14121408
{
14131409
PyObject *old_item;
14141410

@@ -6843,7 +6839,7 @@ static PyObject *
68436839
_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
68446840
/*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/
68456841
{
6846-
Py_ssize_t i;
6842+
size_t i;
68476843
PyObject *new_memo = PyDict_New();
68486844
if (new_memo == NULL)
68496845
return NULL;
@@ -6994,8 +6990,8 @@ static int
69946990
Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
69956991
{
69966992
PyObject **new_memo;
6997-
Py_ssize_t new_memo_size = 0;
6998-
Py_ssize_t i;
6993+
size_t new_memo_size = 0;
6994+
size_t i;
69996995

70006996
if (obj == NULL) {
70016997
PyErr_SetString(PyExc_TypeError,
@@ -7061,7 +7057,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
70617057
error:
70627058
if (new_memo_size) {
70637059
i = new_memo_size;
7064-
while (--i >= 0) {
7060+
for (i = new_memo_size - 1; i != SIZE_MAX; i--) {
70657061
Py_XDECREF(new_memo[i]);
70667062
}
70677063
PyMem_FREE(new_memo);

0 commit comments

Comments
 (0)
0