]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: don't ignore ColumnConverter for unknown input count
authorJonathan Hall <flimzy@flimzy.com>
Mon, 8 Jul 2024 16:14:43 +0000 (18:14 +0200)
committert hepudds <thepudds1460@gmail.com>
Fri, 21 Nov 2025 21:25:48 +0000 (13:25 -0800)
In the case a sql driver implements the ColumnConverter interface and also
returns -1 for NumInputs, indicating an unknown number of input arguments to
a query, the previous implementation would ignore the column converter would
not be called, leading to unexpected or invalid arguments passed to the driver.

Fixes #68342

Change-Id: Ib2ddaf040fa9be669d593eacdaa1e88ba66d7bc2
Reviewed-on: https://go-review.googlesource.com/c/go/+/597115
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/database/sql/convert.go
src/database/sql/sql_test.go

index 26b139ababd178b29de7d6712902e4fbecadf202..8a0457f9f49d22aadf12e824fa79a5b7ffedca1f 100644 (file)
@@ -55,7 +55,7 @@ func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error {
        // it isn't expecting. The final error will be thrown
        // in the argument converter loop.
        index := nv.Ordinal - 1
-       if c.want <= index {
+       if c.want >= 0 && c.want <= index {
                return nil
        }
 
index c3f228ef0ba1040a74f75b66687dd25411dea1f5..6ee850585589e4d4099f6043fa6c43ba637dc8d4 100644 (file)
@@ -5135,3 +5135,50 @@ func TestIssue69728(t *testing.T) {
                t.Errorf("not equal; v1 = %v, v2 = %v", v1, v2)
        }
 }
+
+func TestColumnConverterWithUnknownInputCount(t *testing.T) {
+       db := OpenDB(&unknownInputsConnector{})
+       stmt, err := db.Prepare("SELECT ?")
+       if err != nil {
+               t.Fatal(err)
+       }
+       _, err = stmt.Exec(1)
+       if err != nil {
+               t.Fatal(err)
+       }
+}
+
+type unknownInputsConnector struct{}
+
+func (unknownInputsConnector) Connect(context.Context) (driver.Conn, error) {
+       return unknownInputsConn{}, nil
+}
+
+func (unknownInputsConnector) Driver() driver.Driver { return nil }
+
+type unknownInputsConn struct{}
+
+func (unknownInputsConn) Prepare(string) (driver.Stmt, error) { return unknownInputsStmt{}, nil }
+func (unknownInputsConn) Close() error                        { return nil }
+func (unknownInputsConn) Begin() (driver.Tx, error)           { return nil, nil }
+
+type unknownInputsStmt struct{}
+
+func (unknownInputsStmt) Close() error  { return nil }
+func (unknownInputsStmt) NumInput() int { return -1 }
+func (unknownInputsStmt) Exec(args []driver.Value) (driver.Result, error) {
+       if _, ok := args[0].(string); !ok {
+               return nil, fmt.Errorf("Expected string, got %T", args[0])
+       }
+       return nil, nil
+}
+func (unknownInputsStmt) Query([]driver.Value) (driver.Rows, error) { return nil, nil }
+func (unknownInputsStmt) ColumnConverter(idx int) driver.ValueConverter {
+       return unknownInputsValueConverter{}
+}
+
+type unknownInputsValueConverter struct{}
+
+func (unknownInputsValueConverter) ConvertValue(v any) (driver.Value, error) {
+       return "string", nil
+}