From 769813766302a9b249871827fdbaed8d03c8f4f2 Mon Sep 17 00:00:00 2001 From: Lloyd Pique Date: Fri, 11 Mar 2022 19:10:07 -0800 Subject: [PATCH] server: Safe cast a "wl_object *" to "wl_resource *" Client message observers 5/6 When given an array of wl_arguments for a wl_closure, the .o field is an opaque wl_object pointer, which the server implementation cannot really do anything with, without a potentially unsafe cast that assumes details about the internal implementation. By adding a wl_resource_from_object() function to the client interface, the client can safely get the wl_resource pointer. This can be used by server protocol loggers in particular to get the resource id and class name, for logging those details Signed-off-by: Lloyd Pique --- src/wayland-server-core.h | 3 +++ src/wayland-server.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index b1baa25f..1fbb0da5 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -628,6 +628,9 @@ struct wl_listener * wl_resource_get_destroy_listener(struct wl_resource *resource, wl_notify_func_t notify); +struct wl_resource * +wl_resource_from_object(struct wl_object *object); + #define wl_resource_for_each(resource, list) \ for (resource = 0, resource = wl_resource_from_link((list)->next); \ wl_resource_get_link(resource) != (list); \ diff --git a/src/wayland-server.c b/src/wayland-server.c index 01fe87f4..f8cdea95 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -905,6 +905,28 @@ wl_resource_get_class(struct wl_resource *resource) return resource->object.interface->name; } +/** Safely converts an object into its corresponding resource + * + * \param object object to get the resource for + * \return A corresponding resource, or NULL on failure + * + * Safely converts an object into its corresponding resource. + * + * This is useful for implementing functions that are given a \c wl_argument + * array, and that need to do further introspection on the ".o" field, as it + * is otherwise an opaque type. + * + * \memberof wl_resource + */ +WL_EXPORT struct wl_resource * +wl_resource_from_object(struct wl_object *object) +{ + struct wl_resource *resource; + if (object == NULL) + return NULL; + return wl_container_of(object, resource, object); +} + /** * Add a listener to be called at the beginning of wl_client destruction *