mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	bpo-42143: Ensure PyFunction_NewWithQualName() can't fail after creating the func object (GH-22953) (GH-23021)
func_dealloc() does not handle partially-created objects. Best not to give it any.
(cherry picked from commit 350526105f)
Co-authored-by: Yonatan Goldschmidt <yon.goldschmidt@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									577d7c4e62
								
							
						
					
					
						commit
						60324d26b5
					
				
					 2 changed files with 19 additions and 14 deletions
				
			
		|  | @ -0,0 +1,2 @@ | ||||||
|  | Fix handling of errors during creation of ``PyFunctionObject``, which resulted | ||||||
|  | in operations on uninitialized memory. Patch by Yonatan Goldschmidt. | ||||||
|  | @ -20,9 +20,23 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname | ||||||
|             return NULL; |             return NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); |     /* __module__: If module name is in globals, use it.
 | ||||||
|     if (op == NULL) |        Otherwise, use None. */ | ||||||
|  |     module = PyDict_GetItemWithError(globals, __name__); | ||||||
|  |     if (module) { | ||||||
|  |         Py_INCREF(module); | ||||||
|  |     } | ||||||
|  |     else if (PyErr_Occurred()) { | ||||||
|         return NULL; |         return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); | ||||||
|  |     if (op == NULL) { | ||||||
|  |         Py_XDECREF(module); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |     /* Note: No failures from this point on, since func_dealloc() does not
 | ||||||
|  |        expect a partially-created object. */ | ||||||
| 
 | 
 | ||||||
|     op->func_weakreflist = NULL; |     op->func_weakreflist = NULL; | ||||||
|     Py_INCREF(code); |     Py_INCREF(code); | ||||||
|  | @ -35,6 +49,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname | ||||||
|     op->func_kwdefaults = NULL; /* No keyword only defaults */ |     op->func_kwdefaults = NULL; /* No keyword only defaults */ | ||||||
|     op->func_closure = NULL; |     op->func_closure = NULL; | ||||||
|     op->vectorcall = _PyFunction_Vectorcall; |     op->vectorcall = _PyFunction_Vectorcall; | ||||||
|  |     op->func_module = module; | ||||||
| 
 | 
 | ||||||
|     consts = ((PyCodeObject *)code)->co_consts; |     consts = ((PyCodeObject *)code)->co_consts; | ||||||
|     if (PyTuple_Size(consts) >= 1) { |     if (PyTuple_Size(consts) >= 1) { | ||||||
|  | @ -48,20 +63,8 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname | ||||||
|     op->func_doc = doc; |     op->func_doc = doc; | ||||||
| 
 | 
 | ||||||
|     op->func_dict = NULL; |     op->func_dict = NULL; | ||||||
|     op->func_module = NULL; |  | ||||||
|     op->func_annotations = NULL; |     op->func_annotations = NULL; | ||||||
| 
 | 
 | ||||||
|     /* __module__: If module name is in globals, use it.
 |  | ||||||
|        Otherwise, use None. */ |  | ||||||
|     module = PyDict_GetItemWithError(globals, __name__); |  | ||||||
|     if (module) { |  | ||||||
|         Py_INCREF(module); |  | ||||||
|         op->func_module = module; |  | ||||||
|     } |  | ||||||
|     else if (PyErr_Occurred()) { |  | ||||||
|         Py_DECREF(op); |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
|     if (qualname) |     if (qualname) | ||||||
|         op->func_qualname = qualname; |         op->func_qualname = qualname; | ||||||
|     else |     else | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Skeleton (bot)
						Miss Skeleton (bot)