summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2021-05-20 13:01:00 +0200
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2021-05-20 13:10:59 +0200
commit8ea5d0c0b8e7dc74e516ae24c3841a7c4b5a0d21 (patch)
tree8d588cff5bd51187969be19f0e573011f8476c24
parent391386cfb9efb277813bb6b53d727497b642dd97 (diff)
downloadpsycopg2-8ea5d0c0b8e7dc74e516ae24c3841a7c4b5a0d21.tar.gz
Fix segfault initialising Column object manually
Close #1252
-rw-r--r--NEWS3
-rw-r--r--psycopg/column_type.c25
-rwxr-xr-xtests/test_cursor.py10
3 files changed, 34 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 4e4b68f..352eafd 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,8 @@ What's new in psycopg 2.9
What's new in psycopg 2.8.7
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Accept empty params as `~psycopg2.connect()` (:ticket:`#1250).
+- Accept empty params as `~psycopg2.connect()` (:ticket:`#1250).
+- Fix attributes refcount in `Column` initialisation (:ticket:`#1252`).
What's new in psycopg 2.8.6
diff --git a/psycopg/column_type.c b/psycopg/column_type.c
index b700706..80e6d31 100644
--- a/psycopg/column_type.c
+++ b/psycopg/column_type.c
@@ -97,17 +97,36 @@ column_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
static int
column_init(columnObject *self, PyObject *args, PyObject *kwargs)
{
+ PyObject *name = NULL;
+ PyObject *type_code = NULL;
+ PyObject *display_size = NULL;
+ PyObject *internal_size = NULL;
+ PyObject *precision = NULL;
+ PyObject *scale = NULL;
+ PyObject *null_ok = NULL;
+ PyObject *table_oid = NULL;
+ PyObject *table_column = NULL;
+
static char *kwlist[] = {
"name", "type_code", "display_size", "internal_size",
"precision", "scale", "null_ok", "table_oid", "table_column", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOOOOOOO", kwlist,
- &self->name, &self->type_code, &self->display_size,
- &self->internal_size, &self->precision, &self->scale,
- &self->null_ok, &self->table_oid, &self->table_column)) {
+ &name, &type_code, &display_size, &internal_size, &precision,
+ &scale, &null_ok, &table_oid, &table_column)) {
return -1;
}
+ Py_XINCREF(name); self->name = name;
+ Py_XINCREF(type_code); self->type_code = type_code;
+ Py_XINCREF(display_size); self->display_size = display_size;
+ Py_XINCREF(internal_size); self->internal_size = internal_size;
+ Py_XINCREF(precision); self->precision = precision;
+ Py_XINCREF(scale); self->scale = scale;
+ Py_XINCREF(null_ok); self->null_ok = null_ok;
+ Py_XINCREF(table_oid); self->table_oid = table_oid;
+ Py_XINCREF(table_column); self->table_column = table_column;
+
return 0;
}
diff --git a/tests/test_cursor.py b/tests/test_cursor.py
index d293b2b..e59c974 100755
--- a/tests/test_cursor.py
+++ b/tests/test_cursor.py
@@ -250,6 +250,16 @@ class CursorTests(ConnectingTestCase):
self.assertEqual(description, unpickled)
+ def test_column_refcount(self):
+ # Reproduce crash describe in ticket #1252
+ from psycopg2.extensions import Column
+
+ def do_stuff():
+ _ = Column(name='my_column')
+
+ for _ in range(1000):
+ do_stuff()
+
def test_bad_subclass(self):
# check that we get an error message instead of a segfault
# for badly written subclasses.