Update of /cvsroot/ctypes/ctypes/source
In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv8674
Modified Files:
_ctypes.c
Log Message:
Change the way unique_key calculates the keys into the b_objects
array. The previous way was broken for arrays or structures having
more than 256 components, which led to strange errors.
Index: _ctypes.c
===================================================================
RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v
retrieving revision 1.326
retrieving revision 1.327
diff -C2 -d -r1.326 -r1.327
*** _ctypes.c 18 May 2006 09:45:53 -0000 1.326
--- _ctypes.c 19 May 2006 15:41:49 -0000 1.327
***************
*** 1814,1834 ****
static PyObject *
! unique_key(CDataObject *target, int index)
{
! char string[256]; /* XXX is that enough? */
char *cp = string;
! *cp++ = index + '0';
while (target->b_base) {
! *cp++ = target->b_index + '0';
target = target->b_base;
}
return PyString_FromStringAndSize(string, cp-string);
}
! /* Keep a reference to 'keep' in the 'target', at index 'index' */
/*
! * KeepRef travels the target's b_base pointer down to the root,
! * building a sequence of indexes during the path. The indexes, which are a
! * couple of small integers, are used to build a byte string usable as
! * key int the root object's _objects dict.
*
* Note: This function steals a refcount of the third argument, even if it
--- 1814,1853 ----
static PyObject *
! unique_key(CDataObject *target, Py_ssize_t index)
{
! char string[256];
char *cp = string;
! size_t bytes_left;
!
! assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
! cp += sprintf(cp, "%x", index);
while (target->b_base) {
! bytes_left = sizeof(string) - (cp - string) - 1;
! /* Hex format needs 2 characters per byte */
! if (bytes_left < sizeof(Py_ssize_t) * 2) {
! PyErr_SetString(PyExc_ValueError,
! "ctypes object structure too deep");
! return NULL;
! }
! cp += sprintf(cp, ":%x", index);
target = target->b_base;
}
return PyString_FromStringAndSize(string, cp-string);
}
!
/*
! * Keep a reference to 'keep' in the 'target', at index 'index'.
! *
! * If 'keep' is None, do nothing.
! *
! * Otherwise create a dictionary (if it does not yet exist) id the root
! * objects 'b_objects' item, which will store the 'keep' object under a unique
! * key.
! *
! * The unique_key helper travels the target's b_base pointer down to the root,
! * building a string containing hex-formatted indexes found during traversal,
! * separated by colons.
! *
! * The index tuple is used as a key into the root object's b_objects dict.
*
* Note: This function steals a refcount of the third argument, even if it
***************
*** 1854,1857 ****
--- 1873,1880 ----
}
key = unique_key(target, index);
+ if (key == NULL) {
+ Py_DECREF(keep);
+ return -1;
+ }
result = PyDict_SetItem(ob->b_objects, key, keep);
Py_DECREF(key);
|