You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2020/10/11 09:18:40 UTC

[shardingsphere] branch master updated: Fix mysql binlog type decode (#7725)

This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 37efe1c  Fix mysql binlog type decode (#7725)
37efe1c is described below

commit 37efe1c94a05fa3d23f3dd69f80783fbdaefe54e
Author: avalon5666 <64...@users.noreply.github.com>
AuthorDate: Sun Oct 11 17:18:14 2020 +0800

    Fix mysql binlog type decode (#7725)
    
    * Fix mysql binlog type decode
    
    * For checkstyle
---
 .../value/string/MySQLStringBinlogProtocolValue.java | 20 +++++++++++++++++---
 .../string/MySQLStringBinlogProtocolValueTest.java   | 10 ++++++++++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValue.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValue.java
index 27f2479..36c25f5 100644
--- a/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValue.java
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValue.java
@@ -31,18 +31,32 @@ public final class MySQLStringBinlogProtocolValue implements MySQLBinlogProtocol
     
     @Override
     public Serializable read(final MySQLBinlogColumnDef columnDef, final MySQLPacketPayload payload) {
-        switch (MySQLColumnType.valueOf(columnDef.getColumnMeta() >> 8)) {
+        int type = columnDef.getColumnMeta() >> 8;
+        int length = columnDef.getColumnMeta() & 0xff;
+        // unpack type & length, see https://bugs.mysql.com/bug.php?id=37426.
+        if ((type & 0x30) != 0x30) {
+            length += ((type & 0x30) ^ 0x30) << 4;
+            type |= 0x30;
+        }
+        switch (MySQLColumnType.valueOf(type)) {
             case MYSQL_TYPE_ENUM:
-                return readEnumValue(columnDef.getColumnMeta() & 0xff, payload);
+                return readEnumValue(length, payload);
             case MYSQL_TYPE_SET:
                 return payload.getByteBuf().readByte();
             case MYSQL_TYPE_STRING:
-                return payload.readStringFix(payload.getByteBuf().readUnsignedByte());
+                return payload.readStringFix(readActualLength(length, payload));
             default:
                 throw new UnsupportedOperationException("");
         }
     }
     
+    private int readActualLength(final int length, final MySQLPacketPayload payload) {
+        if (length < 256) {
+            return payload.getByteBuf().readUnsignedByte();
+        }
+        return payload.getByteBuf().readUnsignedShortLE();
+    }
+    
     private Serializable readEnumValue(final int meta, final MySQLPacketPayload payload) {
         switch (meta) {
             case 1:
diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValueTest.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValueTest.java
index 371eaaa..7f91c50 100644
--- a/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValueTest.java
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/binlog/row/column/value/string/MySQLStringBinlogProtocolValueTest.java
@@ -85,6 +85,16 @@ public final class MySQLStringBinlogProtocolValueTest {
         assertThat(new MySQLStringBinlogProtocolValue().read(columnDef, payload), is(expected));
     }
     
+    @Test
+    public void assertReadLongStringValue() {
+        String expected = "test_value";
+        columnDef.setColumnMeta((MySQLColumnType.MYSQL_TYPE_STRING.getValue() ^ ((256 & 0x300) >> 4)) << 8);
+        when(payload.getByteBuf()).thenReturn(byteBuf);
+        when(byteBuf.readUnsignedShortLE()).thenReturn(expected.length());
+        when(payload.readStringFix(expected.length())).thenReturn(expected);
+        assertThat(new MySQLStringBinlogProtocolValue().read(columnDef, payload), is(expected));
+    }
+    
     @Test(expected = UnsupportedOperationException.class)
     public void assertReadValueWithUnknownType() {
         columnDef.setColumnMeta(MySQLColumnType.MYSQL_TYPE_VAR_STRING.getValue() << 8);