@@ -58,6 +58,41 @@ check_cursor_locked(pysqlite_Cursor *cur)
5858    return  1 ;
5959}
6060
61+ static  pysqlite_state  * 
62+ get_module_state_by_cursor (pysqlite_Cursor  * cursor )
63+ {
64+     if  (cursor -> connection  !=  NULL  &&  cursor -> connection -> state  !=  NULL ) {
65+         return  cursor -> connection -> state ;
66+     }
67+     return  pysqlite_get_state_by_type (Py_TYPE (cursor ));
68+ }
69+ 
70+ static  void 
71+ cursor_sqlite3_internal_error (pysqlite_Cursor  * cursor ,
72+                               const  char  * error_message ,
73+                               int  chain_exceptions )
74+ {
75+     pysqlite_state  * state  =  get_module_state_by_cursor (cursor );
76+     if  (chain_exceptions ) {
77+         assert (PyErr_Occurred ());
78+         PyObject  * exc  =  PyErr_GetRaisedException ();
79+         PyErr_SetString (state -> InternalError , error_message );
80+         _PyErr_ChainExceptions1 (exc );
81+     }
82+     else  {
83+         assert (!PyErr_Occurred ());
84+         PyErr_SetString (state -> InternalError , error_message );
85+    }
86+ }
87+ 
88+ static  void 
89+ cursor_cannot_reset_stmt_error (pysqlite_Cursor  * cursor , int  chain_exceptions )
90+ {
91+     cursor_sqlite3_internal_error (cursor ,
92+                                   "cannot reset statement" ,
93+                                   chain_exceptions );
94+ }
95+ 
6196/*[clinic input] 
6297module _sqlite3 
6398class _sqlite3.Cursor "pysqlite_Cursor *" "clinic_state()->CursorType" 
@@ -173,8 +208,12 @@ cursor_clear(PyObject *op)
173208    Py_CLEAR (self -> row_factory );
174209    if  (self -> statement ) {
175210        /* Reset the statement if the user has not closed the cursor */ 
176-         stmt_reset (self -> statement );
211+         int   rc   =   stmt_reset (self -> statement );
177212        Py_CLEAR (self -> statement );
213+         if  (rc  !=  SQLITE_OK ) {
214+             cursor_cannot_reset_stmt_error (self , 0 );
215+             PyErr_FormatUnraisable ("Exception ignored in cursor_clear()" );
216+         }
178217    }
179218
180219    return  0 ;
@@ -837,7 +876,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
837876
838877    if  (self -> statement ) {
839878        // Reset pending statements on this cursor. 
840-         (void )stmt_reset (self -> statement );
879+         if  (stmt_reset (self -> statement ) !=  SQLITE_OK ) {
880+             goto reset_failure ;
881+         }
841882    }
842883
843884    PyObject  * stmt  =  get_statement_from_cache (self , operation );
@@ -861,7 +902,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
861902        }
862903    }
863904
864-     (void )stmt_reset (self -> statement );
905+     if  (stmt_reset (self -> statement ) !=  SQLITE_OK ) {
906+         goto reset_failure ;
907+     }
865908    self -> rowcount  =  self -> statement -> is_dml  ? 0L  : -1L ;
866909
867910    /* We start a transaction implicitly before a DML statement. 
@@ -943,7 +986,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
943986            if  (self -> statement -> is_dml ) {
944987                self -> rowcount  +=  (long )sqlite3_changes (self -> connection -> db );
945988            }
946-             stmt_reset (self -> statement );
989+             if  (stmt_reset (self -> statement ) !=  SQLITE_OK ) {
990+                 goto reset_failure ;
991+             }
947992        }
948993        Py_XDECREF (parameters );
949994    }
@@ -968,8 +1013,15 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
9681013
9691014    if  (PyErr_Occurred ()) {
9701015        if  (self -> statement ) {
971-             (void )stmt_reset (self -> statement );
1016+             sqlite3  * db  =  sqlite3_db_handle (self -> statement -> st );
1017+             int  sqlite3_state  =  sqlite3_errcode (db );
1018+             // stmt_reset() may return a previously set exception, 
1019+             // either triggered because of Python or sqlite3. 
1020+             rc  =  stmt_reset (self -> statement );
9721021            Py_CLEAR (self -> statement );
1022+             if  (sqlite3_state  ==  SQLITE_OK  &&  rc  !=  SQLITE_OK ) {
1023+                 cursor_cannot_reset_stmt_error (self , 1 );
1024+             }
9731025        }
9741026        self -> rowcount  =  -1L ;
9751027        return  NULL ;
@@ -978,6 +1030,20 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
9781030        Py_CLEAR (self -> statement );
9791031    }
9801032    return  Py_NewRef ((PyObject  * )self );
1033+ 
1034+ reset_failure :
1035+     /* suite to execute when stmt_reset() failed and no exception is set */ 
1036+     assert (!PyErr_Occurred ());
1037+ 
1038+     Py_XDECREF (parameters );
1039+     Py_XDECREF (parameters_iter );
1040+     Py_XDECREF (parameters_list );
1041+ 
1042+     self -> locked  =  0 ;
1043+     self -> rowcount  =  -1L ;
1044+     Py_CLEAR (self -> statement );
1045+     cursor_cannot_reset_stmt_error (self , 0 );
1046+     return  NULL ;
9811047}
9821048
9831049/*[clinic input] 
@@ -1120,14 +1186,20 @@ pysqlite_cursor_iternext(PyObject *op)
11201186        if  (self -> statement -> is_dml ) {
11211187            self -> rowcount  =  (long )sqlite3_changes (self -> connection -> db );
11221188        }
1123-         ( void ) stmt_reset (self -> statement );
1189+         rc   =   stmt_reset (self -> statement );
11241190        Py_CLEAR (self -> statement );
1191+         if  (rc  !=  SQLITE_OK ) {
1192+             goto reset_failure ;
1193+         }
11251194    }
11261195    else  if  (rc  !=  SQLITE_ROW ) {
1127-         set_error_from_db (self -> connection -> state , self -> connection -> db );
1128-         ( void ) stmt_reset (self -> statement );
1196+         rc   =   set_error_from_db (self -> connection -> state , self -> connection -> db );
1197+         int   reset_rc   =   stmt_reset (self -> statement );
11291198        Py_CLEAR (self -> statement );
11301199        Py_DECREF (row );
1200+         if  (rc  ==  SQLITE_OK  &&  reset_rc  !=  SQLITE_OK ) {
1201+             goto reset_failure ;
1202+         }
11311203        return  NULL ;
11321204    }
11331205    if  (!Py_IsNone (self -> row_factory )) {
@@ -1137,6 +1209,10 @@ pysqlite_cursor_iternext(PyObject *op)
11371209        Py_SETREF (row , new_row );
11381210    }
11391211    return  row ;
1212+ 
1213+ reset_failure :
1214+     cursor_cannot_reset_stmt_error (self , 0 );
1215+     return  NULL ;
11401216}
11411217
11421218/*[clinic input] 
@@ -1291,8 +1367,15 @@ pysqlite_cursor_close_impl(pysqlite_Cursor *self)
12911367    }
12921368
12931369    if  (self -> statement ) {
1294-         (void )stmt_reset (self -> statement );
1370+         int  rc  =  stmt_reset (self -> statement );
1371+         // Force self->statement to be NULL even if stmt_reset() may have 
1372+         // failed to avoid a possible double-free if someone calls close() 
1373+         // twice as a leak here would be better than a double-free. 
12951374        Py_CLEAR (self -> statement );
1375+         if  (rc  !=  SQLITE_OK ) {
1376+             cursor_cannot_reset_stmt_error (self , 0 );
1377+             return  NULL ;
1378+         }
12961379    }
12971380
12981381    self -> closed  =  1 ;
0 commit comments