From 6d460d51fe6dd88d2d217c1a1e007604a5fd239e Mon Sep 17 00:00:00 2001 From: Martin Molinero Date: Fri, 20 Jul 2018 15:58:10 -0300 Subject: [PATCH] Fixing memory leaks in the conversion of some types --- src/runtime/converter.cs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 481ee73c2..ad8a8af02 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -1,8 +1,6 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Globalization; -using System.Reflection; using System.Runtime.InteropServices; using System.Security; @@ -55,13 +53,13 @@ static Converter() IntPtr dateTimeMod = Runtime.PyImport_ImportModule("datetime"); if (dateTimeMod == null) throw new PythonException(); - + decimalCtor = Runtime.PyObject_GetAttrString(decimalMod, "Decimal"); if (decimalCtor == null) throw new PythonException(); - + dateTimeCtor = Runtime.PyObject_GetAttrString(dateTimeMod, "datetime"); if (dateTimeCtor == null) throw new PythonException(); - + timeSpanCtor = Runtime.PyObject_GetAttrString(dateTimeMod, "timedelta"); if (timeSpanCtor == null) throw new PythonException(); @@ -224,7 +222,10 @@ internal static IntPtr ToPython(object value, Type type) IntPtr timeSpanArgs = Runtime.PyTuple_New(1); Runtime.PyTuple_SetItem(timeSpanArgs, 0, Runtime.PyFloat_FromDouble(timespan.TotalDays)); - return Runtime.PyObject_CallObject(timeSpanCtor, timeSpanArgs); + var returnTimeSpan = Runtime.PyObject_CallObject(timeSpanCtor, timeSpanArgs); + // clean up + Runtime.XDecref(timeSpanArgs); + return returnTimeSpan; } return CLRObject.GetInstHandle(value, type); @@ -283,12 +284,14 @@ internal static IntPtr ToPython(object value, Type type) IntPtr d2p = Runtime.PyString_FromString(d2s); IntPtr decimalArgs = Runtime.PyTuple_New(1); Runtime.PyTuple_SetItem(decimalArgs, 0, d2p); - - return Runtime.PyObject_CallObject(decimalCtor, decimalArgs); + var returnDecimal = Runtime.PyObject_CallObject(decimalCtor, decimalArgs); + // clean up + Runtime.XDecref(decimalArgs); + return returnDecimal; case TypeCode.DateTime: var datetime = (DateTime)value; - + IntPtr dateTimeArgs = Runtime.PyTuple_New(8); Runtime.PyTuple_SetItem(dateTimeArgs, 0, Runtime.PyInt_FromInt32(datetime.Year)); Runtime.PyTuple_SetItem(dateTimeArgs, 1, Runtime.PyInt_FromInt32(datetime.Month)); @@ -298,8 +301,10 @@ internal static IntPtr ToPython(object value, Type type) Runtime.PyTuple_SetItem(dateTimeArgs, 5, Runtime.PyInt_FromInt32(datetime.Second)); Runtime.PyTuple_SetItem(dateTimeArgs, 6, Runtime.PyInt_FromInt32(datetime.Millisecond)); Runtime.PyTuple_SetItem(dateTimeArgs, 7, TzInfo(datetime.Kind)); - - return Runtime.PyObject_CallObject(dateTimeCtor, dateTimeArgs); + var returnDateTime = Runtime.PyObject_CallObject(dateTimeCtor, dateTimeArgs); + // clean up + Runtime.XDecref(dateTimeArgs); + return returnDateTime; default: if (value is IEnumerable) @@ -329,7 +334,9 @@ private static IntPtr TzInfo(DateTimeKind kind) IntPtr tzInfoArgs = Runtime.PyTuple_New(2); Runtime.PyTuple_SetItem(tzInfoArgs, 0, Runtime.PyFloat_FromDouble(offset.Hours)); Runtime.PyTuple_SetItem(tzInfoArgs, 1, Runtime.PyFloat_FromDouble(offset.Minutes)); - return Runtime.PyObject_CallObject(tzInfoCtor, tzInfoArgs); + var returnValue = Runtime.PyObject_CallObject(tzInfoCtor, tzInfoArgs); + Runtime.XDecref(tzInfoArgs); + return returnValue; }