mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 22:43:03 +01:00
Fixed #8027: Broken gbak statistics
This commit is contained in:
parent
f674c7f53c
commit
210310eab3
@ -124,10 +124,10 @@ namespace {
|
||||
status_exception::raise(Arg::Gds(isc_imp_exc) << Arg::Gds(isc_blktoobig));
|
||||
}
|
||||
|
||||
class SaveString
|
||||
class UsePreallocatedBuffer
|
||||
{
|
||||
public:
|
||||
SaveString(cstring& toSave, ULONG newLength, UCHAR* newBuffer)
|
||||
UsePreallocatedBuffer(cstring& toSave, ULONG newLength, UCHAR* newBuffer)
|
||||
: ptr(&toSave),
|
||||
oldValue(*ptr)
|
||||
{
|
||||
@ -135,16 +135,30 @@ namespace {
|
||||
ptr->cstr_allocated = newLength;
|
||||
}
|
||||
|
||||
~SaveString()
|
||||
~UsePreallocatedBuffer()
|
||||
{
|
||||
*ptr = oldValue;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
cstring* ptr;
|
||||
private:
|
||||
cstring oldValue;
|
||||
};
|
||||
|
||||
class UseStandardBuffer : public UsePreallocatedBuffer
|
||||
{
|
||||
public:
|
||||
UseStandardBuffer(cstring& toSave)
|
||||
: UsePreallocatedBuffer(toSave,0, nullptr)
|
||||
{ }
|
||||
|
||||
~UseStandardBuffer()
|
||||
{
|
||||
ptr->free();
|
||||
}
|
||||
};
|
||||
|
||||
class ClientPortsCleanup : public PortsCleanup
|
||||
{
|
||||
public:
|
||||
@ -4149,7 +4163,7 @@ Statement* Attachment::prepare(CheckStatusWrapper* status, ITransaction* apiTra,
|
||||
}
|
||||
|
||||
P_RESP* response = &packet->p_resp;
|
||||
SaveString temp(response->p_resp_data, buffer.getCount(), buffer.begin());
|
||||
UsePreallocatedBuffer temp(response->p_resp_data, buffer.getCount(), buffer.begin());
|
||||
|
||||
try
|
||||
{
|
||||
@ -5302,7 +5316,7 @@ int Blob::getSegment(CheckStatusWrapper* status, unsigned int bufferLength, void
|
||||
PACKET* packet = &rdb->rdb_packet;
|
||||
P_SGMT* segment = &packet->p_sgmt;
|
||||
P_RESP* response = &packet->p_resp;
|
||||
SaveString temp(response->p_resp_data, bufferLength, bufferPtr);
|
||||
UsePreallocatedBuffer temp(response->p_resp_data, bufferLength, bufferPtr);
|
||||
|
||||
// Handle a blob that has been created rather than opened (this should yield an error)
|
||||
|
||||
@ -7575,6 +7589,9 @@ static void batch_dsql_fetch(rem_port* port,
|
||||
// we need to clear the queue.
|
||||
const bool clear_queue = (id != statement->rsr_id || port->port_type == rem_port::XNET);
|
||||
|
||||
// Avoid damaging preallocated buffer for response data
|
||||
UseStandardBuffer guard(packet->p_resp.p_resp_data);
|
||||
|
||||
statement->rsr_flags.set(Rsr::FETCHED);
|
||||
while (true)
|
||||
{
|
||||
@ -7736,6 +7753,9 @@ static void batch_gds_receive(rem_port* port,
|
||||
clear_queue = true;
|
||||
}
|
||||
|
||||
// Avoid damaging preallocated buffer for response data
|
||||
UseStandardBuffer guard(packet->p_resp.p_resp_data);
|
||||
|
||||
// Receive the whole batch of records, until end-of-batch is seen
|
||||
|
||||
while (true)
|
||||
@ -8142,7 +8162,7 @@ static void info(CheckStatusWrapper* status,
|
||||
// Set up for the response packet.
|
||||
|
||||
P_RESP* response = &packet->p_resp;
|
||||
SaveString temp(response->p_resp_data, buffer_length, buffer);
|
||||
UsePreallocatedBuffer temp(response->p_resp_data, buffer_length, buffer);
|
||||
|
||||
receive_response(status, rdb, packet);
|
||||
}
|
||||
@ -9352,8 +9372,7 @@ static void svcstart(CheckStatusWrapper* status,
|
||||
|
||||
// Set up for the response packet.
|
||||
P_RESP* response = &packet->p_resp;
|
||||
SaveString temp(response->p_resp_data, 0, NULL);
|
||||
response->p_resp_data.cstr_length = 0;
|
||||
UseStandardBuffer temp(response->p_resp_data);
|
||||
|
||||
receive_response(status, rdb, packet);
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ enum SQL_STMT_TYPE
|
||||
};
|
||||
|
||||
static bool alloc_cstring(RemoteXdr*, CSTRING*);
|
||||
static void free_cstring(RemoteXdr*, CSTRING*);
|
||||
static void reset_statement(RemoteXdr*, SSHORT);
|
||||
static bool_t xdr_cstring(RemoteXdr*, CSTRING*);
|
||||
static bool_t xdr_response(RemoteXdr*, CSTRING*);
|
||||
@ -1247,7 +1246,7 @@ static bool alloc_cstring(RemoteXdr* xdrs, CSTRING* cstring)
|
||||
|
||||
if (cstring->cstr_length > cstring->cstr_allocated && cstring->cstr_allocated)
|
||||
{
|
||||
free_cstring(xdrs, cstring);
|
||||
cstring->free(xdrs);
|
||||
}
|
||||
|
||||
if (!cstring->cstr_address)
|
||||
@ -1268,7 +1267,7 @@ static bool alloc_cstring(RemoteXdr* xdrs, CSTRING* cstring)
|
||||
}
|
||||
|
||||
|
||||
static void free_cstring( RemoteXdr* xdrs, CSTRING* cstring)
|
||||
void CSTRING::free(RemoteXdr* xdrs)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1281,14 +1280,15 @@ static void free_cstring( RemoteXdr* xdrs, CSTRING* cstring)
|
||||
*
|
||||
**************************************/
|
||||
|
||||
if (cstring->cstr_allocated)
|
||||
if (cstr_allocated)
|
||||
{
|
||||
delete[] cstring->cstr_address;
|
||||
DEBUG_XDR_FREE(xdrs, cstring, cstring->cstr_address, cstring->cstr_allocated);
|
||||
delete[] cstr_address;
|
||||
if (xdrs)
|
||||
DEBUG_XDR_FREE(xdrs, this, cstr_address, cstr_allocated);
|
||||
}
|
||||
|
||||
cstring->cstr_address = NULL;
|
||||
cstring->cstr_allocated = 0;
|
||||
cstr_address = NULL;
|
||||
cstr_allocated = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1393,7 +1393,7 @@ static bool_t xdr_cstring_with_limit( RemoteXdr* xdrs, CSTRING* cstring, ULONG l
|
||||
return TRUE;
|
||||
|
||||
case XDR_FREE:
|
||||
free_cstring(xdrs, cstring);
|
||||
cstring->free(xdrs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1502,7 +1502,7 @@ static bool_t xdr_longs( RemoteXdr* xdrs, CSTRING* cstring)
|
||||
break;
|
||||
|
||||
case XDR_FREE:
|
||||
free_cstring(xdrs, cstring);
|
||||
cstring->free(xdrs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -324,11 +324,15 @@ enum P_OP
|
||||
|
||||
// Count String Structure
|
||||
|
||||
class RemoteXdr;
|
||||
|
||||
typedef struct cstring
|
||||
{
|
||||
ULONG cstr_length;
|
||||
ULONG cstr_allocated;
|
||||
UCHAR* cstr_address;
|
||||
|
||||
void free(RemoteXdr* xdrs = nullptr);
|
||||
} CSTRING;
|
||||
|
||||
// CVC: Only used in p_blob, p_sgmt & p_ddl, to validate constness.
|
||||
|
Loading…
Reference in New Issue
Block a user