Skip to content

Commit

Permalink
Ensure backward compatibility with legacy EOF format
Browse files Browse the repository at this point in the history
  • Loading branch information
tz70s committed Sep 5, 2020
1 parent c34acf9 commit ea32d9f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 47 deletions.
25 changes: 14 additions & 11 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,16 @@ func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {

// Read Result
columnCount, err := stmt.readPrepareResultPacket()
if err != nil {
return stmt, err
}

if err := mc.readPackets(stmt.paramCount); err != nil {
return nil, err
}
if err == nil {
if stmt.paramCount > 0 {
if err = mc.readUntilEOF(); err != nil {
return nil, err
}
}

if err := mc.readPackets(int(columnCount)); err != nil {
return nil, err
if columnCount > 0 {
err = mc.readUntilEOF()
}
}

return stmt, err
Expand Down Expand Up @@ -415,8 +415,11 @@ func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
rows.mc = mc
rows.rs.columns = []mysqlField{{fieldType: fieldTypeVarChar}}

if err := mc.readPackets(resLen); err != nil {
return nil, err
if resLen > 0 {
// Columns
if err := mc.readUntilEOF(); err != nil {
return nil, err
}
}

dest := make([]driver.Value, resLen)
Expand Down
51 changes: 16 additions & 35 deletions packets.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ func readStatus(b []byte) statusFlag {
}

// Ok Packet
// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet
// https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html
func (mc *mysqlConn) handleOkPacket(data []byte) error {
// 0x00 or 0xFE [1 byte]
n := 1
Expand All @@ -640,22 +640,26 @@ func (mc *mysqlConn) handleOkPacket(data []byte) error {

// isEOFPacket will return true if the data is either a EOF-Packet or OK-Packet
// acting as an EOF.
func isEOFPacket(data []byte) bool {
return data[0] == iEOF && len(data) < 9
func (mc *mysqlConn) isEOFPacket(data []byte) bool {
// Legacy EOF packet
if data[0] == iEOF && (len(data) == 5 || len(data) == 1) && mc.flags&clientDeprecateEOF == 0 {
return true
}
return data[0] == iEOF && len(data) < 9 && mc.flags&clientDeprecateEOF != 0
}

// Read Packets as Field Packets until EOF-Packet or an Error appears
// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnDefinition41
func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
columns := make([]mysqlField, count)

for i := 0; i < count; i++ {
for i := 0; ; i++ {
data, err := mc.readPacket()
if err != nil {
return nil, err
}

if mc.flags&clientDeprecateEOF == 0 && isEOFPacket(data) {
if mc.isEOFPacket(data) {
if i == count {
return columns, nil
}
Expand Down Expand Up @@ -741,7 +745,6 @@ func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
// defaultVal, _, err = bytesToLengthCodedBinary(data[pos:])
//}
}
return columns, nil
}

// Read Packets as Field Packets until EOF/OK-Packet or an Error appears
Expand All @@ -759,12 +762,13 @@ func (rows *textRows) readRow(dest []driver.Value) error {
}

// EOF Packet
if isEOFPacket(data) {
if mc.isEOFPacket(data) {
if mc.flags&clientDeprecateEOF == 0 {
// server_status [2 bytes]
rows.mc.status = readStatus(data[3:])
} else {
if err := mc.handleOkPacket(data); err != nil {
rows.mc = nil
return err
}
}
Expand Down Expand Up @@ -830,39 +834,15 @@ func (mc *mysqlConn) readUntilEOF() error {
switch {
case data[0] == iERR:
return mc.handleErrorPacket(data)
case isEOFPacket(data):
case mc.isEOFPacket(data):
if mc.flags&clientDeprecateEOF == 0 {
mc.status = readStatus(data[3:])
} else {
return mc.handleOkPacket(data)
return nil
}
return nil
}
}
}

func (mc *mysqlConn) readPackets(num int) error {

// we need to read EOF as well
if mc.flags&clientDeprecateEOF == 0 {
num++
}

for i := 0; i < num; i++ {
data, err := mc.readPacket()
if err != nil {
return err
}

switch {
case data[0] == iERR:
return mc.handleErrorPacket(data)
case mc.flags&clientDeprecateEOF == 0 && isEOFPacket(data):
mc.status = readStatus(data[3:])
return nil
return mc.handleOkPacket(data)
}
}
return nil
}

/******************************************************************************
Expand Down Expand Up @@ -1223,11 +1203,12 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {

// packet indicator [1 byte]
if data[0] != iOK {
if isEOFPacket(data) {
if rows.mc.isEOFPacket(data) {
if rows.mc.flags&clientDeprecateEOF == 0 {
rows.mc.status = readStatus(data[3:])
} else {
if err := rows.mc.handleOkPacket(data); err != nil {
rows.mc = nil
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (rows *textRows) Next(dest []driver.Value) error {
if err := mc.error(); err != nil {
return err
}

errLog.Print("perform next read")
// Fetch next row from stream
return rows.readRow(dest)
}
Expand Down

0 comments on commit ea32d9f

Please sign in to comment.