Fixed segmentation fault in case of much XML output
Because of the multi telegrams it is impossible to use a fixed buffer for XML output on the stack. Now the buffer is allocated on the heap. These also leads to a change in return behaviour for all XML functions, because it's possible that the buffer is NULL. For variable data this buffer grows every time there are less than 1024 bytes left for a new record.
This commit is contained in:
@ -1214,44 +1214,58 @@ mbus_data_variable_xml_normalized(mbus_data_variable *data)
|
||||
{
|
||||
mbus_data_record *record;
|
||||
mbus_record *norm_record;
|
||||
static char buff[8192];
|
||||
char *buff = NULL;
|
||||
char str_encoded[768];
|
||||
size_t len = 0;
|
||||
size_t len = 0, buff_size = 8192;
|
||||
size_t i;
|
||||
|
||||
if (data)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
|
||||
buff = (char*) malloc(buff_size);
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "%s", mbus_data_variable_header_xml(&(data->header)));
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "%s", mbus_data_variable_header_xml(&(data->header)));
|
||||
|
||||
for (record = data->record, i = 0; record; record = record->next, i++)
|
||||
{
|
||||
norm_record = mbus_parse_variable_record(record);
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"%zd\">\n", i);
|
||||
if ((buff_size - len) < 1024)
|
||||
{
|
||||
buff_size *= 2;
|
||||
buff = (char*) realloc(buff,buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, " <DataRecord id=\"%zd\">\n", i);
|
||||
|
||||
if (norm_record != NULL)
|
||||
{
|
||||
mbus_str_xml_encode(str_encoded, norm_record->function_medium, sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Function>%s</Function>\n", str_encoded);
|
||||
|
||||
mbus_str_xml_encode(str_encoded, norm_record->unit, sizeof(str_encoded));
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
|
||||
mbus_str_xml_encode(str_encoded, norm_record->quantity, sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Quantity>%s</Quantity>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Quantity>%s</Quantity>\n", str_encoded);
|
||||
|
||||
|
||||
if (norm_record->is_numeric)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%f</Value>\n", norm_record->value.real_val);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%f</Value>\n", norm_record->value.real_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbus_str_xml_encode(str_encoded, norm_record->value.str_val.value, sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%s</Value>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%s</Value>\n", str_encoded);
|
||||
}
|
||||
|
||||
mbus_record_free(norm_record);
|
||||
@ -1260,15 +1274,15 @@ mbus_data_variable_xml_normalized(mbus_data_variable *data)
|
||||
{
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " </DataRecord>\n\n");
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1290,7 +1304,7 @@ mbus_frame_data_xml_normalized(mbus_frame_data *data)
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbus_handle *
|
||||
|
@ -3358,29 +3358,42 @@ char *
|
||||
mbus_data_variable_xml(mbus_data_variable *data)
|
||||
{
|
||||
mbus_data_record *record;
|
||||
static char buff[8192];
|
||||
char str_encoded[768];
|
||||
size_t len = 0;
|
||||
char *buff = NULL;
|
||||
size_t len = 0, buff_size = 8192;
|
||||
int i;
|
||||
|
||||
if (data)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
|
||||
buff = (char*) malloc(buff_size);
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "%s",
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "%s",
|
||||
mbus_data_variable_header_xml(&(data->header)));
|
||||
|
||||
for (record = data->record, i = 0; record; record = record->next, i++)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "%s",
|
||||
if ((buff_size - len) < 1024)
|
||||
{
|
||||
buff_size *= 2;
|
||||
buff = (char*) realloc(buff,buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "%s",
|
||||
mbus_data_variable_record_xml(record, i, -1, &(data->header)));
|
||||
}
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -3389,64 +3402,69 @@ mbus_data_variable_xml(mbus_data_variable *data)
|
||||
char *
|
||||
mbus_data_fixed_xml(mbus_data_fixed *data)
|
||||
{
|
||||
static char buff[8192];
|
||||
char *buff = NULL;
|
||||
char str_encoded[256];
|
||||
size_t len = 0;
|
||||
size_t len = 0, buff_size = 8192;
|
||||
|
||||
if (data)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
|
||||
buff = (char*) malloc(buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <SlaveInformation>\n");
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Id>%d</Id>\n", (int)mbus_data_bcd_decode(data->id_bcd, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, " <SlaveInformation>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " <Id>%d</Id>\n", (int)mbus_data_bcd_decode(data->id_bcd, 4));
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_fixed_medium(data), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Medium>%s</Medium>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Medium>%s</Medium>\n", str_encoded);
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <AccessNumber>%d</AccessNumber>\n", data->tx_cnt);
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Status>%.2X</Status>\n", data->status);
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " </SlaveInformation>\n\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " <AccessNumber>%d</AccessNumber>\n", data->tx_cnt);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Status>%.2X</Status>\n", data->status);
|
||||
len += snprintf(&buff[len], buff_size - len, " </SlaveInformation>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"0\">\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " <DataRecord id=\"0\">\n");
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_fixed_function(data->status), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Function>%s</Function>\n", str_encoded);
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_fixed_unit(data->cnt1_type), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt1_val, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt1_val, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt1_val, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt1_val, 4));
|
||||
}
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " </DataRecord>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"1\">\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " <DataRecord id=\"1\">\n");
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_fixed_function(data->status), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Function>%s</Function>\n", str_encoded);
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_fixed_unit(data->cnt2_type), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
|
||||
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt2_val, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt2_val, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt2_val, 4));
|
||||
len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt2_val, 4));
|
||||
}
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " </DataRecord>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -3455,20 +3473,25 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
|
||||
char *
|
||||
mbus_data_error_xml(int error)
|
||||
{
|
||||
static char buff[512];
|
||||
char *buff = NULL;
|
||||
char str_encoded[256];
|
||||
size_t len = 0;
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
|
||||
size_t len = 0, buff_size = 8192;
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <SlaveInformation>\n");
|
||||
buff = (char*) malloc(buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, " <SlaveInformation>\n");
|
||||
|
||||
mbus_str_xml_encode(str_encoded, mbus_data_error_lookup(error), sizeof(str_encoded));
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Error>%s</Error>\n", str_encoded);
|
||||
len += snprintf(&buff[len], buff_size - len, " <Error>%s</Error>\n", str_encoded);
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " </SlaveInformation>\n\n");
|
||||
len += snprintf(&buff[len], buff_size - len, " </SlaveInformation>\n\n");
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
|
||||
|
||||
return buff;
|
||||
}
|
||||
@ -3497,7 +3520,7 @@ mbus_frame_data_xml(mbus_frame_data *data)
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -3511,9 +3534,9 @@ mbus_frame_xml(mbus_frame *frame)
|
||||
mbus_frame *iter;
|
||||
|
||||
mbus_data_record *record;
|
||||
static char buff[8192];
|
||||
char *buff = NULL;
|
||||
|
||||
size_t len = 0;
|
||||
size_t len = 0, buff_size = 8192;
|
||||
int record_cnt = 0, frame_cnt;
|
||||
|
||||
if (frame)
|
||||
@ -3544,25 +3567,39 @@ mbus_frame_xml(mbus_frame *frame)
|
||||
{
|
||||
//
|
||||
// generate XML for a sequence of variable data frames
|
||||
//
|
||||
//
|
||||
|
||||
buff = (char*) malloc(buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
|
||||
// include frame counter in XML output if more than one frame
|
||||
// is available (frame_cnt = -1 => not included in output)
|
||||
frame_cnt = (frame->next == NULL) ? -1 : 0;
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
|
||||
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
|
||||
|
||||
// only print the header info for the first frame (should be
|
||||
// the same for each frame in a sequence of a multi-telegram
|
||||
// transfer.
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "%s",
|
||||
len += snprintf(&buff[len], buff_size - len, "%s",
|
||||
mbus_data_variable_header_xml(&(frame_data.data_var.header)));
|
||||
|
||||
// loop through all records in the current frame, using a global
|
||||
// record count as record ID in the XML output
|
||||
for (record = frame_data.data_var.record; record; record = record->next, record_cnt++)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "%s",
|
||||
if ((buff_size - len) < 1024)
|
||||
{
|
||||
buff_size *= 2;
|
||||
buff = (char*) realloc(buff,buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "%s",
|
||||
mbus_data_variable_record_xml(record, record_cnt, frame_cnt, &(frame_data.data_var.header)));
|
||||
}
|
||||
|
||||
@ -3586,7 +3623,16 @@ mbus_frame_xml(mbus_frame *frame)
|
||||
// record count as record ID in the XML output
|
||||
for (record = frame_data.data_var.record; record; record = record->next, record_cnt++)
|
||||
{
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "%s",
|
||||
if ((buff_size - len) < 1024)
|
||||
{
|
||||
buff_size *= 2;
|
||||
buff = (char*) realloc(buff,buff_size);
|
||||
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], buff_size - len, "%s",
|
||||
mbus_data_variable_record_xml(record, record_cnt, frame_cnt, &(frame_data.data_var.header)));
|
||||
}
|
||||
|
||||
@ -3595,15 +3641,15 @@ mbus_frame_xml(mbus_frame *frame)
|
||||
{
|
||||
mbus_data_record_free(frame_data.data_var.record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n");
|
||||
len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
|
||||
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user