@@ -164,45 +164,117 @@ String _runPythonProgram(
164164
165165String getPythonError (CPython cpython) {
166166 // get error object
167- var exPtr = cpython.PyErr_GetRaisedException ();
167+ final exPtr = cpython.PyErr_GetRaisedException ();
168+ if (exPtr == nullptr) {
169+ return "Unknown Python error (no exception set)." ;
170+ }
168171
169172 // use 'traceback' module to format exception
170173 final tracebackModuleNamePtr = "traceback" .toNativeUtf8 ();
171174 var tracebackModulePtr =
172175 cpython.PyImport_ImportModule (tracebackModuleNamePtr.cast <Char >());
173- cpython. Py_DecRef (tracebackModuleNamePtr. cast () );
176+ malloc. free (tracebackModuleNamePtr);
174177
175178 if (tracebackModulePtr != nullptr) {
176179 //spDebug("Traceback module loaded");
177180
178181 final formatFuncName = "format_exception" .toNativeUtf8 ();
179182 final pFormatFunc = cpython.PyObject_GetAttrString (
180183 tracebackModulePtr, formatFuncName.cast ());
181- cpython. Py_DecRef (tracebackModuleNamePtr. cast () );
184+ malloc. free (formatFuncName );
182185
183186 if (pFormatFunc != nullptr && cpython.PyCallable_Check (pFormatFunc) != 0 ) {
184187 // call `traceback.format_exception()` method
185188 final pArgs = cpython.PyTuple_New (1 );
189+ if (pArgs == nullptr) {
190+ final fallback = cpython.PyObject_Str (exPtr);
191+ if (fallback == nullptr) {
192+ cpython.Py_DecRef (pFormatFunc);
193+ cpython.Py_DecRef (tracebackModulePtr);
194+ cpython.Py_DecRef (exPtr);
195+ return "Failed to allocate args to format Python exception." ;
196+ }
197+ final s = cpython
198+ .PyUnicode_AsUTF8 (fallback)
199+ .cast <Utf8 >()
200+ .toDartString ();
201+ cpython.Py_DecRef (fallback);
202+ cpython.Py_DecRef (pFormatFunc);
203+ cpython.Py_DecRef (tracebackModulePtr);
204+ cpython.Py_DecRef (exPtr);
205+ return s;
206+ }
207+ // Keep a reference for fallback error formatting.
208+ cpython.Py_IncRef (exPtr);
186209 cpython.PyTuple_SetItem (pArgs, 0 , exPtr);
187210
188211 // result is a list
189212 var listPtr = cpython.PyObject_CallObject (pFormatFunc, pArgs);
213+ cpython.Py_DecRef (pArgs);
214+ cpython.Py_DecRef (pFormatFunc);
215+ cpython.Py_DecRef (tracebackModulePtr);
190216
191217 // get and combine list items
192218 var exLines = [];
219+ if (listPtr == nullptr) {
220+ final fallback = cpython.PyObject_Str (exPtr);
221+ if (fallback == nullptr) {
222+ cpython.Py_DecRef (exPtr);
223+ return "Failed to format Python exception." ;
224+ }
225+ final s = cpython
226+ .PyUnicode_AsUTF8 (fallback)
227+ .cast <Utf8 >()
228+ .toDartString ();
229+ cpython.Py_DecRef (fallback);
230+ cpython.Py_DecRef (exPtr);
231+ return s;
232+ }
233+
193234 var listSize = cpython.PyList_Size (listPtr);
235+ if (listSize < 0 ) {
236+ cpython.Py_DecRef (listPtr);
237+ final fallback = cpython.PyObject_Str (exPtr);
238+ if (fallback == nullptr) {
239+ cpython.Py_DecRef (exPtr);
240+ return "Failed to format Python exception." ;
241+ }
242+ final s = cpython
243+ .PyUnicode_AsUTF8 (fallback)
244+ .cast <Utf8 >()
245+ .toDartString ();
246+ cpython.Py_DecRef (fallback);
247+ cpython.Py_DecRef (exPtr);
248+ return s;
249+ }
194250 for (var i = 0 ; i < listSize; i++ ) {
195251 var itemObj = cpython.PyList_GetItem (listPtr, i);
196252 var itemObjStr = cpython.PyObject_Str (itemObj);
197- var s =
198- cpython.PyUnicode_AsUTF8 (itemObjStr).cast <Utf8 >().toDartString ();
253+ if (itemObjStr == nullptr) {
254+ continue ;
255+ }
256+ final cStr = cpython.PyUnicode_AsUTF8 (itemObjStr);
257+ if (cStr == nullptr) {
258+ cpython.Py_DecRef (itemObjStr);
259+ continue ;
260+ }
261+ var s = cStr.cast <Utf8 >().toDartString ();
262+ cpython.Py_DecRef (itemObjStr);
199263 exLines.add (s);
200264 }
265+ cpython.Py_DecRef (listPtr);
266+ cpython.Py_DecRef (exPtr);
201267 return exLines.join ("" );
202268 } else {
269+ if (pFormatFunc != nullptr) {
270+ cpython.Py_DecRef (pFormatFunc);
271+ }
272+ cpython.Py_DecRef (tracebackModulePtr);
273+ cpython.Py_DecRef (exPtr);
203274 return "traceback.format_exception() method not found." ;
204275 }
205276 } else {
277+ cpython.Py_DecRef (exPtr);
206278 return "Error loading traceback module." ;
207279 }
208280}
0 commit comments