Require parameter names to not begin with a symbol.
Change-Id: I5dfe9d4e181f0daf71dad2f395aca41c68678cbe
Reviewed-on: https://go-review.googlesource.com/33493
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
"reflect"
"strconv"
"time"
+ "unicode"
+ "unicode/utf8"
)
var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
return fmt.Sprintf("with name %q", nv.Name)
}
+func validateNamedValueName(name string) error {
+ if len(name) == 0 {
+ return nil
+ }
+ r, _ := utf8.DecodeRuneInString(name)
+ if unicode.IsLetter(r) {
+ return nil
+ }
+ return fmt.Errorf("name %q does not begin with a letter", name)
+}
+
// driverArgs converts arguments from callers of Stmt.Exec and
// Stmt.Query into driver Values.
//
nv := &nvargs[n]
nv.Ordinal = n + 1
if np, ok := arg.(NamedArg); ok {
+ if err := validateNamedValueName(np.Name); err != nil {
+ return nil, err
+ }
arg = np.Value
nvargs[n].Name = np.Name
}
nv := &nvargs[n]
nv.Ordinal = n + 1
if np, ok := arg.(NamedArg); ok {
+ if err := validateNamedValueName(np.Name); err != nil {
+ return nil, err
+ }
arg = np.Value
nv.Name = np.Name
}
type Value interface{}
// NamedValue holds both the value name and value.
-// The Ordinal is the position of the parameter starting from one and is always set.
-// If the Name is not empty it should be used for the parameter identifier and
-// not the ordinal position.
type NamedValue struct {
- Name string
+ // If the Name is not empty it should be used for the parameter identifier and
+ // not the ordinal position.
+ //
+ // Name will not have a symbol prefix.
+ Name string
+
+ // Ordinal position of the parameter starting from one and is always set.
Ordinal int
- Value Value
+
+ // Value is the parameter value.
+ Value Value
}
// Driver is the interface that must be implemented by a database
} else {
// Assign value from argument placeholder name.
for _, a := range args {
- if a.Name == strvalue {
+ if a.Name == strvalue[1:] {
val = a.Value
break
}
} else {
// Assign arg value from placeholder name.
for _, a := range args {
- if a.Name == wcol.Placeholder {
+ if a.Name == wcol.Placeholder[1:] {
argValue = a.Value
break
}
// Name of the parameter placeholder. If empty the ordinal position in the
// argument list will be used.
+ //
+ // Name must omit any symbol prefix.
Name string
// Value of the parameter. It may be assigned the same value types as
rows, err := db.Query(
// Ensure the name and age parameters only match on placeholder name, not position.
"SELECT|people|age,name|name=?name,age=?age",
- Named("?age", 2),
- Named("?name", "Bob"),
+ Named("age", 2),
+ Named("name", "Bob"),
)
if err != nil {
t.Fatalf("Query: %v", err)