untrusted comment: verify with openbsd-78-base.pub
RWS3/nvFmk4SWbzqNcHR7Ii9UmQYt8kO4UHcE36sopJCezAUHD925f5lT9kQo/rNpEdzdgIPycdXCl4uR0tfzlt27InQ3rBRIQE=

OpenBSD 7.8 errata 009, December 3, 2025:

Fix incorrect handling of invalid inputs to xkbcomp(1).
CVE-2018-15853 CVE-2018-15859 CVE-2018-15861 CVE-2018-15863

Apply by doing:
    signify -Vep /etc/signify/openbsd-78-base.pub -x 009_xkbcomp.patch.sig \
        -m - | (cd /usr/xenocara && patch -p0)

And then rebuild and install xkbcomp:
    cd /usr/xenocara/app/xkbcomp
    make -f Makefile.bsd-wrapper obj
    make -f Makefile.bsd-wrapper build

Index: app/xkbcomp/compat.c
===================================================================
RCS file: /cvs/xenocara/app/xkbcomp/compat.c,v
diff -u -p -r1.10 compat.c
--- app/xkbcomp/compat.c	4 May 2024 09:53:35 -0000	1.10
+++ app/xkbcomp/compat.c	27 Nov 2025 12:39:31 -0000
@@ -307,6 +307,8 @@ ResolveStateAndPredicate(ExprDef * expr,
     {
         char *pred_txt =
             XkbAtomText(NULL, expr->value.action.name, XkbMessage);
+        if (!pred_txt || !expr->value.action.args)
+            goto leave;
         if (uStrCaseCmp(pred_txt, "noneof") == 0)
             *pred_rtrn = XkbSI_NoneOf;
         else if (uStrCaseCmp(pred_txt, "anyofornone") == 0)
@@ -319,7 +321,8 @@ ResolveStateAndPredicate(ExprDef * expr,
             *pred_rtrn = XkbSI_Exactly;
         else
         {
-            ERROR("Illegal modifier predicate \"%s\"\n", pred_txt);
+leave:      ERROR("Illegal modifier predicate \"%s\"\n",
+                  (pred_txt ? pred_txt : "(none)"));
             ACTION("Ignored\n");
             return False;
         }
Index: app/xkbcomp/expr.c
===================================================================
RCS file: /cvs/xenocara/app/xkbcomp/expr.c,v
diff -u -p -r1.7 expr.c
--- app/xkbcomp/expr.c	4 May 2024 09:53:35 -0000	1.7
+++ app/xkbcomp/expr.c	27 Nov 2025 12:39:31 -0000
@@ -137,16 +137,20 @@ ExprResolveLhs(ExprDef * expr,
         elem_rtrn->str = NULL;
         field_rtrn->str = XkbAtomGetString(NULL, expr->value.str);
         *index_rtrn = NULL;
-        return True;
+        return (field_rtrn->str != NULL);
     case ExprFieldRef:
         elem_rtrn->str = XkbAtomGetString(NULL, expr->value.field.element);
         field_rtrn->str = XkbAtomGetString(NULL, expr->value.field.field);
         *index_rtrn = NULL;
-        return True;
+        return (elem_rtrn->str != NULL && field_rtrn->str != NULL);
     case ExprArrayRef:
         elem_rtrn->str = XkbAtomGetString(NULL, expr->value.array.element);
         field_rtrn->str = XkbAtomGetString(NULL, expr->value.array.field);
         *index_rtrn = expr->value.array.entry;
+        if (expr->value.array.element != None && elem_rtrn->str == NULL)
+            return False;
+        if (field_rtrn->str == NULL)
+            return False;
         return True;
     }
     WSGO("Unexpected operator %d in ResolveLhs\n", expr->op);
@@ -438,7 +442,7 @@ ExprResolveBoolean(ExprDef * expr,
         return ok;
     case OpInvert:
     case OpNot:
-        ok = ExprResolveBoolean(expr, val_rtrn, lookup, lookupPriv);
+        ok = ExprResolveBoolean(expr->value.child, val_rtrn, lookup, lookupPriv);
         if (ok)
             val_rtrn->uval = !val_rtrn->uval;
         return ok;
