From f2b4d25b81f05fd3b3ec1a07386858e21d635ad2 Mon Sep 17 00:00:00 2001 From: Ollie Date: Thu, 28 May 2026 21:42:02 +0200 Subject: [PATCH] selection: fix use-after-free crash from duplicate handler delete --- WINGs/selection_x11.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/WINGs/selection_x11.c b/WINGs/selection_x11.c index 13428a2..c3d792e 100644 --- a/WINGs/selection_x11.c +++ b/WINGs/selection_x11.c @@ -360,30 +360,20 @@ Bool WMCreateSelectionHandler(WMView * view, WMNativeAtom selection, Time timest /* On Wayland (no X11 SelectionRequest events), immediately push * the selection data via the clipboard store path so external - * clients can paste it. The data is fetched from the view's - * convertSelection callback. */ - /* On Wayland (no X11 SelectionRequest events), push selection data - * to the compositor via the clipboard store path. If a handler - * already exists for this view+selection, just push fresh data - * so selection is always current (otherwise double-click to - * reselect would be skipped since ownsSelection is stale). */ - if (vb->selection_fetch) { - /* Delete any existing handler for this view+selection first */ - WMDeleteSelectionHandler(view, selection, WM_CURRENT_TIME); - if (handler->procs.convertSelection) { - WMNativeAtom textAtom = XA_STRING; - WMNativeAtom type; - WMData *d = handler->procs.convertSelection(handler->view, - selection, textAtom, handler->data, &type); - if (d) { - if (view->screen->viewBackend->clipboard_store) { - view->screen->viewBackend->clipboard_store( - view->screen->viewBackendCtx, - WMDataBytes(d), - WMGetDataLength(d)); - } - WMReleaseData(d); + * clients can paste it. */ + if (vb->selection_fetch && handler->procs.convertSelection) { + WMNativeAtom textAtom = XA_STRING; + WMNativeAtom type; + WMData *d = handler->procs.convertSelection(handler->view, + selection, textAtom, handler->data, &type); + if (d) { + if (view->screen->viewBackend->clipboard_store) { + view->screen->viewBackend->clipboard_store( + view->screen->viewBackendCtx, + WMDataBytes(d), + WMGetDataLength(d)); } + WMReleaseData(d); } }