Skip to content

Commit 2a3d211

Browse files
committed
collation in auth handshake are 1-byte
1 parent 8551be2 commit 2a3d211

File tree

3 files changed

+21
-15
lines changed

3 files changed

+21
-15
lines changed

client/auth.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,6 @@ func (c *Conn) writeAuthHandshake() error {
284284
// the 23 bytes of filler is used to send the right middle 8 bits of the collation id.
285285
// see https://github.com/mysql/mysql-server/pull/541
286286
data[12] = byte(collation.ID & 0xff)
287-
// if the collation ID is <= 255 the middle 8 bits are 0s so this is the equivalent of
288-
// padding the filler with a 0. If ID is > 255 then the first byte of filler will contain
289-
// the right middle 8 bits of the collation ID.
290-
data[13] = byte((collation.ID & 0xff00) >> 8)
291287

292288
// SSL Connection Request Packet
293289
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
@@ -309,12 +305,8 @@ func (c *Conn) writeAuthHandshake() error {
309305
}
310306

311307
// Filler [23 bytes] (all 0x00)
312-
// the filler starts at position 13, but the first byte of the filler
313-
// has been set with the collation id earlier, so position 13 at this point
314-
// will be either 0x00, or the right middle 8 bits of the collation id.
315-
// Therefore, we start at position 14 and fill the remaining 22 bytes with 0x00.
316-
pos := 14
317-
for ; pos < 14+22; pos++ {
308+
pos := 13
309+
for ; pos < 13+23; pos++ {
318310
data[pos] = 0
319311
}
320312

client/auth_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ func TestConnCollation(t *testing.T) {
6666
// if the collation ID is <= 255 the collation ID is stored in the 12th byte
6767
if collation.ID <= 255 {
6868
require.Equal(t, byte(collation.ID), handShakeResponse[12])
69-
// the 13th byte should always be 0x00
70-
require.Equal(t, byte(0x00), handShakeResponse[13])
7169
} else {
72-
// if the collation ID is > 255 the collation ID is stored in the 12th and 13th bytes
70+
// if the collation ID is > 255 the collation ID should just be the lower-8 bits
7371
require.Equal(t, byte(collation.ID&0xff), handShakeResponse[12])
74-
require.Equal(t, byte(collation.ID>>8), handShakeResponse[13])
7572
}
7673

74+
// the 13th byte should always be 0x00
75+
require.Equal(t, byte(0x00), handShakeResponse[13])
76+
7777
// sanity check: validate the 22 bytes of filler with value 0x00 are set correctly
78-
for i := 14; i < 14+22; i++ {
78+
for i := 13; i < 13+23; i++ {
7979
require.Equal(t, byte(0x00), handShakeResponse[i])
8080
}
8181

client/conn.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/pingcap/errors"
14+
"github.com/pingcap/tidb/pkg/parser/charset"
1415

1516
. "github.com/go-mysql-org/go-mysql/mysql"
1617
"github.com/go-mysql-org/go-mysql/packet"
@@ -133,6 +134,19 @@ func ConnectWithDialer(ctx context.Context, network string, addr string, user st
133134
c.Conn.Compression = MYSQL_COMPRESS_ZSTD
134135
}
135136

137+
// if a collation was set with a ID of > 255, then we need to call SET NAMES ...
138+
// since the auth handshake response only support collations with 1-byte ids
139+
if len(c.collation) != 0 {
140+
collation, err := charset.GetCollationByName(c.collation)
141+
if err != nil {
142+
return nil, errors.Trace(fmt.Errorf("invalid collation name %s", c.collation))
143+
}
144+
145+
if collation.ID > 255 {
146+
c.SetCharset(c.collation)
147+
}
148+
}
149+
136150
return c, nil
137151
}
138152

0 commit comments

Comments
 (0)