forked from mirror/go-sqlcipher
fix double free in SQLiteBackup.Close() on error
The sqlite3_backup_finish() function never fails, it just returns the error code from previous operations. Previously if it returned an error, the finalizer wouldn't be unset and sqlite3_backup_finish() would be run again on an already-finished backup. This results in a double-free and often segfaults. The error handling is described in more detail in the "Error handling" section of https://www.sqlite.org/backup.html.
This commit is contained in:
parent
e5a3c16c5c
commit
bdab31cc98
|
@ -65,10 +65,15 @@ func (b *SQLiteBackup) Finish() error {
|
||||||
|
|
||||||
func (b *SQLiteBackup) Close() error {
|
func (b *SQLiteBackup) Close() error {
|
||||||
ret := C.sqlite3_backup_finish(b.b)
|
ret := C.sqlite3_backup_finish(b.b)
|
||||||
|
|
||||||
|
// sqlite3_backup_finish() never fails, it just returns the
|
||||||
|
// error code from previous operations, so clean up before
|
||||||
|
// checking and returning an error
|
||||||
|
b.b = nil
|
||||||
|
runtime.SetFinalizer(b, nil)
|
||||||
|
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
return Error{Code: ErrNo(ret)}
|
return Error{Code: ErrNo(ret)}
|
||||||
}
|
}
|
||||||
b.b = nil
|
|
||||||
runtime.SetFinalizer(b, nil)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue