qapi: fix error propagation

Don't overwrite / leak previously set errors.
Make traversal cope with missing mandatory sub-structs.
Don't try to end a container that could not be started.

v1->v2:
- unchanged

v2->v3:
- instead of examining, assert that we never overwrite errors with
  error_set()
- allow visitors to set a NULL struct pointer successfully, so traversal
  of incomplete objects can continue
- check for a NULL "obj" before accessing "(*obj)->has_XXX" (this is not a
  typo, "obj != NULL" implies "*obj != NULL" here)
- fix start_struct / end_struct balance for unions as well

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
This commit is contained in:
Paolo Bonzini 2012-07-17 16:17:04 +02:00 committed by Stefan Hajnoczi
parent 837c36e787
commit d195325b05
6 changed files with 120 additions and 69 deletions

View file

@ -39,9 +39,8 @@ void visit_start_struct(Visitor *v, void **obj, const char *kind,
void visit_end_struct(Visitor *v, Error **errp)
{
if (!error_is_set(errp)) {
v->end_struct(v, errp);
}
assert(!error_is_set(errp));
v->end_struct(v, errp);
}
void visit_start_list(Visitor *v, const char *name, Error **errp)
@ -62,9 +61,8 @@ GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
void visit_end_list(Visitor *v, Error **errp)
{
if (!error_is_set(errp)) {
v->end_list(v, errp);
}
assert(!error_is_set(errp));
v->end_list(v, errp);
}
void visit_start_optional(Visitor *v, bool *present, const char *name,