From 0520500059aedb6c1bcb07b8abf8d8ff82009798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Fri, 7 Feb 2025 16:00:02 +0100 Subject: [PATCH 1/2] server: Correctly handle COM_STMT_EXECUTE without rebind --- server/stmt.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/server/stmt.go b/server/stmt.go index 56c80c507..95a46b068 100644 --- a/server/stmt.go +++ b/server/stmt.go @@ -155,10 +155,10 @@ func (c *Conn) handleStmtExecute(data []byte) (*mysql.Result, error) { pos += paramNum << 1 paramValues = data[pos:] - } - if err := c.bindStmtArgs(s, nullBitmaps, paramTypes, paramValues); err != nil { - return nil, errors.Trace(err) + if err := c.bindStmtArgs(s, nullBitmaps, paramTypes, paramValues); err != nil { + return nil, errors.Trace(err) + } } } @@ -176,6 +176,11 @@ func (c *Conn) handleStmtExecute(data []byte) (*mysql.Result, error) { func (c *Conn) bindStmtArgs(s *Stmt, nullBitmap, paramTypes, paramValues []byte) error { args := s.Args + // Every param should have a 1-byte type and a 1-byte flag + if len(paramTypes)/2 != s.Params { + return mysql.ErrMalformPacket + } + pos := 0 var v []byte @@ -190,7 +195,7 @@ func (c *Conn) bindStmtArgs(s *Stmt, nullBitmap, paramTypes, paramValues []byte) } tp := paramTypes[i<<1] - isUnsigned := (paramTypes[(i<<1)+1] & 0x80) > 0 + isUnsigned := (paramTypes[(i<<1)+1] & mysql.PARAM_UNSIGNED) > 0 switch tp { case mysql.MYSQL_TYPE_NULL: From cfbbb8a3da599d447342d7c40fa29698612b34b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Fri, 7 Feb 2025 16:03:31 +0100 Subject: [PATCH 2/2] update comment --- server/stmt.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/stmt.go b/server/stmt.go index 95a46b068..cc99b40ba 100644 --- a/server/stmt.go +++ b/server/stmt.go @@ -176,7 +176,10 @@ func (c *Conn) handleStmtExecute(data []byte) (*mysql.Result, error) { func (c *Conn) bindStmtArgs(s *Stmt, nullBitmap, paramTypes, paramValues []byte) error { args := s.Args - // Every param should have a 1-byte type and a 1-byte flag + // Every param should have a type-and-flag of 2 bytes + // 0xfe80 == Type 0xfe and Flag 0x80 + // The flag only has one bit and that indicates if it is unsigned or not. + // Types are 1 byte, but might grow into the 7 unused bits in the future. if len(paramTypes)/2 != s.Params { return mysql.ErrMalformPacket }