Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package dmenu for openSUSE:Factory checked 
in at 2026-04-09 16:09:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dmenu (Old)
 and      /work/SRC/openSUSE:Factory/.dmenu.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dmenu"

Thu Apr  9 16:09:41 2026 rev:21 rq:1345443 version:5.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/dmenu/dmenu.changes      2024-04-04 
22:27:42.070497513 +0200
+++ /work/SRC/openSUSE:Factory/.dmenu.new.21863/dmenu.changes   2026-04-09 
16:22:47.441689401 +0200
@@ -1,0 +2,9 @@
+Wed Feb 11 08:27:21 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 5.4:
+  * Avoid integer underflow in drw_text()
+  * render invalid utf8 sequences as U+FFFD
+  * overhaul utf8decode
+  * use XUngrabKeyboard instead of XUngrabKey
+
+-------------------------------------------------------------------

Old:
----
  dmenu-5.3.tar.gz

New:
----
  dmenu-5.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dmenu.spec ++++++
--- /var/tmp/diff_new_pack.wwfPkM/_old  2026-04-09 16:22:47.965710903 +0200
+++ /var/tmp/diff_new_pack.wwfPkM/_new  2026-04-09 16:22:47.969711067 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package dmenu
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           dmenu
-Version:        5.3
+Version:        5.4
 Release:        0
 Summary:        A generic and efficient menu for X
 License:        MIT

++++++ dmenu-5.3.tar.gz -> dmenu-5.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmenu-5.3/config.mk new/dmenu-5.4/config.mk
--- old/dmenu-5.3/config.mk     2024-03-19 12:25:09.000000000 +0100
+++ new/dmenu-5.4/config.mk     2025-08-09 15:00:49.940271203 +0200
@@ -1,5 +1,5 @@
 # dmenu version
-VERSION = 5.3
+VERSION = 5.4
 
 # paths
 PREFIX = /usr/local
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmenu-5.3/dmenu.c new/dmenu-5.4/dmenu.c
--- old/dmenu-5.3/dmenu.c       2024-03-19 12:25:09.000000000 +0100
+++ new/dmenu-5.4/dmenu.c       2025-08-09 15:00:49.950267502 +0200
@@ -100,7 +100,7 @@
 {
        size_t i;
 
-       XUngrabKey(dpy, AnyKey, AnyModifier, root);
+       XUngrabKeyboard(dpy, CurrentTime);
        for (i = 0; i < SchemeLast; i++)
                free(scheme[i]);
        for (i = 0; items && items[i].text; ++i)
@@ -689,7 +689,6 @@
                            CWOverrideRedirect | CWBackPixel | CWEventMask, 
&swa);
        XSetClassHint(dpy, win, &ch);
 
-
        /* input methods */
        if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
                die("XOpenIM failed: could not open input device");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmenu-5.3/drw.c new/dmenu-5.4/drw.c
--- old/dmenu-5.3/drw.c 2024-03-19 12:25:09.000000000 +0100
+++ new/dmenu-5.4/drw.c 2025-08-09 15:00:49.950267502 +0200
@@ -9,54 +9,40 @@
 #include "util.h"
 
 #define UTF_INVALID 0xFFFD
-#define UTF_SIZ     4
 
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 
0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 
0xF8};
-static const long utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  
0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 
0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
-       for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
-               if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
-                       return (unsigned char)c & ~utfmask[*i];
-       return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
+static int
+utf8decode(const char *s_in, long *u, int *err)
 {
-       if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
-               *u = UTF_INVALID;
-       for (i = 1; *u > utfmax[i]; ++i)
-               ;
-       return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
-       size_t i, j, len, type;
-       long udecoded;
+       static const unsigned char lens[] = {
+               /* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+               /* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0,  /* invalid */
+               /* 110XX */ 2, 2, 2, 2,
+               /* 1110X */ 3, 3,
+               /* 11110 */ 4,
+               /* 11111 */ 0,  /* invalid */
+       };
+       static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 };
+       static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 };
 
+       const unsigned char *s = (const unsigned char *)s_in;
+       int len = lens[*s >> 3];
        *u = UTF_INVALID;
-       if (!clen)
-               return 0;
-       udecoded = utf8decodebyte(c[0], &len);
-       if (!BETWEEN(len, 1, UTF_SIZ))
+       *err = 1;
+       if (len == 0)
                return 1;
-       for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
-               udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
-               if (type)
-                       return j;
+
+       long cp = s[0] & leading_mask[len - 1];
+       for (int i = 1; i < len; ++i) {
+               if (s[i] == '\0' || (s[i] & 0xC0) != 0x80)
+                       return i;
+               cp = (cp << 6) | (s[i] & 0x3F);
        }
-       if (j < len)
-               return 0;
-       *u = udecoded;
-       utf8validate(u, len);
+       /* out of range, surrogate, overlong encoding */
+       if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1])
+               return len;
 
+       *err = 0;
+       *u = cp;
        return len;
 }
 
@@ -242,7 +228,7 @@
        unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
        XftDraw *d = NULL;
        Fnt *usedfont, *curfont, *nextfont;
-       int utf8strlen, utf8charlen, render = x || y || w || h;
+       int utf8strlen, utf8charlen, utf8err, render = x || y || w || h;
        long utf8codepoint = 0;
        const char *utf8str;
        FcCharSet *fccharset;
@@ -251,7 +237,8 @@
        XftResult result;
        int charexists = 0, overflow = 0;
        /* keep track of a couple codepoints for which we have no match. */
-       static unsigned int nomatches[128], ellipsis_width;
+       static unsigned int nomatches[128], ellipsis_width, invalid_width;
+       static const char invalid[] = "�";
 
        if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
                return 0;
@@ -261,6 +248,8 @@
        } else {
                XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : 
ColBg].pixel);
                XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
+               if (w < lpad)
+                       return x + w;
                d = XftDrawCreate(drw->dpy, drw->drawable,
                                  DefaultVisual(drw->dpy, drw->screen),
                                  DefaultColormap(drw->dpy, drw->screen));
@@ -271,12 +260,14 @@
        usedfont = drw->fonts;
        if (!ellipsis_width && render)
                ellipsis_width = drw_fontset_getwidth(drw, "...");
+       if (!invalid_width && render)
+               invalid_width = drw_fontset_getwidth(drw, invalid);
        while (1) {
-               ew = ellipsis_len = utf8strlen = 0;
+               ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0;
                utf8str = text;
                nextfont = NULL;
                while (*text) {
-                       utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
+                       utf8charlen = utf8decode(text, &utf8codepoint, 
&utf8err);
                        for (curfont = drw->fonts; curfont; curfont = 
curfont->next) {
                                charexists = charexists || 
XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
                                if (charexists) {
@@ -298,9 +289,9 @@
                                                else
                                                        utf8strlen = 
ellipsis_len;
                                        } else if (curfont == usedfont) {
-                                               utf8strlen += utf8charlen;
                                                text += utf8charlen;
-                                               ew += tmpw;
+                                               utf8strlen += utf8err ? 0 : 
utf8charlen;
+                                               ew += utf8err ? 0 : tmpw;
                                        } else {
                                                nextfont = curfont;
                                        }
@@ -308,7 +299,7 @@
                                }
                        }
 
-                       if (overflow || !charexists || nextfont)
+                       if (overflow || !charexists || nextfont || utf8err)
                                break;
                        else
                                charexists = 0;
@@ -323,6 +314,12 @@
                        x += ew;
                        w -= ew;
                }
+               if (utf8err && (!render || invalid_width < w)) {
+                       if (render)
+                               drw_text(drw, x, y, w, h, 0, invalid, invert);
+                       x += invalid_width;
+                       w -= invalid_width;
+               }
                if (render && overflow)
                        drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", 
invert);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dmenu-5.3/util.c new/dmenu-5.4/util.c
--- old/dmenu-5.3/util.c        2024-03-19 12:25:09.000000000 +0100
+++ new/dmenu-5.4/util.c        2025-08-09 15:00:49.950267502 +0200
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -10,17 +11,17 @@
 die(const char *fmt, ...)
 {
        va_list ap;
+       int saved_errno;
+
+       saved_errno = errno;
 
        va_start(ap, fmt);
        vfprintf(stderr, fmt, ap);
        va_end(ap);
 
-       if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
-               fputc(' ', stderr);
-               perror(NULL);
-       } else {
-               fputc('\n', stderr);
-       }
+       if (fmt[0] && fmt[strlen(fmt)-1] == ':')
+               fprintf(stderr, " %s", strerror(saved_errno));
+       fputc('\n', stderr);
 
        exit(1);
 }

Reply via email to