diff options
author | Michael Roth | 2011-09-15 21:39:52 +0200 |
---|---|---|
committer | Luiz Capitulino | 2011-10-04 16:00:46 +0200 |
commit | 5666dd19dd95d966be00d0c3e7efdfaecc096ff3 (patch) | |
tree | 034ac3fd5d50ef4058c58e879e5aceba327ecab4 /qapi | |
parent | qapi: fixup command generation for functions that return list types (diff) | |
download | qemu-5666dd19dd95d966be00d0c3e7efdfaecc096ff3.tar.gz qemu-5666dd19dd95d966be00d0c3e7efdfaecc096ff3.tar.xz qemu-5666dd19dd95d966be00d0c3e7efdfaecc096ff3.zip |
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')
-rw-r--r-- | qapi/qapi-dealloc-visitor.c | 20 |
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) |