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:
parent
6d6bd4436a
commit
c0b2a807ff
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue