From db716c3c7ae9010daafb2bc81eec41375c6a9344 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Wed, 12 Sep 2018 10:59:23 +0300 Subject: [PATCH] dir_list: fix memory leak when list is free'd. Signed-off-by: Andrew Borodin --- src/filemanager/dir.c | 37 +++++++++++++++++++++++-------------- src/filemanager/dir.h | 1 + src/filemanager/midnight.c | 2 +- src/filemanager/panel.c | 2 +- src/viewer/lib.c | 5 ++--- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/filemanager/dir.c b/src/filemanager/dir.c index aa5cfd018..e8e628459 100644 --- a/src/filemanager/dir.c +++ b/src/filemanager/dir.c @@ -218,18 +218,7 @@ alloc_dir_copy (int size) if (dir_copy.size < size) { if (dir_copy.list != NULL) - { - int i; - - for (i = 0; i < dir_copy.len; i++) - { - file_entry_t *fentry; - - fentry = &(dir_copy.list)[i]; - g_free (fentry->fname); - } - g_free (dir_copy.list); - } + dir_list_free_list (&dir_copy); dir_copy.list = g_new0 (file_entry_t, size); dir_copy.size = size; @@ -538,6 +527,26 @@ dir_list_clean (dir_list * list) dir_list_grow (list, DIR_LIST_MIN_SIZE - list->size); } +/* --------------------------------------------------------------------------------------------- */ + +void +dir_list_free_list (dir_list * list) +{ + int i; + + for (i = 0; i < list->len; i++) + { + file_entry_t *fentry; + + fentry = &list->list[i]; + g_free (fentry->fname); + } + + MC_PTR_FREE (list->list); + list->len = 0; + list->size = 0; +} + /* --------------------------------------------------------------------------------------------- */ /** Used to set up a directory list when there is no access to a directory */ @@ -744,7 +753,7 @@ dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort, dir_list_clean (list); if (!dir_list_init (list)) { - dir_list_clean (&dir_copy); + dir_list_free_list (&dir_copy); return; } @@ -805,7 +814,7 @@ dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort, dir_list_sort (list, sort, sort_op); - dir_list_clean (&dir_copy); + dir_list_free_list (&dir_copy); rotate_dash (FALSE); } diff --git a/src/filemanager/dir.h b/src/filemanager/dir.h index a87e92d41..f04065e68 100644 --- a/src/filemanager/dir.h +++ b/src/filemanager/dir.h @@ -55,6 +55,7 @@ void dir_list_reload (dir_list * list, const vfs_path_t * vpath, GCompareFunc so void dir_list_sort (dir_list * list, GCompareFunc sort, const dir_sort_options_t * sort_op); gboolean dir_list_init (dir_list * list); void dir_list_clean (dir_list * list); +void dir_list_free_list (dir_list * list); gboolean handle_path (const char *path, struct stat *buf1, int *link_to_dir, int *stale_link); /* Sorting functions */ diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index e8e43735a..988a5b100 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -1801,7 +1801,7 @@ do_nc (void) /* don't handle VFS timestamps for dirs opened in panels */ mc_event_destroy (MCEVENT_GROUP_CORE, "vfs_timestamp"); - dir_list_clean (&panelized_panel.list); + dir_list_free_list (&panelized_panel.list); } /* Program end */ diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index c3bfafd6a..6c056493b 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -4233,7 +4233,7 @@ panel_clean_dir (WPanel * panel) panel->content_shift = -1; panel->max_shift = -1; - dir_list_clean (&panel->dir); + dir_list_free_list (&panel->dir); } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/viewer/lib.c b/src/viewer/lib.c index 0ed66bc86..a10c1025e 100644 --- a/src/viewer/lib.c +++ b/src/viewer/lib.c @@ -247,10 +247,9 @@ mcview_done (WView * view) if (mc_global.mc_run_mode == MC_RUN_VIEWER && view->dir != NULL) { /* mcviewer is the owner of file list */ - dir_list_clean (view->dir); - g_free (view->dir->list); - g_free (view->dir_idx); + dir_list_free_list (view->dir); g_free (view->dir); + g_free (view->dir_idx); } view->dir = NULL;