From e84c63a2ca4bf2366af96eb1a1222cf494e228c9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 27 Jul 2021 08:55:27 +0100
Subject: [PATCH] python: Don't leak fields when creating Python structs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When creating and returning a Python struct we were adding fields from
the C struct, but did not reduce the ref count on the temporary value
after it had been moved to the struct, resulting in a memory leak.
Reported-by: 朱丹 <zhudan24@huawei.com>
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1985912
---
generator/python.ml | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/generator/python.ml b/generator/python.ml
index b3d3a5579..1afd05dd6 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -173,44 +173,52 @@ and generate_python_structs () =
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, FBuffer ->
pr " value = PyBytes_FromStringAndSize (%s->%s, %s->%s_len);\n"
typ name typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, FUUID ->
pr " value = guestfs_int_py_fromstringsize (%s->%s, 32);\n"
typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, (FBytes|FUInt64) ->
pr " value = PyLong_FromUnsignedLongLong (%s->%s);\n" typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, FInt64 ->
pr " value = PyLong_FromLongLong (%s->%s);\n" typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, FUInt32 ->
pr " value = PyLong_FromUnsignedLong (%s->%s);\n" typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, FInt32 ->
pr " value = PyLong_FromLong (%s->%s);\n" typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
| name, FOptPercent ->
pr " if (%s->%s >= 0) {\n" typ name;
pr " value = PyFloat_FromDouble ((double) %s->%s);\n" typ name;
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n";
pr " }\n";
pr " else {\n";
pr " Py_INCREF (Py_None);\n";
@@ -222,6 +230,7 @@ and generate_python_structs () =
pr " if (value == NULL)\n";
pr " goto err;\n";
pr " PyDict_SetItemString (dict, \"%s\", value);\n" name;
+ pr " Py_DECREF (value);\n"
) cols;
pr " return dict;\n";
pr " err:\n";
--
2.31.1