mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +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 (PyCode_Check(cmd)) { | ||||||
| 		if (PyTuple_GET_SIZE(((PyCodeObject *)cmd)->co_freevars) > 0) { | 		if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) { | ||||||
| 			PyErr_SetString(PyExc_TypeError, | 			PyErr_SetString(PyExc_TypeError, | ||||||
| 		"code object passed to eval() may not contain free variables"); | 		"code object passed to eval() may not contain free variables"); | ||||||
| 			return NULL; | 			return NULL; | ||||||
|  |  | ||||||
|  | @ -2094,7 +2094,7 @@ eval_frame(PyFrameObject *f) | ||||||
| 			int nfree; | 			int nfree; | ||||||
| 			v = POP(); /* code object */ | 			v = POP(); /* code object */ | ||||||
| 			x = PyFunction_New(v, f->f_globals); | 			x = PyFunction_New(v, f->f_globals); | ||||||
| 			nfree = PyTuple_GET_SIZE(((PyCodeObject *)v)->co_freevars); | 			nfree = PyCode_GetNumFree((PyCodeObject *)v); | ||||||
| 			Py_DECREF(v); | 			Py_DECREF(v); | ||||||
| 			/* XXX Maybe this should be a separate opcode? */ | 			/* XXX Maybe this should be a separate opcode? */ | ||||||
| 			if (x != NULL && nfree > 0) { | 			if (x != NULL && nfree > 0) { | ||||||
|  | @ -3631,6 +3631,11 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals, | ||||||
| 	if (PyDict_GetItemString(globals, "__builtins__") == NULL) | 	if (PyDict_GetItemString(globals, "__builtins__") == NULL) | ||||||
| 		PyDict_SetItemString(globals, "__builtins__", f->f_builtins); | 		PyDict_SetItemString(globals, "__builtins__", f->f_builtins); | ||||||
| 	if (PyCode_Check(prog)) { | 	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); | 		v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals); | ||||||
| 	} | 	} | ||||||
| 	else if (PyFile_Check(prog)) { | 	else if (PyFile_Check(prog)) { | ||||||
|  |  | ||||||
|  | @ -2273,7 +2273,7 @@ com_and_test(struct compiling *c, node *n) | ||||||
| static int | static int | ||||||
| com_make_closure(struct compiling *c, PyCodeObject *co) | 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) | 	if (free == 0) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	for (i = 0; i < free; ++i) { | 	for (i = 0; i < free; ++i) { | ||||||
|  | @ -2333,7 +2333,7 @@ com_test(struct compiling *c, node *n) | ||||||
| 		com_push(c, 1); | 		com_push(c, 1); | ||||||
| 		if (closure) { | 		if (closure) { | ||||||
| 			com_addoparg(c, MAKE_CLOSURE, ndefs); | 			com_addoparg(c, MAKE_CLOSURE, ndefs); | ||||||
| 			com_pop(c, PyTuple_GET_SIZE(co->co_freevars)); | 			com_pop(c, PyCode_GetNumFree(co)); | ||||||
| 		} else | 		} else | ||||||
| 			com_addoparg(c, MAKE_FUNCTION, ndefs); | 			com_addoparg(c, MAKE_FUNCTION, ndefs); | ||||||
| 		Py_DECREF(co); | 		Py_DECREF(co); | ||||||
|  | @ -3590,7 +3590,7 @@ com_classdef(struct compiling *c, node *n) | ||||||
| 		com_push(c, 1); | 		com_push(c, 1); | ||||||
| 		if (closure) { | 		if (closure) { | ||||||
| 			com_addoparg(c, MAKE_CLOSURE, 0); | 			com_addoparg(c, MAKE_CLOSURE, 0); | ||||||
| 			com_pop(c, PyTuple_GET_SIZE(co->co_freevars)); | 			com_pop(c, PyCode_GetNumFree(co)); | ||||||
| 		} else | 		} else | ||||||
| 			com_addoparg(c, MAKE_FUNCTION, 0); | 			com_addoparg(c, MAKE_FUNCTION, 0); | ||||||
| 		com_addoparg(c, CALL_FUNCTION, 0); | 		com_addoparg(c, CALL_FUNCTION, 0); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Hylton
						Jeremy Hylton