1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2From: Lloyd Pique <[email protected]> 3Date: Fri, 11 Mar 2022 19:10:07 -0800 4Subject: [PATCH 5/6] server: Safe cast a "wl_object *" to "wl_resource *" 5 6Client message observers 5/6 7 8When given an array of wl_arguments for a wl_closure, the .o field is an 9opaque wl_object pointer, which the server implementation cannot really do 10anything with, without a potentially unsafe cast that assumes details about the 11internal implementation. 12 13By adding a wl_resource_from_object() function to the client interface, the client 14can safely get the wl_resource pointer. 15 16This can be used by server protocol loggers in particular to get the resource id 17and class name, for logging those details 18 19Signed-off-by: Lloyd Pique <[email protected]> 20 21diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h 22index df95821..63c6a62 100644 23--- a/src/wayland-server-core.h 24+++ b/src/wayland-server-core.h 25@@ -608,6 +608,9 @@ struct wl_listener * 26 wl_resource_get_destroy_listener(struct wl_resource *resource, 27 wl_notify_func_t notify); 28 29+struct wl_resource * 30+wl_resource_from_object(struct wl_object *object); 31+ 32 #define wl_resource_for_each(resource, list) \ 33 for (resource = 0, resource = wl_resource_from_link((list)->next); \ 34 wl_resource_get_link(resource) != (list); \ 35diff --git a/src/wayland-server.c b/src/wayland-server.c 36index be98f7d..468322d 100644 37--- a/src/wayland-server.c 38+++ b/src/wayland-server.c 39@@ -866,6 +866,28 @@ wl_resource_get_class(struct wl_resource *resource) 40 return resource->object.interface->name; 41 } 42 43+/** Safely converts an object into its corresponding resource 44+ * 45+ * \param object object to get the resource for 46+ * \return A corresponding resource, or NULL on failure 47+ * 48+ * Safely converts an object into its corresponding resource. 49+ * 50+ * This is useful for implementing functions that are given a \c wl_argument 51+ * array, and that need to do further introspection on the ".o" field, as it 52+ * is otherwise an opaque type. 53+ * 54+ * \memberof wl_resource 55+ */ 56+WL_EXPORT struct wl_resource * 57+wl_resource_from_object(struct wl_object *object) 58+{ 59+ struct wl_resource *resource; 60+ if (object == NULL) 61+ return NULL; 62+ return wl_container_of(object, resource, object); 63+} 64+ 65 /** 66 * Add a listener to be called at the beginning of wl_client destruction 67 * 68