1*84e872a0SLloyd PiqueFrom 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2*84e872a0SLloyd PiqueFrom: Lloyd Pique <[email protected]> 3*84e872a0SLloyd PiqueDate: Fri, 11 Mar 2022 18:17:20 -0800 4*84e872a0SLloyd PiqueSubject: [PATCH 4/6] client: Safe cast a "wl_object *" to "wl_proxy *" 5*84e872a0SLloyd Pique 6*84e872a0SLloyd PiqueClient message observers 4/6 7*84e872a0SLloyd Pique 8*84e872a0SLloyd PiqueWhen given an array of wl_arguments for a wl_closure, the ".o" field is an 9*84e872a0SLloyd Piqueopaque wl_object pointer, which the client code cannot really do anything with, 10*84e872a0SLloyd Piquewithout a potentially unsafe cast that assumes details about the internal 11*84e872a0SLloyd Piqueimplementation. 12*84e872a0SLloyd Pique 13*84e872a0SLloyd PiqueBy adding a wl_proxy_from_object() function to the client interface, the client 14*84e872a0SLloyd Piquecan safely get the wl_proxy pointer. 15*84e872a0SLloyd Pique 16*84e872a0SLloyd PiqueThis can be used by client message observers in particular to get the proxy id 17*84e872a0SLloyd Piqueand class name, for logging those details. 18*84e872a0SLloyd Pique 19*84e872a0SLloyd PiqueSigned-off-by: Lloyd Pique <[email protected]> 20*84e872a0SLloyd Pique 21*84e872a0SLloyd Piquediff --git a/src/wayland-client-core.h b/src/wayland-client-core.h 22*84e872a0SLloyd Piqueindex 2aa72a4..a57cbe0 100644 23*84e872a0SLloyd Pique--- a/src/wayland-client-core.h 24*84e872a0SLloyd Pique+++ b/src/wayland-client-core.h 25*84e872a0SLloyd Pique@@ -222,6 +222,9 @@ wl_proxy_get_class(struct wl_proxy *proxy); 26*84e872a0SLloyd Pique void 27*84e872a0SLloyd Pique wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue); 28*84e872a0SLloyd Pique 29*84e872a0SLloyd Pique+struct wl_proxy * 30*84e872a0SLloyd Pique+wl_proxy_from_object(struct wl_object *object); 31*84e872a0SLloyd Pique+ 32*84e872a0SLloyd Pique struct wl_display * 33*84e872a0SLloyd Pique wl_display_connect(const char *name); 34*84e872a0SLloyd Pique 35*84e872a0SLloyd Piquediff --git a/src/wayland-client.c b/src/wayland-client.c 36*84e872a0SLloyd Piqueindex 04b4f60..ab68bdb 100644 37*84e872a0SLloyd Pique--- a/src/wayland-client.c 38*84e872a0SLloyd Pique+++ b/src/wayland-client.c 39*84e872a0SLloyd Pique@@ -2594,6 +2594,28 @@ wl_proxy_wrapper_destroy(void *proxy_wrapper) 40*84e872a0SLloyd Pique free(wrapper); 41*84e872a0SLloyd Pique } 42*84e872a0SLloyd Pique 43*84e872a0SLloyd Pique+/** Safely converts an object into its corresponding proxy 44*84e872a0SLloyd Pique+ * 45*84e872a0SLloyd Pique+ * \param object object to get the proxy for 46*84e872a0SLloyd Pique+ * \return A corresponding proxy, or NULL on failure. 47*84e872a0SLloyd Pique+ * 48*84e872a0SLloyd Pique+ * Safely converts an object into its corresponding proxy. 49*84e872a0SLloyd Pique+ * 50*84e872a0SLloyd Pique+ * This is useful for implementing functions that are given a \c wl_argument 51*84e872a0SLloyd Pique+ * array, and that need to do further introspection on the ".o" field, as it 52*84e872a0SLloyd Pique+ * is otherwise an opaque type. 53*84e872a0SLloyd Pique+ * 54*84e872a0SLloyd Pique+ * \memberof wl_proxy 55*84e872a0SLloyd Pique+ */ 56*84e872a0SLloyd Pique+WL_EXPORT struct wl_proxy * 57*84e872a0SLloyd Pique+wl_proxy_from_object(struct wl_object *object) 58*84e872a0SLloyd Pique+{ 59*84e872a0SLloyd Pique+ struct wl_proxy *proxy; 60*84e872a0SLloyd Pique+ if (object == NULL) 61*84e872a0SLloyd Pique+ return NULL; 62*84e872a0SLloyd Pique+ return wl_container_of(object, proxy, object); 63*84e872a0SLloyd Pique+} 64*84e872a0SLloyd Pique+ 65*84e872a0SLloyd Pique WL_EXPORT void 66*84e872a0SLloyd Pique wl_log_set_handler_client(wl_log_func_t handler) 67*84e872a0SLloyd Pique { 68*84e872a0SLloyd Piquediff --git a/tests/protocol-logger-test.c b/tests/protocol-logger-test.c 69*84e872a0SLloyd Piqueindex 082f055..9420b5e 100644 70*84e872a0SLloyd Pique--- a/tests/protocol-logger-test.c 71*84e872a0SLloyd Pique+++ b/tests/protocol-logger-test.c 72*84e872a0SLloyd Pique@@ -275,10 +275,11 @@ client_log_to_stderr_demo(void *user_data, enum wl_client_message_type type, 73*84e872a0SLloyd Pique break; 74*84e872a0SLloyd Pique case 'o': 75*84e872a0SLloyd Pique if (args[i].o) { 76*84e872a0SLloyd Pique- // Note: server logger should instead cast to 77*84e872a0SLloyd Pique- // wl_resource, and use wl_resource_get_class 78*84e872a0SLloyd Pique- // and wl_resource_get_id. 79*84e872a0SLloyd Pique- arg_proxy = (struct wl_proxy *)(args[i].o); 80*84e872a0SLloyd Pique+ // Note: server logger should instead use 81*84e872a0SLloyd Pique+ // wl_resource_from_object, and then 82*84e872a0SLloyd Pique+ // wl_resource_get_class and 83*84e872a0SLloyd Pique+ // wl_resource_get_id. 84*84e872a0SLloyd Pique+ arg_proxy = wl_proxy_from_object(args[i].o); 85*84e872a0SLloyd Pique arg_class = wl_proxy_get_class(arg_proxy); 86*84e872a0SLloyd Pique 87*84e872a0SLloyd Pique fprintf(f, "%s@%u", 88