From 12028e57ff3aa2cd726529448b153727c51db448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Sat, 26 Oct 2024 11:02:03 +0200 Subject: [PATCH] replication: Make ServerVersion a proper string The ServerVersion is a slice of 50 bytes. If the ServerVersion was "9.1.0" then the rest of they bytes would be 0x0. This caused the printout of the FormatDescriptionEvent in go-mysqlbinlog to look weird. Before: ``` === FormatDescriptionEvent === Date: 2024-10-24 14:42:04 Log position: 127 Event size: 123 Version: 4 Server version: 9.1.0^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ Checksum algorithm: 1 ``` After: ``` === FormatDescriptionEvent === Date: 2024-10-24 14:42:04 Log position: 127 Event size: 123 Version: 4 Server version: 9.1.0 Checksum algorithm: 1 ``` --- replication/event.go | 21 +++++++++++++-------- replication/parser_test.go | 4 ++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/replication/event.go b/replication/event.go index b9e13bf1a..6fb614f61 100644 --- a/replication/event.go +++ b/replication/event.go @@ -1,6 +1,7 @@ package replication import ( + "bytes" "encoding/binary" "encoding/hex" "fmt" @@ -145,9 +146,8 @@ func calcVersionProduct(server string) int { } type FormatDescriptionEvent struct { - Version uint16 - //len = 50 - ServerVersion []byte + Version uint16 + ServerVersion string CreateTimestamp uint32 EventHeaderLength uint8 EventTypeHeaderLengths []byte @@ -161,8 +161,8 @@ func (e *FormatDescriptionEvent) Decode(data []byte) error { e.Version = binary.LittleEndian.Uint16(data[pos:]) pos += 2 - e.ServerVersion = make([]byte, 50) - copy(e.ServerVersion, data[pos:]) + serverVersionRaw := make([]byte, 50) + copy(serverVersionRaw, data[pos:]) pos += 50 e.CreateTimestamp = binary.LittleEndian.Uint32(data[pos:]) @@ -175,13 +175,18 @@ func (e *FormatDescriptionEvent) Decode(data []byte) error { return errors.Errorf("invalid event header length %d, must 19", e.EventHeaderLength) } - server := string(e.ServerVersion) + serverVersionLength := bytes.Index(serverVersionRaw, []byte{0x0}) + if serverVersionLength < 0 { + e.ServerVersion = string(serverVersionRaw) + } else { + e.ServerVersion = string(serverVersionRaw[:serverVersionLength]) + } checksumProduct := checksumVersionProductMysql - if strings.Contains(strings.ToLower(server), "mariadb") { + if strings.Contains(strings.ToLower(e.ServerVersion), "mariadb") { checksumProduct = checksumVersionProductMariaDB } - if calcVersionProduct(string(e.ServerVersion)) >= checksumProduct { + if calcVersionProduct(e.ServerVersion) >= checksumProduct { // here, the last 5 bytes is 1 byte check sum alg type and 4 byte checksum if exists e.ChecksumAlgorithm = data[len(data)-5] e.EventTypeHeaderLengths = data[pos : len(data)-5] diff --git a/replication/parser_test.go b/replication/parser_test.go index d1774f8c7..165038109 100644 --- a/replication/parser_test.go +++ b/replication/parser_test.go @@ -12,7 +12,7 @@ func TestIndexOutOfRange(t *testing.T) { parser.format = &FormatDescriptionEvent{ Version: 0x4, - ServerVersion: []uint8{0x35, 0x2e, 0x36, 0x2e, 0x32, 0x30, 0x2d, 0x6c, 0x6f, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + ServerVersion: "8.0.11", CreateTimestamp: 0x0, EventHeaderLength: 0x13, EventTypeHeaderLengths: []uint8{0x38, 0xd, 0x0, 0x8, 0x0, 0x12, 0x0, 0x4, 0x4, 0x4, 0x4, 0x12, 0x0, 0x0, 0x5c, 0x0, 0x4, 0x1a, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x2, 0x0, 0x0, 0x0, 0xa, 0xa, 0xa, 0x19, 0x19, 0x0, 0x12, 0x34, 0x0, 0xa, 0x28, 0x0}, @@ -48,7 +48,7 @@ func TestParseEvent(t *testing.T) { parser := NewBinlogParser() parser.format = &FormatDescriptionEvent{ Version: 0x4, - ServerVersion: []uint8{0x35, 0x2e, 0x36, 0x2e, 0x32, 0x30, 0x2d, 0x6c, 0x6f, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + ServerVersion: "8.0.11", CreateTimestamp: 0x0, EventHeaderLength: 0x13, EventTypeHeaderLengths: []uint8{0x38, 0xd, 0x0, 0x8, 0x0, 0x12, 0x0, 0x4, 0x4, 0x4, 0x4, 0x12, 0x0, 0x0, 0x5c, 0x0, 0x4, 0x1a, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x2, 0x0, 0x0, 0x0, 0xa, 0xa, 0xa, 0x19, 0x19, 0x0, 0x12, 0x34, 0x0, 0xa, 0x28, 0x0},