Skip to content

Commit 2a93d21

Browse files
committed
Merge pull request #143 from arnehormann/no-panic
no panic on closed connection reuse
2 parents ae73333 + baf9f1c commit 2a93d21

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

connection.go

+12
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ func (mc *mysqlConn) handleParams() (err error) {
9999
}
100100

101101
func (mc *mysqlConn) Begin() (driver.Tx, error) {
102+
if mc.netConn == nil {
103+
return nil, errInvalidConn
104+
}
102105
err := mc.exec("START TRANSACTION")
103106
if err == nil {
104107
return &mysqlTx{mc}, err
@@ -122,6 +125,9 @@ func (mc *mysqlConn) Close() (err error) {
122125
}
123126

124127
func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
128+
if mc.netConn == nil {
129+
return nil, errInvalidConn
130+
}
125131
// Send command
126132
err := mc.writeCommandPacketStr(comStmtPrepare, query)
127133
if err != nil {
@@ -150,6 +156,9 @@ func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
150156
}
151157

152158
func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
159+
if mc.netConn == nil {
160+
return nil, errInvalidConn
161+
}
153162
if len(args) == 0 { // no args, fastpath
154163
mc.affectedRows = 0
155164
mc.insertId = 0
@@ -191,6 +200,9 @@ func (mc *mysqlConn) exec(query string) error {
191200
}
192201

193202
func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
203+
if mc.netConn == nil {
204+
return nil, errInvalidConn
205+
}
194206
if len(args) == 0 { // no args, fastpath
195207
// Send command
196208
err := mc.writeCommandPacketStr(comQuery, query)

driver_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,40 @@ func (dbt *DBTest) mustQuery(query string, args ...interface{}) (rows *sql.Rows)
108108
return rows
109109
}
110110

111+
func TestReuseClosedConnection(t *testing.T) {
112+
// this test does not use sql.database, it uses the driver directly
113+
if !available {
114+
t.Skipf("MySQL-Server not running on %s", netAddr)
115+
}
116+
driver := &MySQLDriver{}
117+
conn, err := driver.Open(dsn)
118+
if err != nil {
119+
t.Fatalf("Error connecting: %s", err.Error())
120+
}
121+
stmt, err := conn.Prepare("DO 1")
122+
if err != nil {
123+
t.Fatalf("Error preparing statement: %s", err.Error())
124+
}
125+
_, err = stmt.Exec(nil)
126+
if err != nil {
127+
t.Fatalf("Error executing statement: %s", err.Error())
128+
}
129+
err = conn.Close()
130+
if err != nil {
131+
t.Fatalf("Error closing connection: %s", err.Error())
132+
}
133+
defer func() {
134+
if err := recover(); err != nil {
135+
t.Errorf("Panic after reusing a closed connection: %v", err)
136+
}
137+
}()
138+
_, err = stmt.Exec(nil)
139+
if err != nil && err != errInvalidConn {
140+
t.Errorf("Unexpected error '%s', expected '%s'",
141+
err.Error(), errInvalidConn.Error())
142+
}
143+
}
144+
111145
func TestCharset(t *testing.T) {
112146
if !available {
113147
t.Skipf("MySQL-Server not running on %s", netAddr)

statement.go

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ func (stmt *mysqlStmt) NumInput() int {
3434
}
3535

3636
func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
37+
if stmt.mc.netConn == nil {
38+
return nil, errInvalidConn
39+
}
3740
// Send command
3841
err := stmt.writeExecutePacket(args)
3942
if err != nil {
@@ -70,6 +73,9 @@ func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
7073
}
7174

7275
func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
76+
if stmt.mc.netConn == nil {
77+
return nil, errInvalidConn
78+
}
7379
// Send command
7480
err := stmt.writeExecutePacket(args)
7581
if err != nil {

0 commit comments

Comments
 (0)