# HG changeset patch # User Franz Glasner # Date 1741484837 -3600 # Node ID c8ba67c8b1f5e5b5e509bb44c1f5986cdcfba24d # Parent 5df3b8e28ee2293e7374d9fded5763a7773d7c82 FIX: Refcount bug in the Python plugin -- introduced in Git commit fe44f47. Previously PyList_GetItem() and PyTuple_GetItem() were used: these functions return borrowed referenced. Now -- with PySequence_GetItem() new references are returned: they need to be decrefed. diff -r 5df3b8e28ee2 -r c8ba67c8b1f5 uwsginl/files/patch-plugins_python_pyutils.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uwsginl/files/patch-plugins_python_pyutils.c Sun Mar 09 02:47:17 2025 +0100 @@ -0,0 +1,81 @@ +--- plugins/python/pyutils.c.orig 2024-10-26 09:59:26 UTC ++++ plugins/python/pyutils.c +@@ -58,6 +58,12 @@ struct uwsgi_buffer *uwsgi_python_backtrace(struct wsg + PyObject *traceback = NULL; + struct uwsgi_buffer *ub = NULL; + ++ PyObject *t = NULL; ++ PyObject *tb_filename = NULL; ++ PyObject *tb_lineno = NULL; ++ PyObject *tb_function = NULL; ++ PyObject *tb_text = NULL; ++ + PyErr_Fetch(&type, &value, &traceback); + PyErr_NormalizeException(&type, &value, &traceback); + +@@ -84,11 +90,16 @@ struct uwsgi_buffer *uwsgi_python_backtrace(struct wsg + Py_ssize_t i; + // we have to build a uwsgi array with 5 items (4 are taken from the python tb) + for(i=0;i< PySequence_Size(result);i++) { +- PyObject *t = PySequence_GetItem(result, i); +- PyObject *tb_filename = PySequence_GetItem(t, 0); +- PyObject *tb_lineno = PySequence_GetItem(t, 1); +- PyObject *tb_function = PySequence_GetItem(t, 2); +- PyObject *tb_text = PySequence_GetItem(t, 3); ++ // ++ // fag: the previous concrete implementations PyList_GetItem() ++ // and PyTuple_GetItem() returned borrowed references! ++ // Now decref is needed. ++ // ++ t = PySequence_GetItem(result, i); ++ tb_filename = PySequence_GetItem(t, 0); ++ tb_lineno = PySequence_GetItem(t, 1); ++ tb_function = PySequence_GetItem(t, 2); ++ tb_text = PySequence_GetItem(t, 3); + + int64_t line_no = PyInt_AsLong(tb_lineno); + #ifdef PYTHREE +@@ -137,7 +148,7 @@ struct uwsgi_buffer *uwsgi_python_backtrace(struct wsg + else { + if (uwsgi_buffer_u16le(ub, 0)) { goto end0; } + } +- ++ + #else + // filename + if (uwsgi_buffer_u16le(ub, PyString_Size(tb_filename))) goto end0; +@@ -158,13 +169,24 @@ struct uwsgi_buffer *uwsgi_python_backtrace(struct wsg + // custom (unused) + if (uwsgi_buffer_u16le(ub, 0)) goto end0; + if (uwsgi_buffer_append(ub, "", 0)) goto end0; +- ++ ++ Py_CLEAR(tb_text); ++ Py_CLEAR(tb_function); ++ Py_CLEAR(tb_lineno); ++ Py_CLEAR(tb_filename); ++ Py_CLEAR(t); + } + + Py_DECREF(result); + goto end; + + end0: ++ Py_XDECREF(tb_text); ++ Py_XDECREF(tb_function); ++ Py_XDECREF(tb_lineno); ++ Py_XDECREF(tb_filename); ++ Py_XDECREF(t); ++ + Py_DECREF(result); + uwsgi_buffer_destroy(ub); + ub = NULL; +@@ -241,7 +263,7 @@ struct uwsgi_buffer *uwsgi_python_exception_repr(struc + } + + struct uwsgi_buffer *uwsgi_python_exception_repr(struct wsgi_request *wsgi_req) { +- ++ + struct uwsgi_buffer *ub_class = uwsgi_python_exception_class(wsgi_req); + if (!ub_class) return NULL; +