Skip to content

Commit

Permalink
Backported fix for #7298: Info result parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexPeshkoff committed Sep 30, 2022
1 parent bd01904 commit 4d0e5e0
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 175 deletions.
21 changes: 8 additions & 13 deletions src/alice/tdr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,22 +288,22 @@ void TDR_list_limbo(FB_API_HANDLE handle, const TEXT* name, const SINT64 switche

TraNumber id;
tdr* trans;
UCHAR* ptr = buffer;
bool flag = true;

while (flag)
for (Firebird::ClumpletReader p(Firebird::ClumpletReader::InfoResponse, buffer, sizeof(buffer));
!p.isEof(); p.moveNext())
{
const USHORT item = *ptr++;
const USHORT length = (USHORT) gds__vax_integer(ptr, 2);
ptr += 2;
UCHAR item = p.getClumpTag();
if (item == isc_info_end)
break;

const USHORT length = (USHORT) p.getClumpLength();
switch (item)
{
case isc_info_limbo:
id = isc_portable_integer(ptr, length);
id = p.getBigInt();
if (switches & (sw_commit | sw_rollback | sw_two_phase | sw_prompt))
{
TDR_reconnect_multiple(handle, id, name, switches);
ptr += length;
break;
}
if (!tdgbl->uSvc->isService())
Expand All @@ -326,7 +326,6 @@ void TDR_list_limbo(FB_API_HANDLE handle, const TEXT* name, const SINT64 switche
tdgbl->uSvc->putSInt64(isc_spb_single_tra_id_64, id);
else
tdgbl->uSvc->putSLong(isc_spb_single_tra_id, (SLONG) id);
ptr += length;
break;

case isc_info_truncated:
Expand All @@ -336,10 +335,6 @@ void TDR_list_limbo(FB_API_HANDLE handle, const TEXT* name, const SINT64 switche
// msg 72: More limbo transactions than fit. Try again
// And how it's going to retry with a bigger buffer if the buffer is fixed size?
}
// fall through

case isc_info_end:
flag = false;
break;

default:
Expand Down
2 changes: 0 additions & 2 deletions src/burp/restore.epp
Original file line number Diff line number Diff line change
Expand Up @@ -3182,8 +3182,6 @@ rec_type get_data(BurpGlobals* tdgbl, burp_rel* relation, bool skip_relation)
Firebird::ClumpletReader rdr(Firebird::ClumpletReader::InfoResponse, infoBuf, sizeof infoBuf);
for (rdr.rewind(); !rdr.isEof(); rdr.moveNext())
{
if (rdr.getClumpTag() == isc_info_end)
break;
switch (rdr.getClumpTag())
{
case Firebird::IBatch::INF_BUFFER_BYTES_SIZE:
Expand Down
14 changes: 14 additions & 0 deletions src/common/classes/ClumpletReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,20 @@ void ClumpletReader::moveNext()
{
if (isEof())
return; // no need to raise useless exceptions

switch (kind)
{
case InfoResponse:
switch (getClumpTag())
{
case isc_info_end:
case isc_info_truncated:
// terminating clumplet
cur_offset = getBufferLength();
return;
}
}

FB_SIZE_T cs = getClumpletSize(true, true, true);
adjustSpbState();
cur_offset += cs;
Expand Down
25 changes: 12 additions & 13 deletions src/isql/isql.epp
Original file line number Diff line number Diff line change
Expand Up @@ -6087,22 +6087,22 @@ void ISQL_get_version(bool call_by_create_db)
return;
}

const UCHAR* p = buffer;
while (*p != isc_info_end && *p != isc_info_truncated && p < buffer + sizeof(buffer))
for (Firebird::ClumpletReader p(Firebird::ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
{
const UCHAR item = (UCHAR) *p++;
const USHORT length = gds__vax_integer(p, sizeof(USHORT));
p += sizeof(USHORT);
UCHAR item = p.getClumpTag();
if (item == isc_info_end)
break;

switch (item)
{
case isc_info_ods_version:
isqlGlob.major_ods = gds__vax_integer(p, length);
isqlGlob.major_ods = p.getInt();
break;
case isc_info_ods_minor_version:
isqlGlob.minor_ods = gds__vax_integer(p, length);
isqlGlob.minor_ods = p.getInt();
break;
case isc_info_db_sql_dialect:
global_dialect_spoken = gds__vax_integer(p, length);
global_dialect_spoken = p.getInt();
if (isqlGlob.major_ods < ODS_VERSION10)
{
if (isqlGlob.SQL_dialect > SQL_DIALECT_V5 && setValues.Warnings)
Expand Down Expand Up @@ -6151,7 +6151,7 @@ void ISQL_get_version(bool call_by_create_db)
case isc_info_error:
// Error indicates an option was not understood by the
// remote server.
if (*p == isc_info_firebird_version)
if (p.getBytes()[0] == isc_info_firebird_version)
{
// must be an old or non Firebird server
break;
Expand Down Expand Up @@ -6197,8 +6197,8 @@ void ISQL_get_version(bool call_by_create_db)
// to put it all. It's a FULL or NOTHING answer. It grows with redirection.
// The command SHOW version that calls isc_version() will return more info.
isqlGlob.printf("Server version:%s", NEWLINE);
const UCHAR* q = p; // We don't want to spoil p with a wrong calculation.
const UCHAR* limit = q + length;
const UCHAR* q = p.getBytes(); // We don't want to spoil p with a wrong calculation.
const UCHAR* limit = q + p.getClumpLength();
for (int times = *q++; times && q < limit; --times)
{
int l = *q++;
Expand All @@ -6212,15 +6212,14 @@ void ISQL_get_version(bool call_by_create_db)
break;

case frb_info_att_charset:
isqlGlob.att_charset = gds__vax_integer(p, length);
isqlGlob.att_charset = p.getInt();
break;

default:
isqlGlob.printf("Internal error: Unexpected isc_info_value %d%s",
item, NEWLINE);
break;
}
p += length;
}

if (isqlGlob.major_ods < ODS_VERSION8)
Expand Down

0 comments on commit 4d0e5e0

Please sign in to comment.