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:
Michael Roth 2011-09-15 14:39:52 -05:00 committed by Luiz Capitulino
parent 15e43e64b6
commit 5666dd19dd

View File

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