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