mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 22:43:03 +01:00
Fixed #8027: Broken gbak statistics
(cherry picked from commit 210310eab3
)
This commit is contained in:
parent
d78e3b2574
commit
eb2d922617
@ -128,10 +128,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)
|
||||
{
|
||||
@ -139,16 +139,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:
|
||||
@ -4146,7 +4160,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
|
||||
{
|
||||
@ -5064,7 +5078,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)
|
||||
|
||||
@ -7366,6 +7380,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)
|
||||
{
|
||||
@ -7511,6 +7528,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)
|
||||
@ -7928,7 +7948,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);
|
||||
}
|
||||
@ -9138,8 +9158,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*);
|
||||
@ -1242,7 +1241,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)
|
||||
@ -1263,7 +1262,7 @@ static bool alloc_cstring(RemoteXdr* xdrs, CSTRING* cstring)
|
||||
}
|
||||
|
||||
|
||||
static void free_cstring( RemoteXdr* xdrs, CSTRING* cstring)
|
||||
void CSTRING::free(RemoteXdr* xdrs)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1276,14 +1275,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;
|
||||
}
|
||||
|
||||
|
||||
@ -1388,7 +1388,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;
|
||||
}
|
||||
|
||||
@ -1497,7 +1497,7 @@ static bool_t xdr_longs( RemoteXdr* xdrs, CSTRING* cstring)
|
||||
break;
|
||||
|
||||
case XDR_FREE:
|
||||
free_cstring(xdrs, cstring);
|
||||
cstring->free(xdrs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -303,11 +303,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