input: Fix weston_seat_init_keyboard() error path

The pointer seat->keyboard was set before some possible error returns.
That pointer was left unchanged in case of failure, pointing to an
uninitialized keyboard struct (that was also leaked). If a client sent
a wl_seat::get_keyboard request, that would cause Weston to crash.

Fix this by setting the seat->keyboard pointer only after the keymap
initialization is done and there is no more possibilities for failure.
Also plug the memory leaks on the error path.

https://bugs.freedesktop.org/show_bug.cgi?id=74035
This commit is contained in:
Ander Conselvan de Oliveira 2014-01-31 17:35:45 +02:00 committed by Kristian Høgsberg
parent 23900f70e5
commit 4d363cfcf6

View file

@ -2019,19 +2019,15 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
return -1; return -1;
} }
seat->keyboard = keyboard;
seat->keyboard_device_count = 1;
keyboard->seat = seat;
#ifdef ENABLE_XKBCOMMON #ifdef ENABLE_XKBCOMMON
if (seat->compositor->use_xkbcommon) { if (seat->compositor->use_xkbcommon) {
if (keymap != NULL) { if (keymap != NULL) {
keyboard->xkb_info = weston_xkb_info_create(keymap); keyboard->xkb_info = weston_xkb_info_create(keymap);
if (keyboard->xkb_info == NULL) if (keyboard->xkb_info == NULL)
return -1; goto err;
} else { } else {
if (weston_compositor_build_global_keymap(seat->compositor) < 0) if (weston_compositor_build_global_keymap(seat->compositor) < 0)
return -1; goto err;
keyboard->xkb_info = seat->compositor->xkb_info; keyboard->xkb_info = seat->compositor->xkb_info;
keyboard->xkb_info->ref_count++; keyboard->xkb_info->ref_count++;
} }
@ -2039,16 +2035,27 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap); keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
if (keyboard->xkb_state.state == NULL) { if (keyboard->xkb_state.state == NULL) {
weston_log("failed to initialise XKB state\n"); weston_log("failed to initialise XKB state\n");
return -1; goto err;
} }
keyboard->xkb_state.leds = 0; keyboard->xkb_state.leds = 0;
} }
#endif #endif
seat->keyboard = keyboard;
seat->keyboard_device_count = 1;
keyboard->seat = seat;
seat_send_updated_caps(seat); seat_send_updated_caps(seat);
return 0; return 0;
err:
if (keyboard->xkb_info)
weston_xkb_info_destroy(keyboard->xkb_info);
free(keyboard);
return -1;
} }
static void static void