aboutsummaryrefslogtreecommitdiff
path: root/qapi/qapi-dealloc-visitor.c
diff options
context:
space:
mode:
authorMichael Roth <mdroth@linux.vnet.ibm.com>2011-09-15 14:39:52 -0500
committerLuiz Capitulino <lcapitulino@redhat.com>2011-10-04 11:00:46 -0300
commit5666dd19dd95d966be00d0c3e7efdfaecc096ff3 (patch)
tree034ac3fd5d50ef4058c58e879e5aceba327ecab4 /qapi/qapi-dealloc-visitor.c
parent15e43e64b6bac61811e829634ee048e8de4c976d (diff)
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>
Diffstat (limited to 'qapi/qapi-dealloc-visitor.c')
-rw-r--r--qapi/qapi-dealloc-visitor.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index f6290611fe..6b586ade13 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -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)