Merged revisions 64968,64971 via svnmerge from
authorThomas Heller <theller@ctypes.org>
Tue, 15 Jul 2008 17:25:07 +0000 (17:25 +0000)
committerThomas Heller <theller@ctypes.org>
Tue, 15 Jul 2008 17:25:07 +0000 (17:25 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r64968 | thomas.heller | 2008-07-15 19:03:08 +0200 (Di, 15 Jul 2008) | 4 lines

  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.
........
  r64971 | thomas.heller | 2008-07-15 19:19:50 +0200 (Di, 15 Jul 2008) | 2 lines

  NEWS entry for #issue 3258.
........

Lib/ctypes/test/test_pep3118.py
Misc/NEWS
Modules/_ctypes/_ctypes.c

index 42a124eac960903097629981bae5a61c38173632..9a830e99d781f1e7058954606bc307aea6afb3df 100644 (file)
@@ -12,6 +12,8 @@ else:
 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)
 
@@ -84,6 +86,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
@@ -141,6 +151,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
index a6ecc0eb0206ccc4de67c0e1fa8998e8cb19da6b..010c06f4e62e4b042f7b997ff8feee02996dca2e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,6 +27,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #3258: Fixed a crash when a ctypes POINTER type to an
+  incomplete structure was created.
+
 - Issue #2683: Fix inconsistency in subprocess.Popen.communicate(): the
   argument now must be a bytes object in any case.
 
index c4ca29aacdb1e51ba2982f5ebf8300883a46b88d..48fe7725082fffc1026bfa606d3c36cef95d59da 100644 (file)
@@ -353,6 +353,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;
 
@@ -871,7 +876,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;