diff --git a/ChangeLog b/ChangeLog index 4a0c77bfc..fad59f3ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ Fixed access to uninitialized memory on clearing view after graphical preview. + Fixed possible crashes after certain patterns of using view mode and + closing tabs. + 0.10-beta to 0.10 (2018-11-11) Display list of files in removal confirmation dialog. Thanks to ovk. diff --git a/src/filelist.c b/src/filelist.c index 2100accda..dfde08032 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -310,6 +310,7 @@ flist_free_view(view_t *view) update_string(&view->preview_prg_g, NULL); view_info_free(view->vi); + view->vi = NULL; regfree(&view->primary_group); } diff --git a/src/modes/view.c b/src/modes/view.c index b950991c5..f2806e583 100644 --- a/src/modes/view.c +++ b/src/modes/view.c @@ -1673,12 +1673,16 @@ view_info_alloc(void) } void -view_info_free(view_info_t *vi) +view_info_free(view_info_t *info) { - if(vi != NULL) + if(info != NULL) { - free_view_info(vi); - free(vi); + free_view_info(info); + free(info); + if(info == vi) + { + vi = NULL; + } } } diff --git a/tests/misc/commands_tabs.c b/tests/misc/commands_tabs.c index 46f5724ea..2b903b7a4 100644 --- a/tests/misc/commands_tabs.c +++ b/tests/misc/commands_tabs.c @@ -7,12 +7,14 @@ #include "../../src/cfg/config.h" #include "../../src/engine/keys.h" #include "../../src/modes/modes.h" +#include "../../src/modes/view.h" #include "../../src/modes/wk.h" #include "../../src/ui/tabs.h" #include "../../src/ui/ui.h" #include "../../src/utils/fs.h" #include "../../src/cmd_core.h" #include "../../src/compare.h" +#include "../../src/filelist.h" #include "utils.h" @@ -325,5 +327,59 @@ TEST(tabs_are_moved) } } +TEST(view_mode_is_fine_with_tabs) +{ + char cwd[PATH_MAX + 1]; + assert_non_null(get_cwd(cwd, sizeof(cwd))); + make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), TEST_DATA_PATH, "read", + cwd); + populate_dir_list(&lwin, 0); + + (void)vle_keys_exec_timed_out(WK_e); + (void)vle_keys_exec_timed_out(WK_q); + + assert_success(exec_commands("tabnew", &lwin, CIT_COMMAND)); + assert_int_equal(2, tabs_count(&lwin)); + + (void)vle_keys_exec_timed_out(WK_e); + (void)vle_keys_exec_timed_out(WK_q); + + assert_success(exec_commands("tabclose", &lwin, CIT_COMMAND)); + assert_int_equal(1, tabs_count(&lwin)); + + (void)vle_keys_exec_timed_out(WK_e); + (void)vle_keys_exec_timed_out(WK_q); +} + +TEST(left_view_mode_is_fine_with_tabs) +{ + char cwd[PATH_MAX + 1]; + assert_non_null(get_cwd(cwd, sizeof(cwd))); + make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), TEST_DATA_PATH, "read", + cwd); + populate_dir_list(&lwin, 0); + + (void)vle_keys_exec_timed_out(WK_e); + (void)vle_keys_exec_timed_out(WK_C_i); + + assert_success(exec_commands("tabnew", &lwin, CIT_COMMAND)); + assert_int_equal(2, tabs_count(&lwin)); + + (void)vle_keys_exec_timed_out(WK_SPACE); + (void)vle_keys_exec_timed_out(WK_e); + (void)vle_keys_exec_timed_out(WK_C_i); + + assert_success(exec_commands("tabnew", &lwin, CIT_COMMAND)); + assert_int_equal(3, tabs_count(&lwin)); + + assert_success(exec_commands("q", &lwin, CIT_COMMAND)); + assert_int_equal(2, tabs_count(&lwin)); + assert_success(exec_commands("q", &lwin, CIT_COMMAND)); + assert_int_equal(1, tabs_count(&lwin)); + + (void)vle_keys_exec_timed_out(WK_SPACE); + (void)vle_keys_exec_timed_out(WK_q); +} + /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set cinoptions+=t0 : */