BUG/MINOR: spoa/python: Cleanup references for failed Module Addobject operations
authorGilchrist Dadaglo <dadaglo@amazon.com>
Tue, 8 Dec 2020 14:37:11 +0000 (14:37 +0000)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 14 Dec 2020 10:49:38 +0000 (11:49 +0100)
As per https://docs.python.org/3/c-api/module.html#c.PyModule_AddObject,
references are stolen by the function only for success. We must do
cleanup manually if there is a failure

This patch must be backported as far as 2.0.

(cherry picked from commit 132d8f61e9440b9254069ca2c4bcff67df29bb6f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 2efe413b82d4fd35178ecb96e7b5f4336deb4cc5)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e795c1f99bb9c99369aac2a97e2447a215176089)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

contrib/spoa_server/ps_python.c

index 30dba89..3ce85c8 100644 (file)
@@ -321,8 +321,19 @@ static int ps_python_start_worker(struct worker *w)
        }
 
        spoa_error = PyErr_NewException("spoa.error", NULL, NULL);
+        /* PyModule_AddObject will steal the reference to spoa_error
+        * in case of success only
+        * We need to increment the counters to continue using it
+        * but cleanup in case of failure
+        */
        Py_INCREF(spoa_error);
-       PyModule_AddObject(m, "error", spoa_error);
+       ret = PyModule_AddObject(m, "error", spoa_error);
+       if (ret == -1) {
+               Py_DECREF(m);
+               Py_DECREF(spoa_error);
+               PyErr_Print();
+               return 0;
+       }
 
 
        value = PyLong_FromLong(SPOE_SCOPE_PROC);
@@ -333,54 +344,68 @@ static int ps_python_start_worker(struct worker *w)
 
        ret = PyModule_AddObject(m, "scope_proc", value);
        if (ret == -1) {
+               Py_DECREF(m);
+               Py_DECREF(value);
                PyErr_Print();
                return 0;
        }
 
        value = PyLong_FromLong(SPOE_SCOPE_SESS);
        if (value == NULL) {
+               Py_DECREF(m);
                PyErr_Print();
                return 0;
        }
 
        ret = PyModule_AddObject(m, "scope_sess", value);
        if (ret == -1) {
+               Py_DECREF(m);
+               Py_DECREF(value);
                PyErr_Print();
                return 0;
        }
 
        value = PyLong_FromLong(SPOE_SCOPE_TXN);
        if (value == NULL) {
+               Py_DECREF(m);
                PyErr_Print();
                return 0;
        }
 
        ret = PyModule_AddObject(m, "scope_txn", value);
        if (ret == -1) {
+               Py_DECREF(m);
+               Py_DECREF(value);
                PyErr_Print();
                return 0;
        }
 
        value = PyLong_FromLong(SPOE_SCOPE_REQ);
        if (value == NULL) {
+               Py_DECREF(m);
                PyErr_Print();
                return 0;
        }
 
        ret = PyModule_AddObject(m, "scope_req", value);
        if (ret == -1) {
+               Py_DECREF(m);
+               Py_DECREF(value);
                PyErr_Print();
                return 0;
        }
 
        value = PyLong_FromLong(SPOE_SCOPE_RES);
        if (value == NULL) {
+               Py_DECREF(m);
                PyErr_Print();
                return 0;
        }
 
        ret = PyModule_AddObject(m, "scope_res", value);
        if (ret == -1) {
+               Py_DECREF(m);
+               Py_DECREF(value);
                PyErr_Print();
                return 0;
        }