]> git.ipfire.org Git - pakfire.git/commitdiff
python: Prevent early deallocation of logging callback
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 21 Sep 2021 16:14:25 +0000 (16:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 21 Sep 2021 16:14:25 +0000 (16:14 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c

index f6784db9e50953e7d88ee425a20710da371aa62a..9c4401d3ee65ab1070fb89afdb9eb41bb76c1914 100644 (file)
@@ -108,6 +108,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                "enable_ccache", "enable_snapshot", NULL };
        const char* path = NULL;
        const char* arch = NULL;
+       PyObject* logger = NULL;
        const char* conf = NULL;
        int offline = 0;
        int build = 0;
@@ -115,12 +116,12 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
        int enable_snapshot = 1;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOpzppp", kwlist,
-                       &path, &arch, &self->logger, &offline, &conf, &build,
+                       &path, &arch, &logger, &offline, &conf, &build,
                        &enable_ccache, &enable_snapshot))
                return -1;
 
        // Check if logger is callable
-       if (self->logger && !PyCallable_Check(self->logger)) {
+       if (logger && !PyCallable_Check(logger)) {
                PyErr_SetString(PyExc_TypeError, "logger must be callable\n");
                return -1;
        }
@@ -144,7 +145,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
 
        // Create a new Pakfire instance
        int r = pakfire_create(&self->pakfire, path, arch, conf, flags,
-                       (self->logger) ? Pakfire_logging_callback : NULL, self->logger);
+                       (logger) ? Pakfire_logging_callback : NULL, logger);
        if (r) {
                switch (errno) {
                        // Invalid architecture or path
@@ -160,7 +161,11 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                return -1;
     }
 
-       Py_XINCREF(self->logger);
+       // Store a reference to the logger
+       if (logger) {
+               self->logger = logger;
+               Py_INCREF(self->logger);
+       }
 
        return 0;
 }
@@ -169,8 +174,18 @@ static void Pakfire_dealloc(PakfireObject* self) {
        if (self->pakfire)
                pakfire_unref(self->pakfire);
 
+#if 0
+       /*
+               It might happen, that the Pakfire python object is deallocated but the
+               actual struct pakfire object isn't yet. However, it might still happen
+               that the logging function is called which will try to call the logging
+               callback which has already been deallocated.
+
+               TODO This has to move into struct pakfire or something similar.
+       */
        if (self->logger)
                Py_DECREF(self->logger);
+#endif
 
        Py_TYPE(self)->tp_free((PyObject *)self);
 }