From 24ef5c60dc4bcd16785ecc5032532bfa7b71c2c4 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Thu, 20 May 2021 13:01:00 +0200 Subject: [PATCH] Fix segfault initialising Column object manually Close #1252 --- NEWS | 3 ++- psycopg/column_type.c | 25 ++++++++++++++++++++++--- tests/test_cursor.py | 10 ++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index bf58d8e3..9512e4a8 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,8 @@ Current release 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 b7007065..80e6d31b 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 d293b2be..e59c974f 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.