8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

This should fix CORE-4872: v3 fbclient cannot work with servers older than v2.5 via the remote protocol.

This commit is contained in:
dimitr 2015-07-15 12:07:25 +00:00
parent 48645308b9
commit 1776ee04ab
3 changed files with 58 additions and 42 deletions

View File

@ -31,15 +31,16 @@
#include "../common/StatusHolder.h"
#include "../jrd/align.h"
#include "../dsql/sqlda_pub.h"
#include "../remote/protocol.h"
using namespace Firebird;
namespace Remote
{
BlrFromMessage::BlrFromMessage(IMessageMetadata* metadata, unsigned aDialect)
BlrFromMessage::BlrFromMessage(IMessageMetadata* metadata, unsigned aDialect, unsigned aProtocol)
: BlrWriter(*getDefaultMemoryPool()),
expectedMessageLength(0), dialect(aDialect)
expectedMessageLength(0), dialect(aDialect), protocol(aProtocol)
{
buildBlr(metadata);
}
@ -147,9 +148,19 @@ void BlrFromMessage::buildBlr(IMessageMetadata* metadata)
break;
case SQL_BLOB:
appendUChar(blr_blob2);
appendUShort(subType);
appendUShort(charSet);
if (protocol >= PROTOCOL_VERSION12)
{
appendUChar(blr_blob2);
appendUShort(subType);
appendUShort(charSet);
}
else
{
// Servers prior to FB 2.5 don't expect blr_blob2 in remote messages,
// so BLOB IDs are described as blr_quad instead
appendUChar(blr_quad);
appendUChar(0);
}
dtype = dtype_blob;
break;

View File

@ -37,7 +37,7 @@ namespace Remote {
class BlrFromMessage : public Firebird::BlrWriter
{
public:
BlrFromMessage(Firebird::IMessageMetadata* metadata, unsigned dialect);
BlrFromMessage(Firebird::IMessageMetadata* metadata, unsigned dialect, unsigned protocol);
unsigned getLength();
const unsigned char* getBytes();
@ -50,6 +50,7 @@ private:
unsigned expectedMessageLength;
unsigned dialect;
unsigned protocol;
};
} // namespace Firebird

View File

@ -1715,19 +1715,27 @@ Firebird::ITransaction* Statement::execute(CheckStatusWrapper* status, Firebird:
Rdb* rdb = statement->rsr_rdb;
CHECK_HANDLE(rdb, isc_bad_db_handle);
BlrFromMessage inBlr(inMetadata, dialect);
rem_port* port = rdb->rdb_port;
BlrFromMessage inBlr(inMetadata, dialect, port->port_protocol);
const unsigned int in_blr_length = inBlr.getLength();
const UCHAR* const in_blr = inBlr.getBytes();
const unsigned int in_msg_length = inBlr.getMsgLength();
UCHAR* const in_msg = static_cast<UCHAR*>(inBuffer);
BlrFromMessage outBlr(outMetadata, dialect);
BlrFromMessage outBlr(outMetadata, dialect, port->port_protocol);
const unsigned int out_blr_length = outBlr.getLength();
const UCHAR* const out_blr = outBlr.getBytes();
const unsigned int out_msg_length = outBlr.getMsgLength();
UCHAR* const out_msg = static_cast<UCHAR*>(outBuffer);
rem_port* port = rdb->rdb_port;
// Validate data length
CHECK_LENGTH(port, in_blr_length);
CHECK_LENGTH(port, in_msg_length);
CHECK_LENGTH(port, out_blr_length);
CHECK_LENGTH(port, out_msg_length);
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);
Rtr* transaction = NULL;
@ -1738,13 +1746,6 @@ Firebird::ITransaction* Statement::execute(CheckStatusWrapper* status, Firebird:
CHECK_HANDLE(transaction, isc_bad_trans_handle);
}
// Validate data length
CHECK_LENGTH(port, in_blr_length);
CHECK_LENGTH(port, in_msg_length);
CHECK_LENGTH(port, out_blr_length);
CHECK_LENGTH(port, out_msg_length);
// 24-Mar-2004 Nickolay Samofatov
// Unconditionally deallocate existing formats that are left from
// previous executions (possibly with different statement if
@ -1887,7 +1888,9 @@ ResultSet* Statement::openCursor(CheckStatusWrapper* status, Firebird::ITransact
Rdb* rdb = statement->rsr_rdb;
CHECK_HANDLE(rdb, isc_bad_db_handle);
BlrFromMessage inBlr(inMetadata, dialect);
rem_port* port = rdb->rdb_port;
BlrFromMessage inBlr(inMetadata, dialect, port->port_protocol);
const unsigned int in_blr_length = inBlr.getLength();
const UCHAR* const in_blr = inBlr.getBytes();
const unsigned int in_msg_length = inBlr.getMsgLength();
@ -1907,11 +1910,16 @@ ResultSet* Statement::openCursor(CheckStatusWrapper* status, Firebird::ITransact
}
}
BlrFromMessage outBlr((outFormat == DELAYED_OUT_FORMAT ? NULL : outFormat), dialect);
BlrFromMessage outBlr((outFormat == DELAYED_OUT_FORMAT ? NULL : outFormat), dialect, port->port_protocol);
const unsigned int out_blr_length = outBlr.getLength();
const UCHAR* const out_blr = outBlr.getBytes();
rem_port* port = rdb->rdb_port;
// Validate data length
CHECK_LENGTH(port, in_blr_length);
CHECK_LENGTH(port, in_msg_length);
CHECK_LENGTH(port, out_blr_length);
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);
Rtr* transaction = NULL;
@ -1922,12 +1930,6 @@ ResultSet* Statement::openCursor(CheckStatusWrapper* status, Firebird::ITransact
CHECK_HANDLE(transaction, isc_bad_trans_handle);
}
// Validate data length
CHECK_LENGTH(port, in_blr_length);
CHECK_LENGTH(port, in_msg_length);
CHECK_LENGTH(port, out_blr_length);
// 24-Mar-2004 Nickolay Samofatov
// Unconditionally deallocate existing formats that are left from
// previous executions (possibly with different statement if
@ -2052,29 +2054,20 @@ ITransaction* Attachment::execute(CheckStatusWrapper* status, ITransaction* apiT
CHECK_HANDLE(rdb, isc_bad_db_handle);
BlrFromMessage inBlr(inMetadata, dialect);
rem_port* port = rdb->rdb_port;
BlrFromMessage inBlr(inMetadata, dialect, port->port_protocol);
const unsigned int in_blr_length = inBlr.getLength();
const UCHAR* const in_blr = inBlr.getBytes();
const unsigned int in_msg_length = inBlr.getMsgLength();
UCHAR* const in_msg = static_cast<UCHAR*>(inBuffer);
BlrFromMessage outBlr(outMetadata, dialect);
BlrFromMessage outBlr(outMetadata, dialect, port->port_protocol);
const unsigned int out_blr_length = outBlr.getLength();
const UCHAR* const out_blr = outBlr.getBytes();
const unsigned int out_msg_length = outBlr.getMsgLength();
UCHAR* const out_msg = static_cast<UCHAR*>(outBuffer);
rem_port* port = rdb->rdb_port;
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);
Rtr* transaction = NULL;
Transaction* rt = remoteTransactionInterface(apiTra);
if (rt)
{
transaction = rt->getTransaction();
CHECK_HANDLE(transaction, isc_bad_trans_handle);
}
// Validate data length
CHECK_LENGTH(port, in_blr_length);
@ -2089,6 +2082,16 @@ ITransaction* Attachment::execute(CheckStatusWrapper* status, ITransaction* apiT
CHECK_LENGTH(port, stmtLength);
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);
Rtr* transaction = NULL;
Transaction* rt = remoteTransactionInterface(apiTra);
if (rt)
{
transaction = rt->getTransaction();
CHECK_HANDLE(transaction, isc_bad_trans_handle);
}
if (dialect > 10)
{
// dimitr: adjust dialect received after
@ -2770,20 +2773,21 @@ int ResultSet::fetchNext(CheckStatusWrapper* status, void* buffer)
Rdb* rdb = statement->rsr_rdb;
CHECK_HANDLE(rdb, isc_bad_db_handle);
BlrFromMessage outBlr(outputFormat, stmt->getDialect());
rem_port* port = rdb->rdb_port;
BlrFromMessage outBlr(outputFormat, stmt->getDialect(), port->port_protocol);
unsigned int blr_length = outBlr.getLength();
const UCHAR* blr = outBlr.getBytes();
const unsigned int msg_length = outBlr.getMsgLength();
UCHAR* msg = static_cast<UCHAR*>(buffer);
rem_port* port = rdb->rdb_port;
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);
// Validate data length
CHECK_LENGTH(port, blr_length);
CHECK_LENGTH(port, msg_length);
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);
// On first fetch, clear the end-of-stream flag & reset the message buffers
if (!statement->rsr_flags.test(Rsr::FETCHED))