@@ -602,9 +602,9 @@ typedef struct {
602602} PyMemoEntry ;
603603
604604typedef struct {
605- Py_ssize_t mt_mask ;
606- Py_ssize_t mt_used ;
607- Py_ssize_t mt_allocated ;
605+ size_t mt_mask ;
606+ size_t mt_used ;
607+ size_t mt_allocated ;
608608 PyMemoEntry * mt_table ;
609609} PyMemoTable ;
610610
@@ -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
@@ -737,7 +737,6 @@ PyMemoTable_New(void)
737737static PyMemoTable *
738738PyMemoTable_Copy (PyMemoTable * self )
739739{
740- Py_ssize_t i ;
741740 PyMemoTable * new = PyMemoTable_New ();
742741 if (new == NULL )
743742 return NULL ;
@@ -754,7 +753,7 @@ PyMemoTable_Copy(PyMemoTable *self)
754753 PyErr_NoMemory ();
755754 return NULL ;
756755 }
757- for (i = 0 ; i < self -> mt_allocated ; i ++ ) {
756+ for (size_t i = 0 ; i < self -> mt_allocated ; i ++ ) {
758757 Py_XINCREF (self -> mt_table [i ].me_key );
759758 }
760759 memcpy (new -> mt_table , self -> mt_table ,
@@ -800,7 +799,7 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
800799{
801800 size_t i ;
802801 size_t perturb ;
803- size_t mask = ( size_t ) self -> mt_mask ;
802+ size_t mask = self -> mt_mask ;
804803 PyMemoEntry * table = self -> mt_table ;
805804 PyMemoEntry * entry ;
806805 Py_hash_t hash = (Py_hash_t )key >> 3 ;
@@ -821,22 +820,24 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
821820
822821/* Returns -1 on failure, 0 on success. */
823822static int
824- _PyMemoTable_ResizeTable (PyMemoTable * self , Py_ssize_t min_size )
823+ _PyMemoTable_ResizeTable (PyMemoTable * self , size_t min_size )
825824{
826825 PyMemoEntry * oldtable = NULL ;
827826 PyMemoEntry * oldentry , * newentry ;
828- Py_ssize_t new_size = MT_MINSIZE ;
829- Py_ssize_t to_process ;
827+ size_t new_size = MT_MINSIZE ;
828+ size_t to_process ;
830829
831830 assert (min_size > 0 );
832831
833- /* Find the smallest valid table size >= min_size. */
834- while (new_size < min_size && new_size > 0 )
835- new_size <<= 1 ;
836- if (new_size <= 0 ) {
832+ if (min_size > PY_SSIZE_T_MAX ) {
837833 PyErr_NoMemory ();
838834 return -1 ;
839835 }
836+
837+ /* Find the smallest valid table size >= min_size. */
838+ while (new_size < min_size ) {
839+ new_size <<= 1 ;
840+ }
840841 /* new_size needs to be a power of two. */
841842 assert ((new_size & (new_size - 1 )) == 0 );
842843
@@ -909,10 +910,12 @@ PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value)
909910 * Very large memo tables (over 50K items) use doubling instead.
910911 * This may help applications with severe memory constraints.
911912 */
912- if (!( self -> mt_used * 3 >= ( self -> mt_mask + 1 ) * 2 ))
913+ if (SIZE_MAX / 3 >= self -> mt_used && self -> mt_used * 3 < self -> mt_allocated * 2 ) {
913914 return 0 ;
914- return _PyMemoTable_ResizeTable (self ,
915- (self -> mt_used > 50000 ? 2 : 4 ) * self -> mt_used );
915+ }
916+ // self->mt_used is always < PY_SSIZE_T_MAX, so this can't overflow.
917+ size_t desired_size = (self -> mt_used > 50000 ? 2 : 4 ) * self -> mt_used ;
918+ return _PyMemoTable_ResizeTable (self , desired_size );
916919}
917920
918921#undef MT_MINSIZE
@@ -1376,9 +1379,9 @@ _Unpickler_Readline(UnpicklerObject *self, char **result)
13761379/* Returns -1 (with an exception set) on failure, 0 on success. The memo array
13771380 will be modified in place. */
13781381static int
1379- _Unpickler_ResizeMemoList (UnpicklerObject * self , Py_ssize_t new_size )
1382+ _Unpickler_ResizeMemoList (UnpicklerObject * self , size_t new_size )
13801383{
1381- Py_ssize_t i ;
1384+ size_t i ;
13821385
13831386 assert (new_size > self -> memo_size );
13841387
@@ -1397,9 +1400,9 @@ _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
13971400
13981401/* Returns NULL if idx is out of bounds. */
13991402static PyObject *
1400- _Unpickler_MemoGet (UnpicklerObject * self , Py_ssize_t idx )
1403+ _Unpickler_MemoGet (UnpicklerObject * self , size_t idx )
14011404{
1402- if (idx < 0 || idx >= self -> memo_size )
1405+ if (idx >= self -> memo_size )
14031406 return NULL ;
14041407
14051408 return self -> memo [idx ];
@@ -1408,7 +1411,7 @@ _Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx)
14081411/* Returns -1 (with an exception set) on failure, 0 on success.
14091412 This takes its own reference to `value`. */
14101413static int
1411- _Unpickler_MemoPut (UnpicklerObject * self , Py_ssize_t idx , PyObject * value )
1414+ _Unpickler_MemoPut (UnpicklerObject * self , size_t idx , PyObject * value )
14121415{
14131416 PyObject * old_item ;
14141417
@@ -4413,14 +4416,13 @@ static PyObject *
44134416_pickle_PicklerMemoProxy_copy_impl (PicklerMemoProxyObject * self )
44144417/*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/
44154418{
4416- Py_ssize_t i ;
44174419 PyMemoTable * memo ;
44184420 PyObject * new_memo = PyDict_New ();
44194421 if (new_memo == NULL )
44204422 return NULL ;
44214423
44224424 memo = self -> pickler -> memo ;
4423- for (i = 0 ; i < memo -> mt_allocated ; ++ i ) {
4425+ for (size_t i = 0 ; i < memo -> mt_allocated ; ++ i ) {
44244426 PyMemoEntry entry = memo -> mt_table [i ];
44254427 if (entry .me_key != NULL ) {
44264428 int status ;
@@ -6843,7 +6845,7 @@ static PyObject *
68436845_pickle_UnpicklerMemoProxy_copy_impl (UnpicklerMemoProxyObject * self )
68446846/*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/
68456847{
6846- Py_ssize_t i ;
6848+ size_t i ;
68476849 PyObject * new_memo = PyDict_New ();
68486850 if (new_memo == NULL )
68496851 return NULL ;
@@ -6994,8 +6996,7 @@ static int
69946996Unpickler_set_memo (UnpicklerObject * self , PyObject * obj )
69956997{
69966998 PyObject * * new_memo ;
6997- Py_ssize_t new_memo_size = 0 ;
6998- Py_ssize_t i ;
6999+ size_t new_memo_size = 0 ;
69997000
70007001 if (obj == NULL ) {
70017002 PyErr_SetString (PyExc_TypeError ,
@@ -7012,7 +7013,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
70127013 if (new_memo == NULL )
70137014 return -1 ;
70147015
7015- for (i = 0 ; i < new_memo_size ; i ++ ) {
7016+ for (size_t i = 0 ; i < new_memo_size ; i ++ ) {
70167017 Py_XINCREF (unpickler -> memo [i ]);
70177018 new_memo [i ] = unpickler -> memo [i ];
70187019 }
@@ -7060,8 +7061,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
70607061
70617062 error :
70627063 if (new_memo_size ) {
7063- i = new_memo_size ;
7064- while (-- i >= 0 ) {
7064+ for (size_t i = new_memo_size - 1 ; i != SIZE_MAX ; i -- ) {
70657065 Py_XDECREF (new_memo [i ]);
70667066 }
70677067 PyMem_FREE (new_memo );
0 commit comments