do not bail out on finalize error in closeCachedStmtsLocked
Finalize all cached statements even if one fails. Leaving a finalized statement in the cache map would be a use-after-finalize bug per SQLite documentation.
This commit is contained in:
11
sqlite3.go
11
sqlite3.go
@@ -1884,9 +1884,7 @@ func (c *SQLiteConn) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(c, nil)
|
runtime.SetFinalizer(c, nil)
|
||||||
if err := c.closeCachedStmtsLocked(); err != nil {
|
c.closeCachedStmtsLocked()
|
||||||
return err
|
|
||||||
}
|
|
||||||
rv := C.sqlite3_close_v2(c.db)
|
rv := C.sqlite3_close_v2(c.db)
|
||||||
if rv != C.SQLITE_OK {
|
if rv != C.SQLITE_OK {
|
||||||
return lastError(c.db)
|
return lastError(c.db)
|
||||||
@@ -1949,23 +1947,20 @@ func (c *SQLiteConn) putCachedStmt(s *SQLiteStmt) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SQLiteConn) closeCachedStmtsLocked() error {
|
func (c *SQLiteConn) closeCachedStmtsLocked() {
|
||||||
for key, stmts := range c.stmtCache {
|
for key, stmts := range c.stmtCache {
|
||||||
for _, s := range stmts {
|
for _, s := range stmts {
|
||||||
if s == nil || s.s == nil {
|
if s == nil || s.s == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(s, nil)
|
runtime.SetFinalizer(s, nil)
|
||||||
if rv := C.sqlite3_finalize(s.s); rv != C.SQLITE_OK {
|
C.sqlite3_finalize(s.s)
|
||||||
return lastError(c.db)
|
|
||||||
}
|
|
||||||
s.s = nil
|
s.s = nil
|
||||||
s.c = nil
|
s.c = nil
|
||||||
}
|
}
|
||||||
delete(c.stmtCache, key)
|
delete(c.stmtCache, key)
|
||||||
}
|
}
|
||||||
c.stmtCacheCount = 0
|
c.stmtCacheCount = 0
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the query string. Return a new statement.
|
// Prepare the query string. Return a new statement.
|
||||||
|
|||||||
Reference in New Issue
Block a user