qapi: dealloc visitor, fix premature free and iteration logic
Currently we do 3 things wrong: 1) The list iterator, in practice, is used in a manner where the pointer we pass in is the same as the pointer we assign the output to from visit_next_list(). This causes an infinite loop where we keep freeing the same structures. 2) We attempt to free list->value rather than list. visit_type_<type> handles this. We should only be concerned with the containing list. 3) We free prematurely: iterator function will continue accessing values we've already freed. This patch should fix all of these issues. QmpOutputVisitor also suffers from 1). Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
		
							parent
							
								
									15e43e64b6
								
							
						
					
					
						commit
						5666dd19dd
					
				| 
						 | 
				
			
			@ -26,6 +26,7 @@ struct QapiDeallocVisitor
 | 
			
		|||
{
 | 
			
		||||
    Visitor visitor;
 | 
			
		||||
    QTAILQ_HEAD(, StackEntry) stack;
 | 
			
		||||
    bool is_list_head;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QapiDeallocVisitor *to_qov(Visitor *v)
 | 
			
		||||
| 
						 | 
				
			
			@ -70,15 +71,24 @@ static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
 | 
			
		|||
 | 
			
		||||
static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    QapiDeallocVisitor *qov = to_qov(v);
 | 
			
		||||
    qov->is_list_head = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **list,
 | 
			
		||||
static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp,
 | 
			
		||||
                                           Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    GenericList *retval = *list;
 | 
			
		||||
    g_free(retval->value);
 | 
			
		||||
    *list = retval->next;
 | 
			
		||||
    return retval;
 | 
			
		||||
    GenericList *list = *listp;
 | 
			
		||||
    QapiDeallocVisitor *qov = to_qov(v);
 | 
			
		||||
 | 
			
		||||
    if (!qov->is_list_head) {
 | 
			
		||||
        *listp = list->next;
 | 
			
		||||
        g_free(list);
 | 
			
		||||
        return *listp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qov->is_list_head = false;
 | 
			
		||||
    return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qapi_dealloc_end_list(Visitor *v, Error **errp)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue