summaryrefslogtreecommitdiffstats
path: root/gio/ginputstream.override
diff options
context:
space:
mode:
authorPaul Pogonyshev <pogonyshev@gmx.net>2009-01-29 19:39:53 +0000
committerPaul Pogonyshev <paulp@src.gnome.org>2009-01-29 19:39:53 +0000
commit432122fd0e62e0bfc46e49581fc4dceeb11db717 (patch)
treec69dae1d95c62e82048325d5816530296db2816e /gio/ginputstream.override
parent90ca9dac132dc396e0f064ff01556740ca09e2b0 (diff)
downloadpygobject-432122fd0e62e0bfc46e49581fc4dceeb11db717.tar.gz
pygobject-432122fd0e62e0bfc46e49581fc4dceeb11db717.tar.xz
pygobject-432122fd0e62e0bfc46e49581fc4dceeb11db717.zip
Bug 567792 – gio.InputStream.read_async can cause memory corruption
2009-01-29 Paul Pogonyshev <pogonyshev@gmx.net> Bug 567792 – gio.InputStream.read_async can cause memory corruption * gio/gio.override (py_decref_callback): Remove (unused now). (pygio_notify_allocate_buffer, pygio_notify_attach_to_result) (pygio_notify_get_attached): New functions. (async_result_callback_marshal): Attach to the result object if asked and then don't free self. Fix reference leak (spotted by Gustavo). * gio/ginputstream.override (async_result_callback_marshal_read): Remove. Use new attachment functionality in async_result_callback_marshal() instead. (_wrap_g_input_stream_read_async): Use the new functions (also those mentioned in the cleanup log below). (_wrap_g_input_stream_read_finish): Use the new functions. svn path=/trunk/; revision=999
Diffstat (limited to 'gio/ginputstream.override')
-rw-r--r--gio/ginputstream.override100
1 files changed, 21 insertions, 79 deletions
diff --git a/gio/ginputstream.override b/gio/ginputstream.override
index 43cd22f..ae5b3a2 100644
--- a/gio/ginputstream.override
+++ b/gio/ginputstream.override
@@ -23,55 +23,6 @@
headers
#define BUFSIZE 8192
-typedef struct {
- PyObject *callback;
- PyObject *data;
- guchar *buffer;
-} PyGIONotifyRead;
-
-static void
-async_result_callback_marshal_read(GObject *source_object,
- GAsyncResult *result,
- PyGIONotifyRead *notify)
-{
- PyObject *ret;
- PyGILState_STATE state;
- static GQuark quark = 0;
-
- state = pyg_gil_state_ensure();
-
- /* buffer is only used by read_async */
- if (notify->buffer) {
- if (!quark)
- quark = g_quark_from_string("pygio::buffer");
- g_object_set_qdata_full(G_OBJECT(result), quark,
- notify->buffer, py_decref_callback);
- }
-
- if (notify->data)
- ret = PyEval_CallFunction(notify->callback, "(OOO)",
- pygobject_new(source_object),
- pygobject_new((GObject *)result),
- notify->data);
- else
- ret = PyObject_CallFunction(notify->callback, "(OO)",
- pygobject_new(source_object),
- pygobject_new((GObject *)result));
-
- if (ret == NULL)
- {
- PyErr_Print();
- PyErr_Clear();
- }
-
- Py_XDECREF(ret);
-
- Py_DECREF(notify->callback);
- Py_XDECREF(notify->data);
- g_slice_free(PyGIONotifyRead, notify);
-
- pyg_gil_state_release(state);
-}
%%
override g_input_stream_read kwargs
static PyObject *
@@ -224,9 +175,9 @@ _wrap_g_input_stream_read_async(PyGObject *self,
int io_priority = G_PRIORITY_DEFAULT;
PyGObject *pycancellable = NULL;
GCancellable *cancellable;
- PyGIONotifyRead *notify;
+ PyGIONotify *notify;
- notify = g_slice_new0(PyGIONotifyRead);
+ notify = pygio_notify_new();
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"lO|iOO:InputStream.read_async",
@@ -236,37 +187,34 @@ _wrap_g_input_stream_read_async(PyGObject *self,
&io_priority,
&pycancellable,
&notify->data))
- {
- g_slice_free(PyGIONotifyRead, notify);
- return NULL;
- }
+ goto error;
- if (!PyCallable_Check(notify->callback))
- {
- PyErr_SetString(PyExc_TypeError, "callback argument not callable");
- g_slice_free(PyGIONotifyRead, notify);
- return NULL;
- }
- Py_INCREF(notify->callback);
- Py_XINCREF(notify->data);
+ if (!pygio_notify_callback_is_valid(notify))
+ goto error;
if (!pygio_check_cancellable(pycancellable, &cancellable))
- return NULL;
+ goto error;
- notify->buffer = g_malloc(count);
- if (notify->buffer == NULL)
- return NULL;
+ if (!pygio_notify_allocate_buffer(notify, count))
+ goto error;
+
+ pygio_notify_reference_callback(notify);
+ pygio_notify_attach_to_result(notify);
g_input_stream_read_async(G_INPUT_STREAM(self->obj),
notify->buffer,
- count,
+ notify->buffer_size,
io_priority,
cancellable,
- (GAsyncReadyCallback)async_result_callback_marshal_read,
+ (GAsyncReadyCallback) async_result_callback_marshal,
notify);
Py_INCREF(Py_None);
return Py_None;
+
+ error:
+ pygio_notify_free(notify);
+ return NULL;
}
%%
override g_input_stream_read_finish kwargs
@@ -278,31 +226,25 @@ _wrap_g_input_stream_read_finish(PyGObject *self,
static char *kwlist[] = { "result", NULL };
PyGObject *result;
GError *error = NULL;
- static GQuark quark = 0;
- gchar *buffer;
Py_ssize_t bytesread;
-
- if (!quark)
- quark = g_quark_from_string("pygio::buffer");
+ PyGIONotify *notify;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"O!:GInputStream.read_finish",
kwlist, &PyGAsyncResult_Type, &result))
return NULL;
-
bytesread = g_input_stream_read_finish(G_INPUT_STREAM(self->obj),
G_ASYNC_RESULT(result->obj), &error);
if (pyg_error_check(&error))
return NULL;
- if (bytesread == 0) {
+ if (bytesread == 0)
return PyString_FromString("");
- }
- buffer = g_object_get_qdata(G_OBJECT(result->obj), quark);
- return PyString_FromStringAndSize(buffer, bytesread);
+ notify = pygio_notify_get_attached(result);
+ return PyString_FromStringAndSize(notify->buffer, bytesread);
}
%%
override g_input_stream_close_async kwargs