@@ -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 ;
@@ -834,7 +873,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
834873
835874    if  (self -> statement ) {
836875        // Reset pending statements on this cursor. 
837-         (void )stmt_reset (self -> statement );
876+         if  (stmt_reset (self -> statement ) !=  SQLITE_OK ) {
877+             goto reset_failure ;
878+         }
838879    }
839880
840881    PyObject  * stmt  =  get_statement_from_cache (self , operation );
@@ -858,7 +899,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
858899        }
859900    }
860901
861-     (void )stmt_reset (self -> statement );
902+     if  (stmt_reset (self -> statement ) !=  SQLITE_OK ) {
903+         goto reset_failure ;
904+     }
862905    self -> rowcount  =  self -> statement -> is_dml  ? 0L  : -1L ;
863906
864907    /* We start a transaction implicitly before a DML statement. 
@@ -940,7 +983,9 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
940983            if  (self -> statement -> is_dml ) {
941984                self -> rowcount  +=  (long )sqlite3_changes (self -> connection -> db );
942985            }
943-             stmt_reset (self -> statement );
986+             if  (stmt_reset (self -> statement ) !=  SQLITE_OK ) {
987+                 goto reset_failure ;
988+             }
944989        }
945990        Py_XDECREF (parameters );
946991    }
@@ -965,8 +1010,15 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
9651010
9661011    if  (PyErr_Occurred ()) {
9671012        if  (self -> statement ) {
968-             (void )stmt_reset (self -> statement );
1013+             sqlite3  * db  =  sqlite3_db_handle (self -> statement -> st );
1014+             int  sqlite3_state  =  sqlite3_errcode (db );
1015+             // stmt_reset() may return a previously set exception, 
1016+             // either triggered because of Python or sqlite3. 
1017+             rc  =  stmt_reset (self -> statement );
9691018            Py_CLEAR (self -> statement );
1019+             if  (sqlite3_state  ==  SQLITE_OK  &&  rc  !=  SQLITE_OK ) {
1020+                 cursor_cannot_reset_stmt_error (self , 1 );
1021+             }
9701022        }
9711023        self -> rowcount  =  -1L ;
9721024        return  NULL ;
@@ -975,6 +1027,20 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
9751027        Py_CLEAR (self -> statement );
9761028    }
9771029    return  Py_NewRef ((PyObject  * )self );
1030+ 
1031+ reset_failure :
1032+     /* suite to execute when stmt_reset() failed and no exception is set */ 
1033+     assert (!PyErr_Occurred ());
1034+ 
1035+     Py_XDECREF (parameters );
1036+     Py_XDECREF (parameters_iter );
1037+     Py_XDECREF (parameters_list );
1038+ 
1039+     self -> locked  =  0 ;
1040+     self -> rowcount  =  -1L ;
1041+     Py_CLEAR (self -> statement );
1042+     cursor_cannot_reset_stmt_error (self , 0 );
1043+     return  NULL ;
9781044}
9791045
9801046/*[clinic input] 
@@ -1117,14 +1183,20 @@ pysqlite_cursor_iternext(PyObject *op)
11171183        if  (self -> statement -> is_dml ) {
11181184            self -> rowcount  =  (long )sqlite3_changes (self -> connection -> db );
11191185        }
1120-         ( void ) stmt_reset (self -> statement );
1186+         int   rc   =   stmt_reset (self -> statement );
11211187        Py_CLEAR (self -> statement );
1188+         if  (rc  !=  SQLITE_OK ) {
1189+             goto reset_failure ;
1190+         }
11221191    }
11231192    else  if  (rc  !=  SQLITE_ROW ) {
1124-         set_error_from_db (self -> connection -> state , self -> connection -> db );
1125-         ( void ) stmt_reset (self -> statement );
1193+         rc   =   set_error_from_db (self -> connection -> state , self -> connection -> db );
1194+         int   reset_ok   =   stmt_reset (self -> statement );
11261195        Py_CLEAR (self -> statement );
11271196        Py_DECREF (row );
1197+         if  (rc  ==  SQLITE_OK  &&  reset_ok  !=  SQLITE_OK ) {
1198+             goto reset_failure ;
1199+         }
11281200        return  NULL ;
11291201    }
11301202    if  (!Py_IsNone (self -> row_factory )) {
@@ -1134,6 +1206,10 @@ pysqlite_cursor_iternext(PyObject *op)
11341206        Py_SETREF (row , new_row );
11351207    }
11361208    return  row ;
1209+ 
1210+ reset_failure :
1211+     cursor_cannot_reset_stmt_error (self , 0 );
1212+     return  NULL ;
11371213}
11381214
11391215/*[clinic input] 
@@ -1291,11 +1367,12 @@ pysqlite_cursor_close_impl(pysqlite_Cursor *self)
12911367        return  NULL ;
12921368    }
12931369
1294-     if  (self -> statement ) {
1295-         ( void ) stmt_reset ( self -> statement );
1296-         Py_CLEAR ( self -> statement ) ;
1370+     if  (self -> statement   &&   stmt_reset ( self -> statement )  !=   SQLITE_OK ) {
1371+         cursor_cannot_reset_stmt_error ( self ,  0 );
1372+         return   NULL ;
12971373    }
12981374
1375+     Py_CLEAR (self -> statement );
12991376    self -> closed  =  1 ;
13001377
13011378    Py_RETURN_NONE ;
0 commit comments