1818#define ERROR -1
1919
2020#define RETURN_IF_ERROR (X ) \
21- if ((X) == -1 ) { \
21+ if ((X) < 0 ) { \
2222 return ERROR; \
2323 }
2424
@@ -448,13 +448,17 @@ static PyObject *
448448dict_keys_inorder (PyObject * dict , Py_ssize_t offset )
449449{
450450 PyObject * tuple , * k , * v ;
451- Py_ssize_t i , pos = 0 , size = PyDict_GET_SIZE (dict );
451+ Py_ssize_t pos = 0 , size = PyDict_GET_SIZE (dict );
452452
453453 tuple = PyTuple_New (size );
454454 if (tuple == NULL )
455455 return NULL ;
456456 while (PyDict_Next (dict , & pos , & k , & v )) {
457- i = PyLong_AS_LONG (v );
457+ Py_ssize_t i = PyLong_AsSsize_t (v );
458+ if (i == -1 && PyErr_Occurred ()) {
459+ Py_DECREF (tuple );
460+ return NULL ;
461+ }
458462 assert ((i - offset ) < size );
459463 assert ((i - offset ) >= 0 );
460464 PyTuple_SET_ITEM (tuple , i - offset , Py_NewRef (k ));
@@ -466,24 +470,34 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
466470extern void _Py_set_localsplus_info (int , PyObject * , unsigned char ,
467471 PyObject * , PyObject * );
468472
469- static void
473+ static int
470474compute_localsplus_info (_PyCompile_CodeUnitMetadata * umd , int nlocalsplus ,
471475 PyObject * names , PyObject * kinds )
472476{
473477 PyObject * k , * v ;
474478 Py_ssize_t pos = 0 ;
475479 while (PyDict_Next (umd -> u_varnames , & pos , & k , & v )) {
476- int offset = (int )PyLong_AS_LONG (v );
480+ int offset = _PyLong_AsInt (v );
481+ if (offset == -1 && PyErr_Occurred ()) {
482+ return ERROR ;
483+ }
477484 assert (offset >= 0 );
478485 assert (offset < nlocalsplus );
486+
479487 // For now we do not distinguish arg kinds.
480488 _PyLocals_Kind kind = CO_FAST_LOCAL ;
481- if (PyDict_Contains (umd -> u_fasthidden , k )) {
489+ int has_key = PyDict_Contains (umd -> u_fasthidden , k );
490+ RETURN_IF_ERROR (has_key );
491+ if (has_key ) {
482492 kind |= CO_FAST_HIDDEN ;
483493 }
484- if (PyDict_GetItem (umd -> u_cellvars , k ) != NULL ) {
494+
495+ has_key = PyDict_Contains (umd -> u_cellvars , k );
496+ RETURN_IF_ERROR (has_key );
497+ if (has_key ) {
485498 kind |= CO_FAST_CELL ;
486499 }
500+
487501 _Py_set_localsplus_info (offset , k , kind , names , kinds );
488502 }
489503 int nlocals = (int )PyDict_GET_SIZE (umd -> u_varnames );
@@ -492,12 +506,18 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
492506 int numdropped = 0 ;
493507 pos = 0 ;
494508 while (PyDict_Next (umd -> u_cellvars , & pos , & k , & v )) {
495- if (PyDict_GetItem (umd -> u_varnames , k ) != NULL ) {
509+ int has_name = PyDict_Contains (umd -> u_varnames , k );
510+ RETURN_IF_ERROR (has_name );
511+ if (has_name ) {
496512 // Skip cells that are already covered by locals.
497513 numdropped += 1 ;
498514 continue ;
499515 }
500- int offset = (int )PyLong_AS_LONG (v );
516+
517+ int offset = _PyLong_AsInt (v );
518+ if (offset == -1 && PyErr_Occurred ()) {
519+ return ERROR ;
520+ }
501521 assert (offset >= 0 );
502522 offset += nlocals - numdropped ;
503523 assert (offset < nlocalsplus );
@@ -506,12 +526,16 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
506526
507527 pos = 0 ;
508528 while (PyDict_Next (umd -> u_freevars , & pos , & k , & v )) {
509- int offset = (int )PyLong_AS_LONG (v );
529+ int offset = _PyLong_AsInt (v );
530+ if (offset == -1 && PyErr_Occurred ()) {
531+ return ERROR ;
532+ }
510533 assert (offset >= 0 );
511534 offset += nlocals - numdropped ;
512535 assert (offset < nlocalsplus );
513536 _Py_set_localsplus_info (offset , k , CO_FAST_FREE , names , kinds );
514537 }
538+ return SUCCESS ;
515539}
516540
517541static PyCodeObject *
@@ -556,7 +580,10 @@ makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_
556580 if (localspluskinds == NULL ) {
557581 goto error ;
558582 }
559- compute_localsplus_info (umd , nlocalsplus , localsplusnames , localspluskinds );
583+ if (compute_localsplus_info (umd , nlocalsplus ,
584+ localsplusnames , localspluskinds ) == ERROR ) {
585+ goto error ;
586+ }
560587
561588 struct _PyCodeConstructor con = {
562589 .filename = filename ,
0 commit comments