From 1239b56d8a1b6242135a7cc6ae15340c86c40e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Higor=20Eur=C3=ADpedes?= Date: Mon, 15 Jun 2015 14:36:16 -0300 Subject: [PATCH] (XMB) Fix segfault --- menu/cbs/menu_cbs_iterate.c | 1 + menu/drivers/xmb.c | 47 ++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/menu/cbs/menu_cbs_iterate.c b/menu/cbs/menu_cbs_iterate.c index 7ff85d27ae..67574050dc 100644 --- a/menu/cbs/menu_cbs_iterate.c +++ b/menu/cbs/menu_cbs_iterate.c @@ -542,6 +542,7 @@ static int action_iterate_main(const char *label, unsigned action) break; case ITERATE_TYPE_DEFAULT: selected = menu_navigation_get_current_selection(); + /* FIXME: selected > selection_buf->list->size, i don't know why. */ selected = max(min(selected, menu_list_get_size(menu_list)-1), 0); menu_entry_get(&entry, selected, NULL, false); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index c55f7a25fd..6a6fc32b44 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -1602,13 +1602,7 @@ static void xmb_free(void *data) return; if (xmb->menu_stack_old) - { - /* list nodes are owned by menu->menu_list->menu_stack */ - if (xmb->menu_stack_old->list) - free(xmb->menu_stack_old->list); - - free(xmb->menu_stack_old); - } + file_list_free(xmb->menu_stack_old); xmb->menu_stack_old = NULL; if (xmb->selection_buf_old) @@ -1958,6 +1952,41 @@ static void xmb_list_free(file_list_t *list, { } +static void xmb_list_deep_copy(menu_handle_t *menu, const file_list_t *src, file_list_t *dst) +{ + size_t size, i; + + size = dst->size; + for (i = 0; i < size; ++i) + { + file_list_free_userdata(dst, i); + file_list_free_actiondata(dst, i); + } + + file_list_copy(src, dst); + + size = dst->size; + for (i = 0; i < size; ++i) + { + void *src_udata = file_list_get_userdata_at_offset(src, i); + void *src_adata = file_list_get_actiondata_at_offset(src, i); + + if (src_udata) + { + void *data = calloc(sizeof(xmb_node_t), 1); + memcpy(data, src_udata, sizeof(xmb_node_t)); + file_list_set_userdata(dst, i, data); + } + + if (src_adata) + { + void *data = calloc(sizeof(menu_file_list_cbs_t), 1); + memcpy(data, src_adata, sizeof(menu_file_list_cbs_t)); + file_list_set_actiondata(dst, i, data); + } + } +} + static void xmb_list_cache(menu_list_type_t type, unsigned action) { size_t stack_size, list_size; @@ -1974,8 +2003,8 @@ static void xmb_list_cache(menu_list_type_t type, unsigned action) if (!xmb) return; - file_list_copy(menu_list->selection_buf, xmb->selection_buf_old); - file_list_copy(menu_list->menu_stack, xmb->menu_stack_old); + xmb_list_deep_copy(menu, menu_list->selection_buf, xmb->selection_buf_old); + xmb_list_deep_copy(menu, menu_list->menu_stack, xmb->menu_stack_old); xmb->selection_ptr_old = nav->selection_ptr; switch (type)