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 ef630cba2e9 Fix firebird blob unknown handle (#40100)
ef630cba2e9 is described below
commit ef630cba2e9e22bdb544352055ce921620200269
Author: Maxim Igoshin <[email protected]>
AuthorDate: Sat Oct 17 04:57:37 2026 +0300
Fix firebird blob unknown handle (#40100)
* Reject Firebird op_get_segment with an unknown BLOB handle
The server answers op_get_segment for a BLOB handle that is not open on the
connection with isc_bad_segstr_handle instead of the end of BLOB.
* Fix CODE_OF_CONDUCT violations in Firebird BLOB segment handle tests
---
.../FirebirdGetBlobSegmentCommandExecutor.java | 3 ++
.../FirebirdGetBlobSegmentCommandExecutorTest.java | 40 ++++++++++++++++------
2 files changed, 33 insertions(+), 10 deletions(-)
diff --git
a/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutor.java
b/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutor.java
index 1a2e3620375..28f7f9edaea 100644
---
a/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutor.java
+++
b/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutor.java
@@ -18,10 +18,12 @@
package org.apache.shardingsphere.proxy.frontend.firebird.command.query.blob;
import lombok.RequiredArgsConstructor;
+import
org.apache.shardingsphere.database.exception.firebird.exception.protocol.InvalidSegstrHandleException;
import
org.apache.shardingsphere.database.protocol.firebird.packet.command.query.blob.FirebirdGetBlobSegmentCommandPacket;
import
org.apache.shardingsphere.database.protocol.firebird.packet.command.query.blob.FirebirdGetBlobSegmentResponsePacket;
import
org.apache.shardingsphere.database.protocol.firebird.packet.generic.FirebirdGenericResponsePacket;
import org.apache.shardingsphere.database.protocol.packet.DatabasePacket;
+import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
import
org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor;
import
org.apache.shardingsphere.proxy.frontend.firebird.command.query.blob.cache.FirebirdBlobReadCache;
@@ -63,6 +65,7 @@ public final class FirebirdGetBlobSegmentCommandExecutor
implements CommandExecu
public Collection<DatabasePacket> execute() {
int connectionId = connectionSession.getConnectionId();
int blobHandle =
FirebirdBlobHandleGenerator.getInstance().resolveBlobHandle(connectionId,
packet.getBlobHandle());
+
ShardingSpherePreconditions.checkState(FirebirdBlobHandleGenerator.getInstance().isAllocated(connectionId,
blobHandle), () -> new InvalidSegstrHandleException(blobHandle));
Optional<BlobSegment> blobSegment =
FirebirdBlobReadCache.getInstance().readSegment(connectionId, blobHandle,
getMaxSegmentDataLength());
if (!blobSegment.isPresent()) {
return Collections.singleton(new
FirebirdGenericResponsePacket().setHandle(SEGMENT_STATE_EOF));
diff --git
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutorTest.java
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutorTest.java
index dc0a144fff0..61b59d3d7de 100644
---
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutorTest.java
+++
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/blob/FirebirdGetBlobSegmentCommandExecutorTest.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.proxy.frontend.firebird.command.query.blob;
import lombok.SneakyThrows;
+import
org.apache.shardingsphere.database.exception.firebird.exception.protocol.InvalidSegstrHandleException;
import
org.apache.shardingsphere.database.protocol.firebird.packet.command.query.blob.FirebirdGetBlobSegmentCommandPacket;
import
org.apache.shardingsphere.database.protocol.firebird.packet.command.query.blob.FirebirdGetBlobSegmentResponsePacket;
import
org.apache.shardingsphere.database.protocol.firebird.packet.generic.FirebirdGenericResponsePacket;
@@ -44,6 +45,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isA;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@@ -51,7 +53,7 @@ class FirebirdGetBlobSegmentCommandExecutorTest {
private static final int CONNECTION_ID = 1;
- private static final int BLOB_HANDLE = 7;
+ private static final int BLOB_HANDLE = 1;
@Mock
private FirebirdGetBlobSegmentCommandPacket packet;
@@ -62,6 +64,7 @@ class FirebirdGetBlobSegmentCommandExecutorTest {
@BeforeEach
void setUp() {
FirebirdBlobHandleGenerator.getInstance().registerConnection(CONNECTION_ID);
+
FirebirdBlobHandleGenerator.getInstance().nextBlobHandle(CONNECTION_ID);
FirebirdBlobReadCache.getInstance().registerConnection(CONNECTION_ID);
when(connectionSession.getConnectionId()).thenReturn(CONNECTION_ID);
when(packet.getBlobHandle()).thenReturn(BLOB_HANDLE);
@@ -87,7 +90,19 @@ class FirebirdGetBlobSegmentCommandExecutorTest {
}
@Test
- void assertExecuteWithUnknownBlobExpectsEof() {
+ void assertExecuteWithUnknownBlobHandle() {
+ when(packet.getBlobHandle()).thenReturn(99);
+ assertThrows(InvalidSegstrHandleException.class, () -> new
FirebirdGetBlobSegmentCommandExecutor(packet, connectionSession).execute());
+ }
+
+ @Test
+ void assertExecuteWithReleasedBlobHandle() {
+
FirebirdBlobHandleGenerator.getInstance().releaseBlobHandle(CONNECTION_ID,
BLOB_HANDLE);
+ assertThrows(InvalidSegstrHandleException.class, () -> new
FirebirdGetBlobSegmentCommandExecutor(packet, connectionSession).execute());
+ }
+
+ @Test
+ void assertExecuteWithoutBlobContent() {
FirebirdGetBlobSegmentCommandExecutor executor = new
FirebirdGetBlobSegmentCommandExecutor(packet, connectionSession);
Collection<DatabasePacket> actualPackets = executor.execute();
assertThat(actualPackets.size(), is(1));
@@ -180,15 +195,20 @@ class FirebirdGetBlobSegmentCommandExecutorTest {
}
@Test
- void assertExecuteWithOtherConnectionBlobExpectsEof() {
+ void assertExecuteWithOtherConnectionBlobHandle() {
+ FirebirdBlobHandleGenerator.getInstance().registerConnection(2);
FirebirdBlobReadCache.getInstance().registerConnection(2);
- FirebirdBlobReadCache.getInstance().registerBlob(2, BLOB_HANDLE, new
byte[]{1, 2, 3}, false);
- FirebirdGetBlobSegmentCommandExecutor executor = new
FirebirdGetBlobSegmentCommandExecutor(packet, connectionSession);
- Collection<DatabasePacket> actualPackets = executor.execute();
- FirebirdGenericResponsePacket actualGenericPacket =
(FirebirdGenericResponsePacket) actualPackets.iterator().next();
- assertThat(actualGenericPacket.getHandle(), is(2));
- assertThat(FirebirdBlobReadCache.getInstance().readSegment(2,
BLOB_HANDLE, 3).get().getData(), is(new byte[]{1, 2, 3}));
- FirebirdBlobReadCache.getInstance().unregisterConnection(2);
+ try {
+ FirebirdBlobHandleGenerator.getInstance().nextBlobHandle(2);
+ int otherBlobHandle =
FirebirdBlobHandleGenerator.getInstance().nextBlobHandle(2);
+ FirebirdBlobReadCache.getInstance().registerBlob(2,
otherBlobHandle, new byte[]{1, 2, 3}, false);
+ when(packet.getBlobHandle()).thenReturn(otherBlobHandle);
+ assertThrows(InvalidSegstrHandleException.class, () -> new
FirebirdGetBlobSegmentCommandExecutor(packet, connectionSession).execute());
+ assertThat(FirebirdBlobReadCache.getInstance().readSegment(2,
otherBlobHandle, 3).get().getData(), is(new byte[]{1, 2, 3}));
+ } finally {
+ FirebirdBlobReadCache.getInstance().unregisterConnection(2);
+ FirebirdBlobHandleGenerator.getInstance().unregisterConnection(2);
+ }
}
private static Stream<Arguments> lastSegmentStateCases() {