aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/database/sql/convert.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2013-02-21 10:43:00 -0800
committerBrad Fitzpatrick <bradfitz@golang.org>2013-02-21 10:43:00 -0800
commitbca3f5fca030599c41523570a3be9527448e73a9 (patch)
treeb288e4dc398094e46d360fdc40a37b4fbcd23cad /src/pkg/database/sql/convert.go
parent5833c96b0a3b1e77b787ee9b908456a7334f7821 (diff)
downloadgo-bca3f5fca030599c41523570a3be9527448e73a9.tar.xz
database/sql: check for nil Scan pointers
Return nice errors and don't panic. Fixes #4859 R=golang-dev, rsc CC=golang-dev https://golang.org/cl/7383046
Diffstat (limited to 'src/pkg/database/sql/convert.go')
-rw-r--r--src/pkg/database/sql/convert.go25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/pkg/database/sql/convert.go b/src/pkg/database/sql/convert.go
index 964dc18485..853a7826c5 100644
--- a/src/pkg/database/sql/convert.go
+++ b/src/pkg/database/sql/convert.go
@@ -14,6 +14,8 @@ import (
"strconv"
)
+var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
+
// driverArgs converts arguments from callers of Stmt.Exec and
// Stmt.Query into driver Values.
//
@@ -75,34 +77,52 @@ func driverArgs(si driver.Stmt, args []interface{}) ([]driver.Value, error) {
// An error is returned if the copy would result in loss of information.
// dest should be a pointer type.
func convertAssign(dest, src interface{}) error {
- // Common cases, without reflect. Fall through.
+ // Common cases, without reflect.
switch s := src.(type) {
case string:
switch d := dest.(type) {
case *string:
+ if d == nil {
+ return errNilPtr
+ }
*d = s
return nil
case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
*d = []byte(s)
return nil
}
case []byte:
switch d := dest.(type) {
case *string:
+ if d == nil {
+ return errNilPtr
+ }
*d = string(s)
return nil
case *interface{}:
+ if d == nil {
+ return errNilPtr
+ }
bcopy := make([]byte, len(s))
copy(bcopy, s)
*d = bcopy
return nil
case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
*d = s
return nil
}
case nil:
switch d := dest.(type) {
case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
*d = nil
return nil
}
@@ -140,6 +160,9 @@ func convertAssign(dest, src interface{}) error {
if dpv.Kind() != reflect.Ptr {
return errors.New("destination not a pointer")
}
+ if dpv.IsNil() {
+ return errNilPtr
+ }
if !sv.IsValid() {
sv = reflect.ValueOf(src)