changeset 178:c8ba67c8b1f5

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.
author Franz Glasner <fzglas.hg@dom66.de>
date Sun, 09 Mar 2025 02:47:17 +0100
parents 5df3b8e28ee2
children ed4b40bc7b69
files uwsginl/files/patch-plugins_python_pyutils.c
diffstat 1 files changed, 81 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /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;
+