diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2014-03-19 08:58:54 +0100 |
---|---|---|
committer | Andreas Färber <afaerber@suse.de> | 2014-03-19 22:01:34 +0100 |
commit | c6aed9833419eed9de19919ff31aa021a6171521 (patch) | |
tree | c436d4aa0b2bbf46aee9264ad5a7f7fd5716e918 | |
parent | f5ec6704c73932291c303d0cf72352ac26411d0d (diff) |
qom: Don't make link NULL on object_property_set_link() failure
The error behavior of object_property_set_link() is dangerous. It sets
the link property object to NULL if an error occurs. A setter function
should either succeed or fail, it shouldn't leave the value NULL on
failure.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
-rw-r--r-- | qom/object.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/qom/object.c b/qom/object.c index 2877a00b81..cc946d9dac 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1080,27 +1080,28 @@ static Object *object_resolve_link(Object *obj, const char *name, static void object_set_link_property(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + Error *local_err = NULL; Object **child = opaque; - Object *old_target; - char *path; - - visit_type_str(v, &path, name, errp); + Object *old_target = *child; + Object *new_target = NULL; + char *path = NULL; - old_target = *child; - *child = NULL; + visit_type_str(v, &path, name, &local_err); - if (strcmp(path, "") != 0) { - Object *target; - - target = object_resolve_link(obj, name, path, errp); - if (target) { - object_ref(target); - *child = target; - } + if (!local_err && strcmp(path, "") != 0) { + new_target = object_resolve_link(obj, name, path, &local_err); } g_free(path); + if (local_err) { + error_propagate(errp, local_err); + return; + } + if (new_target) { + object_ref(new_target); + } + *child = new_target; if (old_target != NULL) { object_unref(old_target); } |