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:
@ -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