Wayland: Avoid SEGV if a modifier notification comes before the keymap
(cherry picked from commit0f81598e9f) (cherry picked from commitde0cb94e72)
This commit is contained in:
1 parent
c4fc20a033
commit
0f6a682ea6
1 file changed
+28
@@ -994,6 +994,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
|||||||
return;
|
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,
|
input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
|
||||||
map_str,
|
map_str,
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||||
@@ -1016,6 +1023,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
|||||||
input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
|
input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
|
||||||
#undef GET_MOD_INDEX
|
#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);
|
input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
|
||||||
if (!input->xkb.state) {
|
if (!input->xkb.state) {
|
||||||
SDL_SetError("failed to create XKB state\n");
|
SDL_SetError("failed to create XKB state\n");
|
||||||
@@ -1061,10 +1075,18 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up XKB compose table */
|
/* 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,
|
input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context,
|
||||||
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
|
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||||
if (input->xkb.compose_table) {
|
if (input->xkb.compose_table) {
|
||||||
/* Set up XKB compose state */
|
/* 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,
|
input->xkb.compose_state = WAYLAND_xkb_compose_state_new(input->xkb.compose_table,
|
||||||
XKB_COMPOSE_STATE_NO_FLAGS);
|
XKB_COMPOSE_STATE_NO_FLAGS);
|
||||||
if (!input->xkb.compose_state) {
|
if (!input->xkb.compose_state) {
|
||||||
@@ -1299,6 +1321,12 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
|||||||
Wayland_Keymap keymap;
|
Wayland_Keymap keymap;
|
||||||
const uint32_t modstate = (mods_depressed | mods_latched | mods_locked);
|
const uint32_t modstate = (mods_depressed | mods_latched | mods_locked);
|
||||||
|
|
||||||
|
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,
|
WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
|
||||||
mods_locked, 0, 0, group);
|
mods_locked, 0, 0, group);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user