summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Heller <theller@ctypes.org>2008-07-15 17:03:08 (GMT)
committerThomas Heller <theller@ctypes.org>2008-07-15 17:03:08 (GMT)
commitc0b2a807ff9ce7d2c0c83ee808678eb841aa9778 (patch)
tree5ecf61706a8a77f736e65e36edb79922f428b9c5
parent6d6bd4436a08e557cc7cb52d6ae26f8662063f50 (diff)
downloadcpython-c0b2a807ff9ce7d2c0c83ee808678eb841aa9778.zip
cpython-c0b2a807ff9ce7d2c0c83ee808678eb841aa9778.tar.gz
cpython-c0b2a807ff9ce7d2c0c83ee808678eb841aa9778.tar.bz2
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.
-rw-r--r--Lib/ctypes/test/test_pep3118.py20
-rw-r--r--Modules/_ctypes/_ctypes.c13
2 files changed, 32 insertions, 1 deletions
diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/ctypes/test/test_pep3118.py
index cf628d8..119b0ad 100644
--- a/Lib/ctypes/test/test_pep3118.py
+++ b/Lib/ctypes/test/test_pep3118.py
@@ -33,6 +33,8 @@ class memoryview(object):
def normalize(format):
# Remove current endian specifier and white space from a format
# string
+ if format is None:
+ return ""
format = format.replace(OTHER_ENDIAN, THIS_ENDIAN)
return re.sub(r"\s", "", format)
@@ -105,6 +107,14 @@ class EmptyStruct(Structure):
class aUnion(Union):
_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
@@ -162,6 +172,16 @@ native_types = [
# the pep does't support unions
(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
# function signatures are not implemented
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 73542c7..9c7355a 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -386,6 +386,11 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
}
Py_DECREF(result->tp_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;
@@ -907,7 +912,13 @@ PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (proto) {
StgDictObject *itemdict = PyType_stgdict(proto);
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) {
Py_DECREF((PyObject *)stgdict);
return NULL;