Wayland: Avoid SEGV if a modifier notification comes before the keymap

main
Chris Collins 2024-02-08 16:06:12 +11:00 committed by Frank Praznik
parent f95b7ee4da
commit 0f81598e9f
1 changed files with 28 additions and 0 deletions

View File

@ -1146,6 +1146,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
return;
}
if (input->xkb.keymap != NULL) {
/* if there's already a keymap loaded, throw it away rather than leaking it before
* parsing the new one
*/
WAYLAND_xkb_keymap_unref(input->xkb.keymap);
input->xkb.keymap = NULL;
}
input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
map_str,
XKB_KEYMAP_FORMAT_TEXT_V1,
@ -1169,6 +1176,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
#undef GET_MOD_INDEX
if (input->xkb.state != NULL) {
/* if there's already a state, throw it away rather than leaking it before
* trying to create a new one with the new keymap.
*/
WAYLAND_xkb_state_unref(input->xkb.state);
input->xkb.state = NULL;
}
input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
if (!input->xkb.state) {
SDL_SetError("failed to create XKB state\n");
@ -1214,10 +1228,18 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
}
/* Set up XKB compose table */
if (input->xkb.compose_table != NULL) {
WAYLAND_xkb_compose_table_unref(input->xkb.compose_table);
input->xkb.compose_table = NULL;
}
input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context,
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
if (input->xkb.compose_table) {
/* Set up XKB compose state */
if (input->xkb.compose_state != NULL) {
WAYLAND_xkb_compose_state_unref(input->xkb.compose_state);
input->xkb.compose_state = NULL;
}
input->xkb.compose_state = WAYLAND_xkb_compose_state_new(input->xkb.compose_table,
XKB_COMPOSE_STATE_NO_FLAGS);
if (!input->xkb.compose_state) {
@ -1607,6 +1629,12 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
struct SDL_WaylandInput *input = data;
Wayland_Keymap keymap;
if (input->xkb.state == NULL) {
/* if we get a modifier notification before the keymap, there's nothing we can do with the information
*/
return;
}
WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);