mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Fix for SF bug [ #492403 ] exec() segfaults on closure's func_code
Based on the patch from Danny Yoo. The fix is in exec_statement() in ceval.c. There are also changes to introduce use of PyCode_GetNumFree() in several places.
This commit is contained in:
		
							parent
							
								
									3095a4c228
								
							
						
					
					
						commit
						733c8935f9
					
				
					 3 changed files with 10 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -497,7 +497,7 @@ builtin_eval(PyObject *self, PyObject *args)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (PyCode_Check(cmd)) {
 | 
			
		||||
		if (PyTuple_GET_SIZE(((PyCodeObject *)cmd)->co_freevars) > 0) {
 | 
			
		||||
		if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) {
 | 
			
		||||
			PyErr_SetString(PyExc_TypeError,
 | 
			
		||||
		"code object passed to eval() may not contain free variables");
 | 
			
		||||
			return NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2094,7 +2094,7 @@ eval_frame(PyFrameObject *f)
 | 
			
		|||
			int nfree;
 | 
			
		||||
			v = POP(); /* code object */
 | 
			
		||||
			x = PyFunction_New(v, f->f_globals);
 | 
			
		||||
			nfree = PyTuple_GET_SIZE(((PyCodeObject *)v)->co_freevars);
 | 
			
		||||
			nfree = PyCode_GetNumFree((PyCodeObject *)v);
 | 
			
		||||
			Py_DECREF(v);
 | 
			
		||||
			/* XXX Maybe this should be a separate opcode? */
 | 
			
		||||
			if (x != NULL && nfree > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3631,6 +3631,11 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
 | 
			
		|||
	if (PyDict_GetItemString(globals, "__builtins__") == NULL)
 | 
			
		||||
		PyDict_SetItemString(globals, "__builtins__", f->f_builtins);
 | 
			
		||||
	if (PyCode_Check(prog)) {
 | 
			
		||||
		if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) {
 | 
			
		||||
			PyErr_SetString(PyExc_TypeError,
 | 
			
		||||
		"code object passed to exec may not contain free variables");
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
 | 
			
		||||
	}
 | 
			
		||||
	else if (PyFile_Check(prog)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2273,7 +2273,7 @@ com_and_test(struct compiling *c, node *n)
 | 
			
		|||
static int
 | 
			
		||||
com_make_closure(struct compiling *c, PyCodeObject *co)
 | 
			
		||||
{
 | 
			
		||||
	int i, free = PyTuple_GET_SIZE(co->co_freevars);
 | 
			
		||||
	int i, free = PyCode_GetNumFree(co);
 | 
			
		||||
	if (free == 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
	for (i = 0; i < free; ++i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2333,7 +2333,7 @@ com_test(struct compiling *c, node *n)
 | 
			
		|||
		com_push(c, 1);
 | 
			
		||||
		if (closure) {
 | 
			
		||||
			com_addoparg(c, MAKE_CLOSURE, ndefs);
 | 
			
		||||
			com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
 | 
			
		||||
			com_pop(c, PyCode_GetNumFree(co));
 | 
			
		||||
		} else
 | 
			
		||||
			com_addoparg(c, MAKE_FUNCTION, ndefs);
 | 
			
		||||
		Py_DECREF(co);
 | 
			
		||||
| 
						 | 
				
			
			@ -3590,7 +3590,7 @@ com_classdef(struct compiling *c, node *n)
 | 
			
		|||
		com_push(c, 1);
 | 
			
		||||
		if (closure) {
 | 
			
		||||
			com_addoparg(c, MAKE_CLOSURE, 0);
 | 
			
		||||
			com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
 | 
			
		||||
			com_pop(c, PyCode_GetNumFree(co));
 | 
			
		||||
		} else
 | 
			
		||||
			com_addoparg(c, MAKE_FUNCTION, 0);
 | 
			
		||||
		com_addoparg(c, CALL_FUNCTION, 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue