From e69906b8b9b60ffb09679fe7c8227481b2aae82f Mon Sep 17 00:00:00 2001 From: Rafael mreis Date: Fri, 6 Nov 2026 22:01:07 -0300 Subject: [PATCH] fix(remote): backport IBatch BLOB continuation kind guard to v5.0 (#9251) --- src/remote/protocol.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/remote/protocol.cpp b/src/remote/protocol.cpp index 0cf080ee1e8..acb39735b17 100644 --- a/src/remote/protocol.cpp +++ b/src/remote/protocol.cpp @@ -27,6 +27,17 @@ * */ +/* + * IBatch BLOB-kind invariant (issue #9251): + * NEW : nonzero BLOB ID + no BPB -> use batch default kind flag. + * BPB : nonzero BLOB ID + BPB -> decode the explicit kind from BPB. + * CONT : zero BLOB ID -> preserve the current BLOB kind. + * + * Build diagnostics: keep compiler warnings visible. They help detect unsafe + * conversions and flag handling; suppressing them cannot fix protocol bugs. + * The guard below adds no dependency, allocation or public ABI change. + */ + #include "firebird.h" #include #include @@ -2362,6 +2373,15 @@ static Rtr* getTransaction(RemoteXdr* xdrs, USHORT tran_id) } } +// One action: apply the default kind only to a new BLOB without an explicit BPB. +// Continuations retain the kind established by the preceding BLOB header. +static inline void applyDefaultBlobKind(Rsr::BatchStream& stream, const ISC_QUAD& blobId, + ULONG bpbSize, ULONG batchFlags) noexcept +{ + if (!bpbSize && (blobId.gds_quad_high || blobId.gds_quad_low)) + stream.segmented = (batchFlags & (1U << Jrd::DsqlBatch::FLAG_DEFAULT_SEGMENTED)) != 0; +} + static bool_t xdr_blob_stream(RemoteXdr* xdrs, SSHORT statement_id, CSTRING* strmPortion) { if (xdrs->x_op == XDR_FREE) @@ -2509,8 +2529,7 @@ static bool_t xdr_blob_stream(RemoteXdr* xdrs, SSHORT statement_id, CSTRING* str flow.newBlob(*blobSize, *bpbSize); localStrm.curBpb.clear(); - if (!flow.bpbSize) - localStrm.segmented = statement->rsr_batch_flags & (1 << Jrd::DsqlBatch::FLAG_DEFAULT_SEGMENTED); + applyDefaultBlobKind(localStrm, *batchBlobId, flow.bpbSize, statement->rsr_batch_flags); continue; }