From 6bb6f42169bcaccda9ba98a394fa937451a38657 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 9 Feb 2020 15:26:13 +0000 Subject: [PATCH] Clearer object ownership in psyco_conn_curs Make sure the object is assigned only to one variable at time, across obj, curs, rv (we create it on obj, pass it to curs when we know the type is right, pass it to rv when we know there was no error). --- psycopg/connection_type.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 5caf644d..fa5c4c8e 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -60,6 +60,7 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs) { PyObject *obj = NULL; cursorObject *curs = NULL; + PyObject *rv = NULL; PyObject *name = Py_None; PyObject *factory = Py_None; PyObject *withhold = Py_False; @@ -110,12 +111,13 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs) if (PyObject_IsInstance(obj, (PyObject *)&cursorType) == 0) { PyErr_SetString(PyExc_TypeError, "cursor factory must be subclass of psycopg2.extensions.cursor"); - Py_DECREF(obj); - obj = NULL; goto exit; } + /* pass ownership from obj to curs */ curs = (cursorObject *)obj; + obj = NULL; + if (0 > curs_withhold_set(curs, withhold)) { goto error; } @@ -128,26 +130,31 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *kwargs) obj, Py_REFCNT(obj) ); - obj = NULL; + /* pass ownership from curs to rv */ + rv = (PyObject *)curs; + curs = NULL; + goto exit; error: { PyObject *error_type, *error_value, *error_traceback; PyObject *close; - curs = NULL; PyErr_Fetch(&error_type, &error_value, &error_traceback); - close = PyObject_CallMethod(obj, "close", NULL); - if (close) - Py_DECREF(close); - else - PyErr_WriteUnraisable(obj); + if (curs) { + close = PyObject_CallMethod((PyObject *)curs, "close", NULL); + if (close) + Py_DECREF(close); + else + PyErr_WriteUnraisable((PyObject *)curs); + } PyErr_Restore(error_type, error_value, error_traceback); } exit: Py_XDECREF(obj); - return (PyObject *)curs; + Py_XDECREF(curs); + return rv; }