mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:40:38 +01:00
Fixed #7298: Info result parsing
This commit is contained in:
parent
a46096d447
commit
f75ff97b66
@ -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())
|
||||
@ -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:
|
||||
@ -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:
|
||||
|
@ -11636,8 +11636,6 @@ IBatch* WriteRelationMeta::createBatch(BurpGlobals* tdgbl, IAttachment* att)
|
||||
ClumpletReader rdr(ClumpletReader::InfoResponse, infoBuf, sizeof infoBuf);
|
||||
for (rdr.rewind(); !rdr.isEof(); rdr.moveNext())
|
||||
{
|
||||
if (rdr.getClumpTag() == isc_info_end)
|
||||
break;
|
||||
switch (rdr.getClumpTag())
|
||||
{
|
||||
case IBatch::INF_BUFFER_BYTES_SIZE:
|
||||
|
@ -687,6 +687,20 @@ void ClumpletReader::moveNext()
|
||||
if (isEof())
|
||||
return; // no need to raise useless exceptions
|
||||
FB_SIZE_T cs = getClumpletSize(true, true, true);
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case InfoResponse:
|
||||
switch (getClumpTag())
|
||||
{
|
||||
case isc_info_end:
|
||||
case isc_info_truncated:
|
||||
// terminating clumplet
|
||||
cur_offset = getBufferLength();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
adjustSpbState();
|
||||
cur_offset += cs;
|
||||
}
|
||||
|
@ -6160,22 +6160,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)
|
||||
@ -6224,7 +6224,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;
|
||||
@ -6270,8 +6270,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++;
|
||||
@ -6285,7 +6285,7 @@ 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:
|
||||
@ -6293,7 +6293,6 @@ void ISQL_get_version(bool call_by_create_db)
|
||||
item, NEWLINE);
|
||||
break;
|
||||
}
|
||||
p += length;
|
||||
}
|
||||
|
||||
if (isqlGlob.major_ods < ODS_VERSION8)
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "../jrd/intl.h"
|
||||
#include "../common/intlobj_new.h"
|
||||
#include "../common/classes/AlignedBuffer.h"
|
||||
#include "../common/classes/ClumpletReader.h"
|
||||
#include "../isql/isql_proto.h"
|
||||
#include "../isql/show_proto.h"
|
||||
#include "../isql/iutils_proto.h"
|
||||
@ -408,12 +409,12 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
|
||||
*info_buf = '\0';
|
||||
SCHAR* info = info_buf;
|
||||
for (const UCHAR* d = buffer; *d != isc_info_end;)
|
||||
|
||||
for (Firebird::ClumpletReader p(Firebird::ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
UCHAR item = p.getClumpTag();
|
||||
SINT64 value_out = 0;
|
||||
const UCHAR item = *d++;
|
||||
const int length = ISQL_vax_integer(d, 2);
|
||||
d += 2;
|
||||
|
||||
/*
|
||||
* This is not the best solution but it fixes the lack of <LF> characters
|
||||
* in Windows ISQL. This will need to remain until we modify the messages
|
||||
@ -426,12 +427,12 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case isc_info_page_size:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf(info, "PAGE_SIZE %" SQUADFORMAT"%s", value_out, separator);
|
||||
break;
|
||||
|
||||
case isc_info_db_size_in_pages:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
IUTILS_msg_get(NUMBER_PAGES, msg, SafeArg() << value_out);
|
||||
@ -442,7 +443,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case fb_info_pages_used:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
IUTILS_msg_get(NUMBER_USED_PAGES, msg, SafeArg() << value_out);
|
||||
@ -453,7 +454,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case fb_info_pages_free:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
IUTILS_msg_get(NUMBER_FREE_PAGES, msg, SafeArg() << value_out);
|
||||
@ -464,8 +465,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case fb_info_crypt_state:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
Firebird::string s;
|
||||
@ -495,7 +495,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case isc_info_sweep_interval:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
IUTILS_msg_get(SWEEP_INTERV, msg, SafeArg() << value_out);
|
||||
@ -506,32 +506,32 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case isc_info_forced_writes:
|
||||
value_out = ISQL_vax_integer (d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf (info, "Forced Writes are %s%s", (value_out == 1 ? "ON" : "OFF"), separator);
|
||||
break;
|
||||
|
||||
case isc_info_oldest_transaction :
|
||||
value_out = ISQL_vax_integer (d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf(info, "Transaction - oldest = %" SQUADFORMAT"%s", value_out, separator);
|
||||
break;
|
||||
|
||||
case isc_info_oldest_active :
|
||||
value_out = ISQL_vax_integer (d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf(info, "Transaction - oldest active = %" SQUADFORMAT"%s", value_out, separator);
|
||||
break;
|
||||
|
||||
case isc_info_oldest_snapshot :
|
||||
value_out = ISQL_vax_integer (d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf(info, "Transaction - oldest snapshot = %" SQUADFORMAT"%s", value_out, separator);
|
||||
break;
|
||||
|
||||
case isc_info_next_transaction :
|
||||
value_out = ISQL_vax_integer (d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf (info, "Transaction - Next = %" SQUADFORMAT"%s", value_out, separator);
|
||||
break;
|
||||
|
||||
case isc_info_base_level:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
IUTILS_msg_get(BASE_LEVEL, msg, SafeArg() << value_out);
|
||||
@ -542,7 +542,7 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case isc_info_limbo:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (translate)
|
||||
{
|
||||
IUTILS_msg_get(LIMBO, msg, SafeArg() << value_out);
|
||||
@ -553,21 +553,21 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case isc_info_ods_version:
|
||||
isqlGlob.major_ods = ISQL_vax_integer(d, length);
|
||||
isqlGlob.major_ods = p.getInt();
|
||||
break;
|
||||
case isc_info_ods_minor_version:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
sprintf(info, "ODS = %" SLONGFORMAT".%" SQUADFORMAT"%s",
|
||||
(SLONG) isqlGlob.major_ods, value_out, separator);
|
||||
break;
|
||||
|
||||
case fb_info_wire_crypt:
|
||||
if (d && length)
|
||||
sprintf (info, "Wire crypt plugin: %.*s%s", length, d, separator);
|
||||
if (p.getClumpLength())
|
||||
sprintf (info, "Wire crypt plugin: %.*s%s", p.getClumpLength(), p.getBytes(), separator);
|
||||
break;
|
||||
|
||||
case fb_info_protocol_version:
|
||||
value_out = ISQL_vax_integer(d, length);
|
||||
value_out = p.getInt();
|
||||
if (value_out)
|
||||
sprintf(info, "Protocol version = %" SQUADFORMAT"%s", value_out, separator);
|
||||
else
|
||||
@ -575,14 +575,14 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case isc_info_creation_date:
|
||||
if (length == sizeof(ISC_TIMESTAMP) && !crdatePrinted)
|
||||
if (p.getClumpLength() == sizeof(ISC_TIMESTAMP) && !crdatePrinted)
|
||||
{
|
||||
ISC_TIMESTAMP ts;
|
||||
|
||||
const UCHAR* p = d;
|
||||
ts.timestamp_date = ISQL_vax_integer(p, sizeof(ISC_DATE));
|
||||
p += sizeof(ISC_DATE);
|
||||
ts.timestamp_time = ISQL_vax_integer(p, sizeof(ISC_TIME));
|
||||
const UCHAR* t = p.getBytes();
|
||||
ts.timestamp_date = ISQL_vax_integer(t, sizeof(ISC_DATE));
|
||||
t += sizeof(ISC_DATE);
|
||||
ts.timestamp_time = ISQL_vax_integer(t, sizeof(ISC_TIME));
|
||||
|
||||
struct tm time;
|
||||
isc_decode_timestamp(&ts, &time);
|
||||
@ -594,16 +594,16 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
break;
|
||||
|
||||
case fb_info_creation_timestamp_tz:
|
||||
if (length == sizeof(ISC_TIMESTAMP_TZ))
|
||||
if (p.getClumpLength() == sizeof(ISC_TIMESTAMP))
|
||||
{
|
||||
ISC_TIMESTAMP_TZ tsz;
|
||||
|
||||
const UCHAR* p = d;
|
||||
tsz.utc_timestamp.timestamp_date = ISQL_vax_integer(p, sizeof(ISC_DATE));
|
||||
p += sizeof(ISC_DATE);
|
||||
tsz.utc_timestamp.timestamp_time = ISQL_vax_integer(p, sizeof(ISC_TIME));
|
||||
p += sizeof(ISC_TIME);
|
||||
tsz.time_zone = ISQL_vax_integer(p, sizeof(ULONG));
|
||||
const UCHAR* t = p.getBytes();
|
||||
tsz.utc_timestamp.timestamp_date = ISQL_vax_integer(t, sizeof(ISC_DATE));
|
||||
t += sizeof(ISC_DATE);
|
||||
tsz.utc_timestamp.timestamp_time = ISQL_vax_integer(t, sizeof(ISC_TIME));
|
||||
t += sizeof(ISC_TIME);
|
||||
tsz.time_zone = ISQL_vax_integer(t, sizeof(ULONG));
|
||||
|
||||
unsigned year, month, day, hours, minutes, seconds, fractions;
|
||||
char timeZone[Firebird::TimeZoneUtil::MAX_SIZE];
|
||||
@ -627,8 +627,8 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
{
|
||||
// Will print with garbage for now.
|
||||
//It's sprintf(info, "DB/Host = %.*s", length, d);
|
||||
const UCHAR* s = d;
|
||||
const UCHAR* end = s + length;
|
||||
const UCHAR* s = p.getBytes();
|
||||
const UCHAR* end = s + p.getClumpLength();
|
||||
++s; // Skip useless indicator.
|
||||
int len = *s++;
|
||||
printf("DB = %.*s\n", len, s);
|
||||
@ -646,8 +646,6 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle,
|
||||
case isc_info_truncated:
|
||||
return info > info_buf; // If we got some items, we are (partially) successful.
|
||||
}
|
||||
|
||||
d += length;
|
||||
info += strlen(info);
|
||||
}
|
||||
|
||||
@ -6406,17 +6404,10 @@ static processing_state show_users()
|
||||
|
||||
processing_state rc = OBJECT_NOT_FOUND;
|
||||
|
||||
for (const UCHAR* data = buffer; *data != isc_info_end;)
|
||||
for (Firebird::ClumpletReader p(Firebird::ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
const UCHAR item = *data++;
|
||||
const int length = gds__vax_integer(data, 2);
|
||||
data += 2;
|
||||
|
||||
switch (item)
|
||||
switch (p.getClumpTag())
|
||||
{
|
||||
case isc_info_end:
|
||||
break;
|
||||
|
||||
case isc_info_user_names:
|
||||
{
|
||||
if (rc == OBJECT_NOT_FOUND)
|
||||
@ -6427,9 +6418,9 @@ static processing_state show_users()
|
||||
rc = SKIP; // We found at least one user.
|
||||
}
|
||||
|
||||
int len = *data;
|
||||
fb_assert(len == length - 1);
|
||||
const UCHAR* uname = data + 1;
|
||||
unsigned len = p.getBytes()[0];
|
||||
fb_assert(len == p.getClumpLength() - 1);
|
||||
const UCHAR* uname = p.getBytes() + 1;
|
||||
// Let's mark all attachments with our same user with a # prefix.
|
||||
bool same(len == my_user->vary_length && !memcmp(my_user->vary_string, uname, len));
|
||||
isqlGlob.printf("%c %.*s", same ? '#' : ' ', len, uname);
|
||||
@ -6444,10 +6435,6 @@ static processing_state show_users()
|
||||
isqlGlob.printf("%s\n", msg);
|
||||
return rc; // If we got some items, we are (partially) successful.
|
||||
}
|
||||
|
||||
data += length;
|
||||
if (data >= buffer + sizeof(buffer))
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -124,21 +124,15 @@ bool checkCreateDatabaseGrant(const MetaString& userName, const MetaString& trus
|
||||
check("IAttachment::getInfo", &st);
|
||||
|
||||
int dialect = SQL_DIALECT_V5; // reasonable default
|
||||
const UCHAR* p = buffer;
|
||||
while (*p != isc_info_end && *p != isc_info_truncated && p < buffer + sizeof(buffer))
|
||||
{
|
||||
const UCHAR item = (UCHAR) *p++;
|
||||
const USHORT length = gds__vax_integer(p, sizeof(USHORT));
|
||||
p += sizeof(USHORT);
|
||||
|
||||
switch (item)
|
||||
for (ClumpletReader p(ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
switch (p.getClumpTag())
|
||||
{
|
||||
case isc_info_db_sql_dialect:
|
||||
dialect = gds__vax_integer(p, length);
|
||||
dialect = p.getInt();
|
||||
break;
|
||||
}
|
||||
|
||||
p += length;
|
||||
}
|
||||
|
||||
UserId::makeRoleName(role, dialect);
|
||||
|
@ -158,37 +158,33 @@ void IscConnection::attach(thread_db* tdbb)
|
||||
memset(m_features, false, sizeof(m_features));
|
||||
m_sqlDialect = 1;
|
||||
|
||||
const unsigned char* p = buff, *end = buff + sizeof(buff);
|
||||
while (p < end)
|
||||
for (ClumpletReader p(ClumpletReader::InfoResponse, buff, sizeof(buff)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
const UCHAR item = *p++;
|
||||
const USHORT len = m_iscProvider.isc_vax_integer(p, sizeof(USHORT));
|
||||
p += sizeof(USHORT);
|
||||
|
||||
switch (item)
|
||||
const UCHAR* b = p.getBytes();
|
||||
switch (p.getClumpTag())
|
||||
{
|
||||
case isc_info_db_sql_dialect:
|
||||
m_sqlDialect = m_iscProvider.isc_vax_integer(p, len);
|
||||
m_sqlDialect = p.getInt();
|
||||
break;
|
||||
|
||||
case fb_info_features:
|
||||
for (int i = 0; i < len; i++)
|
||||
for (unsigned i = 0; i < p.getClumpLength(); i++)
|
||||
{
|
||||
if (p[i] == 0)
|
||||
if (b[i] == 0)
|
||||
ERR_post(Arg::Gds(isc_random) << Arg::Str("Bad provider feature value"));
|
||||
|
||||
if (p[i] < fb_feature_max)
|
||||
setFeature(static_cast<info_features>(p[i]));
|
||||
if (b[i] < fb_feature_max)
|
||||
setFeature(static_cast<info_features>(b[i]));
|
||||
// else this provider supports unknown feature, ignore it.
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_info_error:
|
||||
{
|
||||
const ULONG err = m_iscProvider.isc_vax_integer(p + 1, len - 1);
|
||||
const ULONG err = m_iscProvider.isc_vax_integer(p.getBytes() + 1, p.getClumpLength() - 1);
|
||||
if (err == isc_infunk)
|
||||
{
|
||||
if (*p == fb_info_features)
|
||||
if (p.getBytes()[0] == fb_info_features)
|
||||
{
|
||||
// Used provider follow Firebird error reporting conventions but is not aware of
|
||||
// this info item. Assume Firebird 3 or earlier.
|
||||
@ -203,14 +199,8 @@ void IscConnection::attach(thread_db* tdbb)
|
||||
|
||||
case isc_info_truncated:
|
||||
ERR_post(Arg::Gds(isc_random) << Arg::Str("Result truncation in isc_database_info"));
|
||||
|
||||
case isc_info_end:
|
||||
p = end;
|
||||
break;
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void IscConnection::doDetach(thread_db* tdbb)
|
||||
|
@ -2754,11 +2754,11 @@ static USHORT check_statement_type( Rsr* statement)
|
||||
|
||||
if (!(local_status.getState() & Firebird::IStatus::STATE_ERRORS))
|
||||
{
|
||||
for (const UCHAR* info = buffer; (*info != isc_info_end) && !done;)
|
||||
for (ClumpletReader p(ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
const USHORT l = (USHORT) gds__vax_integer(info + 1, 2);
|
||||
const USHORT type = (USHORT) gds__vax_integer(info + 3, l);
|
||||
switch (*info)
|
||||
const USHORT type = (USHORT) p.getInt();
|
||||
|
||||
switch (p.getClumpTag())
|
||||
{
|
||||
case isc_info_sql_stmt_type:
|
||||
switch (type)
|
||||
@ -2773,17 +2773,12 @@ static USHORT check_statement_type( Rsr* statement)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_info_sql_batch_fetch:
|
||||
if (type == 0)
|
||||
ret |= STMT_NO_BATCH;
|
||||
break;
|
||||
case isc_info_error:
|
||||
case isc_info_truncated:
|
||||
done = true;
|
||||
break;
|
||||
|
||||
}
|
||||
info += 3 + l;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "../yvalve/MasterImplementation.h"
|
||||
#include "../common/classes/rwlock.h"
|
||||
#include "../common/classes/ClumpletReader.h"
|
||||
#include "firebird/impl/inf_pub.h"
|
||||
#include "../common/isc_proto.h"
|
||||
#include "../jrd/acl.h"
|
||||
@ -107,36 +108,26 @@ bool DTransaction::buildPrepareInfo(CheckStatusWrapper* status, TdrBuffer& tdr,
|
||||
if (status->getState() & IStatus::STATE_ERRORS)
|
||||
return false;
|
||||
|
||||
UCHAR* const end = bigBuffer.end();
|
||||
|
||||
while (buf < end)
|
||||
for (ClumpletReader p(ClumpletReader::InfoResponse, buf, bigBuffer.getCount()); !p.isEof(); p.moveNext())
|
||||
{
|
||||
UCHAR item = buf[0];
|
||||
++buf;
|
||||
const USHORT length = (USHORT) gds__vax_integer(buf, 2);
|
||||
const USHORT length = (USHORT) p.getClumpLength();
|
||||
// Prevent information out of sync.
|
||||
UCHAR lengthByte = length > MAX_UCHAR ? MAX_UCHAR : length;
|
||||
buf += 2;
|
||||
|
||||
switch(item)
|
||||
switch(p.getClumpTag())
|
||||
{
|
||||
case isc_info_tra_id:
|
||||
tdr.add(TDR_TRANSACTION_ID);
|
||||
tdr.add(lengthByte);
|
||||
tdr.add(buf, lengthByte);
|
||||
tdr.add(p.getBytes(), lengthByte);
|
||||
break;
|
||||
|
||||
case fb_info_tra_dbpath:
|
||||
tdr.add(TDR_DATABASE_PATH);
|
||||
tdr.add(lengthByte);
|
||||
tdr.add(buf, lengthByte);
|
||||
tdr.add(p.getBytes(), lengthByte);
|
||||
break;
|
||||
|
||||
case isc_info_end:
|
||||
return true;
|
||||
}
|
||||
|
||||
buf += length;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -458,29 +458,23 @@ void UtilInterface::getFbVersion(CheckStatusWrapper* status, IAttachment* att,
|
||||
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
return;
|
||||
|
||||
const UCHAR* p = buf;
|
||||
redo = false;
|
||||
ClumpletReader p(ClumpletReader::InfoResponse, buf, buf_len);
|
||||
|
||||
while (!redo && *p != isc_info_end && p < buf + buf_len)
|
||||
for (redo = false; !(redo || p.isEof()); p.moveNext())
|
||||
{
|
||||
const UCHAR item = *p++;
|
||||
const USHORT len = static_cast<USHORT>(gds__vax_integer(p, 2));
|
||||
|
||||
p += 2;
|
||||
|
||||
switch (item)
|
||||
switch (p.getClumpTag())
|
||||
{
|
||||
case isc_info_firebird_version:
|
||||
versions = (TEXT*) p;
|
||||
versions = (TEXT*) p.getBytes();
|
||||
break;
|
||||
|
||||
case isc_info_implementation:
|
||||
implementations = (TEXT*) p;
|
||||
implementations = (TEXT*) p.getBytes();
|
||||
break;
|
||||
|
||||
case fb_info_implementation:
|
||||
dbis = p;
|
||||
if (dbis[0] * 6 + 1 > len)
|
||||
dbis = p.getBytes();
|
||||
if (dbis[0] * 6u + 1u > p.getClumpLength())
|
||||
{
|
||||
// fb_info_implementation value appears incorrect
|
||||
dbis = NULL;
|
||||
@ -493,13 +487,13 @@ void UtilInterface::getFbVersion(CheckStatusWrapper* status, IAttachment* att,
|
||||
|
||||
case isc_info_truncated:
|
||||
redo = true;
|
||||
// fall down...
|
||||
case isc_info_end:
|
||||
break;
|
||||
|
||||
default:
|
||||
(Arg::Gds(isc_random) << "Invalid info item").raise();
|
||||
}
|
||||
|
||||
p += len;
|
||||
}
|
||||
|
||||
// Our buffer wasn't large enough to hold all the information,
|
||||
@ -1441,37 +1435,35 @@ int API_ROUTINE gds__blob_size(FB_API_HANDLE* b, SLONG* size, SLONG* seg_count,
|
||||
*
|
||||
**************************************/
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
SCHAR buffer[64];
|
||||
UCHAR buffer[64];
|
||||
|
||||
if (isc_blob_info(status_vector, b, sizeof(blob_items), blob_items, sizeof(buffer), buffer))
|
||||
if (isc_blob_info(status_vector, b, sizeof(blob_items), blob_items, sizeof(buffer), (SCHAR*)buffer))
|
||||
{
|
||||
isc_print_status(status_vector);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const UCHAR* p = reinterpret_cast<UCHAR*>(buffer);
|
||||
UCHAR item;
|
||||
while ((item = *p++) != isc_info_end)
|
||||
for (ClumpletReader p(ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
const USHORT l = gds__vax_integer(p, 2);
|
||||
p += 2;
|
||||
const SLONG n = gds__vax_integer(p, l);
|
||||
p += l;
|
||||
UCHAR item = p.getClumpTag();
|
||||
if (item == isc_info_end)
|
||||
break;
|
||||
|
||||
switch (item)
|
||||
{
|
||||
case isc_info_blob_max_segment:
|
||||
if (max_seg)
|
||||
*max_seg = n;
|
||||
*max_seg = p.getInt();
|
||||
break;
|
||||
|
||||
case isc_info_blob_num_segments:
|
||||
if (seg_count)
|
||||
*seg_count = n;
|
||||
*seg_count = p.getInt();
|
||||
break;
|
||||
|
||||
case isc_info_blob_total_length:
|
||||
if (size)
|
||||
*size = n;
|
||||
*size = p.getInt();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2976,16 +2968,10 @@ static void get_ods_version(CheckStatusWrapper* status, IAttachment* att,
|
||||
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
return;
|
||||
|
||||
const UCHAR* p = buffer;
|
||||
UCHAR item;
|
||||
|
||||
while ((item = *p++) != isc_info_end)
|
||||
for (ClumpletReader p(ClumpletReader::InfoResponse, buffer, sizeof(buffer)); !p.isEof(); p.moveNext())
|
||||
{
|
||||
const USHORT l = static_cast<USHORT>(gds__vax_integer(p, 2));
|
||||
p += 2;
|
||||
const USHORT n = static_cast<USHORT>(gds__vax_integer(p, l));
|
||||
p += l;
|
||||
switch (item)
|
||||
const USHORT n = static_cast<USHORT>(p.getInt());
|
||||
switch (p.getClumpTag())
|
||||
{
|
||||
case isc_info_ods_version:
|
||||
*ods_version = n;
|
||||
@ -2995,6 +2981,9 @@ static void get_ods_version(CheckStatusWrapper* status, IAttachment* att,
|
||||
*ods_minor_version = n;
|
||||
break;
|
||||
|
||||
case isc_info_end:
|
||||
break;
|
||||
|
||||
default:
|
||||
(Arg::Gds(isc_random) << "Invalid info item").raise();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user