diff options
Diffstat (limited to 'Modules')
28 files changed, 431 insertions, 299 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index 2a3ac5c..ad45936 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -1797,7 +1797,6 @@ DB_join(DBObject* self, PyObject* args) DBC** cursors; DBC* dbc; - if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags)) return NULL; @@ -1811,6 +1810,11 @@ DB_join(DBObject* self, PyObject* args) length = PyObject_Length(cursorsObj); cursors = malloc((length+1) * sizeof(DBC*)); + if (!cursors) { + PyErr_NoMemory(); + return NULL; + } + cursors[length] = NULL; for (x=0; x<length; x++) { PyObject* item = PySequence_GetItem(cursorsObj, x); @@ -2622,11 +2626,13 @@ DB_verify(DBObject* self, PyObject* args, PyObject* kwargs) CHECK_DB_NOT_CLOSED(self); if (outFileName) outFile = fopen(outFileName, "w"); + /* XXX(nnorwitz): it should probably be an exception if outFile + can't be opened. */ MYDB_BEGIN_ALLOW_THREADS; err = self->db->verify(self->db, fileName, dbName, outFile, flags); MYDB_END_ALLOW_THREADS; - if (outFileName) + if (outFile) fclose(outFile); /* DB.verify acts as a DB handle destructor (like close); this was diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 405fd7a..4dbceb7 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -192,7 +192,8 @@ escape_encode(PyObject *self, buf = PyString_AS_STRING (str); len = PyString_GET_SIZE (str); memmove(buf, buf+1, len-2); - _PyString_Resize(&str, len-2); + if (_PyString_Resize(&str, len-2) < 0) + return NULL; return codec_tuple(str, PyString_Size(str)); } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 76d88de..e4aae2d 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -140,6 +140,31 @@ char *conversion_mode_errors = NULL; accessible fields somehow. */ +static PyCArgObject * +StructUnionType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + StgDictObject *stgdict; + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = 'V'; + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for structure/union instances */ + parg->pffi_type = &stgdict->ffi_type_pointer; + /* For structure parameters (by value), parg->value doesn't contain the structure + data itself, instead parg->value.p *points* to the structure's data + See also _ctypes.c, function _call_function_pointer(). + */ + parg->value.p = self->b_ptr; + parg->size = self->b_size; + Py_INCREF(self); + parg->obj = (PyObject *)self; + return parg; +} + static PyObject * StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct) { @@ -172,6 +197,8 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt Py_DECREF(result->tp_dict); result->tp_dict = (PyObject *)dict; + dict->paramfunc = StructUnionType_paramfunc; + fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); if (!fields) { StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); @@ -287,6 +314,7 @@ static char from_param_doc[] = static PyObject * CDataType_from_param(PyObject *type, PyObject *value) { + PyObject *as_parameter; if (1 == PyObject_IsInstance(value, type)) { Py_INCREF(value); return value; @@ -300,7 +328,6 @@ CDataType_from_param(PyObject *type, PyObject *value) /* If we got a PyCArgObject, we must check if the object packed in it is an instance of the type's dict->proto */ -// if(dict && ob && dict->proto == (PyObject *)ob->ob_type){ if(dict && ob && PyObject_IsInstance(ob, dict->proto)) { Py_INCREF(value); @@ -330,6 +357,13 @@ CDataType_from_param(PyObject *type, PyObject *value) } /* ... and leave the rest */ #endif + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = CDataType_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } PyErr_Format(PyExc_TypeError, "expected %s instance instead of %s", ((PyTypeObject *)type)->tp_name, @@ -540,6 +574,23 @@ PointerType_SetProto(StgDictObject *stgdict, PyObject *proto) return 0; } +static PyCArgObject * +PointerType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(self); + parg->obj = (PyObject *)self; + parg->value.p = *(void **)self->b_ptr; + return parg; +} + static PyObject * PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -563,6 +614,7 @@ PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->align = getentry("P")->pffi_type->alignment; stgdict->length = 1; stgdict->ffi_type_pointer = ffi_type_pointer; + stgdict->paramfunc = PointerType_paramfunc; proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ if (proto && -1 == PointerType_SetProto(stgdict, proto)) { @@ -620,6 +672,7 @@ PointerType_from_param(PyObject *type, PyObject *value) return PyInt_FromLong(0); /* NULL pointer */ typedict = PyType_stgdict(type); + assert(typedict); /* Cannot be NULL for pointer types */ /* If we expect POINTER(<type>), but receive a <type> instance, accept it by calling byref(<type>). @@ -640,6 +693,7 @@ PointerType_from_param(PyObject *type, PyObject *value) the item types are the same. */ StgDictObject *v = PyObject_stgdict(value); + assert(v); /* Cannot be NULL for pointer or array objects */ if (PyObject_IsSubclass(v->proto, typedict->proto)) { Py_INCREF(value); return value; @@ -906,6 +960,19 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp) return 0; } +static PyCArgObject * +ArrayType_paramfunc(CDataObject *self) +{ + PyCArgObject *p = new_CArgObject(); + if (p == NULL) + return NULL; + p->tag = 'P'; + p->pffi_type = &ffi_type_pointer; + p->value.p = (char *)self->b_ptr; + Py_INCREF(self); + p->obj = (PyObject *)self; + return p; +} static PyObject * ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -961,6 +1028,8 @@ ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_INCREF(proto); stgdict->proto = proto; + stgdict->paramfunc = &ArrayType_paramfunc; + /* Arrays are passed as pointers to function calls. */ stgdict->ffi_type_pointer = ffi_type_pointer; @@ -1055,6 +1124,7 @@ static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv"; static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) { + PyObject *as_parameter; #if (PYTHON_API_VERSION < 1012) # error not supported #endif @@ -1067,6 +1137,8 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) struct fielddesc *fd = getentry("Z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1083,7 +1155,9 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_wchar array instance or pointer(c_wchar(...)) */ StgDictObject *dt = PyObject_stgdict(value); - StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; + StgDictObject *dict; + assert(dt); /* Cannot be NULL for pointer or array objects */ + dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == getentry("u")->setfunc)) { Py_INCREF(value); return value; @@ -1098,6 +1172,13 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) return value; } } + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = c_wchar_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } /* XXX better message */ PyErr_SetString(PyExc_TypeError, "wrong type"); @@ -1107,6 +1188,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) static PyObject * c_char_p_from_param(PyObject *type, PyObject *value) { + PyObject *as_parameter; #if (PYTHON_API_VERSION < 1012) # error not supported #endif @@ -1119,6 +1201,8 @@ c_char_p_from_param(PyObject *type, PyObject *value) struct fielddesc *fd = getentry("z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1135,7 +1219,9 @@ c_char_p_from_param(PyObject *type, PyObject *value) if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_char array instance or pointer(c_char(...)) */ StgDictObject *dt = PyObject_stgdict(value); - StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; + StgDictObject *dict; + assert(dt); /* Cannot be NULL for pointer or array objects */ + dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == getentry("c")->setfunc)) { Py_INCREF(value); return value; @@ -1150,6 +1236,13 @@ c_char_p_from_param(PyObject *type, PyObject *value) return value; } } + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = c_char_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } /* XXX better message */ PyErr_SetString(PyExc_TypeError, "wrong type"); @@ -1160,6 +1253,7 @@ static PyObject * c_void_p_from_param(PyObject *type, PyObject *value) { StgDictObject *stgd; + PyObject *as_parameter; #if (PYTHON_API_VERSION < 1012) # error not supported #endif @@ -1176,6 +1270,8 @@ c_void_p_from_param(PyObject *type, PyObject *value) struct fielddesc *fd = getentry("P"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'P'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1191,6 +1287,8 @@ c_void_p_from_param(PyObject *type, PyObject *value) struct fielddesc *fd = getentry("z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1206,6 +1304,8 @@ c_void_p_from_param(PyObject *type, PyObject *value) struct fielddesc *fd = getentry("Z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1242,6 +1342,8 @@ c_void_p_from_param(PyObject *type, PyObject *value) CFuncPtrObject *func; func = (CFuncPtrObject *)value; parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'P'; Py_INCREF(value); @@ -1269,6 +1371,13 @@ c_void_p_from_param(PyObject *type, PyObject *value) return (PyObject *)parg; } } + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = c_void_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } /* XXX better message */ PyErr_SetString(PyExc_TypeError, "wrong type"); @@ -1355,6 +1464,33 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject return (PyObject *)result; } +static PyCArgObject * +SimpleType_paramfunc(CDataObject *self) +{ + StgDictObject *dict; + char *fmt; + PyCArgObject *parg; + struct fielddesc *fd; + + dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ + fmt = PyString_AsString(dict->proto); + assert(fmt); + + fd = getentry(fmt); + assert(fd); + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = fmt[0]; + parg->pffi_type = fd->pffi_type; + Py_INCREF(self); + parg->obj = (PyObject *)self; + memcpy(&parg->value, self->b_ptr, self->b_size); + return parg; +} static PyObject * SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1404,6 +1540,8 @@ SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; + + stgdict->paramfunc = SimpleType_paramfunc; /* if (result->tp_base != &Simple_Type) { stgdict->setfunc = NULL; @@ -1502,23 +1640,6 @@ SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* * This is a *class method*. * Convert a parameter into something that ConvParam can handle. - * - * This is either an instance of the requested type, a Python integer, or a - * 'magic' 3-tuple. - * - * (These are somewhat related to Martin v. Loewis 'Enhanced Argument Tuples', - * described in PEP 286.) - * - * The tuple must contain - * - * - a format character, currently 'ifdqc' are understood - * which will inform ConvParam about how to push the argument on the stack. - * - * - a corresponding Python object: i - integer, f - float, d - float, - * q - longlong, c - integer - * - * - any object which can be used to keep the original parameter alive - * as long as the tuple lives. */ static PyObject * SimpleType_from_param(PyObject *type, PyObject *value) @@ -1527,6 +1648,7 @@ SimpleType_from_param(PyObject *type, PyObject *value) char *fmt; PyCArgObject *parg; struct fielddesc *fd; + PyObject *as_parameter; /* If the value is already an instance of the requested type, we can use it as is */ @@ -1552,11 +1674,20 @@ SimpleType_from_param(PyObject *type, PyObject *value) parg->tag = fmt[0]; parg->pffi_type = fd->pffi_type; parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; + if (parg->obj) + return (PyObject *)parg; + PyErr_Clear(); + Py_DECREF(parg); + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = SimpleType_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; } - return (PyObject *)parg; + PyErr_SetString(PyExc_TypeError, + "wrong type"); + return NULL; } static PyMethodDef SimpleType_methods[] = { @@ -1721,6 +1852,23 @@ make_funcptrtype_dict(StgDictObject *stgdict) } +static PyCArgObject * +CFuncPtrType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(self); + parg->obj = (PyObject *)self; + parg->value.p = *(void **)self->b_ptr; + return parg; +} + static PyObject * CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1732,6 +1880,8 @@ CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!stgdict) return NULL; + stgdict->paramfunc = CFuncPtrType_paramfunc; + /* create the new instance (which is a class, since we are a metatype!) */ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); @@ -1921,6 +2071,7 @@ static int CData_clear(CDataObject *self) { StgDictObject *dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ Py_CLEAR(self->b_objects); if ((self->b_needsfree) && ((size_t)dict->size > sizeof(self->b_value))) @@ -2218,7 +2369,9 @@ _CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, StgDictObject *p1, *p2; PyObject *keep; p1 = PyObject_stgdict(value); + assert(p1); /* Cannot be NULL for array instances */ p2 = PyType_stgdict(type); + assert(p2); /* Cannot be NULL for pointer types */ if (p1->proto != p2->proto) { PyErr_Format(PyExc_TypeError, @@ -2308,23 +2461,6 @@ GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) CFuncPtr_Type */ -static PyObject * -CFuncPtr_as_parameter(CDataObject *self) -{ - PyCArgObject *parg; - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; - parg->value.p = *(void **)self->b_ptr; - return (PyObject *)parg; -} - static int CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob) { @@ -2384,7 +2520,7 @@ CFuncPtr_get_restype(CFuncPtrObject *self) return self->restype; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); + assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ if (dict->restype) { Py_INCREF(dict->restype); return dict->restype; @@ -2426,7 +2562,7 @@ CFuncPtr_get_argtypes(CFuncPtrObject *self) return self->argtypes; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); + assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ if (dict->argtypes) { Py_INCREF(dict->argtypes); return dict->argtypes; @@ -2444,9 +2580,6 @@ static PyGetSetDef CFuncPtr_getsets[] = { { "argtypes", (getter)CFuncPtr_get_argtypes, (setter)CFuncPtr_set_argtypes, "specify the argument types", NULL }, - { "_as_parameter_", (getter)CFuncPtr_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, { NULL, NULL } }; @@ -2475,6 +2608,8 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type) where n is 0, 4, 8, 12, ..., 128 */ mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ + if (!mangled_name) + return NULL; for (i = 0; i < 32; ++i) { sprintf(mangled_name, "_%s@%d", name, i*4); address = (PPROC)GetProcAddress(handle, mangled_name); @@ -2520,8 +2655,12 @@ static int _validate_paramflags(PyTypeObject *type, PyObject *paramflags) { int i, len; - StgDictObject *dict = PyType_stgdict((PyObject *)type); - PyObject *argtypes = dict->argtypes; + StgDictObject *dict; + PyObject *argtypes; + + dict = PyType_stgdict((PyObject *)type); + assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */ + argtypes = dict->argtypes; if (paramflags == NULL || dict->argtypes == NULL) return 1; @@ -2744,6 +2883,8 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (ptr == NULL) return NULL; ob = (CDataObject *)GenericCData_new(type, args, kwds); + if (ob == NULL) + return NULL; *(void **)ob->b_ptr = ptr; return (PyObject *)ob; } @@ -2791,6 +2932,8 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + if (self == NULL) + return NULL; Py_INCREF(callable); self->callable = callable; @@ -2987,6 +3130,13 @@ _build_callargs(CFuncPtrObject *self, PyObject *argtypes, } ob = PyTuple_GET_ITEM(argtypes, i); dict = PyType_stgdict(ob); + if (dict == NULL) { + /* Cannot happen: _validate_paramflags() + would not accept such an object */ + PyErr_Format(PyExc_RuntimeError, + "NULL stgdict unexpected"); + goto error; + } if (PyString_Check(dict->proto)) { PyErr_Format( PyExc_TypeError, @@ -3129,7 +3279,7 @@ CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds) int outmask; unsigned int numretvals; - assert(dict); /* if not, it's a bug */ + assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ restype = self->restype ? self->restype : dict->restype; converters = self->converters ? self->converters : dict->converters; checker = self->checker ? self->checker : dict->checker; @@ -3349,30 +3499,6 @@ IBUG(char *msg) return -1; } -static PyObject * -Struct_as_parameter(CDataObject *self) -{ - PyCArgObject *parg; - StgDictObject *stgdict; - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = 'V'; - stgdict = PyObject_stgdict((PyObject *)self); - parg->pffi_type = &stgdict->ffi_type_pointer; - /* For structure parameters (by value), parg->value doesn't contain the structure - data itself, instead parg->value.p *points* to the structure's data - See also _ctypes.c, function _call_function_pointer(). - */ - parg->value.p = self->b_ptr; - parg->size = self->b_size; - Py_INCREF(self); - parg->obj = (PyObject *)self; - return (PyObject *)parg; -} - static int Struct_init(PyObject *self, PyObject *args, PyObject *kwds) { @@ -3447,13 +3573,6 @@ Struct_init(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -static PyGetSetDef Struct_getsets[] = { - { "_as_parameter_", (getter)Struct_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, - { NULL, NULL } -}; - static PyTypeObject Struct_Type = { PyObject_HEAD_INIT(NULL) 0, @@ -3485,7 +3604,7 @@ static PyTypeObject Struct_Type = { 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - Struct_getsets, /* tp_getset */ + 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3528,7 +3647,7 @@ static PyTypeObject Union_Type = { 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - Struct_getsets, /* tp_getset */ + 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3581,7 +3700,7 @@ Array_item(PyObject *_self, Py_ssize_t index) } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); + assert(stgdict); /* Cannot be NULL for array instances */ /* Would it be clearer if we got the item size from stgdict->proto's stgdict? */ @@ -3612,8 +3731,11 @@ Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh) len = ihigh - ilow; stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array object instances */ proto = stgdict->proto; itemdict = PyType_stgdict(proto); + assert(itemdict); /* proto is the item type of the array, a ctypes + type, so this cannot be NULL */ if (itemdict->getfunc == getentry("c")->getfunc) { char *ptr = (char *)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); @@ -3650,6 +3772,7 @@ Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value) } stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array object instances */ if (index < 0 || index >= stgdict->length) { PyErr_SetString(PyExc_IndexError, "invalid index"); @@ -3726,26 +3849,6 @@ static PySequenceMethods Array_as_sequence = { 0, /* sq_inplace_repeat; */ }; -static PyObject * -Array_as_parameter(CDataObject *self) -{ - PyCArgObject *p = new_CArgObject(); - if (p == NULL) - return NULL; - p->tag = 'P'; - p->pffi_type = &ffi_type_pointer; - p->value.p = (char *)self->b_ptr; - Py_INCREF(self); - p->obj = (PyObject *)self; - return (PyObject *)p; -} - -static PyGetSetDef Array_getsets[] = { - { "_as_parameter_", (getter)Array_as_parameter, - (setter)NULL, "convert to a parameter", NULL }, - { NULL }, -}; - PyTypeObject Array_Type = { PyObject_HEAD_INIT(NULL) 0, @@ -3777,7 +3880,7 @@ PyTypeObject Array_Type = { 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - Array_getsets, /* tp_getset */ + 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3861,6 +3964,7 @@ Simple_set_value(CDataObject *self, PyObject *value) PyObject *result; StgDictObject *dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ assert(dict->setfunc); result = dict->setfunc(self->b_ptr, value, dict->size); if (!result) @@ -3886,40 +3990,14 @@ Simple_get_value(CDataObject *self) { StgDictObject *dict; dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ assert(dict->getfunc); - dict = PyObject_stgdict((PyObject *)self); return dict->getfunc(self->b_ptr, self->b_size); } -static PyObject * -Simple_as_parameter(CDataObject *self) -{ - StgDictObject *dict = PyObject_stgdict((PyObject *)self); - char *fmt = PyString_AsString(dict->proto); - PyCArgObject *parg; - struct fielddesc *fd; - - fd = getentry(fmt); - assert(fd); - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = fmt[0]; - parg->pffi_type = fd->pffi_type; - Py_INCREF(self); - parg->obj = (PyObject *)self; - memcpy(&parg->value, self->b_ptr, self->b_size); - return (PyObject *)parg; -} - static PyGetSetDef Simple_getsets[] = { { "value", (getter)Simple_get_value, (setter)Simple_set_value, "current value", NULL }, - { "_as_parameter_", (getter)Simple_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, { NULL, NULL } }; @@ -4085,12 +4163,14 @@ Pointer_item(PyObject *_self, Py_ssize_t index) } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); - assert(stgdict->proto); + assert(stgdict); /* Cannot be NULL for pointer object instances */ proto = stgdict->proto; - /* XXXXXX MAKE SURE PROTO IS NOT NULL! */ + assert(proto); itemdict = PyType_stgdict(proto); + assert(itemdict); /* proto is the item type of the pointer, a ctypes + type, so this cannot be NULL */ + size = itemdict->size; offset = index * itemdict->size; @@ -4120,12 +4200,15 @@ Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value) } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); - assert(stgdict->proto); + assert(stgdict); /* Cannot be NULL fr pointer instances */ proto = stgdict->proto; - /* XXXXXX MAKE SURE PROTO IS NOT NULL! */ + assert(proto); + itemdict = PyType_stgdict(proto); + assert(itemdict); /* Cannot be NULL because the itemtype of a pointer + is always a ctypes type */ + size = itemdict->size; offset = index * itemdict->size; @@ -4145,7 +4228,7 @@ Pointer_get_contents(CDataObject *self, void *closure) } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); + assert(stgdict); /* Cannot be NULL fr pointer instances */ return CData_FromBaseObj(stgdict->proto, (PyObject *)self, 0, *(void **)self->b_ptr); @@ -4164,7 +4247,7 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) return -1; } stgdict = PyObject_stgdict((PyObject *)self); - /* should have been catched in Pointer_new() */ + assert(stgdict); /* Cannot be NULL fr pointer instances */ assert(stgdict->proto); if (!CDataObject_Check(value) || 0 == PyObject_IsInstance(value, stgdict->proto)) { @@ -4193,30 +4276,10 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) return KeepRef(self, 0, keep); } -static PyObject * -Pointer_as_parameter(CDataObject *self) -{ - PyCArgObject *parg; - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; - parg->value.p = *(void **)self->b_ptr; - return (PyObject *)parg; -} - static PyGetSetDef Pointer_getsets[] = { { "contents", (getter)Pointer_get_contents, (setter)Pointer_set_contents, "the object this pointer points to (read-write)", NULL }, - { "_as_parameter_", (getter)Pointer_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, { NULL, NULL } }; @@ -4260,8 +4323,11 @@ Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh) len = ihigh - ilow; stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL fr pointer instances */ proto = stgdict->proto; + assert(proto); itemdict = PyType_stgdict(proto); + assert(itemdict); if (itemdict->getfunc == getentry("c")->getfunc) { char *ptr = *(char **)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); @@ -4676,7 +4742,7 @@ init_ctypes(void) #endif PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); - PyModule_AddStringConstant(m, "__version__", "1.0.0"); + PyModule_AddStringConstant(m, "__version__", "1.0.1"); PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 99cc7a9..7331d01 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -197,18 +197,6 @@ EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value, #endif -EXPORT(int) _testfunc_ppp(char ***p) -{ - static char message[] = "Hello, World"; - if (p) { - *p = (char **)malloc(sizeof(char *)); - printf("malloc returned %p\n", *p); - **p = message; - return 1; - } - return 0; -} - typedef struct { char *name; char *value; diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index c091d88..c8e669a 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -205,7 +205,7 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print() result = PyObject_CallObject(callable, arglist); CHECK("'calling callback function'", result); - if ((restype != &ffi_type_void) && result && result != Py_None) { + if ((restype != &ffi_type_void) && result) { PyObject *keep; assert(setfunc); #ifdef WORDS_BIGENDIAN @@ -225,13 +225,13 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print() itself knows how to manage the refcount of these objects. */ if (keep == NULL) /* Could not convert callback result. */ - PyErr_WriteUnraisable(Py_None); + PyErr_WriteUnraisable(callable); else if (keep == Py_None) /* Nothing to keep */ Py_DECREF(keep); else if (setfunc != getentry("O")->setfunc) { if (-1 == PyErr_Warn(PyExc_RuntimeWarning, "memory leak in callback function.")) - PyErr_WriteUnraisable(Py_None); + PyErr_WriteUnraisable(callable); } } Py_XDECREF(result); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index d6f875b..e0765e9 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -465,7 +465,21 @@ struct argument { */ static int ConvParam(PyObject *obj, int index, struct argument *pa) { + StgDictObject *dict; pa->keep = NULL; /* so we cannot forget it later */ + + dict = PyObject_stgdict(obj); + if (dict) { + PyCArgObject *carg; + assert(dict->paramfunc); + /* If it has an stgdict, it is a CDataObject */ + carg = dict->paramfunc((CDataObject *)obj); + pa->ffi_type = carg->pffi_type; + memcpy(&pa->value, &carg->value, sizeof(pa->value)); + pa->keep = (PyObject *)carg; + return 0; + } + if (PyCArg_CheckExact(obj)) { PyCArgObject *carg = (PyCArgObject *)obj; pa->ffi_type = carg->pffi_type; @@ -548,25 +562,12 @@ static int ConvParam(PyObject *obj, int index, struct argument *pa) as parameters (they have to expose the '_as_parameter_' attribute) */ - if (arg == 0) { - PyErr_Format(PyExc_TypeError, - "Don't know how to convert parameter %d", index); - return -1; + if (arg) { + int result; + result = ConvParam(arg, index, pa); + Py_DECREF(arg); + return result; } - if (PyCArg_CheckExact(arg)) { - PyCArgObject *carg = (PyCArgObject *)arg; - pa->ffi_type = carg->pffi_type; - memcpy(&pa->value, &carg->value, sizeof(pa->value)); - pa->keep = arg; - return 0; - } - if (PyInt_Check(arg)) { - pa->ffi_type = &ffi_type_sint; - pa->value.i = PyInt_AS_LONG(arg); - pa->keep = arg; - return 0; - } - Py_DECREF(arg); PyErr_Format(PyExc_TypeError, "Don't know how to convert parameter %d", index); return -1; @@ -915,6 +916,10 @@ PyObject *_CallProc(PPROC pProc, #endif args = (struct argument *)alloca(sizeof(struct argument) * argcount); + if (!args) { + PyErr_NoMemory(); + return NULL; + } memset(args, 0, sizeof(struct argument) * argcount); argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; #ifdef MS_WIN32 @@ -968,6 +973,10 @@ PyObject *_CallProc(PPROC pProc, avalues = (void **)alloca(sizeof(void *) * argcount); atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount); + if (!resbuf || !avalues || !atypes) { + PyErr_NoMemory(); + goto cleanup; + } for (i = 0; i < argcount; ++i) { atypes[i] = args[i].ffi_type; if (atypes[i]->type == FFI_TYPE_STRUCT) @@ -1068,6 +1077,11 @@ static PyObject *load_library(PyObject *self, PyObject *args) return NULL; #ifdef _UNICODE name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR)); + if (!name) { + PyErr_NoMemory(); + return NULL; + } + { int r; char *aname = PyString_AsString(nameobj); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 3595b05..c16a387 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -105,6 +105,12 @@ CField_FromDesc(PyObject *desc, int index, StgDictObject *idict; if (adict && adict->proto) { idict = PyType_stgdict(adict->proto); + if (!idict) { + PyErr_SetString(PyExc_TypeError, + "has no _stginfo_"); + Py_DECREF(self); + return NULL; + } if (idict->getfunc == getentry("c")->getfunc) { struct fielddesc *fd = getentry("s"); getfunc = fd->getfunc; @@ -1094,7 +1100,7 @@ O_get(void *ptr, unsigned size) if (!PyErr_Occurred()) /* Set an error if not yet set */ PyErr_SetString(PyExc_ValueError, - "PyObject is NULL?"); + "PyObject is NULL"); return NULL; } Py_INCREF(ob); diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 303eda3..0af7851 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -23,9 +23,11 @@ typedef int Py_ssize_t; #define PY_LONG_LONG LONG_LONG #endif +typedef struct tagPyCArgObject PyCArgObject; typedef struct tagCDataObject CDataObject; typedef PyObject *(* GETFUNC)(void *, unsigned size); typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size); +typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj); /* A default buffer in CDataObject, which can be used for small C types. If this buffer is too small, PyMem_Malloc will be called to create a larger one, @@ -205,6 +207,7 @@ typedef struct { PyObject *proto; /* Only for Pointer/ArrayObject */ SETFUNC setfunc; /* Only for simple objects */ GETFUNC getfunc; /* Only for simple objects */ + PARAMFUNC paramfunc; /* Following fields only used by CFuncPtrType_Type instances */ PyObject *argtypes; /* tuple of CDataObjects */ @@ -283,7 +286,7 @@ PyObject *_CallProc(PPROC pProc, #define DICTFLAG_FINAL 0x1000 -typedef struct { +struct tagPyCArgObject { PyObject_HEAD ffi_type *pffi_type; char tag; @@ -302,7 +305,7 @@ typedef struct { } value; PyObject *obj; int size; /* for the 'V' tag */ -} PyCArgObject; +}; extern PyTypeObject PyCArg_Type; extern PyCArgObject *new_CArgObject(void); diff --git a/Modules/_ctypes/libffi/configure b/Modules/_ctypes/libffi/configure index 9eded5a..9808384 100755 --- a/Modules/_ctypes/libffi/configure +++ b/Modules/_ctypes/libffi/configure @@ -3470,6 +3470,7 @@ fi TARGETDIR="unknown" case "$host" in +x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;; mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;; sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; diff --git a/Modules/_ctypes/libffi/configure.ac b/Modules/_ctypes/libffi/configure.ac index 384959e..1308034 100644 --- a/Modules/_ctypes/libffi/configure.ac +++ b/Modules/_ctypes/libffi/configure.ac @@ -21,6 +21,7 @@ AC_FUNC_MMAP_BLACKLIST TARGETDIR="unknown" case "$host" in +x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;; mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;; sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in index 3364049..7a98216 100644 --- a/Modules/_ctypes/libffi/fficonfig.py.in +++ b/Modules/_ctypes/libffi/fficonfig.py.in @@ -43,6 +43,3 @@ ffi_sources += ffi_platforms['@MKTARGET@'] ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources] ffi_cflags = '@CFLAGS@' -# I think this may no longer be needed: -if sys.platform == "openbsd3": - ffi_cflags += " -fno-stack-protector" diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index b4d8196..0942b48 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -204,12 +204,12 @@ MakeFields(PyObject *type, CFieldObject *descr, continue; } new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL); - assert(new_descr->ob_type == &CField_Type); if (new_descr == NULL) { Py_DECREF(fdescr); Py_DECREF(fieldlist); return -1; } + assert(new_descr->ob_type == &CField_Type); new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index ec55c8e..2921d53 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -1784,7 +1784,6 @@ static PyObject * PyCurses_InitScr(PyObject *self) { WINDOW *win; - PyObject *nlines, *cols; if (initialised == TRUE) { wrefresh(stdscr); @@ -1803,7 +1802,12 @@ PyCurses_InitScr(PyObject *self) /* This was moved from initcurses() because it core dumped on SGI, where they're not defined until you've called initscr() */ #define SetDictInt(string,ch) \ - PyDict_SetItemString(ModDict,string,PyInt_FromLong((long) (ch))); + do { \ + PyObject *o = PyInt_FromLong((long) (ch)); \ + if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \ + Py_DECREF(o); \ + } \ + } while (0) /* Here are some graphic symbols you can use */ SetDictInt("ACS_ULCORNER", (ACS_ULCORNER)); @@ -1872,12 +1876,8 @@ PyCurses_InitScr(PyObject *self) SetDictInt("ACS_STERLING", (ACS_STERLING)); #endif - nlines = PyInt_FromLong((long) LINES); - PyDict_SetItemString(ModDict, "LINES", nlines); - Py_DECREF(nlines); - cols = PyInt_FromLong((long) COLS); - PyDict_SetItemString(ModDict, "COLS", cols); - Py_DECREF(cols); + SetDictInt("LINES", LINES); + SetDictInt("COLS", COLS); return (PyObject *)PyCursesWindow_New(win); } @@ -2554,6 +2554,8 @@ init_curses(void) /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); + if (d == NULL) + return; ModDict = d; /* For PyCurses_InitScr to use later */ /* Add a CObject for the C API */ @@ -2667,6 +2669,10 @@ init_curses(void) if (strncmp(key_n,"KEY_F(",6)==0) { char *p1, *p2; key_n2 = malloc(strlen(key_n)+1); + if (!key_n2) { + PyErr_NoMemory(); + break; + } p1 = key_n; p2 = key_n2; while (*p1) { @@ -2679,7 +2685,7 @@ init_curses(void) *p2 = (char)0; } else key_n2 = key_n; - PyDict_SetItemString(d,key_n2,PyInt_FromLong((long) key)); + SetDictInt(key_n2,key); if (key_n2 != key_n) free(key_n2); } diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index fe30f30..e5d61c6 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -48,7 +48,7 @@ #include "Python.h" -#define VERSION "1.0.6-snapshot" +#define VERSION "1.0.6" /* -------------------------------------------------------------------- */ /* configuration */ @@ -809,7 +809,7 @@ element_findtext(ElementObject* self, PyObject* args) PyObject* text = element_get_text(item); if (text == Py_None) return PyString_FromString(""); - Py_INCREF(text); + Py_XINCREF(text); return text; } } @@ -1599,6 +1599,10 @@ LOCAL(PyObject*) treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) { if (!self->data) { + if (self->last == (ElementObject*) Py_None) { + /* ignore calls to data before the first call to start */ + Py_RETURN_NONE; + } /* store the first item as is */ Py_INCREF(data); self->data = data; } else { diff --git a/Modules/_hotshot.c b/Modules/_hotshot.c index 6d9776f..21bd383 100644 --- a/Modules/_hotshot.c +++ b/Modules/_hotshot.c @@ -313,6 +313,11 @@ unpack_string(LogReaderObject *self, PyObject **pvalue) return err; buf = (char *)malloc(len); + if (!buf) { + PyErr_NoMemory(); + return ERR_EXCEPTION; + } + for (i=0; i < len; i++) { ch = fgetc(self->logfp); buf[i] = ch; diff --git a/Modules/_sre.c b/Modules/_sre.c index 6f1e2b6..d30a350 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1166,6 +1166,9 @@ entrance: /* install new repeat context */ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep)); + /* XXX(nnorwitz): anything else we need to do on error? */ + if (!ctx->u.rep) + RETURN_FAILURE; ctx->u.rep->count = -1; ctx->u.rep->pattern = ctx->pattern; ctx->u.rep->prev = state->repeat; diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 088fbb9..4347383 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -2493,8 +2493,10 @@ Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) } v = Tktt_New(func); - v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, - (ClientData)v); + if (v) { + v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, + (ClientData)v); + } return (PyObject *) v; } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index e44b8e1..6ce6b07 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -702,6 +702,8 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) /* Special case "a[i:j] = a" -- copy b first */ int ret; v = array_slice(b, 0, n); + if (!v) + return -1; ret = array_ass_slice(a, ilow, ihigh, v); Py_DECREF(v); return ret; @@ -1573,9 +1575,8 @@ array_repr(arrayobject *a) static PyObject* array_subscr(arrayobject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i==-1 && PyErr_Occurred()) { return NULL; } @@ -1623,9 +1624,8 @@ array_subscr(arrayobject* self, PyObject* item) static int array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i==-1 && PyErr_Occurred()) return -1; if (i < 0) @@ -1706,6 +1706,8 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) if (self == av) { value = array_slice(av, 0, av->ob_size); av = (arrayobject*)value; + if (!av) + return -1; } else { Py_INCREF(value); diff --git a/Modules/bz2module.c b/Modules/bz2module.c index b0075a0..146e2ee 100644 --- a/Modules/bz2module.c +++ b/Modules/bz2module.c @@ -805,12 +805,12 @@ BZ2File_write(BZ2FileObject *self, PyObject *args) case MODE_CLOSED: PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - goto cleanup;; + goto cleanup; default: PyErr_SetString(PyExc_IOError, "file is not ready for writing"); - goto cleanup;; + goto cleanup; } self->f_softspace = 0; @@ -854,6 +854,21 @@ BZ2File_writelines(BZ2FileObject *self, PyObject *seq) int bzerror; ACQUIRE_LOCK(self); + switch (self->mode) { + case MODE_WRITE: + break; + + case MODE_CLOSED: + PyErr_SetString(PyExc_ValueError, + "I/O operation on closed file"); + goto error; + + default: + PyErr_SetString(PyExc_IOError, + "file is not ready for writing"); + goto error; + } + islist = PyList_Check(seq); if (!islist) { iter = PyObject_GetIter(seq); diff --git a/Modules/collectionsmodule.c b/Modules/collectionsmodule.c index d761dce..cb12b3a 100644 --- a/Modules/collectionsmodule.c +++ b/Modules/collectionsmodule.c @@ -211,6 +211,7 @@ deque_popleft(dequeobject *deque, PyObject *unused) PyErr_SetString(PyExc_IndexError, "pop from an empty deque"); return NULL; } + assert(deque->leftblock != NULL); item = deque->leftblock->data[deque->leftindex]; deque->leftindex++; deque->len--; @@ -226,7 +227,6 @@ deque_popleft(dequeobject *deque, PyObject *unused) } else { assert(deque->leftblock != deque->rightblock); prevblock = deque->leftblock->rightlink; - assert(deque->leftblock != NULL); PyMem_Free(deque->leftblock); assert(prevblock != NULL); prevblock->leftlink = NULL; diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 882470d..e04426d 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -2795,6 +2795,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc, unsigned long uriHash = 0; ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); + if (!id) + return XML_ERROR_NO_MEMORY; b = id->prefix->binding; if (!b) return XML_ERROR_UNBOUND_PREFIX; @@ -5340,6 +5342,8 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, return NULL; id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); + if (!id->prefix) + return NULL; if (id->prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index afe9916..a728d3d 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -815,31 +815,19 @@ static PyTypeObject mmap_object_type = { static Py_ssize_t _GetMapSize(PyObject *o) { - PyNumberMethods *nb = o->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(o); + if (PyIndex_Check(o)) { + Py_ssize_t i = PyNumber_AsSsize_t(o, PyExc_OverflowError); if (i==-1 && PyErr_Occurred()) return -1; - if (i < 0) - goto onnegoverflow; - if (i==PY_SSIZE_T_MAX) - goto onposoverflow; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "memory mapped size must be positive"); + return -1; + } return i; } - else { - PyErr_SetString(PyExc_TypeError, - "map size must be an integral value"); - return -1; - } - - onnegoverflow: - PyErr_SetString(PyExc_OverflowError, - "memory mapped size must be positive"); - return -1; - onposoverflow: - PyErr_SetString(PyExc_OverflowError, - "memory mapped size is too large (limited by C int)"); + PyErr_SetString(PyExc_TypeError, "map size must be an integral value"); return -1; } @@ -1138,6 +1126,15 @@ static struct PyMethodDef mmap_functions[] = { {NULL, NULL} /* Sentinel */ }; +static void +setint(PyObject *d, const char *name, long value) +{ + PyObject *o = PyInt_FromLong(value); + if (o && PyDict_SetItemString(d, name, o) == 0) { + Py_DECREF(o); + } +} + PyMODINIT_FUNC initmmap(void) { @@ -1150,47 +1147,40 @@ PyMODINIT_FUNC if (module == NULL) return; dict = PyModule_GetDict(module); + if (!dict) + return; mmap_module_error = PyExc_EnvironmentError; - Py_INCREF(mmap_module_error); PyDict_SetItemString(dict, "error", mmap_module_error); #ifdef PROT_EXEC - PyDict_SetItemString(dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) ); + setint(dict, "PROT_EXEC", PROT_EXEC); #endif #ifdef PROT_READ - PyDict_SetItemString(dict, "PROT_READ", PyInt_FromLong(PROT_READ) ); + setint(dict, "PROT_READ", PROT_READ); #endif #ifdef PROT_WRITE - PyDict_SetItemString(dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) ); + setint(dict, "PROT_WRITE", PROT_WRITE); #endif #ifdef MAP_SHARED - PyDict_SetItemString(dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) ); + setint(dict, "MAP_SHARED", MAP_SHARED); #endif #ifdef MAP_PRIVATE - PyDict_SetItemString(dict, "MAP_PRIVATE", - PyInt_FromLong(MAP_PRIVATE) ); + setint(dict, "MAP_PRIVATE", MAP_PRIVATE); #endif #ifdef MAP_DENYWRITE - PyDict_SetItemString(dict, "MAP_DENYWRITE", - PyInt_FromLong(MAP_DENYWRITE) ); + setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); #endif #ifdef MAP_EXECUTABLE - PyDict_SetItemString(dict, "MAP_EXECUTABLE", - PyInt_FromLong(MAP_EXECUTABLE) ); + setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); #endif #ifdef MAP_ANONYMOUS - PyDict_SetItemString(dict, "MAP_ANON", PyInt_FromLong(MAP_ANONYMOUS) ); - PyDict_SetItemString(dict, "MAP_ANONYMOUS", - PyInt_FromLong(MAP_ANONYMOUS) ); + setint(dict, "MAP_ANON", MAP_ANONYMOUS); + setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); #endif - PyDict_SetItemString(dict, "PAGESIZE", - PyInt_FromLong((long)my_getpagesize())); + setint(dict, "PAGESIZE", (long)my_getpagesize()); - PyDict_SetItemString(dict, "ACCESS_READ", - PyInt_FromLong(ACCESS_READ)); - PyDict_SetItemString(dict, "ACCESS_WRITE", - PyInt_FromLong(ACCESS_WRITE)); - PyDict_SetItemString(dict, "ACCESS_COPY", - PyInt_FromLong(ACCESS_COPY)); + setint(dict, "ACCESS_READ", ACCESS_READ); + setint(dict, "ACCESS_WRITE", ACCESS_WRITE); + setint(dict, "ACCESS_COPY", ACCESS_COPY); } diff --git a/Modules/operator.c b/Modules/operator.c index bf3def4..fa40da4 100644 --- a/Modules/operator.c +++ b/Modules/operator.c @@ -137,15 +137,7 @@ op_ipow(PyObject *s, PyObject *a) static PyObject * op_index(PyObject *s, PyObject *a) { - Py_ssize_t i; - PyObject *a1; - if (!PyArg_UnpackTuple(a,"index", 1, 1, &a1)) - return NULL; - i = PyNumber_Index(a1); - if (i == -1 && PyErr_Occurred()) - return NULL; - else - return PyInt_FromSsize_t(i); + return PyNumber_Index(a); } static PyObject* @@ -247,7 +239,7 @@ spam1o(isMappingType, spam1(is_, "is_(a, b) -- Same as a is b.") spam1(is_not, "is_not(a, b) -- Same as a is not b.") -spam2(index, __index__, "index(a) -- Same as a.__index__()") +spam2o(index, __index__, "index(a) -- Same as a.__index__()") spam2(add,__add__, "add(a, b) -- Same as a + b.") spam2(sub,__sub__, "sub(a, b) -- Same as a - b.") spam2(mul,__mul__, "mul(a, b) -- Same as a * b.") diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d968b6c..5c67be6 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1121,6 +1121,8 @@ fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) #else ival = PyInt_FromLong((long)sec); #endif + if (!ival) + return; if (_stat_float_times) { fval = PyFloat_FromDouble(sec + 1e-9*nsec); } else { diff --git a/Modules/rgbimgmodule.c b/Modules/rgbimgmodule.c index a2b91c4..0f9ee71 100644 --- a/Modules/rgbimgmodule.c +++ b/Modules/rgbimgmodule.c @@ -410,6 +410,11 @@ longimagedata(PyObject *self, PyObject *args) addlongimgtag(base, xsize, ysize); #endif verdat = (unsigned char *)malloc(xsize); + if (!verdat) { + Py_CLEAR(rv); + goto finally; + } + fseek(inf, 512, SEEK_SET); for (z = 0; z < zsize; z++) { lptr = base; @@ -431,10 +436,14 @@ longimagedata(PyObject *self, PyObject *args) copybw((Py_Int32 *) base, xsize * ysize); } finally: - free(starttab); - free(lengthtab); - free(rledat); - free(verdat); + if (starttab) + free(starttab); + if (lengthtab) + free(lengthtab); + if (rledat) + free(rledat); + if (verdat) + free(verdat); fclose(inf); return rv; } diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index bb99bde..f03b34c 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3041,17 +3041,20 @@ gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af) if ((addr_list = PyList_New(0)) == NULL) goto err; - for (pch = h->h_aliases; *pch != NULL; pch++) { - int status; - tmp = PyString_FromString(*pch); - if (tmp == NULL) - goto err; - - status = PyList_Append(name_list, tmp); - Py_DECREF(tmp); - - if (status) - goto err; + /* SF #1511317: h_aliases can be NULL */ + if (h->h_aliases) { + for (pch = h->h_aliases; *pch != NULL; pch++) { + int status; + tmp = PyString_FromString(*pch); + if (tmp == NULL) + goto err; + + status = PyList_Append(name_list, tmp); + Py_DECREF(tmp); + + if (status) + goto err; + } } for (pch = h->h_addr_list; *pch != NULL; pch++) { diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 1b0be28..a11a0b7 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1,8 +1,8 @@ /* ------------------------------------------------------------------------ - unicodedata -- Provides access to the Unicode 3.2 data base. + unicodedata -- Provides access to the Unicode 4.1 data base. - Data was extracted from the Unicode 3.2 UnicodeData.txt file. + Data was extracted from the Unicode 4.1 UnicodeData.txt file. Written by Marc-Andre Lemburg (mal@lemburg.com). Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com) @@ -1078,6 +1078,7 @@ unicodedata_lookup(PyObject* self, PyObject* args) { Py_UCS4 code; Py_UNICODE str[1]; + char errbuf[256]; char* name; int namelen; @@ -1085,11 +1086,19 @@ unicodedata_lookup(PyObject* self, PyObject* args) return NULL; if (!_getcode(self, name, namelen, &code)) { + /* XXX(nnorwitz): why are we allocating for the error msg? + Why not always use snprintf? */ char fmt[] = "undefined character name '%s'"; char *buf = PyMem_MALLOC(sizeof(fmt) + namelen); - sprintf(buf, fmt, name); + if (buf) + sprintf(buf, fmt, name); + else { + buf = errbuf; + PyOS_snprintf(buf, sizeof(errbuf), fmt, name); + } PyErr_SetString(PyExc_KeyError, buf); - PyMem_FREE(buf); + if (buf != errbuf) + PyMem_FREE(buf); return NULL; } @@ -1173,11 +1182,11 @@ PyDoc_STRVAR(unicodedata_docstring, "This module provides access to the Unicode Character Database which\n\ defines character properties for all Unicode characters. The data in\n\ this database is based on the UnicodeData.txt file version\n\ -3.2.0 which is publically available from ftp://ftp.unicode.org/.\n\ +4.1.0 which is publically available from ftp://ftp.unicode.org/.\n\ \n\ The module uses the same names and symbols as defined by the\n\ -UnicodeData File Format 3.2.0 (see\n\ -http://www.unicode.org/Public/3.2-Update/UnicodeData-3.2.0.html)."); +UnicodeData File Format 4.1.0 (see\n\ +http://www.unicode.org/Public/4.1.0/ucd/UCD.html)."); PyMODINIT_FUNC initunicodedata(void) diff --git a/Modules/zipimport.c b/Modules/zipimport.c index d59ebd8..69b2881 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -950,6 +950,9 @@ normalize_line_endings(PyObject *source) char *buf, *q, *p = PyString_AsString(source); PyObject *fixed_source; + if (!p) + return NULL; + /* one char extra for trailing \n and one for terminating \0 */ buf = (char *)PyMem_Malloc(PyString_Size(source) + 2); if (buf == NULL) { |