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

zhaojinchao 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 034c7bde9c0 Fix raw bytes corrupted when decoding FIELD_TYPE_STRING in 
MySQL protocol (#28236)
034c7bde9c0 is described below

commit 034c7bde9c0d84a35275374e7faeca14c18fa059
Author: 吴伟杰 <wuwei...@apache.org>
AuthorDate: Wed Aug 23 17:52:18 2023 +0800

    Fix raw bytes corrupted when decoding FIELD_TYPE_STRING in MySQL protocol 
(#28236)
    
    * Fix raw bytes corrupted when decoding FIELD_TYPE_STRING in MySQL protocol
    
    * Apply spotless
---
 .../protocol/MySQLBinaryProtocolValueFactory.java  | 15 ++++---
 .../MySQLByteLenencBinaryProtocolValue.java        | 40 +++++++++++++++++
 .../MySQLBinaryProtocolValueFactoryTest.java       | 10 ++---
 .../MySQLByteLenencBinaryProtocolValueTest.java    | 52 ++++++++++++++++++++++
 4 files changed, 107 insertions(+), 10 deletions(-)

diff --git 
a/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactory.java
 
b/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactory.java
index 60e6aa885ea..d27b28ba46a 100644
--- 
a/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactory.java
+++ 
b/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactory.java
@@ -36,6 +36,7 @@ public final class MySQLBinaryProtocolValueFactory {
     
     static {
         setStringLenencBinaryProtocolValue();
+        setByteLenencBinaryProtocolValue();
         setInt8BinaryProtocolValue();
         setInt4BinaryProtocolValue();
         setInt2BinaryProtocolValue();
@@ -49,21 +50,25 @@ public final class MySQLBinaryProtocolValueFactory {
     
     private static void setStringLenencBinaryProtocolValue() {
         MySQLStringLenencBinaryProtocolValue binaryProtocolValue = new 
MySQLStringLenencBinaryProtocolValue();
-        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.STRING, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.VARCHAR, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.VAR_STRING, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.ENUM, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.SET, 
binaryProtocolValue);
-        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.LONG_BLOB, 
binaryProtocolValue);
-        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.MEDIUM_BLOB, 
binaryProtocolValue);
-        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.BLOB, 
binaryProtocolValue);
-        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.TINY_BLOB, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.GEOMETRY, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.BIT, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.DECIMAL, 
binaryProtocolValue);
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.NEWDECIMAL, 
binaryProtocolValue);
     }
     
+    private static void setByteLenencBinaryProtocolValue() {
+        MySQLByteLenencBinaryProtocolValue binaryProtocolValue = new 
MySQLByteLenencBinaryProtocolValue();
+        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.STRING, 
binaryProtocolValue);
+        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.LONG_BLOB, 
binaryProtocolValue);
+        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.MEDIUM_BLOB, 
binaryProtocolValue);
+        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.BLOB, 
binaryProtocolValue);
+        BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.TINY_BLOB, 
binaryProtocolValue);
+    }
+    
     private static void setInt8BinaryProtocolValue() {
         MySQLInt8BinaryProtocolValue binaryProtocolValue = new 
MySQLInt8BinaryProtocolValue();
         BINARY_PROTOCOL_VALUES.put(MySQLBinaryColumnType.LONGLONG, 
binaryProtocolValue);
diff --git 
a/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLByteLenencBinaryProtocolValue.java
 
b/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLByteLenencBinaryProtocolValue.java
new file mode 100644
index 00000000000..84003a99d92
--- /dev/null
+++ 
b/db-protocol/mysql/src/main/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLByteLenencBinaryProtocolValue.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.db.protocol.mysql.packet.command.query.binary.execute.protocol;
+
+import org.apache.shardingsphere.db.protocol.mysql.payload.MySQLPacketPayload;
+
+/**
+ * Binary protocol value for byte lenenc for MySQL. Actually this is string 
lenenc, but converting to {@link String} may corrupt the raw bytes.
+ */
+public final class MySQLByteLenencBinaryProtocolValue implements 
MySQLBinaryProtocolValue {
+    
+    @Override
+    public Object read(final MySQLPacketPayload payload, final boolean 
unsigned) {
+        return payload.readStringLenencByBytes();
+    }
+    
+    @Override
+    public void write(final MySQLPacketPayload payload, final Object value) {
+        if (value instanceof byte[]) {
+            payload.writeBytesLenenc((byte[]) value);
+        } else {
+            payload.writeStringLenenc(value.toString());
+        }
+    }
+}
diff --git 
a/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactoryTest.java
 
b/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactoryTest.java
index fb4801aa44e..1ddf0b8fade 100644
--- 
a/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactoryTest.java
+++ 
b/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLBinaryProtocolValueFactoryTest.java
@@ -29,7 +29,7 @@ class MySQLBinaryProtocolValueFactoryTest {
     
     @Test
     void assertGetBinaryProtocolValueWithMySQLTypeString() {
-        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.STRING),
 instanceOf(MySQLStringLenencBinaryProtocolValue.class));
+        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.STRING),
 instanceOf(MySQLByteLenencBinaryProtocolValue.class));
     }
     
     @Test
@@ -54,22 +54,22 @@ class MySQLBinaryProtocolValueFactoryTest {
     
     @Test
     void assertGetBinaryProtocolValueWithMySQLTypeLongBlob() {
-        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.LONG_BLOB),
 instanceOf(MySQLStringLenencBinaryProtocolValue.class));
+        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.LONG_BLOB),
 instanceOf(MySQLByteLenencBinaryProtocolValue.class));
     }
     
     @Test
     void assertGetBinaryProtocolValueWithMySQLTypeMediumBlob() {
-        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.MEDIUM_BLOB),
 instanceOf(MySQLStringLenencBinaryProtocolValue.class));
+        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.MEDIUM_BLOB),
 instanceOf(MySQLByteLenencBinaryProtocolValue.class));
     }
     
     @Test
     void assertGetBinaryProtocolValueWithMySQLTypeBlob() {
-        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.BLOB),
 instanceOf(MySQLStringLenencBinaryProtocolValue.class));
+        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.BLOB),
 instanceOf(MySQLByteLenencBinaryProtocolValue.class));
     }
     
     @Test
     void assertGetBinaryProtocolValueWithMySQLTypeTinyBlob() {
-        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.TINY_BLOB),
 instanceOf(MySQLStringLenencBinaryProtocolValue.class));
+        
assertThat(MySQLBinaryProtocolValueFactory.getBinaryProtocolValue(MySQLBinaryColumnType.TINY_BLOB),
 instanceOf(MySQLByteLenencBinaryProtocolValue.class));
     }
     
     @Test
diff --git 
a/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLByteLenencBinaryProtocolValueTest.java
 
b/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLByteLenencBinaryProtocolValueTest.java
new file mode 100644
index 00000000000..6ee5d588ebf
--- /dev/null
+++ 
b/db-protocol/mysql/src/test/java/org/apache/shardingsphere/db/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLByteLenencBinaryProtocolValueTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.db.protocol.mysql.packet.command.query.binary.execute.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import org.apache.shardingsphere.db.protocol.mysql.payload.MySQLPacketPayload;
+import org.junit.jupiter.api.Test;
+
+import java.nio.charset.StandardCharsets;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+class MySQLByteLenencBinaryProtocolValueTest {
+    
+    @Test
+    void assertRead() {
+        byte[] input = {0x0d, 0x0a, 0x33, 0x18, 0x01, 0x4a, 0x08, 0x0a, (byte) 
0x9a, 0x01, 0x18, 0x01, 0x4a, 0x6f};
+        byte[] expected = {0x0a, 0x33, 0x18, 0x01, 0x4a, 0x08, 0x0a, (byte) 
0x9a, 0x01, 0x18, 0x01, 0x4a, 0x6f};
+        ByteBuf byteBuf = Unpooled.wrappedBuffer(input);
+        MySQLPacketPayload payload = new MySQLPacketPayload(byteBuf, 
StandardCharsets.UTF_8);
+        byte[] actual = (byte[]) new 
MySQLByteLenencBinaryProtocolValue().read(payload, false);
+        assertThat(actual, is(expected));
+    }
+    
+    @Test
+    void assertWrite() {
+        byte[] input = {0x0a, 0x33, 0x18, 0x01, 0x4a, 0x08, 0x0a, (byte) 0x9a, 
0x01, 0x18, 0x01, 0x4a, 0x6f};
+        byte[] expected = {0x0d, 0x0a, 0x33, 0x18, 0x01, 0x4a, 0x08, 0x0a, 
(byte) 0x9a, 0x01, 0x18, 0x01, 0x4a, 0x6f};
+        ByteBuf actual = Unpooled.wrappedBuffer(new 
byte[expected.length]).writerIndex(0);
+        MySQLPacketPayload payload = new MySQLPacketPayload(actual, 
StandardCharsets.UTF_8);
+        new MySQLByteLenencBinaryProtocolValue().write(payload, input);
+        assertThat(ByteBufUtil.getBytes(actual), is(expected));
+    }
+}

Reply via email to