Skip to content

Commit 9db6daf

Browse files
fixes
1 parent dce449e commit 9db6daf

File tree

4 files changed

+32
-30
lines changed

4 files changed

+32
-30
lines changed

canal/canal_test.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,13 +388,10 @@ func TestGenerateCharsetQuery(t *testing.T) {
388388
expected := `
389389
SELECT
390390
c.ORDINAL_POSITION,
391-
COALESCE(
392-
c.CHARACTER_SET_NAME,
393-
CASE
394-
WHEN c.DATA_TYPE IN ('binary','varbinary','tinyblob','blob','mediumblob','longblob') THEN col.CHARACTER_SET_NAME
395-
ELSE NULL
396-
END
397-
) AS CHARACTER_SET_NAME,
391+
CASE
392+
WHEN c.CHARACTER_SET_NAME IS NOT NULL THEN c.CHARACTER_SET_NAME
393+
WHEN c.DATA_TYPE IN ('binary','varbinary','tinyblob','blob','mediumblob','longblob') THEN col.CHARACTER_SET_NAME
394+
END AS CHARACTER_SET_NAME,
398395
c.COLUMN_NAME
399396
FROM
400397
information_schema.COLUMNS c

cmd/go-binlogparser/.!93441!main.go

Whitespace-only changes.

replication/row_event.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strconv"
2323
"strings"
2424
"time"
25+
"unicode/utf8"
2526
)
2627

2728
var errMissingTableMapEvent = errors.New("invalid table id, no corresponding table map event")
@@ -1195,8 +1196,12 @@ func convertToString(s interface{}) (string, bool) {
11951196
}
11961197
switch v := s.(type) {
11971198
case []uint8:
1198-
str := sanitizeNonPrintable(string(v))
1199-
return str, true
1199+
// Only convert to string if the bytes are valid UTF-8; otherwise keep as bytes
1200+
if utf8.Valid(v) {
1201+
str := string(v)
1202+
return str, true
1203+
}
1204+
return "", false
12001205
default:
12011206
return "", false
12021207
}
@@ -1206,16 +1211,13 @@ func decodeStringByCharSet(data []byte, charset string, length int) (v string, n
12061211
enc, err := getDecoderByCharsetName(charset)
12071212
if err != nil {
12081213
log.Errorf(err.Error())
1209-
v, n = decodeString(data, length)
1210-
return sanitizeNonPrintable(v), n
1214+
return decodeString(data, length)
12111215
}
12121216
if enc == nil {
12131217
log.Warnf("Falling back to default decoding for charset: %s", charset)
1214-
v, n = decodeString(data, length)
1215-
return sanitizeNonPrintable(v), n
1218+
return decodeString(data, length)
12161219
}
1217-
v, n = decodeStringWithEncoder(data, length, enc)
1218-
return sanitizeNonPrintable(v), n
1220+
return decodeStringWithEncoder(data, length, enc)
12191221
}
12201222

12211223
// sanitizeNonPrintable replaces non-printable runes with space for readability.

replication/row_event_test.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,27 +1614,30 @@ func TestDecodeByCharSet(t *testing.T) {
16141614
}
16151615
}
16161616

1617-
func TestDecodeValueBinaryLatin1Fallback(t *testing.T) {
1617+
func TestDecodeValueBinaryFallback(t *testing.T) {
16181618
// Simulate VARCHAR/VAR_STRING with charset binary and invalid UTF-8
16191619
e := &RowsEvent{}
16201620
// Length-encoded: 1-byte length + bytes
16211621
// bytes correspond to expected visual string "1rHuÎ ð XÅXÄ " after mapping
16221622
// include two leading control bytes [0x86, 0x11] which should become spaces,
16231623
// and a trailing 0x01 which also becomes a space
16241624
raw := []byte{0x11, 0x86, 0x11, '1', 'r', 'H', 'u', 0xce, 0x20, 0xf0, 0x20, 0x20, 0x20, 'X', 0xc5, 'X', 0xc4, 0x01}
1625-
v, n, err := e.decodeValue(raw, mysql.MYSQL_TYPE_VAR_STRING, "latin1", 255)
1626-
if err != nil {
1627-
t.Fatalf("decodeValue error: %v", err)
1628-
}
1629-
if n != int(raw[0])+1 {
1630-
t.Fatalf("read length = %d, want %d", n, int(raw[0])+1)
1631-
}
1632-
s, ok := v.(string)
1633-
if !ok {
1634-
t.Fatalf("value type = %T, want string", v)
1635-
}
1636-
want := " 1rHuÎ ð XÅXÄ "
1637-
if s != want {
1638-
t.Fatalf("decoded string = %q, want %q", s, want)
1625+
charsets := []string{"latin1", "utf8", "utf8mb4", "cp1251", "greek", "hebrew", "cp1256", "gbk", "big5", "sjis"}
1626+
for _, cs := range charsets {
1627+
v, n, err := e.decodeValue(raw, mysql.MYSQL_TYPE_VAR_STRING, cs, 255)
1628+
if err != nil {
1629+
t.Fatalf("decodeValue error (charset=%s): %v", cs, err)
1630+
}
1631+
if n != int(raw[0])+1 {
1632+
t.Fatalf("read length = %d, want %d (charset=%s)", n, int(raw[0])+1, cs)
1633+
}
1634+
s, ok := v.(string)
1635+
if !ok {
1636+
t.Fatalf("value type = %T, want string (charset=%s)", v, cs)
1637+
}
1638+
want := " 1rHuÎ ð XÅXÄ "
1639+
if s != want {
1640+
t.Fatalf("decoded string (charset=%s) = %q, want %q", cs, s, want)
1641+
}
16391642
}
16401643
}

0 commit comments

Comments
 (0)