alexbrainman / odbc

odbc driver written in go
BSD 3-Clause "New" or "Revised" License
348 stars 139 forks source link

panic when values passed in prepare is empty #150

Open pingworld opened 3 years ago

pingworld commented 3 years ago

https://github.com/alexbrainman/odbc/blob/f0492dfa15751dfa8566a9eda47542a084908cdb/param.go#L142

when we execute sql like this:

INSERT INTO cy (addr,city,con,coun,ctor,ctime,ctype,desc,don,emil,id,in_type,lo,mtme,ne,phe,pal,pe,sale,tus,wie) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

_, err = st.Exec("", "", "", "", 0, 16144, "genal", "", "", "", 62199, "", "", 1614, "testtest", "", "", "", 0, "ace", "")

then we got a panic:

2021/02/24 17:13:05 - ERROR - main/server/conn.go:[279] - ClientConn.Run, error:runtime error: index out of range [0] with length 0, stack:goroutine 131 [running]:
test.kk.net/prodd/main/server.(*ClientConn).Run.func1(0xc0003dafc0)
      /mnt/e/workspace/codes/test.kk.net/test/prodd/main/server/conn.go:277 +0xd8
panic(0xff2e00, 0xc0001bc8a0)
      /usr/local/bin/go/src/runtime/panic.go:679 +0x1b2
github.com/alexbrainman/odbc.(*Parameter).BindValue(0xc0001be000, 0x7ff5d8029a20, 0x0, 0xed0ba0, 0x20fa640, 0xc0000c0740, 0x150, 0x150)
        /opt/kk/pkg/mod/test.kk.net/test/odbc@v0.0.0-20210201095729-8f4b33b23435/param.go:147 +0xaeb
github.com/alexbrainman/odbc.(*ODBCStmt).Exec(0xc00040a190, 0xc000130160, 0x15, 0x15, 0xc0000c0740, 0x15, 0x15)
   /opt/kk/pkg/mod/test.kk.net/test/odbc@v0.0.0-20210201095729-8f4b33b23435/odbcstmt.go:118 +0xd2
github.com/alexbrainman/odbc.(*Stmt).Exec(0xc0000b4360, 0xc000130160, 0x15, 0x15, 0x0, 0x0, 0x0, 0x0)
       /opt/kk/pkg/mod/test.kk.net/test/odbc@v0.0.0-20210201095729-8f4b33b23435/stmt.go:64 +0xf1
database/sql.ctxDriverStmtExec(0x1212480, 0xc0000ca568, 0x1212640, 0xc0000b4360, 0xc00009b180, 0x15, 0x15, 0x15, 0x15, 0x0, ...)
        /usr/local/bin/go/src/database/sql/ctxutil.go:77 +0x165
database/sql.resultFromStatement(0x1212480, 0xc0000ca568, 0x1209f40, 0xc0000c0740, 0xc0000da180, 0xc000130010, 0x15, 0x15, 0x0, 0x0, ...)
        /usr/local/bin/go/src/database/sql/sql.go:2435 +0x156
database/sql.(*Stmt).ExecContext(0xc0003db170, 0x1212480, 0xc0000ca568, 0xc000130010, 0x15, 0x15, 0x0, 0x0, 0x0, 0x0)
      /usr/local/bin/go/src/database/sql/sql.go:2411 +0x1f9
database/sql.(*Stmt).Exec(...)
       /usr/local/bin/go/src/database/sql/sql.go:2423
test.kk.net/prodd/bd.(*Conn).execStmt(0xc0003db050, 0xc00022e320, 0xc000420400, 0x14e, 0xc000130000, 0x16, 0x16, 0x42fe4a, 0xc0112d3398, 0xb8e8241c2d8c)
   /mnt/e/workspace/codes/test.kk.net/test/prodd/bd/conn.go:385 +0x16c
test.kk.net/prodd/bd.(*Conn).execute(0xc0003db050, 0xc00022e320, 0xc000155c20, 0xc000155c10, 0xc000130000, 0x16, 0x16, 0x0, 0x0, 0x0)
 /mnt/e/workspace/codes/test.kk.net/test/prodd/bd/conn.go:273 +0x266
test.kk.net/prodd/bd.(*Conn).ExecStmt(0xc0003db050, 0xc00040a1e0, 0xc000164001, 0x88, 0x88)
   /mnt/e/workspace/codes/test.kk.net/test/prodd/bd/conn.go:355 +0x234
test.kk.net/prodd/main/server.(*ClientConn).handleStmtExecute(0xc0003dafc0, 0xc0003db050, 0xc000164001, 0x88, 0x88, 0xc0001bc780, 0xc0001e0f10)
 /mnt/e/workspace/codes/test.kk.net/test/prodd/main/server/conn_stmt.go:109 +0x8d
test.kk.net/prodd/main/server.(*ClientConn).handleCmd(0xc0003dafc0, 0x17, 0xc000164001, 0x88, 0x88, 0xc000155dd8, 0x2)
   /mnt/e/workspace/codes/test.kk.net/test/prodd/main/server/conn.go:353 +0x455
test.kk.net/prodd/main/server.(*ClientConn).dispatch(0xc0003dafc0, 0xc000164001, 0x88, 0x88, 0x0, 0x0)
       /mnt/e/workspace/codes/test.kk.net/test/prodd/main/serv... data too long, soucre-length=3627

After debuging, we found it would be panic when our param addr is empty which type is []byte.

We dig the source code and found this code should raise out of range exception.

So we fix this just like this:

        if len(b) > 0 {
            buf = unsafe.Pointer(&b[0])
        } else {
            buf = unsafe.Pointer(&b)
        }

Am I right?

Thanks for your response.

alexbrainman commented 3 years ago

@pingworld

Am I right?

You could be correct.

Unfortunately I don't have time to debug your issue. But you can do it yourself.

You did not say what database server you use. I will assume you use MS SQL Server. Then add new test to mssql_test.go that reproduces your issue. And then we can fix it. I am happy to review your PR.

Let me know, if you have any questions.

Thank you.

Alex