@@ -114,7 +114,7 @@ PyCode_New(int argcount, int kwonlyargcount,
114114{
115115 PyCodeObject * co ;
116116 unsigned char * cell2arg = NULL ;
117- Py_ssize_t i , n_cellvars ;
117+ Py_ssize_t i , n_cellvars , n_varnames , total_args ;
118118
119119 /* Check argument types */
120120 if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
@@ -150,23 +150,42 @@ PyCode_New(int argcount, int kwonlyargcount,
150150 flags &= ~CO_NOFREE ;
151151 }
152152
153+ n_varnames = PyTuple_GET_SIZE (varnames );
154+ if (argcount <= n_varnames && kwonlyargcount <= n_varnames ) {
155+ /* Never overflows. */
156+ total_args = (Py_ssize_t )argcount + (Py_ssize_t )kwonlyargcount +
157+ ((flags & CO_VARARGS ) != 0 ) + ((flags & CO_VARKEYWORDS ) != 0 );
158+ }
159+ else {
160+ total_args = n_varnames + 1 ;
161+ }
162+ if (total_args > n_varnames ) {
163+ PyErr_SetString (PyExc_ValueError , "code: varnames is too small" );
164+ return NULL ;
165+ }
166+
153167 /* Create mapping between cells and arguments if needed. */
154168 if (n_cellvars ) {
155- Py_ssize_t total_args = argcount + kwonlyargcount +
156- ((flags & CO_VARARGS ) != 0 ) + ((flags & CO_VARKEYWORDS ) != 0 );
157169 Py_ssize_t alloc_size = sizeof (unsigned char ) * n_cellvars ;
158170 bool used_cell2arg = false;
159171 cell2arg = PyMem_MALLOC (alloc_size );
160- if (cell2arg == NULL )
172+ if (cell2arg == NULL ) {
173+ PyErr_NoMemory ();
161174 return NULL ;
175+ }
162176 memset (cell2arg , CO_CELL_NOT_AN_ARG , alloc_size );
163177 /* Find cells which are also arguments. */
164178 for (i = 0 ; i < n_cellvars ; i ++ ) {
165179 Py_ssize_t j ;
166180 PyObject * cell = PyTuple_GET_ITEM (cellvars , i );
167181 for (j = 0 ; j < total_args ; j ++ ) {
168182 PyObject * arg = PyTuple_GET_ITEM (varnames , j );
169- if (!PyUnicode_Compare (cell , arg )) {
183+ int cmp = PyUnicode_Compare (cell , arg );
184+ if (cmp == -1 && PyErr_Occurred ()) {
185+ PyMem_FREE (cell2arg );
186+ return NULL ;
187+ }
188+ if (cmp == 0 ) {
170189 cell2arg [i ] = j ;
171190 used_cell2arg = true;
172191 break ;
0 commit comments