mp.c: Release the `GFN' object through channels on error.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 13 Nov 2019 02:50:55 +0000 (02:50 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 22 Nov 2019 22:18:11 +0000 (22:18 +0000)
If the given element turns out not to actually generate a normal basis
then we have to give up constructing the `GFN' object and raise an
exception.  In turns out that debug versions of Python get really
unhappy if you try to free objects which still have nonzero reference
counts, so:

  * use `Py_DECREF' to free the object on error; and

  * mark the object (by leaving `p' null) so that we don't actually
    free the conversion matrices if they're weren't set up.

mp.c

diff --git a/mp.c b/mp.c
index bad566d..54f1926 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -2369,8 +2369,9 @@ static PyObject *gfn_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
                                   convgf, &p, convgf, &beta))
     goto end;
   gg = PyObject_New(gfn_pyobj, ty);
+  gg->p = 0;
   if (gfn_create(p, beta, &gg->ntop, &gg->pton)) {
-    FREEOBJ(gg);
+    Py_DECREF(gg);
     gg = 0;
     VALERR("can't invert transformation matrix");
   }
@@ -2410,8 +2411,10 @@ XFORMOP(ntop, NTOP)
 
 static void gfn_pydealloc(PyObject *me)
 {
-  gfn_destroy(GFN_PTON(me));
-  gfn_destroy(GFN_NTOP(me));
+  if (GFN_P(me)) {
+    gfn_destroy(GFN_PTON(me));
+    gfn_destroy(GFN_NTOP(me));
+  }
   FREEOBJ(me);
 }