go-sniffer icon indicating copy to clipboard operation
go-sniffer copied to clipboard

mysql plug panic

Open voidint opened this issue 6 years ago • 2 comments

panic: runtime error: index out of range [3] with length 1

goroutine 14 [running]:
encoding/binary.littleEndian.Uint32(...)
	/Users/voidint/.g/go/src/encoding/binary/binary.go:63
github.com/40t/go-sniffer/plugSrc/mysql/build.LengthBinary(0xc000490001, 0x31, 0x5ff, 0x4031ce0, 0x44c3230)
	/Users/voidint/workspace/go/src/github.com/40t/go-sniffer/plugSrc/mysql/build/util.go:41 +0xd4
github.com/40t/go-sniffer/plugSrc/mysql/build.(*stream).resolveServerPacket(0xc000402600, 0xc000490000, 0x32, 0x600, 0x1)
	/Users/voidint/workspace/go/src/github.com/40t/go-sniffer/plugSrc/mysql/build/entry.go:235 +0x306
github.com/40t/go-sniffer/plugSrc/mysql/build.(*stream).resolve(0xc000402600)
	/Users/voidint/workspace/go/src/github.com/40t/go-sniffer/plugSrc/mysql/build/entry.go:195 +0xc5
created by github.com/40t/go-sniffer/plugSrc/mysql/build.(*Mysql).ResolveStream
	/Users/voidint/workspace/go/src/github.com/40t/go-sniffer/plugSrc/mysql/build/entry.go:71 +0x3b6

voidint avatar Dec 05 '19 07:12 voidint

error while server OK packet to return the number of result record

https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html

To convert a length-encoded integer into its numeric value, check the first byte:

https://dev.mysql.com/doc/internals/en/integer.html#packet-Protocol::LengthEncodedInteger

takaidohigasi avatar Mar 16 '20 11:03 takaidohigasi

How to reproduce

execute query which affected rows is larger than 2-byte integer

[email protected] [sbtest] > desc sbtest1;
+-------+-----------+------+-----+---------+----------------+
| Field | Type      | Null | Key | Default | Extra          |
+-------+-----------+------+-----+---------+----------------+
| id    | int(11)   | NO   | PRI | NULL    | auto_increment |
| k     | int(11)   | NO   | MUL | 0       |                |
| c     | char(120) | NO   |     |         |                |
| pad   | char(60)  | NO   |     |         |                |
+-------+-----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

[email protected] [sbtest] > update sbtest1 set c='fuga' where id<100000;
Query OK, 99999 rows affected (0.24 sec)
Rows matched: 99999  Changed: 99999  Warnings: 0

and we can got the correct affected rows by the following modification

diff --git a/plugSrc/mysql/build/entry.go b/plugSrc/mysql/build/entry.go
index 4a1ba39..3859fd6 100644
--- a/plugSrc/mysql/build/entry.go
+++ b/plugSrc/mysql/build/entry.go
@@ -232,7 +232,7 @@ func (stm *stream) resolveServerPacket(payload []byte, seq int) {

                case 0x00:
                        var pos = 1
-                       l,_ := LengthBinary(payload[pos:])
+                       l,_,_ := LengthEncodedInt(payload[pos:])
                        affectedRows := int(l)

takaidohigasi avatar Mar 16 '20 12:03 takaidohigasi