dir_list: fix memory leak when list is free'd.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2018-09-12 10:59:23 +03:00
parent 25a9aa1d45
commit db716c3c7a
5 changed files with 28 additions and 19 deletions

View File

@ -218,18 +218,7 @@ alloc_dir_copy (int size)
if (dir_copy.size < size) if (dir_copy.size < size)
{ {
if (dir_copy.list != NULL) if (dir_copy.list != NULL)
{ dir_list_free_list (&dir_copy);
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_copy.list = g_new0 (file_entry_t, size); dir_copy.list = g_new0 (file_entry_t, size);
dir_copy.size = 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); 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 */ /** 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); dir_list_clean (list);
if (!dir_list_init (list)) if (!dir_list_init (list))
{ {
dir_list_clean (&dir_copy); dir_list_free_list (&dir_copy);
return; 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_sort (list, sort, sort_op);
dir_list_clean (&dir_copy); dir_list_free_list (&dir_copy);
rotate_dash (FALSE); rotate_dash (FALSE);
} }

View File

@ -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); void dir_list_sort (dir_list * list, GCompareFunc sort, const dir_sort_options_t * sort_op);
gboolean dir_list_init (dir_list * list); gboolean dir_list_init (dir_list * list);
void dir_list_clean (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); gboolean handle_path (const char *path, struct stat *buf1, int *link_to_dir, int *stale_link);
/* Sorting functions */ /* Sorting functions */

View File

@ -1801,7 +1801,7 @@ do_nc (void)
/* don't handle VFS timestamps for dirs opened in panels */ /* don't handle VFS timestamps for dirs opened in panels */
mc_event_destroy (MCEVENT_GROUP_CORE, "vfs_timestamp"); mc_event_destroy (MCEVENT_GROUP_CORE, "vfs_timestamp");
dir_list_clean (&panelized_panel.list); dir_list_free_list (&panelized_panel.list);
} }
/* Program end */ /* Program end */

View File

@ -4233,7 +4233,7 @@ panel_clean_dir (WPanel * panel)
panel->content_shift = -1; panel->content_shift = -1;
panel->max_shift = -1; panel->max_shift = -1;
dir_list_clean (&panel->dir); dir_list_free_list (&panel->dir);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

View File

@ -247,10 +247,9 @@ mcview_done (WView * view)
if (mc_global.mc_run_mode == MC_RUN_VIEWER && view->dir != NULL) if (mc_global.mc_run_mode == MC_RUN_VIEWER && view->dir != NULL)
{ {
/* mcviewer is the owner of file list */ /* mcviewer is the owner of file list */
dir_list_clean (view->dir); dir_list_free_list (view->dir);
g_free (view->dir->list);
g_free (view->dir_idx);
g_free (view->dir); g_free (view->dir);
g_free (view->dir_idx);
} }
view->dir = NULL; view->dir = NULL;