Issue #3258: Fix an assertion error (in debug build) and a crash (in

release build) when the format string of a pointer to an incomplete
structure is created.
This commit is contained in:
Thomas Heller 2008-07-15 17:03:08 +00:00
parent 6d6bd4436a
commit c0b2a807ff
2 changed files with 32 additions and 1 deletions

View File

@ -33,6 +33,8 @@ class memoryview(object):
def normalize(format): def normalize(format):
# Remove current endian specifier and white space from a format # Remove current endian specifier and white space from a format
# string # string
if format is None:
return ""
format = format.replace(OTHER_ENDIAN, THIS_ENDIAN) format = format.replace(OTHER_ENDIAN, THIS_ENDIAN)
return re.sub(r"\s", "", format) return re.sub(r"\s", "", format)
@ -105,6 +107,14 @@ class EmptyStruct(Structure):
class aUnion(Union): class aUnion(Union):
_fields_ = [("a", c_int)] _fields_ = [("a", c_int)]
class Incomplete(Structure):
pass
class Complete(Structure):
pass
PComplete = POINTER(Complete)
Complete._fields_ = [("a", c_int)]
################################################################ ################################################################
# #
# This table contains format strings as they look on little endian # This table contains format strings as they look on little endian
@ -162,6 +172,16 @@ native_types = [
# the pep does't support unions # the pep does't support unions
(aUnion, "B", None, aUnion), (aUnion, "B", None, aUnion),
## pointer to incomplete structure
(Incomplete, "B", None, Incomplete),
(POINTER(Incomplete), "&B", None, POINTER(Incomplete)),
# 'Complete' is a structure that starts incomplete, but is completed after the
# pointer type to it has been created.
(Complete, "T{<l:a:}", None, Complete),
# Unfortunately the pointer format string is not fixed...
(POINTER(Complete), "&B", None, POINTER(Complete)),
## other ## other
# function signatures are not implemented # function signatures are not implemented

View File

@ -386,6 +386,11 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
} }
Py_DECREF(result->tp_dict); Py_DECREF(result->tp_dict);
result->tp_dict = (PyObject *)dict; result->tp_dict = (PyObject *)dict;
dict->format = alloc_format_string(NULL, "B");
if (dict->format == NULL) {
Py_DECREF(result);
return NULL;
}
dict->paramfunc = StructUnionType_paramfunc; dict->paramfunc = StructUnionType_paramfunc;
@ -907,7 +912,13 @@ PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (proto) { if (proto) {
StgDictObject *itemdict = PyType_stgdict(proto); StgDictObject *itemdict = PyType_stgdict(proto);
assert(itemdict); assert(itemdict);
stgdict->format = alloc_format_string("&", itemdict->format); /* If itemdict->format is NULL, then this is a pointer to an
incomplete type. We create a generic format string
'pointer to bytes' in this case. XXX Better would be to
fix the format string later...
*/
stgdict->format = alloc_format_string("&",
itemdict->format ? itemdict->format : "B");
if (stgdict->format == NULL) { if (stgdict->format == NULL) {
Py_DECREF((PyObject *)stgdict); Py_DECREF((PyObject *)stgdict);
return NULL; return NULL;