mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-11-04 09:47:30 +03:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									69b2fa282c
								
							
						
					
					
						commit
						d6da4ed09f
					
				
							
								
								
									
										2
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								NEWS
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -8,6 +8,8 @@ What's new in psycopg 2.5.3
 | 
			
		|||
  Chris Withers (:ticket:`#193`).
 | 
			
		||||
- 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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,11 +97,14 @@ HIDDEN int psyco_curs_scrollable_set(cursorObject *self, PyObject *pyvalue);
 | 
			
		|||
 | 
			
		||||
/* 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 \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -413,6 +413,20 @@ class CursorTests(ConnectingTestCase):
 | 
			
		|||
        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__)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user