Hi there,
Me and Johan noticed that it's very easy to crash PyGTK by calling
emit() in your code without checking how many parameters you should
send in. To test, for instance, use:
>>> import gtk
>>> c = gtk.GtkCList()
>>> c.emit("select_row")
Segmentation fault
select_row expects 3 parameters, but it got none. We hacked
gtkmodule.c to check for this (and added an assertion to the actual
argument processing method), so we get:
>>> c.emit("select_row")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/Stoq//lib/python2.1/site-packages/gtk.py", line 169, in emit
return _gtk.gtk_signal_emitv_by_name(self._o,signal,params)
TypeError: not enought arguments supplied to emit, expected 3, found 0
The patch is attached, and in
http://bugzilla.gnome.org/show_bug.cgi?id=96907. James?
Take care,
--
Christian Reis, Senior Engineer, Async Open Source, Brazil.
http://async.com.br/~kiko/ | [+55 16] 261 2331 | NMFL
Index: gtkmodule.c
===================================================================
RCS file: /cvs/gnome/gnome-python/pygtk/Attic/gtkmodule.c,v
retrieving revision 1.53.2.20
diff -u -r1.53.2.20 gtkmodule.c
--- gtkmodule.c 19 Aug 2002 01:41:29 -0000 1.53.2.20
+++ gtkmodule.c 26 Oct 2002 15:25:57 -0000
@@ -3360,21 +3360,26 @@
PyObject *item;
int i;
if (!PySequence_Check(seq))
- return -1;
+ return 1;
for (i = 0; i < nparams; i++) {
item = PySequence_GetItem(seq, i);
+ if (item==NULL) {
+ PyErr_SetString(PyExc_AssertionError,
+ "Tried to grab an argument that didn't exist!");
+ return 1;
+ }
Py_DECREF(item);
if (GtkArg_FromPyObject(&args[i], item)) {
gchar buf[512];
if (args[i].name == NULL)
g_snprintf(buf, 511, "argument %d: expected %s, %s found", i+1,
- gtk_type_name(args[i].type), item->ob_type->tp_name);
+ gtk_type_name(args[i].type), item->ob_type->tp_name);
else
g_snprintf(buf, 511, "argument %s: expected %s, %s found",
args[i].name, gtk_type_name(args[i].type),
item->ob_type->tp_name);
PyErr_SetString(PyExc_TypeError, buf);
- return -1;
+ return 1;
}
}
return 0;
@@ -3808,7 +3813,7 @@
}
static PyObject *_wrap_gtk_signal_emitv_by_name(PyObject *self, PyObject *args) {
- guint signal_id, i, nparams;
+ guint signal_id, i, nparams, npy_params;
GtkSignalQuery *query;
GtkArg *params;
PyObject *obj, *py_params;
@@ -3830,6 +3835,13 @@
query = gtk_signal_query(signal_id);
params = g_new(GtkArg, query->nparams + 1);
nparams = query->nparams;
+ npy_params = PySequence_Size(py_params);
+ if (npy_params != nparams) {
+ gchar err[100];
+ g_snprintf(err, 100, "not enought arguments supplied to emit, expected %d, found
+%d", nparams, npy_params);
+ PyErr_SetString(PyExc_TypeError, err);
+ return NULL;
+ }
for (i = 0; i < nparams; i++) {
params[i].type = query->params[i];
params[i].name = NULL;