diff options
author | Paul Pogonyshev <pogonyshev@gmx.net> | 2009-01-29 19:39:53 +0000 |
---|---|---|
committer | Paul Pogonyshev <paulp@src.gnome.org> | 2009-01-29 19:39:53 +0000 |
commit | 432122fd0e62e0bfc46e49581fc4dceeb11db717 (patch) | |
tree | c69dae1d95c62e82048325d5816530296db2816e /gio/ginputstream.override | |
parent | 90ca9dac132dc396e0f064ff01556740ca09e2b0 (diff) | |
download | pygobject-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.override | 100 |
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, ¬ify->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 |