From 6aaf43fdb6fdac6a6fd4edaf730b81be43e2f9df Mon Sep 17 00:00:00 2001 From: Jason Perlow Date: Sun, 25 Oct 2026 17:17:47 -0400 Subject: [PATCH] fix(lockscreen): clear the freed xkb state and report a missing keymap kb_keymap() unreferenced the old xkb_state but left the pointer set, so if the new keymap failed to compile, kb_key() kept using freed memory. Clear it first. Each keymap failure path also returned silently, which left a lock that drew normally but dropped every key; log the reason, and show "Keyboard unavailable" when a key arrives without a keymap. Assisted-by: Claude Code:claude-opus-5-5 AI-Scope: cleared the stale xkb_state, added failure logging in kb_keymap and the unavailable status in kb_key in lock_main.c. --- src/lockscreen/lock_main.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/lockscreen/lock_main.c b/src/lockscreen/lock_main.c index 4fe5b66..505ee94 100644 --- a/src/lockscreen/lock_main.c +++ b/src/lockscreen/lock_main.c @@ -583,16 +583,29 @@ static void submit_password(void) { /* ── Keyboard ───────────────────────────────────────────────────────────── */ static void kb_keymap(void *data, struct wl_keyboard *kb, uint32_t format, int fd, uint32_t size) { - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { close(fd); return; } + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + fprintf(stderr, "lock: unsupported keymap format %u\n", format); + close(fd); + return; + } char *map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - if (map == MAP_FAILED) return; + if (map == MAP_FAILED) { + fprintf(stderr, "lock: cannot map the keymap\n"); + return; + } if (xkb_keymap) xkb_keymap_unref(xkb_keymap); if (xkb_state) xkb_state_unref(xkb_state); + xkb_state = NULL; xkb_keymap = xkb_keymap_new_from_string(xkb_context, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(map, size); - if (xkb_keymap) xkb_state = xkb_state_new(xkb_keymap); + if (!xkb_keymap) { + fprintf(stderr, "lock: cannot compile the keymap\n"); + return; + } + xkb_state = xkb_state_new(xkb_keymap); + if (!xkb_state) fprintf(stderr, "lock: cannot create the keyboard state\n"); } static void kb_enter(void *d, struct wl_keyboard *kb, uint32_t s, struct wl_surface *sf, struct wl_array *keys) {} static void kb_leave(void *d, struct wl_keyboard *kb, uint32_t s, struct wl_surface *sf) {} @@ -604,8 +617,14 @@ static void kb_repeat(void *d, struct wl_keyboard *kb, int32_t rate, int32_t del static void kb_key(void *data, struct wl_keyboard *kb, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - if (!xkb_state || state != WL_KEYBOARD_KEY_STATE_PRESSED) return; + if (state != WL_KEYBOARD_KEY_STATE_PRESSED) return; if (anim_phase == PHASE_LEAVE) return; + if (!xkb_state) { + snprintf(status_text, sizeof status_text, "%s", "Keyboard unavailable"); + status_error = true; + render_all(); + return; + } xkb_keycode_t kc = key + 8; xkb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, kc);