From 62405fbb75126a7dcad45f3f656e9bc790dbd6dc Mon Sep 17 00:00:00 2001 From: David Maciejak Date: Wed, 22 Feb 2023 19:29:23 +0800 Subject: [PATCH] Detect and override illegal window size hints v2 The patch is trying to mitigate and properly address the issue described at https://github.com/window-maker/wmaker/issues/26 A buggy application (in that example virtualbox) is requesting a window size creation that is way too big and basically at the limit of X11 protocol (width and height are defined as CARD16). See details at https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html During the tests, virtualbox has been seen requesting for window creation of size 843x65508. Even xprop is reporting incorrect values. There had been an attempt before with the commit https://repo.or.cz/wmaker-crm.git?a=commit;h=6668715402a5d8e2ecda6702076a06bf8988721e But the patch is broken and not implemented at the right place. As described in the wWindowConfigure function header, the size passed by the client app should not be trusted and should be vetted with a prior call to wWindowConstrainSize. wWindowConstrainSize call was missing only once in the wClientConfigure function from client.c What wWindowConstrainSize doing now is basically setting a failsafe window size fo 640x480 if both width and height are above the size of CARD16. If only one dimension is oversized, it's setting a default 4/3 window ratio. Oversized here has not been changed and it's defined in windowmaker as double the screen size. --- src/client.c | 1 + src/window.c | 34 +++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/client.c b/src/client.c index 92912b95..2c81eb7c 100644 --- a/src/client.c +++ b/src/client.c @@ -244,6 +244,7 @@ void wClientConfigure(WWindow * wwin, XConfigureRequestEvent * xcre) if (nheight != wwin->old_geometry.height) wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS); + wWindowConstrainSize(wwin, (unsigned int *)&nwidth, (unsigned int *)&nheight); wWindowConfigure(wwin, nx, ny, nwidth, nheight); wwin->old_geometry.x = nx; wwin->old_geometry.y = ny; diff --git a/src/window.c b/src/window.c index 0d12cd5b..f9cffe94 100644 --- a/src/window.c +++ b/src/window.c @@ -1735,9 +1735,8 @@ void wWindowSingleFocus(WWindow *wwin) /* bring window back to visible area */ move = wScreenBringInside(scr, &x, &y, wwin->frame->core->width, wwin->frame->core->height); - if (move) { + if (move) wWindowConfigure(wwin, x, y, wwin->client.width, wwin->client.height); - } } void wWindowFocusPrev(WWindow *wwin, Bool inSameWorkspace) @@ -1901,6 +1900,16 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe int baseW = 0; int baseH = 0; + /* + * X11 proto defines width and height as a CARD16 + * if window size is guaranteed to fail, failsafe to a reasonable size + */ + if (width > USHRT_MAX && height > USHRT_MAX) { + width = 640; + height = 480; + return; + } + if (wwin->normal_hints) { if (!wwin->flags.maximized) { winc = wwin->normal_hints->width_inc; @@ -1921,15 +1930,19 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe baseH = wwin->normal_hints->base_height; } + /* trust the mins provided by the client but not the maxs */ if (width < minW) width = minW; if (height < minH) height = minH; - if (width > maxW) - width = maxW; - if (height > maxH) - height = maxH; + /* if only one dimension is over the top, set a default 4/3 ratio */ + if (width > maxW && height < maxH) { + width = height * 4 / 3; + } else { + if(height > maxH && width < maxW) + height = width * 3 / 4; + } /* aspect ratio code borrowed from olwm */ if (minAX > 0) { @@ -2135,14 +2148,6 @@ void wWindowConfigure(WWindow *wwin, int req_x, int req_y, int req_width, int re int synth_notify = False; int resize; - /* if window size is guaranteed to fail - fix it to some reasonable - * defaults */ - if (req_height > SHRT_MAX) - req_height = 480; - - if (req_width > SHRT_MAX) - req_height = 640; - resize = (req_width != wwin->client.width || req_height != wwin->client.height); /* * if the window is being moved but not resized then @@ -2932,7 +2937,6 @@ static void titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event) } /* maximize window */ - if (dir != 0 && IS_RESIZABLE(wwin)) { int ndir = dir ^ wwin->flags.maximized; -- 2.11.4.GIT