Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package xwayland for openSUSE:Factory checked in at 2026-10-22 19:24:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xwayland (Old) and /work/SRC/openSUSE:Factory/.xwayland.new.2252680 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xwayland" Thu Oct 22 19:24:50 2026 rev:54 rq:1386790 version:24.1.14 Changes: -------- --- /work/SRC/openSUSE:Factory/xwayland/xwayland.changes 2026-10-10 14:58:15.721174121 +0200 +++ /work/SRC/openSUSE:Factory/.xwayland.new.2252680/xwayland.changes 2026-10-22 19:24:52.451702650 +0200 @@ -1,0 +2,19 @@ +Wed Oct 21 11:38:56 UTC 2026 - Stefan Dirsch <[email protected]> + +- Update to version 24.1.14 + * security release +- supersedes the following patches + * 0001-xkb-NULL-text-pointer-after-free-in-_CheckSetDoodad-.patch + * 0002-xkb-allocate-names-keys-to-MAP_LENGTH-in-XkbAllocNam.patch + * 0003-xkb-widen-size_syms-num_syms-size_acts-num_acts-to-u.patch + * 0004-xkb-fix-CheckKeySyms-overwriting-request-range-symsP.patch + * 0005-randr-fix-size-and-offset-in-RRChangeProviderPropert.patch + * 0006-Xi-validate-modifier-values-in-ProcXIPassiveUngrabDe.patch + * 0007-glx-validate-dataBytes-against-cmdlen-in-RenderLarge.patch + * 0008-present-unlink-notifies-from-window-list-in-present_.patch + * 0009-dix-remove-passive-grabs-referencing-a-device-on-rem.patch + * 0010-Xi-add-bounds-check-for-barrier-events-in-input_cons.patch + * 0011-Xi-clean-up-gesture-sprite-traces-in-WindowGone.patch + * 0012-glamor-size-tmp_bits-buffer-for-source-coordinate-ra.patch + +------------------------------------------------------------------- Old: ---- 0001-xkb-NULL-text-pointer-after-free-in-_CheckSetDoodad-.patch 0002-xkb-allocate-names-keys-to-MAP_LENGTH-in-XkbAllocNam.patch 0003-xkb-widen-size_syms-num_syms-size_acts-num_acts-to-u.patch 0004-xkb-fix-CheckKeySyms-overwriting-request-range-symsP.patch 0005-randr-fix-size-and-offset-in-RRChangeProviderPropert.patch 0006-Xi-validate-modifier-values-in-ProcXIPassiveUngrabDe.patch 0007-glx-validate-dataBytes-against-cmdlen-in-RenderLarge.patch 0008-present-unlink-notifies-from-window-list-in-present_.patch 0009-dix-remove-passive-grabs-referencing-a-device-on-rem.patch 0010-Xi-add-bounds-check-for-barrier-events-in-input_cons.patch 0011-Xi-clean-up-gesture-sprite-traces-in-WindowGone.patch 0012-glamor-size-tmp_bits-buffer-for-source-coordinate-ra.patch xwayland-24.1.13.tar.xz xwayland-24.1.13.tar.xz.sig New: ---- xwayland-24.1.14.tar.xz xwayland-24.1.14.tar.xz.sig ----------(Old B)---------- Old:- supersedes the following patches * 0001-xkb-NULL-text-pointer-after-free-in-_CheckSetDoodad-.patch * 0002-xkb-allocate-names-keys-to-MAP_LENGTH-in-XkbAllocNam.patch Old: * 0001-xkb-NULL-text-pointer-after-free-in-_CheckSetDoodad-.patch * 0002-xkb-allocate-names-keys-to-MAP_LENGTH-in-XkbAllocNam.patch * 0003-xkb-widen-size_syms-num_syms-size_acts-num_acts-to-u.patch Old: * 0002-xkb-allocate-names-keys-to-MAP_LENGTH-in-XkbAllocNam.patch * 0003-xkb-widen-size_syms-num_syms-size_acts-num_acts-to-u.patch * 0004-xkb-fix-CheckKeySyms-overwriting-request-range-symsP.patch Old: * 0003-xkb-widen-size_syms-num_syms-size_acts-num_acts-to-u.patch * 0004-xkb-fix-CheckKeySyms-overwriting-request-range-symsP.patch * 0005-randr-fix-size-and-offset-in-RRChangeProviderPropert.patch Old: * 0004-xkb-fix-CheckKeySyms-overwriting-request-range-symsP.patch * 0005-randr-fix-size-and-offset-in-RRChangeProviderPropert.patch * 0006-Xi-validate-modifier-values-in-ProcXIPassiveUngrabDe.patch Old: * 0005-randr-fix-size-and-offset-in-RRChangeProviderPropert.patch * 0006-Xi-validate-modifier-values-in-ProcXIPassiveUngrabDe.patch * 0007-glx-validate-dataBytes-against-cmdlen-in-RenderLarge.patch Old: * 0006-Xi-validate-modifier-values-in-ProcXIPassiveUngrabDe.patch * 0007-glx-validate-dataBytes-against-cmdlen-in-RenderLarge.patch * 0008-present-unlink-notifies-from-window-list-in-present_.patch Old: * 0007-glx-validate-dataBytes-against-cmdlen-in-RenderLarge.patch * 0008-present-unlink-notifies-from-window-list-in-present_.patch * 0009-dix-remove-passive-grabs-referencing-a-device-on-rem.patch Old: * 0008-present-unlink-notifies-from-window-list-in-present_.patch * 0009-dix-remove-passive-grabs-referencing-a-device-on-rem.patch * 0010-Xi-add-bounds-check-for-barrier-events-in-input_cons.patch Old: * 0009-dix-remove-passive-grabs-referencing-a-device-on-rem.patch * 0010-Xi-add-bounds-check-for-barrier-events-in-input_cons.patch * 0011-Xi-clean-up-gesture-sprite-traces-in-WindowGone.patch Old: * 0010-Xi-add-bounds-check-for-barrier-events-in-input_cons.patch * 0011-Xi-clean-up-gesture-sprite-traces-in-WindowGone.patch * 0012-glamor-size-tmp_bits-buffer-for-source-coordinate-ra.patch Old: * 0011-Xi-clean-up-gesture-sprite-traces-in-WindowGone.patch * 0012-glamor-size-tmp_bits-buffer-for-source-coordinate-ra.patch ----------(Old E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xwayland.spec ++++++ --- /var/tmp/diff_new_pack.NnhNvB/_old 2026-10-22 19:24:53.340740179 +0200 +++ /var/tmp/diff_new_pack.NnhNvB/_new 2026-10-22 19:24:53.341740222 +0200 @@ -27,7 +27,7 @@ %endif Name: xwayland -Version: 24.1.13 +Version: 24.1.14 Release: 0 URL: http://xorg.freedesktop.org Summary: Xwayland Xserver @@ -37,20 +37,6 @@ Source1: %{url}/archive/individual/xserver/%{name}-%{version}.tar.xz.sig Source2: xwayland.keyring Patch3: U_xwayland_Dont_run_key_behaviors_and_actions.patch - -Patch1281213: 0001-xkb-NULL-text-pointer-after-free-in-_CheckSetDoodad-.patch -Patch1281236: 0002-xkb-allocate-names-keys-to-MAP_LENGTH-in-XkbAllocNam.patch -Patch1281227: 0003-xkb-widen-size_syms-num_syms-size_acts-num_acts-to-u.patch -Patch1281242: 0004-xkb-fix-CheckKeySyms-overwriting-request-range-symsP.patch -Patch1281238: 0005-randr-fix-size-and-offset-in-RRChangeProviderPropert.patch -Patch1281241: 0006-Xi-validate-modifier-values-in-ProcXIPassiveUngrabDe.patch -Patch1281225: 0007-glx-validate-dataBytes-against-cmdlen-in-RenderLarge.patch -Patch1281218: 0008-present-unlink-notifies-from-window-list-in-present_.patch -Patch1281220: 0009-dix-remove-passive-grabs-referencing-a-device-on-rem.patch -Patch1281233: 0010-Xi-add-bounds-check-for-barrier-events-in-input_cons.patch -Patch1281244: 0011-Xi-clean-up-gesture-sprite-traces-in-WindowGone.patch -Patch1281240: 0012-glamor-size-tmp_bits-buffer-for-source-coordinate-ra.patch - BuildRequires: meson BuildRequires: ninja BuildRequires: pkgconfig ++++++ xwayland-24.1.13.tar.xz -> xwayland-24.1.14.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/Xext/xtest.c new/xwayland-24.1.14/Xext/xtest.c --- old/xwayland-24.1.13/Xext/xtest.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/Xext/xtest.c 2026-10-07 03:40:58.000000000 +0200 @@ -287,14 +287,19 @@ switch (dv->num_valuators) { case 6: valuators[base + 5] = dv->valuator5; + /* fallthrough */ case 5: valuators[base + 4] = dv->valuator4; + /* fallthrough */ case 4: valuators[base + 3] = dv->valuator3; + /* fallthrough */ case 3: valuators[base + 2] = dv->valuator2; + /* fallthrough */ case 2: valuators[base + 1] = dv->valuator1; + /* fallthrough */ case 1: valuators[base] = dv->valuator0; break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/Xi/exevents.c new/xwayland-24.1.14/Xi/exevents.c --- old/xwayland-24.1.13/Xi/exevents.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/Xi/exevents.c 2026-10-07 03:40:58.000000000 +0200 @@ -2873,9 +2873,8 @@ } /** - * Search for window in each touch trace for each device. Remove the window - * and all its subwindows from the trace when found. The initial window - * order is preserved. + * Search for window in each touch and gesture trace for each device. + * Truncate the trace when the window is found. */ void WindowGone(WindowPtr win) @@ -2886,11 +2885,22 @@ TouchClassPtr t = dev->touch; int i; - if (!t) - continue; + if (t) { + for (i = 0; i < t->num_touches; i++) { + SpritePtr sprite = &t->touches[i].sprite; + int j; - for (i = 0; i < t->num_touches; i++) { - SpritePtr sprite = &t->touches[i].sprite; + for (j = 0; j < sprite->spriteTraceGood; j++) { + if (sprite->spriteTrace[j] == win) { + sprite->spriteTraceGood = j; + break; + } + } + } + } + + if (dev->gesture) { + SpritePtr sprite = &dev->gesture->gesture.sprite; int j; for (j = 0; j < sprite->spriteTraceGood; j++) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/Xi/extinit.c new/xwayland-24.1.14/Xi/extinit.c --- old/xwayland-24.1.13/Xi/extinit.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/Xi/extinit.c 2026-10-07 03:40:58.000000000 +0200 @@ -666,10 +666,23 @@ swapl(&ai->min.frac); swapl(&ai->max.integral); swapl(&ai->max.frac); + swapl(&ai->value.integral); + swapl(&ai->value.frac); swapl(&ai->resolution); swaps(&ai->number); } break; + case XIScrollClass: + { + xXIScrollInfo *si = (xXIScrollInfo *) any; + + swaps(&si->number); + swaps(&si->scroll_type); + swapl(&si->flags); + swapl(&si->increment.integral); + swapl(&si->increment.frac); + } + break; } swaps(&any->type); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/Xi/xibarriers.c new/xwayland-24.1.14/Xi/xibarriers.c --- old/xwayland-24.1.13/Xi/xibarriers.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/Xi/xibarriers.c 2026-10-07 03:40:58.000000000 +0200 @@ -416,6 +416,18 @@ InternalEvent *barrier_events = events; DeviceIntPtr master; + /* We cannot know how many events are available in *events, but + * we know it all DDX very protbably allocated them with + * GetMaximumEventsNum() and fill_pointer_events() may have added one. + * + * Let's cap at a maximum of 64 barrier events which is way more than + * we'll need but low enough that we shouldn't OOB on *events. + * + * Changing the signatures to get some sz_events in here is an ABI change + * through miPointerSetPosition so... weeping face. + */ + const int MAX_BARRIER_EVENTS = 64; + if (nevents) *nevents = 0; @@ -460,7 +472,6 @@ if (pbd->barrier_event_id == pbd->release_event_id) continue; - ev.type = ET_BarrierHit; barrier_clamp_to_barrier(nearest, dir, &x, &y); if (barrier_is_vertical(nearest)) { @@ -472,19 +483,22 @@ current_y = y; } - ev.flags = 0; - ev.event_id = pbd->barrier_event_id; - ev.barrierid = c->id; - - ev.dt = new_sequence ? 0 : ms - pbd->last_timestamp; - ev.window = c->window; + if (*nevents < MAX_BARRIER_EVENTS) { + ev.type = ET_BarrierHit; + ev.flags = 0; + ev.event_id = pbd->barrier_event_id; + ev.barrierid = c->id; + + ev.dt = new_sequence ? 0 : ms - pbd->last_timestamp; + ev.window = c->window; + + /* root x/y is filled in later */ + + barrier_events->barrier_event = ev; + barrier_events++; + *nevents += 1; + } pbd->last_timestamp = ms; - - /* root x/y is filled in later */ - - barrier_events->barrier_event = ev; - barrier_events++; - *nevents += 1; } xorg_list_for_each_entry(c, &cs->barriers, entry) { @@ -503,29 +517,31 @@ continue; pbd->hit = FALSE; + pbd->last_timestamp = ms; + /* If we've left the hit box, this is the + * start of a new event ID. */ + pbd->barrier_event_id++; - ev.type = ET_BarrierLeave; + if (*nevents < MAX_BARRIER_EVENTS) { + ev.type = ET_BarrierLeave; - if (pbd->barrier_event_id == pbd->release_event_id) - flags |= XIBarrierPointerReleased; + if (pbd->barrier_event_id == pbd->release_event_id) + flags |= XIBarrierPointerReleased; - ev.flags = flags; - ev.event_id = pbd->barrier_event_id; - ev.barrierid = c->id; + ev.flags = flags; + ev.event_id = pbd->barrier_event_id; + ev.barrierid = c->id; - ev.dt = ms - pbd->last_timestamp; - ev.window = c->window; - pbd->last_timestamp = ms; + ev.dt = ms - pbd->last_timestamp; + ev.window = c->window; - /* root x/y is filled in later */ + /* root x/y is filled in later */ - barrier_events->barrier_event = ev; - barrier_events++; - *nevents += 1; + barrier_events->barrier_event = ev; + barrier_events++; + *nevents += 1; + } - /* If we've left the hit box, this is the - * start of a new event ID. */ - pbd->barrier_event_id++; } out: @@ -557,8 +573,10 @@ int size; int i; struct PointerBarrierClient *ret; + struct PointerBarrierClient *counter; CARD16 *in_devices; DeviceIntPtr dev; + size_t nbarriers = 0; size = sizeof(*ret) + sizeof(DeviceIntPtr) * stuff->num_devices; ret = malloc(size); @@ -578,6 +596,16 @@ screen = pWin->drawable.pScreen; cs = GetBarrierScreen(screen); + /* Only allow for a maximum of 32 barriers to be created. This + * should be more than enough and prevents issues in + * input_constrain_cursor, see MAX_BARRIER_EVENTS in that + * function */ + xorg_list_for_each_entry(counter, &cs->barriers, entry) { + nbarriers++; + if (nbarriers >= 32) + return BadAlloc; + } + ret->screen = screen; ret->window = stuff->window; ret->num_devices = stuff->num_devices; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/Xi/xipassivegrab.c new/xwayland-24.1.14/Xi/xipassivegrab.c --- old/xwayland-24.1.13/Xi/xipassivegrab.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/Xi/xipassivegrab.c 2026-10-07 03:40:58.000000000 +0200 @@ -46,6 +46,10 @@ #include "misc.h" #include "inpututils.h" +#define AllModifiersMask ( \ + ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ + Mod3Mask | Mod4Mask | Mod5Mask ) + int _X_COLD SProcXIPassiveGrabDevice(ClientPtr client) { @@ -349,6 +353,14 @@ if (rc != Success) return rc; + modifiers = (uint32_t *) &stuff[1]; + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) { + if (*modifiers != XIAnyModifier && (*modifiers & ~AllModifiersMask)) { + client->errorValue = *modifiers; + return BadValue; + } + } + mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); tempGrab = AllocGrab(NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/Xi/xiquerydevice.c new/xwayland-24.1.14/Xi/xiquerydevice.c --- old/xwayland-24.1.13/Xi/xiquerydevice.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/Xi/xiquerydevice.c 2026-10-07 03:40:58.000000000 +0200 @@ -441,6 +441,7 @@ swaps(&info->number); swaps(&info->sourceid); swaps(&info->scroll_type); + swapl(&info->flags); swapl(&info->increment.integral); swapl(&info->increment.frac); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/dix/devices.c new/xwayland-24.1.14/dix/devices.c --- old/xwayland-24.1.13/dix/devices.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/dix/devices.c 2026-10-07 03:40:58.000000000 +0200 @@ -1197,6 +1197,40 @@ return BadMatch; } +static Bool +GrabReferencesDevice(void *value, XID id, void *cdata) +{ + GrabPtr grab = value; + DeviceIntPtr dev = cdata; + + return grab->device == dev || grab->modifierDevice == dev; +} + +/** + * Remove all passive grabs that reference the given device, either as + * the grabbed device or as the modifier device. This must be called + * before the device is freed to avoid dangling pointers in GrabRec. + */ +static void +RemovePassiveGrabsForDevice(DeviceIntPtr dev) +{ + int i; + + for (i = 0; i < currentMaxClients; i++) { + GrabPtr grab; + + if (!clients[i]) + continue; + + while ((grab = LookupClientResourceComplex(clients[i], + RT_PASSIVEGRAB, + GrabReferencesDevice, + dev))) { + FreeResource(grab->resource, RT_NONE); + } + } +} + /** * Remove a device from the device list, closes it and thus frees all * resources. @@ -1236,6 +1270,8 @@ flags[dev->id] = XIDeviceDisabled; } + RemovePassiveGrabsForDevice(dev); + flag = IsMaster(dev) ? XIMasterRemoved : XISlaveRemoved; input_lock(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/dix/region.c new/xwayland-24.1.14/dix/region.c --- old/xwayland-24.1.13/dix/region.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/dix/region.c 2026-10-07 03:40:58.000000000 +0200 @@ -1309,6 +1309,11 @@ for (i = 0; i < numRI; i++) xfreeData(&ri[i].reg); free(ri); + /* ri[0].reg.data aliased badreg->data before RegionRectAlloc() could have + * reallocated it above, so badreg->data may now be a stale pointer to + * memory already freed by xfreeData() or by the realloc() itself. + */ + badreg->data = NULL; return RegionBreak(badreg); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/fb/fb.h new/xwayland-24.1.14/fb/fb.h --- old/xwayland-24.1.13/fb/fb.h 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/fb/fb.h 2026-10-07 03:40:58.000000000 +0200 @@ -249,6 +249,7 @@ break; \ case sizeof (FbBits) - 3: \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + /* fallthrough */ \ case sizeof (FbBits) - 2: \ FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ break; \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/glamor/glamor_compositerects.c new/xwayland-24.1.14/glamor/glamor_compositerects.c --- old/xwayland-24.1.13/glamor/glamor_compositerects.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/glamor/glamor_compositerects.c 2026-10-07 03:40:58.000000000 +0200 @@ -191,6 +191,8 @@ return; } + need_free_region = TRUE; + pixmap = glamor_get_drawable_pixmap(dst->pDrawable); priv = glamor_get_pixmap_private(pixmap); @@ -201,8 +203,6 @@ goto fallback; } - need_free_region = TRUE; - DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n", __FUNCTION__, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/glamor/glamor_transfer.c new/xwayland-24.1.14/glamor/glamor_transfer.c --- old/xwayland-24.1.13/glamor/glamor_transfer.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/glamor/glamor_transfer.c 2026-10-07 03:40:58.000000000 +0200 @@ -41,8 +41,14 @@ int bytes_per_pixel = PICT_FORMAT_BPP(f->render_format) >> 3; char *tmp_bits = NULL; - if (glamor_drawable_effective_depth(drawable) == 24 && pixmap->drawable.depth == 32) - tmp_bits = xnfalloc(byte_stride * pixmap->drawable.height); + if (glamor_drawable_effective_depth(drawable) == 24 && pixmap->drawable.depth == 32) { + int tmp_height = pixmap->drawable.height - dy_dst + dy_src; + if (tmp_height > 0) { + if (byte_stride > 0 && tmp_height > INT_MAX / byte_stride) + return; + tmp_bits = xnfalloc(byte_stride * tmp_height); + } + } glamor_make_current(glamor_priv); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/glx/glxcmds.c new/xwayland-24.1.14/glx/glxcmds.c --- old/xwayland-24.1.13/glx/glxcmds.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/glx/glxcmds.c 2026-10-07 03:40:58.000000000 +0200 @@ -2190,6 +2190,9 @@ return BadLength; } + if (dataBytes > cmdlen) + return BadLength; + /* ** Make enough space in the buffer, then copy the entire request. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/hw/xwayland/xwayland-cvt.c new/xwayland-24.1.14/hw/xwayland/xwayland-cvt.c --- old/xwayland-24.1.13/hw/xwayland/xwayland-cvt.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/hw/xwayland/xwayland-cvt.c 2026-10-07 03:40:58.000000000 +0200 @@ -29,7 +29,7 @@ #include "xwayland-cvt.h" -static void +static Bool xwayland_modeinfo_from_cvt(xRRModeInfo *modeinfo, int hdisplay, int vdisplay, float vrefresh, Bool reduced, Bool interlaced) @@ -39,6 +39,9 @@ libxcvt_mode_info = libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced); + if (!libxcvt_mode_info) + return FALSE; + modeinfo->width = libxcvt_mode_info->hdisplay; modeinfo->height = libxcvt_mode_info->vdisplay; modeinfo->dotClock = libxcvt_mode_info->dot_clock * 1000.0; @@ -51,6 +54,8 @@ modeinfo->modeFlags = libxcvt_mode_info->mode_flags; free(libxcvt_mode_info); + + return TRUE; } RRModePtr @@ -59,9 +64,16 @@ { char name[128]; xRRModeInfo modeinfo = { 0, }; + Bool valid_mode; - xwayland_modeinfo_from_cvt(&modeinfo, - hdisplay, vdisplay, vrefresh, reduced, interlaced); + valid_mode = xwayland_modeinfo_from_cvt(&modeinfo, + hdisplay, vdisplay, vrefresh, + reduced, interlaced); + + if (!valid_mode) { + DebugF("XWAYLAND: Warning, invalid mode: %ix%i@%.2f\n", hdisplay, vdisplay, vrefresh); + return NULL; + } /* Horizontal granularity in libxcvt is 8, so if our horizontal size is not * divisible by 8, libxcvt will round it up, and we will advertise a wrong diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/hw/xwayland/xwayland-glamor-gbm.c new/xwayland-24.1.14/hw/xwayland/xwayland-glamor-gbm.c --- old/xwayland-24.1.13/hw/xwayland/xwayland-glamor-gbm.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/hw/xwayland/xwayland-glamor-gbm.c 2026-10-07 03:40:58.000000000 +0200 @@ -144,22 +144,6 @@ } } -static char -is_device_path_render_node (const char *device_path) -{ - char is_render_node; - int fd; - - fd = open(device_path, O_RDWR | O_CLOEXEC); - if (fd < 0) - return 0; - - is_render_node = (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER); - close(fd); - - return is_render_node; -} - static PixmapPtr xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth, @@ -1255,58 +1239,23 @@ }; #endif /* DRI3 */ -static const char * -get_render_node_path_for_device(const drmDevicePtr drm_device, - const char *device_path) +static char * +get_render_node_path(const char* device) { - const char *render_node_path; - int i; + int fd = -1; + char *path = NULL; - if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER))) + fd = open(device, O_RDWR | O_CLOEXEC); + if (fd < 0) return NULL; - render_node_path = drm_device->nodes[DRM_NODE_RENDER]; - for (i = 0; i < DRM_NODE_MAX; i++) { - if (!(drm_device->available_nodes & (1 << i))) - continue; - if (strcmp(device_path, drm_device->nodes[i]) == 0) - return render_node_path; - } - - return NULL; -} - -static char * -get_render_node_path(const char *device_path) -{ - drmDevicePtr *devices = NULL; - char *render_node_path = NULL; - int i, n_devices, max_devices; - - max_devices = drmGetDevices2(0, NULL, 0); - if (max_devices <= 0) - goto out; - - devices = calloc(max_devices, sizeof(drmDevicePtr)); - if (!devices) - goto out; - - n_devices = drmGetDevices2(0, devices, max_devices); - if (n_devices < 0) - goto out; - - for (i = 0; i < n_devices; i++) { - const char *node_path = get_render_node_path_for_device(devices[i], - device_path); - if (node_path) { - render_node_path = strdup(node_path); - break; - } - } + if (drmGetNodeTypeFromFd(fd) != DRM_NODE_RENDER) + path = drmGetRenderDeviceNameFromFd(fd); + else + path = strdup(device); -out: - free(devices); - return render_node_path; + close(fd); + return path; } static void @@ -1315,16 +1264,8 @@ struct xwl_screen *xwl_screen = data; struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); drm_magic_t magic; - char *render_node_path = NULL; - - if (!is_device_path_render_node(device)) - render_node_path = get_render_node_path(device); - - if (render_node_path) - xwl_gbm->device_name = render_node_path; - else - xwl_gbm->device_name = strdup(device); + xwl_gbm->device_name = get_render_node_path(device); if (!xwl_gbm->device_name) { xwl_glamor_gbm_cleanup(xwl_screen); xwl_screen->expecting_event--; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/hw/xwayland/xwayland-output.c new/xwayland-24.1.14/hw/xwayland/xwayland-output.c --- old/xwayland-24.1.13/hw/xwayland/xwayland-output.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/hw/xwayland/xwayland-output.c 2026-10-07 03:40:58.000000000 +0200 @@ -357,14 +357,14 @@ rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr)); if (!rr_modes) - goto err; + FatalError("Failed to allocate memory for list of RR modes"); - /* Add actual output mode */ - rr_modes[0] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0); - if (!rr_modes[0]) - goto err; + *count = 0; - *count = 1; + /* Add actual output mode */ + rr_modes[*count] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0); + if (rr_modes[*count]) + (*count)++; if (!xwl_screen_has_resolution_change_emulation(xwl_screen) && !xwl_screen->force_xrandr_emulation) return rr_modes; @@ -384,15 +384,11 @@ rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0], xwl_output_fake_modes[i][1], xwl_output->refresh / 1000.0, 0, 0); - if (!rr_modes[*count]) - goto err; - - (*count)++; + if (rr_modes[*count]) + (*count)++; } return rr_modes; -err: - FatalError("Failed to allocate memory for list of RR modes"); } RRModePtr @@ -651,10 +647,13 @@ if (xwl_output->randr_output) { /* Build a fresh modes array using the current refresh rate */ randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count); - RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1); - RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0], - xwl_output->x, xwl_output->y, - xwl_output->rotation, NULL, 1, &xwl_output->randr_output); + + if (count > 0) { + RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1); + RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0], + xwl_output->x, xwl_output->y, + xwl_output->rotation, NULL, 1, &xwl_output->randr_output); + } /* RROutputSetModes takes ownership of the passed in modes, so we only * have to free the pointer array. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/hw/xwayland/xwayland-present.c new/xwayland-24.1.14/hw/xwayland/xwayland-present.c --- old/xwayland-24.1.13/hw/xwayland/xwayland-present.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/hw/xwayland/xwayland-present.c 2026-10-07 03:40:58.000000000 +0200 @@ -741,6 +741,7 @@ WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window); struct xwl_window *xwl_window = xwl_window_from_window(present_window); ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr window_pixmap = screen->GetWindowPixmap(present_window); if (reason) *reason = PRESENT_FLIP_REASON_UNKNOWN; @@ -761,9 +762,11 @@ if (valid) return FALSE; - /* Flip pixmap must have same dimensions as window */ + /* Flip pixmap must have same dimensions as the window and its pixmap */ if (present_window->drawable.width != pixmap->drawable.width || - present_window->drawable.height != pixmap->drawable.height) + present_window->drawable.height != pixmap->drawable.height || + pixmap->drawable.width != window_pixmap->drawable.width || + pixmap->drawable.height != window_pixmap->drawable.height) return FALSE; if (!xwl_pixmap_get_wl_buffer(pixmap)) @@ -781,7 +784,7 @@ * window's, e.g. because a client redirected this window or one of its * parents. */ - if (screen->GetWindowPixmap(xwl_window->surface_window) != screen->GetWindowPixmap(present_window)) + if (screen->GetWindowPixmap(xwl_window->surface_window) != window_pixmap) return FALSE; /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/hw/xwayland/xwayland-screen.c new/xwayland-24.1.14/hw/xwayland/xwayland-screen.c --- old/xwayland-24.1.13/hw/xwayland/xwayland-screen.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/hw/xwayland/xwayland-screen.c 2026-10-07 03:40:58.000000000 +0200 @@ -36,7 +36,6 @@ #include <X11/Xatom.h> #include <micmap.h> -#include <misyncshm.h> #include <os.h> #include <fb.h> #include <dixstruct.h> @@ -304,6 +303,10 @@ if (!xwl_seat) xwl_seat = xwl_screen_get_default_seat(xwl_screen); + /* Without an xwl_seat, no need to do anything on the Wayland side */ + if (!xwl_seat) + return; + if (!window) window = XYToWindow(sprite, x, y); @@ -1083,11 +1086,6 @@ ShmRegisterFbFuncs(pScreen); #endif -#ifdef HAVE_XSHMFENCE - if (!miSyncShmScreenInit(pScreen)) - return FALSE; -#endif - #ifdef XWL_HAS_LIBDECOR if (xwl_screen->decorate && !xwl_screen->rootless) { xwl_screen->libdecor_context = libdecor_new(xwl_screen->display, &libdecor_iface); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/include/xkbstr.h new/xwayland-24.1.14/include/xkbstr.h --- old/xwayland-24.1.13/include/xkbstr.h 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/include/xkbstr.h 2026-10-07 03:40:58.000000000 +0200 @@ -312,8 +312,8 @@ XkbAX_NeedOption((c), (w))) typedef struct _XkbServerMapRec { - unsigned short num_acts; - unsigned short size_acts; + unsigned int num_acts; + unsigned int size_acts; XkbAction *acts; XkbBehavior *behaviors; @@ -346,8 +346,8 @@ unsigned char num_types; XkbKeyTypePtr types; - unsigned short size_syms; - unsigned short num_syms; + unsigned int size_syms; + unsigned int num_syms; KeySym *syms; XkbSymMapPtr key_sym_map; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/meson.build new/xwayland-24.1.14/meson.build --- old/xwayland-24.1.13/meson.build 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/meson.build 2026-10-07 03:40:58.000000000 +0200 @@ -3,10 +3,10 @@ 'buildtype=debugoptimized', 'c_std=gnu99', ], - version: '24.1.13', + version: '24.1.14', meson_version: '>= 0.56.0', ) -release_date = '2026-07-08' +release_date = '2026-10-07' add_project_arguments('-DHAVE_DIX_CONFIG_H', language: ['c', 'objc']) cc = meson.get_compiler('c') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/mi/miarc.c new/xwayland-24.1.14/mi/miarc.c --- old/xwayland-24.1.13/mi/miarc.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/mi/miarc.c 2026-10-07 03:40:58.000000000 +0200 @@ -1436,6 +1436,7 @@ polyLen = 5; break; } + /* fallthrough */ case JoinBevel: poly[0] = corner; poly[1] = center; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/miext/damage/damage.c new/xwayland-24.1.14/miext/damage/damage.c --- old/xwayland-24.1.13/miext/damage/damage.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/miext/damage/damage.c 2026-10-07 03:40:58.000000000 +0200 @@ -1458,6 +1458,7 @@ while (*pPrev) { if (*pPrev == pDamage) { *pPrev = pDamage->pNext; + pDamage->pListHead = NULL; return; } pPrev = &(*pPrev)->pNext; @@ -1468,6 +1469,16 @@ #endif } +/* + * Link pDamage onto the list headed by pPrev, remembering that list so that damageRemoveDamage() can later unlink it + * from the same place. + * + * The list a window's damage belongs on is chosen by getDrawableDamageRef() and depends on the window pixmap, which can + * change while the damage is registered (Composite redirection, rootless drawing and Present flips all swap it). + * Re-deriving the list at removal time can therefore consult a different list than the damage was inserted onto, in + * which case the removal silently does nothing and leaves an unregistered -- possibly freed -- damage linked where + * damageRegionAppend() will dereference its NULL pDrawable. + */ static void damageInsertDamage(DamagePtr * pPrev, DamagePtr pDamage) { @@ -1482,6 +1493,7 @@ #endif pDamage->pNext = *pPrev; *pPrev = pDamage; + pDamage->pListHead = pPrev; } static Bool @@ -1554,11 +1566,9 @@ damageScrPriv(pScreen); if ((pDamage = damageGetWinPriv(pWindow))) { - PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow); - DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap); - while (pDamage) { - damageRemoveDamage(pPrev, pDamage); + if (pDamage->pListHead) + damageRemoveDamage(pDamage->pListHead, pDamage); pDamage = pDamage->pNextWin; } } @@ -1722,6 +1732,7 @@ return 0; pDamage->pNext = 0; pDamage->pNextWin = 0; + pDamage->pListHead = NULL; RegionNull(&pDamage->damage); RegionNull(&pDamage->pendingDamage); @@ -1824,7 +1835,8 @@ #endif } pDamage->pDrawable = 0; - damageRemoveDamage(getDrawableDamageRef(pDrawable), pDamage); + if (pDamage->pListHead) + damageRemoveDamage(pDamage->pListHead, pDamage); } void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/miext/damage/damagestr.h new/xwayland-24.1.14/miext/damage/damagestr.h --- old/xwayland-24.1.13/miext/damage/damagestr.h 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/miext/damage/damagestr.h 2026-10-07 03:40:58.000000000 +0200 @@ -35,6 +35,12 @@ typedef struct _damage { DamagePtr pNext; DamagePtr pNextWin; + /* + * Head of the pNext list this damage is currently linked on, or NULL if it is not linked on any list. Recorded at + * insertion time so that removal always unlinks from the list the damage actually went onto; see + * damageInsertDamage(). + */ + DamagePtr *pListHead; RegionRec damage; DamageReportLevel damageLevel; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/os/utils.c new/xwayland-24.1.14/os/utils.c --- old/xwayland-24.1.13/os/utils.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/os/utils.c 2026-10-07 03:40:58.000000000 +0200 @@ -1374,10 +1374,23 @@ if (*type == 'r') { iop = fdopen(pdes[0], type); close(pdes[1]); + if (!iop) + close(pdes[0]); } else { iop = fdopen(pdes[1], type); close(pdes[0]); + if (!iop) + close(pdes[1]); + } + + if (!iop) { + free(cur); +#ifdef HAVE_SETITIMER + if (SmartScheduleEnable() < 0) + perror("signal"); +#endif + return NULL; } cur->fp = iop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/present/present_notify.c new/xwayland-24.1.14/present/present_notify.c --- old/xwayland-24.1.13/present/present_notify.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/present/present_notify.c 2026-10-07 03:40:58.000000000 +0200 @@ -30,14 +30,14 @@ void present_clear_window_notifies(WindowPtr window) { - present_notify_ptr notify; + present_notify_ptr notify, tmp; present_window_priv_ptr window_priv = present_window_priv(window); if (!window_priv) return; - xorg_list_for_each_entry(notify, &window_priv->notifies, window_list) { - notify->window = NULL; + xorg_list_for_each_entry_safe(notify, tmp, &window_priv->notifies, window_list) { + present_free_window_notify(notify); } } @@ -48,6 +48,7 @@ void present_free_window_notify(present_notify_ptr notify) { + notify->window = NULL; xorg_list_del(¬ify->window_list); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/randr/rrproviderproperty.c new/xwayland-24.1.14/randr/rrproviderproperty.c --- old/xwayland-24.1.13/randr/rrproviderproperty.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/randr/rrproviderproperty.c 2026-10-07 03:40:58.000000000 +0200 @@ -191,7 +191,7 @@ RRDestroyProviderProperty(prop); return BadAlloc; } - new_value.size = len; + new_value.size = total_len; new_value.type = type; new_value.format = format; @@ -208,7 +208,7 @@ case PropModePrepend: new_data = new_value.data; old_data = (void *) (((char *) new_value.data) + - (prop_value->size * size_in_bytes)); + (len * size_in_bytes)); break; } if (new_data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/render/glyph.c new/xwayland-24.1.14/render/glyph.c --- old/xwayland-24.1.13/render/glyph.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/render/glyph.c 2026-10-07 03:40:58.000000000 +0200 @@ -268,7 +268,7 @@ gr = FindGlyphRef(&globalGlyphs[format], signature, TRUE, glyph->sha1); if (gr - globalGlyphs[format].table != first) DuplicateRef(glyph, "Found wrong one"); - if (gr->glyph && gr->glyph != DeletedGlyph) { + if (gr->glyph == glyph) { gr->glyph = DeletedGlyph; gr->signature = 0; globalGlyphs[format].tableEntries--; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/test/string.c new/xwayland-24.1.14/test/string.c --- old/xwayland-24.1.13/test/string.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/test/string.c 2026-10-07 03:40:58.000000000 +0200 @@ -54,6 +54,9 @@ char *firsthalf = strndup(sample, 8); char *secondhalf = strndup(sample + 8, 8); + assert(firsthalf != NULL); + assert(secondhalf != NULL); + assert(strcmp(firsthalf, "01234567") == 0); assert(strcmp(secondhalf, "89abcdef") == 0); @@ -61,6 +64,7 @@ free(secondhalf); allofit = strndup(sample, 20); + assert(allofit != NULL); assert(strcmp(allofit, sample) == 0); free(allofit); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/test/xi2/protocol-eventconvert.c new/xwayland-24.1.14/test/xi2/protocol-eventconvert.c --- old/xwayland-24.1.13/test/xi2/protocol-eventconvert.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/test/xi2/protocol-eventconvert.c 2026-10-07 03:40:58.000000000 +0200 @@ -713,20 +713,41 @@ case XIValuatorClass: { xXIValuatorInfo *v = (xXIValuatorInfo *) any; + FP3232 expected; + + if (swap) { + swaps(&v->number); + swapl(&v->value.integral); + swapl(&v->value.frac); + } assert(v->length == bytes_to_int32(sizeof(xXIValuatorInfo))); + assert(v->number < in->num_valuators); + expected = double_to_fp3232(in->valuators[v->number].value); + assert(v->value.integral == expected.integral); + assert(v->value.frac == expected.frac); } break; case XIScrollClass: { xXIScrollInfo *s = (xXIScrollInfo *) any; + FP3232 expected; + uint32_t expected_flags = 0; + + if (swap) { + swaps(&s->number); + swaps(&s->scroll_type); + swapl(&s->flags); + swapl(&s->increment.integral); + swapl(&s->increment.frac); + } assert(s->length == bytes_to_int32(sizeof(xXIScrollInfo))); assert(s->sourceid == in->sourceid); assert(s->number < in->num_valuators); - switch (s->type) { + switch (s->scroll_type) { case XIScrollTypeVertical: assert(in->valuators[s->number].scroll.type == SCROLL_TYPE_VERTICAL); @@ -735,11 +756,22 @@ assert(in->valuators[s->number].scroll.type == SCROLL_TYPE_HORIZONTAL); break; + default: + assert(0); } - if (s->flags & XIScrollFlagPreferred) - assert(in->valuators[s->number].scroll. - flags & SCROLL_FLAG_PREFERRED); + + if (in->valuators[s->number].scroll.flags & SCROLL_FLAG_DONT_EMULATE) + expected_flags |= XIScrollFlagNoEmulation; + if (in->valuators[s->number].scroll.flags & SCROLL_FLAG_PREFERRED) + expected_flags |= XIScrollFlagPreferred; + assert(s->flags == expected_flags); + + expected = double_to_fp3232( + in->valuators[s->number].scroll.increment); + assert(s->increment.integral == expected.integral); + assert(s->increment.frac == expected.frac); } + break; default: dbg("Invalid class type.\n\n"); assert(1); @@ -898,6 +930,23 @@ in.valuators[i].mode = Absolute; test_XIDeviceChangedEvent(&in); } + + memset(in.valuators, 0, sizeof(in.valuators)); + in.num_valuators = 2; + + in.valuators[0].mode = Relative; + in.valuators[0].value = 240.5; + in.valuators[0].scroll.type = SCROLL_TYPE_VERTICAL; + in.valuators[0].scroll.increment = 2.5; + in.valuators[0].scroll.flags = SCROLL_FLAG_PREFERRED; + + in.valuators[1].mode = Relative; + in.valuators[1].value = -350.25; + in.valuators[1].scroll.type = SCROLL_TYPE_HORIZONTAL; + in.valuators[1].scroll.increment = 3.25; + in.valuators[1].scroll.flags = SCROLL_FLAG_DONT_EMULATE; + + test_XIDeviceChangedEvent(&in); } static void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/test/xi2/protocol-xiquerydevice.c new/xwayland-24.1.14/test/xi2/protocol-xiquerydevice.c --- old/xwayland-24.1.13/test/xi2/protocol-xiquerydevice.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/test/xi2/protocol-xiquerydevice.c 2026-10-07 03:40:58.000000000 +0200 @@ -201,6 +201,7 @@ if (client->swapped) { swaps(&si->number); swaps(&si->scroll_type); + swapl(&si->flags); swapl(&si->increment.integral); swapl(&si->increment.frac); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/XKBAlloc.c new/xwayland-24.1.14/xkb/XKBAlloc.c --- old/xwayland-24.1.13/xkb/XKBAlloc.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/XKBAlloc.c 2026-10-07 03:40:58.000000000 +0200 @@ -148,7 +148,7 @@ (!XkbIsLegalKeycode(xkb->max_key_code)) || (xkb->max_key_code < xkb->min_key_code)) return BadValue; - names->keys = calloc((xkb->max_key_code + 1), sizeof(XkbKeyNameRec)); + names->keys = calloc(MAP_LENGTH, sizeof(XkbKeyNameRec)); if (names->keys == NULL) return BadAlloc; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/XKBMAlloc.c new/xwayland-24.1.14/xkb/XKBMAlloc.c --- old/xwayland-24.1.13/xkb/XKBMAlloc.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/XKBMAlloc.c 2026-10-07 03:40:58.000000000 +0200 @@ -385,7 +385,8 @@ } if (nResize > 0) { int nextMatch; - + if (nTotal > INT_MAX / 15) + return BadAlloc; xkb->map->size_syms = (nTotal * 15) / 10; newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); if (newSyms == NULL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/ddxBeep.c new/xwayland-24.1.14/xkb/ddxBeep.c --- old/xwayland-24.1.13/xkb/ddxBeep.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/ddxBeep.c 2026-10-07 03:40:58.000000000 +0200 @@ -142,6 +142,7 @@ switch (xkbInfo->beepType) { default: ErrorF("[xkb] Unknown beep type %d\n", xkbInfo->beepType); + /* fallthrough */ case _BEEP_NONE: duration = 0; break; @@ -210,6 +211,7 @@ case _BEEP_LED_CHANGE: if (name == None) name = ledChange; + /* fallthrough */ case _BEEP_FEATURE_CHANGE: if (name == None) name = featureChange; @@ -240,9 +242,11 @@ case _BEEP_SLOW_PRESS: if (name == None) name = slowPress; + /* fallthrough */ case _BEEP_SLOW_ACCEPT: if (name == None) name = slowAccept; + /* fallthrough */ case _BEEP_SLOW_RELEASE: if (name == None) name = slowRelease; @@ -252,6 +256,7 @@ case _BEEP_BOUNCE_REJECT: if (name == None) name = bounceReject; + /* fallthrough */ case _BEEP_SLOW_REJECT: if (name == None) name = slowReject; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/xkb.c new/xwayland-24.1.14/xkb/xkb.c --- old/xwayland-24.1.13/xkb/xkb.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/xkb.c 2026-10-07 03:40:58.000000000 +0200 @@ -1808,6 +1808,7 @@ wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; } + i = req->firstKeySym + req->nKeySyms; map = &xkb->map->key_sym_map[i]; for (; i <= (unsigned) xkb->max_key_code; i++, map++) { register int g, nG, w; @@ -2222,6 +2223,9 @@ if (XkbKeyNumGroups(xkb, i) > s) s = XkbKeyNumGroups(xkb, i); } + /* Never drop to zero groups: a client is free to clear every key's symbols */ + if (s == 0) + s = 1; if (s != xkb->ctrls->num_groups) { xkbControlsNotify cn; XkbControlsRec old; @@ -5298,7 +5302,8 @@ return status; status = _GetCountedString(&wire, client, &doodad->text.font); if (status != Success) { - free (doodad->text.text); + free(doodad->text.text); + doodad->text.text = NULL; return status; } break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/xkbInit.c new/xwayland-24.1.14/xkb/xkbInit.c --- old/xwayland-24.1.13/xkb/xkbInit.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/xkbInit.c 2026-10-07 03:40:58.000000000 +0200 @@ -486,7 +486,7 @@ if (XkbAllocControls(xkb, XkbAllControlsMask) != Success) FatalError("Couldn't allocate keyboard controls\n"); ctrls = xkb->ctrls; - if (!(xkb->defined & XkmSymbolsMask)) + if (!(xkb->defined & XkmSymbolsMask) || ctrls->num_groups == 0) ctrls->num_groups = 1; ctrls->groups_wrap = XkbSetGroupInfo(1, XkbWrapIntoRange, 0); ctrls->internal.mask = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/xkbUtils.c new/xwayland-24.1.14/xkb/xkbUtils.c --- old/xwayland-24.1.13/xkb/xkbUtils.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/xkbUtils.c 2026-10-07 03:40:58.000000000 +0200 @@ -665,6 +665,13 @@ { unsigned act; + /* A keymap with no groups leaves nothing to adjust into, and every action + * below misbehaves: wrapping divides by zero, clamping underflows to -1, + * and the negative-group loop never terminates. + */ + if (ctrls->num_groups == 0) + return XkbGroup1Index; + act = XkbOutOfRangeGroupAction(ctrls->groups_wrap); if (group < 0) { while (group < 0) { @@ -1437,7 +1444,7 @@ /* geometry */ if (src->geom) { if (!dst->geom) { - dst->geom = calloc(sizeof(XkbGeometryRec), 1); + dst->geom = calloc(1, sizeof(XkbGeometryRec)); if (!dst->geom) return FALSE; } @@ -2140,5 +2147,8 @@ nTG = nG; } } + /* A keymap always has at least one group, even when no key defines any symbols */ + if (nTG == 0) + nTG = 1; dst->ctrls->num_groups = nTG; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xwayland-24.1.13/xkb/xkmread.c new/xwayland-24.1.14/xkb/xkmread.c --- old/xwayland-24.1.13/xkb/xkmread.c 2026-07-08 03:17:38.000000000 +0200 +++ new/xwayland-24.1.14/xkb/xkmread.c 2026-10-07 03:40:58.000000000 +0200 @@ -763,12 +763,20 @@ for (i = minKC; i <= (int) maxKC; i++) { Atom typeName[XkbNumKbdGroups]; XkbKeyTypePtr type[XkbNumKbdGroups]; + int nGroups; if ((tmp = fread(&wireMap, SIZEOF(xkmKeySymMapDesc), 1, file)) < 1) { _XkbLibError(_XkbErrBadLength, "ReadXkmSymbols", 0); return -1; } nRead += tmp * SIZEOF(xkmKeySymMapDesc); + /* group_info carries the out-of-range action and number alongside the + * count, and the count itself is four bits wide while everything it + * indexes here holds only XkbNumKbdGroups entries. + */ + nGroups = XkbNumGroups(wireMap.num_groups); + if (nGroups > XkbNumKbdGroups) + nGroups = XkbNumKbdGroups; memset((char *) typeName, 0, XkbNumKbdGroups * sizeof(Atom)); memset((char *) type, 0, XkbNumKbdGroups * sizeof(XkbKeyTypePtr)); if (wireMap.flags & XkmKeyHasTypes) { @@ -796,12 +804,15 @@ xkb->server->explicit[i] |= XkbExplicitAutoRepeatMask; } xkb->map->modmap[i] = wireMap.modifier_map; - if (XkbNumGroups(wireMap.num_groups) > 0) { + if (nGroups > 0) { KeySym *sym; int nSyms; - if (XkbNumGroups(wireMap.num_groups) > xkb->ctrls->num_groups) - xkb->ctrls->num_groups = wireMap.num_groups; + if (nGroups > xkb->ctrls->num_groups) + xkb->ctrls->num_groups = nGroups; + /* The file still holds symbols for every group it claimed, so read + * and store them all even when we clamped the count above. + */ nSyms = XkbNumGroups(wireMap.num_groups) * wireMap.width; sym = XkbResizeKeySyms(xkb, i, nSyms); if (!sym) @@ -820,7 +831,7 @@ xkb->server->explicit[i] |= XkbExplicitInterpretMask; } } - for (g = 0; g < XkbNumGroups(wireMap.num_groups); g++) { + for (g = 0; g < nGroups; g++) { if (((xkb->server->explicit[i] & (1 << g)) == 0) || (type[g] == NULL)) { KeySym *tmpSyms; @@ -831,7 +842,8 @@ xkb->map->key_sym_map[i].kt_index[g] = type[g] - (&xkb->map->types[0]); } - xkb->map->key_sym_map[i].group_info = wireMap.num_groups; + xkb->map->key_sym_map[i].group_info = + XkbSetNumGroups(wireMap.num_groups, nGroups); xkb->map->key_sym_map[i].width = wireMap.width; if (wireMap.flags & XkmKeyHasBehavior) { xkmBehaviorDesc b; @@ -843,6 +855,12 @@ xkb->server->explicit[i] |= XkbExplicitBehaviorMask; } } + /* A symbols section in which no key defines a group leaves the count at + * the zero it was allocated with, which would put group 0 itself out of + * range for the rest of the server. + */ + if (xkb->ctrls->num_groups == 0) + xkb->ctrls->num_groups = 1; if (totalVModMaps > 0) { xkmVModMapDesc v;
