object_new() has a failure scenario where it will assert() if given an abstract type. Callers which are creating objects based on user input, or unknown/untrusted type names, must manually check the result of object_class_is_abstract() before calling object_new() to propagate an Error, instead of asserting.
Introduce a object_new_dynamic() method which is a counterpart to object_new() that directly returns an Error, instead of asserting. This new method is to be used where the typename is specified dynamically by code separate from the immediate caller. Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> --- include/qom/object.h | 27 +++++++++++++++++++++++++++ qom/object.c | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index 222c60e205..8c2f3551c5 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -624,14 +624,41 @@ Object *object_new_with_class(ObjectClass *klass, Error **errp); * object_new: * @typename: The name of the type of the object to instantiate. * + * This method should be used where @typename is statically specified + * from a const string at build time, where the caller does not expect + * failure to be possible. + * * This function will initialize a new object using heap allocated memory. * The returned object has a reference count of 1, and will be freed when * the last reference is dropped. * + * If an instance of @typename is not permitted to be instantiated, an + * assert will be raised. This can happen if @typename is abstract. + * * Returns: The newly allocated and instantiated object. */ Object *object_new(const char *typename); +/** + * object_new_dynamic: + * @typename: The name of the type of the object to instantiate. + * @errp: pointer to be filled with error details on failure + * + * This method should be used where @typename is dynamically chosen + * at runtime, which has the possibility of unexpected choices leading + * to failures. + * + * This function will initialize a new object using heap allocated memory. + * The returned object has a reference count of 1, and will be freed when + * the last reference is dropped. + * + * If an instance of @typename is not permitted to be instantiated, an + * error will be raised. This can happen if @typename is abstract. + * + * Returns: The newly allocated and instantiated object. + */ +Object *object_new_dynamic(const char *typename, Error **errp); + /** * object_new_with_props: * @typename: The name of the type of the object to instantiate. diff --git a/qom/object.c b/qom/object.c index 1f139aa9c8..1ed62dc2c9 100644 --- a/qom/object.c +++ b/qom/object.c @@ -807,6 +807,12 @@ Object *object_new(const char *typename) return object_new_with_type(ti, &error_abort); } +Object *object_new_dynamic(const char *typename, Error **errp) +{ + TypeImpl *ti = type_get_by_name(typename); + + return object_new_with_type(ti, errp); +} Object *object_new_with_props(const char *typename, Object *parent, -- 2.46.0