Package: python-gtk2 Version: 2.6.3-2 Severity: normal Tags: patch There's a typo in codegen/argtypes.py that causes an incorrect type mapping on 64 bit architectures; it looks like some new lines were pasted in between the maps for guint and guint32, which made the value of the local 'args' variable incorrect.
This is causing a bug that makes quodlibet unusable on 64 bit architectures if the event time exceeds 2**31; it also could potentially cause many other bugs. Attached is a patch to use PyGTK 2.8's argtypes.py, which defines it correctly. -- Joe Wreschnig <[EMAIL PROTECTED]>
--- pygtk-2.6.3.orig/codegen/argtypes.py +++ pygtk-2.6.3/codegen/argtypes.py @@ -175,16 +175,36 @@ info.codeafter.append(' return PyInt_FromLong(ret);') class UIntArg(ArgType): + dflt = (' if (py_%(name)s) {\n' + ' if (PyLong_Check(py_%(name)s))\n' + ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n' + ' else if (PyInt_Check(py_%(name)s))\n' + ' %(name)s = PyInt_AsLong(py_%(name)s);\n' + ' else\n' + ' PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n' + ' if (PyErr_Occurred())\n' + ' return NULL;\n' + ' }\n') + before = (' if (PyLong_Check(py_%(name)s))\n' + ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n' + ' else if (PyInt_Check(py_%(name)s))\n' + ' %(name)s = PyInt_AsLong(py_%(name)s);\n' + ' else\n' + ' PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n' + ' if (PyErr_Occurred())\n' + ' return NULL;\n') def write_param(self, ptype, pname, pdflt, pnull, info): - if pdflt: - info.varlist.add(ptype, pname + ' = ' + pdflt) - else: - info.varlist.add(ptype, pname) - info.arglist.append(pname) - info.add_parselist('I', ['&' + pname], [pname]) + if not pdflt: + pdflt = '0'; + + info.varlist.add(ptype, pname + ' = ' + pdflt) + info.codebefore.append(self.dflt % {'name':pname}) + info.varlist.add('PyObject', "*py_" + pname + ' = NULL') + info.arglist.append(pname) + info.add_parselist('O', ['&py_' + pname], [pname]) def write_return(self, ptype, ownsreturn, info): info.varlist.add(ptype, 'ret') - info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n') + info.codeafter.append(' return PyLong_FromUnsignedLong(ret);') class SizeArg(ArgType): @@ -264,22 +284,30 @@ info.codeafter.append(' return PyInt_FromLong(ret);') class ULongArg(ArgType): - dflt = ' if (py_%(name)s)\n' \ - ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n' - before = ' %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n' def write_param(self, ptype, pname, pdflt, pnull, info): - if pdflt: - info.varlist.add('gulong', pname + ' = ' + pdflt) - info.codebefore.append(self.dflt % {'name':pname}) - else: - info.varlist.add('gulong', pname) - info.codebefore.append(self.before % {'name':pname}) - info.varlist.add('PyObject', "*py_" + pname + ' = NULL') - info.arglist.append(pname) - info.add_parselist('O!', ['&PyLong_Type', '&py_' + pname], [pname]) + if pdflt: + info.varlist.add('unsigned long', pname + ' = ' + pdflt) + else: + info.varlist.add('unsigned long', pname) + info.arglist.append(pname) + info.add_parselist('k', ['&' + pname], [pname]) def write_return(self, ptype, ownsreturn, info): - info.varlist.add('gulong', 'ret') - info.codeafter.append(' return PyLong_FromUnsignedLong(ret);') + info.varlist.add(ptype, 'ret') + info.codeafter.append(' return PyLong_FromUnsignedLong(ret);\n') + +class UInt32Arg(ULongArg): + def write_param(self, ptype, pname, pdflt, pnull, info): + ULongArg.write_param(self, ptype, pname, pdflt, pnull, info) + ## if sizeof(unsigned long) > sizeof(unsigned int), we need to + ## check the value is within guint32 range + if struct.calcsize('L') > struct.calcsize('I'): + info.codebefore.append(( + ' if (%(pname)s > G_MAXUINT32) {\n' + ' PyErr_SetString(PyExc_ValueError,\n' + ' "Value out of range in conversion of"\n' + ' " %(pname)s parameter to unsigned 32 bit integer");\n' + ' return NULL;\n' + ' }\n') % vars()) class Int64Arg(ArgType): def write_param(self, ptype, pname, pdflt, pnull, info): @@ -901,13 +929,7 @@ arg = TimeTArg() matcher.register('time_t', arg) -# If the system maxint is smaller than unsigned int, we need to use -# Long objects with PyLong_AsUnsignedLong -if sys.maxint >= (1L << 32): - matcher.register('guint32', arg) -else: - arg = ULongArg() - matcher.register('guint32', arg) +matcher.register('guint32', UInt32Arg()) arg = ULongArg() matcher.register('gulong', arg)
signature.asc
Description: This is a digitally signed message part