Mercurial > cpython-lru_cache-weakref
diff Python/compile.c @ 33100:356887410bde legacy-trunk
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.
| author | Michael W. Hudson <mwh@python.net> |
|---|---|
| date | Thu, 12 Aug 2004 17:56:29 +0000 |
| parents | 40c3a51cb71c |
| children | 6b8e499687d6 |
line wrap: on
line diff
--- a/Python/compile.c Thu Aug 12 14:42:37 2004 +0000 +++ b/Python/compile.c Thu Aug 12 17:56:29 2004 +0000 @@ -88,6 +88,50 @@ {NULL} /* Sentinel */ }; +/* 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\ varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\ @@ -101,14 +145,13 @@ int nlocals; int stacksize; int flags; - PyObject *co; - PyObject *empty = NULL; + PyObject *co = NULL;; PyObject *code; PyObject *consts; - PyObject *names; - PyObject *varnames; - PyObject *freevars = NULL; - PyObject *cellvars = NULL; + PyObject *names, *ournames = NULL; + PyObject *varnames, *ourvarnames = NULL; + PyObject *freevars = NULL, *ourfreevars = NULL; + PyObject *cellvars = NULL, *ourcellvars = NULL; PyObject *filename; PyObject *name; int firstlineno; @@ -126,27 +169,48 @@ &PyTuple_Type, &cellvars)) 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; - } + 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, names, varnames, - freevars, cellvars, filename, name, - firstlineno, lnotab); - Py_XDECREF(empty); + 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; } @@ -302,21 +366,18 @@ return 1; } -static int +static void intern_strings(PyObject *tuple) { int i; for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { PyObject *v = PyTuple_GET_ITEM(tuple, i); - if (v == NULL || !PyString_Check(v)) { + if (v == NULL || !PyString_CheckExact(v)) { Py_FatalError("non-string found in code slot"); - PyErr_BadInternalCall(); - return -1; } PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i)); } - return 0; } #define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
