This is an automated email from the ASF dual-hosted git repository.
terrymanu 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 52c265e6dae Fix zero-length MySQL binary TIME decoding (#39233)
52c265e6dae is described below
commit 52c265e6dae187f57e9391d45bf21e625721e373
Author: Gimin Kim <[email protected]>
AuthorDate: Tue Jul 28 13:30:41 2026 +0900
Fix zero-length MySQL binary TIME decoding (#39233)
* Fix zero-length MySQL binary TIME decoding
* Update release note link
---------
Co-authored-by: Gimin Kim <[email protected]>
---
RELEASE-NOTES.md | 1 +
.../execute/protocol/MySQLTimeBinaryProtocolValue.java | 4 ++--
.../execute/protocol/MySQLTimeBinaryProtocolValueTest.java | 14 +++++++++++---
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 4a78208c24d..6235a2df527 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -32,6 +32,7 @@
1. Proxy: Fix empty array literal decoding in PostgreSQL array parameter
decoder - [#39137](https://github.com/apache/shardingsphere/pull/39137)
1. Proxy: Fix incorrect generated key handling for explicit auto-increment
values - [#38810](https://github.com/apache/shardingsphere/pull/38810)
1. Proxy: Fix microseconds decoded as nanoseconds in MySQL binary TIME value -
[#39138](https://github.com/apache/shardingsphere/pull/39138)
+1. Proxy: Avoid consuming following prepared statement parameter bytes for
zero-length MySQL binary TIME values -
[#39233](https://github.com/apache/shardingsphere/pull/39233)
1. Proxy: Fix MySQL BLOB data corruption when string-like prepared statement
parameters target BLOB columns -
[#39072](https://github.com/apache/shardingsphere/pull/39072)
1. Proxy: Add MySQL exception mapping for ColumnNotFoundException -
[#39126](https://github.com/apache/shardingsphere/pull/39126)
1. Proxy: Fix MySQL prepared statement parameter signedness decoding -
[#39204](https://github.com/apache/shardingsphere/pull/39204)
diff --git
a/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValue.java
b/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValue.java
index 4ba541b8136..6df0dfbe68c 100644
---
a/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValue.java
+++
b/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValue.java
@@ -35,8 +35,6 @@ public final class MySQLTimeBinaryProtocolValue implements
MySQLBinaryProtocolVa
@Override
public Object read(final MySQLPacketPayload payload, final boolean
unsigned) throws SQLException {
int length = payload.readInt1();
- payload.readInt1();
- payload.readInt4();
switch (length) {
case 0:
return new Timestamp(0L);
@@ -52,6 +50,8 @@ public final class MySQLTimeBinaryProtocolValue implements
MySQLBinaryProtocolVa
}
private Timestamp getTimestamp(final MySQLPacketPayload payload) {
+ payload.readInt1();
+ payload.readInt4();
Timestamp result = Timestamp.valueOf(LocalDateTime.of(0, 1, 1,
payload.readInt1(), payload.readInt1(), payload.readInt1()));
result.setNanos(0);
return result;
diff --git
a/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValueTest.java
b/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValueTest.java
index 2cfe1d8928a..26462b2ce26 100644
---
a/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValueTest.java
+++
b/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/protocol/MySQLTimeBinaryProtocolValueTest.java
@@ -17,6 +17,7 @@
package
org.apache.shardingsphere.database.protocol.mysql.packet.command.query.binary.execute.protocol;
+import io.netty.buffer.Unpooled;
import
org.apache.shardingsphere.database.protocol.mysql.payload.MySQLPacketPayload;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -27,6 +28,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Time;
@@ -66,10 +68,17 @@ class MySQLTimeBinaryProtocolValueTest {
assertThat(binaryProtocolValue.read(payload, false), is(expected));
}
+ @Test
+ void assertReadZeroLengthDoesNotConsumeNextParameterBytes() throws
SQLException {
+ byte[] data = {0x00, (byte) 0xd2, 0x04, 0x00, 0x00};
+ MySQLPacketPayload realPayload = new
MySQLPacketPayload(Unpooled.wrappedBuffer(data), StandardCharsets.UTF_8);
+ assertThat(binaryProtocolValue.read(realPayload, false), is(new
Timestamp(0L)));
+ assertThat(realPayload.readInt4(), is(1234));
+ }
+
@Test
void assertReadWithUnsupportedLength() {
- when(payload.readInt1()).thenReturn(100, 0);
- when(payload.readInt4()).thenReturn(0);
+ when(payload.readInt1()).thenReturn(100);
SQLFeatureNotSupportedException actual =
assertThrows(SQLFeatureNotSupportedException.class, () ->
binaryProtocolValue.read(payload, false));
assertThat(actual.getMessage(), is("Wrong length `100` of
MYSQL_TYPE_DATE"));
}
@@ -95,7 +104,6 @@ class MySQLTimeBinaryProtocolValueTest {
private static Stream<Arguments> readArguments() {
return Stream.of(
- Arguments.of("zero_length", new int[]{0, 0, 0, 0, 0}, new
int[]{0, 0}, new Timestamp(0L)),
Arguments.of("eight_bytes", new int[]{8, 0, 10, 59, 0}, new
int[]{0, 0}, createTimestamp(0)),
Arguments.of("twelve_bytes", new int[]{12, 0, 10, 59, 0}, new
int[]{0, 1000}, createTimestamp(1_000_000)),
Arguments.of("twelve_bytes_fractional_second", new int[]{12,
0, 10, 59, 0}, new int[]{0, 230000}, createTimestamp(230_000_000)));