Don't segfault on uninitialized cursor

It can happen with bad cursor subclasses not calling super's init. Raise
an exception instead of segfaulting.

Closes #195

Conflicts:

	NEWS
This commit is contained in:
Daniele Varrazzo 2014-02-26 19:37:59 +00:00
parent d777b73301
commit 6b43b0088e
3 changed files with 22 additions and 3 deletions

2
NEWS
View File

@ -12,6 +12,8 @@ What's new in psycopg 2.4.7
(:ticket:`#187`).
- Avoid blocking async connections on connect (:ticket:`#194`). Thanks to
Adam Petrovich for the bug report and diagnosis.
- Don't segfault using poorly defined cursor subclasses which forgot to call
the superclass init (:ticket:`#195`).
- Fixed debug build on Windows, thanks to James Emerton.

View File

@ -90,11 +90,14 @@ HIDDEN void curs_reset(cursorObject *self);
/* exception-raising macros */
#define EXC_IF_CURS_CLOSED(self) \
do \
if ((self)->closed || ((self)->conn && (self)->conn->closed)) { \
do { \
if (!(self)->conn) { \
PyErr_SetString(InterfaceError, "the cursor has no connection"); \
return NULL; } \
if ((self)->closed || (self)->conn->closed) { \
PyErr_SetString(InterfaceError, "cursor already closed"); \
return NULL; } \
while (0)
} while (0)
#define EXC_IF_NO_TUPLES(self) \
do \

View File

@ -354,6 +354,20 @@ class CursorTests(unittest.TestCase):
cur.scroll(9, mode='absolute')
self.assertEqual(cur.fetchone(), (9,))
def test_bad_subclass(self):
# check that we get an error message instead of a segfault
# for badly written subclasses.
# see http://stackoverflow.com/questions/22019341/
class StupidCursor(psycopg2.extensions.cursor):
def __init__(self, *args, **kwargs):
# I am stupid so not calling superclass init
pass
cur = StupidCursor()
self.assertRaises(psycopg2.InterfaceError, cur.execute, 'select 1')
self.assertRaises(psycopg2.InterfaceError, cur.executemany,
'select 1', [])
def test_suite():
return unittest.TestLoader().loadTestsFromName(__name__)