[Python-checkins] python/dist/src/Python compile.c,2.314,2.315

mwh at users.sourceforge.net mwh at users.sourceforge.net
Thu Aug 12 19:56:31 CEST 2004


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31215/Python

Modified Files:
	compile.c 
Log Message:
Fix bug

[ 1005248 ] new.code() not cleanly checking its arguments

using the result of new.code() can still destroy the sun, but merely
calling the function shouldn't any more.

I also rewrote the existing tests of new.code() to use vastly less
un-bogus arguments, and added tests for the previous insane behaviours.


Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.314
retrieving revision 2.315
diff -C2 -d -r2.314 -r2.315
*** compile.c	6 Aug 2004 19:46:34 -0000	2.314
--- compile.c	12 Aug 2004 17:56:20 -0000	2.315
***************
*** 89,92 ****
--- 89,136 ----
  };
  
+ /* Helper for code_new: return a shallow copy of a tuple that is
+    guaranteed to contain exact strings, by converting string subclasses
+    to exact strings and complaining if a non-string is found. */
+ static PyObject*
+ validate_and_copy_tuple(PyObject *tup)
+ {
+ 	PyObject *newtuple;
+ 	PyObject *item;
+ 	int i, len;
+ 
+ 	len = PyTuple_GET_SIZE(tup);
+ 	newtuple = PyTuple_New(len);
+ 	if (newtuple == NULL)
+ 		return NULL;
+ 
+ 	for (i = 0; i < len; i++) {
+ 		item = PyTuple_GET_ITEM(tup, i);
+ 		if (PyString_CheckExact(item)) {
+ 			Py_INCREF(item);
+ 		}
+ 		else if (!PyString_Check(item)) {
+ 			PyErr_Format(
+ 				PyExc_TypeError,
+ 				"name tuples must contain only "
+ 				"strings, not '%.500s'",
+ 				item->ob_type->tp_name);
+ 			Py_DECREF(newtuple);
+ 			return NULL;
+ 		}
+ 		else {
+ 			item = PyString_FromStringAndSize(
+ 				PyString_AS_STRING(item),
+ 				PyString_GET_SIZE(item));
+ 			if (item == NULL) {
+ 				Py_DECREF(newtuple);
+ 				return NULL;
+ 			}
+ 		}
+ 		PyTuple_SET_ITEM(newtuple, i, item);
+ 	}
+ 
+ 	return newtuple;
+ }
+ 
  PyDoc_STRVAR(code_doc,
  "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
***************
*** 102,113 ****
  	int stacksize;
  	int flags;
! 	PyObject *co;
! 	PyObject *empty = NULL;
  	PyObject *code;
  	PyObject *consts;
! 	PyObject *names;
! 	PyObject *varnames;
! 	PyObject *freevars = NULL;
! 	PyObject *cellvars = NULL;
  	PyObject *filename;
  	PyObject *name;
--- 146,156 ----
  	int stacksize;
  	int flags;
! 	PyObject *co = NULL;;
  	PyObject *code;
  	PyObject *consts;
! 	PyObject *names, *ournames = NULL;
! 	PyObject *varnames, *ourvarnames = NULL;
! 	PyObject *freevars = NULL, *ourfreevars = NULL;
! 	PyObject *cellvars = NULL, *ourcellvars = NULL;
  	PyObject *filename;
  	PyObject *name;
***************
*** 127,151 ****
  		return NULL;
  
! 	if (!PyObject_CheckReadBuffer(code)) {
! 		PyErr_SetString(PyExc_TypeError,
! 		  "bytecode object must be a single-segment read-only buffer");
! 		return NULL;
  	}
  
! 	if (freevars == NULL || cellvars == NULL) {
! 		empty = PyTuple_New(0);
! 		if (empty == NULL)
! 			return NULL;
! 		if (freevars == NULL)
! 			freevars = empty;
! 		if (cellvars == NULL)
! 			cellvars = empty;
  	}
  
  	co = (PyObject *) PyCode_New(argcount, nlocals, stacksize, flags,
! 				      code, consts, names, varnames,
! 				      freevars, cellvars, filename, name,
! 				      firstlineno, lnotab);
! 	Py_XDECREF(empty);
  	return co;
  }
--- 170,215 ----
  		return NULL;
  
! 	if (argcount < 0) {
! 		PyErr_SetString(
! 			PyExc_ValueError, 
! 			"code: argcount must not be negative");
! 		goto cleanup;
  	}
  
! 	if (nlocals < 0) {
! 		PyErr_SetString(
! 			PyExc_ValueError, 
! 			"code: nlocals must not be negative");
! 		goto cleanup;
  	}
  
+ 	ournames = validate_and_copy_tuple(names);
+ 	if (ournames == NULL)
+ 		goto cleanup;
+ 	ourvarnames = validate_and_copy_tuple(varnames);
+ 	if (ourvarnames == NULL)
+ 		goto cleanup;
+ 	if (freevars)
+ 		ourfreevars = validate_and_copy_tuple(freevars);
+ 	else
+ 		ourfreevars = PyTuple_New(0);
+ 	if (ourfreevars == NULL)
+ 		goto cleanup;
+ 	if (cellvars)
+ 		ourcellvars = validate_and_copy_tuple(cellvars);
+ 	else
+ 		ourcellvars = PyTuple_New(0);
+ 	if (ourcellvars == NULL)
+ 		goto cleanup;
+ 
  	co = (PyObject *) PyCode_New(argcount, nlocals, stacksize, flags,
! 				     code, consts, ournames, ourvarnames,
! 				     ourfreevars, ourcellvars, filename,
! 				     name, firstlineno, lnotab);
!   cleanup:
! 	Py_XDECREF(ournames);
! 	Py_XDECREF(ourvarnames);
! 	Py_XDECREF(ourfreevars);
! 	Py_XDECREF(ourcellvars);
  	return co;
  }
***************
*** 303,307 ****
  }
  
! static int
  intern_strings(PyObject *tuple)
  {
--- 367,371 ----
  }
  
! static void
  intern_strings(PyObject *tuple)
  {
***************
*** 310,321 ****
  	for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
  		PyObject *v = PyTuple_GET_ITEM(tuple, i);
! 		if (v == NULL || !PyString_Check(v)) {
  			Py_FatalError("non-string found in code slot");
- 			PyErr_BadInternalCall();
- 			return -1;
  		}
  		PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
  	}
- 	return 0;
  }
  
--- 374,382 ----
  	for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
  		PyObject *v = PyTuple_GET_ITEM(tuple, i);
! 		if (v == NULL || !PyString_CheckExact(v)) {
  			Py_FatalError("non-string found in code slot");
  		}
  		PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
  	}
  }
  



More information about the Python-checkins mailing list