mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	bpo-44856: Possible reference leak in error paths of update_bases() and __build_class__ (GH-27647) (GH-27651)
(cherry picked from commit a40675c659)
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									c352412123
								
							
						
					
					
						commit
						ed718e9b07
					
				
					 2 changed files with 14 additions and 22 deletions
				
			
		|  | @ -0,0 +1 @@ | ||||||
|  | Fix reference leaks in the error paths of ``update_bases()`` and ``__build_class__``. Patch by Pablo Galindo. | ||||||
|  | @ -71,6 +71,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) | ||||||
|             /* If this is a first successful replacement, create new_bases list and
 |             /* If this is a first successful replacement, create new_bases list and
 | ||||||
|                copy previously encountered bases. */ |                copy previously encountered bases. */ | ||||||
|             if (!(new_bases = PyList_New(i))) { |             if (!(new_bases = PyList_New(i))) { | ||||||
|  |                 Py_DECREF(new_base); | ||||||
|                 goto error; |                 goto error; | ||||||
|             } |             } | ||||||
|             for (j = 0; j < i; j++) { |             for (j = 0; j < i; j++) { | ||||||
|  | @ -81,6 +82,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) | ||||||
|         } |         } | ||||||
|         j = PyList_GET_SIZE(new_bases); |         j = PyList_GET_SIZE(new_bases); | ||||||
|         if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { |         if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { | ||||||
|  |             Py_DECREF(new_base); | ||||||
|             goto error; |             goto error; | ||||||
|         } |         } | ||||||
|         Py_DECREF(new_base); |         Py_DECREF(new_base); | ||||||
|  | @ -102,8 +104,9 @@ static PyObject * | ||||||
| builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | ||||||
|                         PyObject *kwnames) |                         PyObject *kwnames) | ||||||
| { | { | ||||||
|     PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *orig_bases; |     PyObject *func, *name, *winner, *prep; | ||||||
|     PyObject *cls = NULL, *cell = NULL; |     PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL; | ||||||
|  |     PyObject *mkw = NULL, *bases = NULL; | ||||||
|     int isclass = 0;   /* initialize to prevent gcc warning */ |     int isclass = 0;   /* initialize to prevent gcc warning */ | ||||||
| 
 | 
 | ||||||
|     if (nargs < 2) { |     if (nargs < 2) { | ||||||
|  | @ -140,26 +143,20 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | ||||||
|     else { |     else { | ||||||
|         mkw = _PyStack_AsDict(args + nargs, kwnames); |         mkw = _PyStack_AsDict(args + nargs, kwnames); | ||||||
|         if (mkw == NULL) { |         if (mkw == NULL) { | ||||||
|             Py_DECREF(bases); |             goto error; | ||||||
|             return NULL; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass); |         meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass); | ||||||
|         if (meta != NULL) { |         if (meta != NULL) { | ||||||
|             Py_INCREF(meta); |             Py_INCREF(meta); | ||||||
|             if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) { |             if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) { | ||||||
|                 Py_DECREF(meta); |                 goto error; | ||||||
|                 Py_DECREF(mkw); |  | ||||||
|                 Py_DECREF(bases); |  | ||||||
|                 return NULL; |  | ||||||
|             } |             } | ||||||
|             /* metaclass is explicitly given, check if it's indeed a class */ |             /* metaclass is explicitly given, check if it's indeed a class */ | ||||||
|             isclass = PyType_Check(meta); |             isclass = PyType_Check(meta); | ||||||
|         } |         } | ||||||
|         else if (PyErr_Occurred()) { |         else if (PyErr_Occurred()) { | ||||||
|             Py_DECREF(mkw); |             goto error; | ||||||
|             Py_DECREF(bases); |  | ||||||
|             return NULL; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (meta == NULL) { |     if (meta == NULL) { | ||||||
|  | @ -182,10 +179,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | ||||||
|         winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta, |         winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta, | ||||||
|                                                         bases); |                                                         bases); | ||||||
|         if (winner == NULL) { |         if (winner == NULL) { | ||||||
|             Py_DECREF(meta); |             goto error; | ||||||
|             Py_XDECREF(mkw); |  | ||||||
|             Py_DECREF(bases); |  | ||||||
|             return NULL; |  | ||||||
|         } |         } | ||||||
|         if (winner != meta) { |         if (winner != meta) { | ||||||
|             Py_DECREF(meta); |             Py_DECREF(meta); | ||||||
|  | @ -207,10 +201,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | ||||||
|         Py_DECREF(prep); |         Py_DECREF(prep); | ||||||
|     } |     } | ||||||
|     if (ns == NULL) { |     if (ns == NULL) { | ||||||
|         Py_DECREF(meta); |         goto error; | ||||||
|         Py_XDECREF(mkw); |  | ||||||
|         Py_DECREF(bases); |  | ||||||
|         return NULL; |  | ||||||
|     } |     } | ||||||
|     if (!PyMapping_Check(ns)) { |     if (!PyMapping_Check(ns)) { | ||||||
|         PyErr_Format(PyExc_TypeError, |         PyErr_Format(PyExc_TypeError, | ||||||
|  | @ -251,13 +242,13 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, | ||||||
|     } |     } | ||||||
| error: | error: | ||||||
|     Py_XDECREF(cell); |     Py_XDECREF(cell); | ||||||
|     Py_DECREF(ns); |     Py_XDECREF(ns); | ||||||
|     Py_DECREF(meta); |     Py_XDECREF(meta); | ||||||
|     Py_XDECREF(mkw); |     Py_XDECREF(mkw); | ||||||
|     Py_DECREF(bases); |  | ||||||
|     if (bases != orig_bases) { |     if (bases != orig_bases) { | ||||||
|         Py_DECREF(orig_bases); |         Py_DECREF(orig_bases); | ||||||
|     } |     } | ||||||
|  |     Py_DECREF(bases); | ||||||
|     return cls; |     return cls; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)