Skip to content

Commit

Permalink
Merge branch 'memory-fixes'
Browse files Browse the repository at this point in the history
Fix `:tabnew ..` not working due to use of uninitialized data.

Fix access to uninitialized memory on clearing view after graphical
preview.

Fix possible crashes after certain patterns of using view mode and
closing tabs.

Unfortunately, these were discovered right after the release...
  • Loading branch information
xaizek committed Nov 13, 2018
2 parents e24fbea + 20f1cf9 commit 29bbf12
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 9 deletions.
10 changes: 10 additions & 0 deletions ChangeLog
@@ -1,3 +1,13 @@
0.10 to current

Fixed `:tabnew ..` not working due to use of uninitialized data.

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.
Expand Down
7 changes: 6 additions & 1 deletion src/cmd_handlers.c
Expand Up @@ -4139,10 +4139,15 @@ tabnew_cmd(const cmd_info_t *cmd_info)
if(cmd_info->argc > 0)
{
char dir[PATH_MAX + 1];
int updir;

int updir;
flist_pick_cd_path(curr_view, flist_get_dir(curr_view), cmd_info->argv[0],
&updir, dir, sizeof(dir));
if(updir)
{
copy_str(dir, sizeof(dir), "..");
}

to_canonic_path(dir, flist_get_dir(curr_view), canonic_dir,
sizeof(canonic_dir));

Expand Down
1 change: 1 addition & 0 deletions src/filelist.c
Expand Up @@ -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);
}
Expand Down
3 changes: 2 additions & 1 deletion src/filelist.h
Expand Up @@ -100,7 +100,8 @@ int pane_in_dir(const view_t *view, const char path[]);
* be preserved. */
int go_to_sibling_dir(view_t *view, int offset, int wrap);
/* Picks new directory or requested going up one level judging from supplied
* base directory, desired location and current location of the view. */
* base directory, desired location and current location of the view. Buffer is
* not filled if *updir gets set. */
void flist_pick_cd_path(view_t *view, const char base_dir[], const char path[],
int *updir, char buf[], size_t buf_size);

Expand Down
12 changes: 8 additions & 4 deletions src/modes/view.c
Expand Up @@ -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;
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/ui/ui.c
Expand Up @@ -2197,15 +2197,15 @@ ui_view_wipe(view_t *view)
short int fg, bg;
char line_filler[getmaxx(view->win) + 1];

line_filler[sizeof(line_filler) - 1] = '\0';
line_filler[sizeof(line_filler) - 1U] = '\0';
height = getmaxy(view->win);

/* User doesn't need to see fake filling so draw it with the color of
* background. */
(void)pair_content(PAIR_NUMBER(getbkgd(view->win)), &fg, &bg);
wattrset(view->win, COLOR_PAIR(colmgr_get_pair(bg, bg)));

memset(line_filler, '\t', sizeof(line_filler));
memset(line_filler, '\t', sizeof(line_filler) - 1U);
for(i = 0; i < height; ++i)
{
mvwaddstr(view->win, i, 0, line_filler);
Expand Down
77 changes: 76 additions & 1 deletion tests/misc/commands_tabs.c
Expand Up @@ -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"

Expand Down Expand Up @@ -54,7 +56,7 @@ TEARDOWN()
columns_teardown();
}

TEST(tab_without_name_is_created)
TEST(tab_is_created_without_name)
{
tab_info_t tab_info;

Expand Down Expand Up @@ -100,6 +102,25 @@ TEST(tab_in_path_is_created)
assert_true(paths_are_same(lwin.curr_dir, read_data));
}

TEST(tab_in_parent_is_created)
{
char cwd[PATH_MAX + 1];
assert_non_null(get_cwd(cwd, sizeof(cwd)));

char test_data[PATH_MAX + 1];
make_abs_path(test_data, sizeof(test_data), TEST_DATA_PATH, "", cwd);

snprintf(lwin.curr_dir, sizeof(lwin.curr_dir), "%s/read", test_data);

assert_success(exec_commands("tabnew ..", &lwin, CIT_COMMAND));
assert_int_equal(2, tabs_count(&lwin));

tab_info_t tab_info;
assert_true(tabs_get(&lwin, 1, &tab_info));

assert_true(paths_are_same(lwin.curr_dir, test_data));
}

TEST(newtab_fails_in_diff_mode_for_tab_panes)
{
create_file(SANDBOX_PATH "/empty");
Expand Down Expand Up @@ -306,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 : */

0 comments on commit 29bbf12

Please sign in to comment.