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;
|
Visitor visitor;
|
||||||
QTAILQ_HEAD(, StackEntry) stack;
|
QTAILQ_HEAD(, StackEntry) stack;
|
||||||
|
bool is_list_head;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QapiDeallocVisitor *to_qov(Visitor *v)
|
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)
|
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)
|
Error **errp)
|
||||||
{
|
{
|
||||||
GenericList *retval = *list;
|
GenericList *list = *listp;
|
||||||
g_free(retval->value);
|
QapiDeallocVisitor *qov = to_qov(v);
|
||||||
*list = retval->next;
|
|
||||||
return retval;
|
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)
|
static void qapi_dealloc_end_list(Visitor *v, Error **errp)
|
||||||
|
|
Loading…
Reference in New Issue