xwayland: add a size-safe wrapper for xcb_send_event

xcb_send_event expects the caller to always provide 32 byte data, even if the actual event struct is
smaller than that.

Reference: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/18
master
Ilia Bozhinov 8 months ago
parent cc10a5259d
commit c63275d75e

@ -162,4 +162,8 @@ char *xwm_get_atom_name(struct wlr_xwm *xwm, xcb_atom_t atom);
bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms,
size_t num_atoms, enum atom_name needle);
xcb_void_cookie_t xwm_send_event_with_size(xcb_connection_t *c,
uint8_t propagate, xcb_window_t destination,
uint32_t event_mask, const void *event, uint32_t length);
#endif

@ -49,11 +49,12 @@ static void xwm_dnd_send_event(struct wlr_xwm *xwm, xcb_atom_t type,
.data = *data,
};
xcb_send_event(xwm->xcb_conn,
xwm_send_event_with_size(xwm->xcb_conn,
0, // propagate
dest->window_id,
XCB_EVENT_MASK_NO_EVENT,
(const char *)&event);
&event,
sizeof(event));
xcb_flush(xwm->xcb_conn);
}

@ -27,11 +27,12 @@ static void xwm_selection_send_notify(struct wlr_xwm *xwm,
" requestor=%" PRIu32 " selection=%" PRIu32 " target=%" PRIu32 " property=%" PRIu32,
req->requestor, req->time, req->requestor, req->selection, req->target,
selection_notify.property);
xcb_send_event(xwm->xcb_conn,
xwm_send_event_with_size(xwm->xcb_conn,
0, // propagate
req->requestor,
XCB_EVENT_MASK_NO_EVENT,
(const char *)&selection_notify);
&selection_notify,
sizeof(selection_notify));
xcb_flush(xwm->xcb_conn);
}

@ -257,6 +257,25 @@ static void xwm_set_net_active_window(struct wlr_xwm *xwm,
xwm->atoms[WINDOW], 32, 1, &window);
}
/*
* Wrapper for xcb_send_event, which ensures that the event data is 32 byte big.
*/
xcb_void_cookie_t xwm_send_event_with_size(xcb_connection_t *c,
uint8_t propagate, xcb_window_t destination,
uint32_t event_mask, const void *event, uint32_t length)
{
if (length == 32) {
return xcb_send_event(c, propagate, destination, event_mask, event);
} else if (length < 32) {
char buf[32];
memcpy(buf, event, length);
memset(buf + length, 0, 32 - length);
return xcb_send_event(c, propagate, destination, event_mask, buf);
} else {
assert(false && "Event too long");
}
}
static void xwm_send_wm_message(struct wlr_xwayland_surface *surface,
xcb_client_message_data_t *data, uint32_t event_mask) {
struct wlr_xwm *xwm = surface->xwm;
@ -270,11 +289,12 @@ static void xwm_send_wm_message(struct wlr_xwayland_surface *surface,
.data = *data,
};
xcb_send_event(xwm->xcb_conn,
xwm_send_event_with_size(xwm->xcb_conn,
0, // propagate
surface->window_id,
event_mask,
(const char *)&event);
&event,
sizeof(event));
xcb_flush(xwm->xcb_conn);
}
@ -1824,9 +1844,10 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface,
.height = height,
};
xcb_send_event(xwm->xcb_conn, 0, xsurface->window_id,
xwm_send_event_with_size(xwm->xcb_conn, 0, xsurface->window_id,
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
(const char *)&configure_notify);
&configure_notify,
sizeof(configure_notify));
}
xcb_flush(xwm->xcb_conn);

Loading…
Cancel
Save