python: Don't leak fields when creating Python structs

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
This commit is contained in:
Richard W.M. Jones
2021-07-27 08:55:27 +01:00
parent e68a844eb4
commit e84c63a2ca

View File

@@ -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";