database/sql: guard against panics in driver.Stmt implementation

For #13677, but there is more to do.

Change-Id: Id1af999dc972d07cdfc771e5855a1a7dca47ca96
Reviewed-on: https://go-review.googlesource.com/18046
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Russ Cox 2015-12-18 12:16:05 -05:00
parent 81adfa508a
commit 99ed71a02c
3 changed files with 75 additions and 6 deletions

View file

@ -1477,10 +1477,14 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) {
return nil, driver.ErrBadConn
}
func resultFromStatement(ds driverStmt, args ...interface{}) (Result, error) {
func driverNumInput(ds driverStmt) int {
ds.Lock()
want := ds.si.NumInput()
ds.Unlock()
defer ds.Unlock() // in case NumInput panics
return ds.si.NumInput()
}
func resultFromStatement(ds driverStmt, args ...interface{}) (Result, error) {
want := driverNumInput(ds)
// -1 means the driver doesn't know how to count the number of
// placeholders, so we won't sanity check input here and instead let the
@ -1495,8 +1499,8 @@ func resultFromStatement(ds driverStmt, args ...interface{}) (Result, error) {
}
ds.Lock()
defer ds.Unlock()
resi, err := ds.si.Exec(dargs)
ds.Unlock()
if err != nil {
return nil, err
}
@ -1927,6 +1931,6 @@ func stack() string {
// withLock runs while holding lk.
func withLock(lk sync.Locker, fn func()) {
lk.Lock()
defer lk.Unlock() // in case fn panics
fn()
lk.Unlock()
}