From 1ac839d20c2a277d54aa00286b69f61ffeaec929 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sat, 19 Oct 2024 10:38:06 +0300 Subject: [PATCH] Ticket #4600: fix segfault on panel filter. mc segfaults if filter makes file panel empty. * (panel_current_entry): improve. Add checks if panel->current is in range of file list. * A lot of changes to use modified panel_current_entry(). * (format_file): * (display_mini_info): fix drawing of mini-status if file panel is empty. Signed-off-by: Andrew Borodin --- src/diffviewer/ydiff.c | 11 +++ src/filemanager/achown.c | 11 ++- src/filemanager/chattr.c | 11 ++- src/filemanager/chmod.c | 11 ++- src/filemanager/chown.c | 11 ++- src/filemanager/cmd.c | 52 ++++++++--- src/filemanager/file.c | 21 ++++- src/filemanager/filemanager.c | 29 ++++-- src/filemanager/info.c | 2 + src/filemanager/layout.c | 8 +- src/filemanager/panel.c | 167 ++++++++++++++++++++++++---------- src/filemanager/panel.h | 9 +- src/usermenu.c | 27 +++++- src/viewer/actions_cmd.c | 7 +- 14 files changed, 288 insertions(+), 89 deletions(-) diff --git a/src/diffviewer/ydiff.c b/src/diffviewer/ydiff.c index 6f7caf239..b543186bd 100644 --- a/src/diffviewer/ydiff.c +++ b/src/diffviewer/ydiff.c @@ -3460,6 +3460,12 @@ dview_diff_cmd (const void *f0, const void *f1) const file_entry_t *fe0, *fe1; fe0 = panel_current_entry (panel0); + if (fe0 == NULL) + { + message (D_ERROR, MSG_ERROR, "%s", _("File name is empty!")); + goto ret; + } + file0 = vfs_path_append_new (panel0->cwd_vpath, fe0->fname->str, (char *) NULL); is_dir0 = S_ISDIR (fe0->st.st_mode); if (is_dir0) @@ -3470,6 +3476,11 @@ dview_diff_cmd (const void *f0, const void *f1) } fe1 = panel_current_entry (panel1); + if (fe1 == NULL) + { + message (D_ERROR, MSG_ERROR, "%s", _("File name is empty!")); + goto ret; + } file1 = vfs_path_append_new (panel1->cwd_vpath, fe1->fname->str, (char *) NULL); is_dir1 = S_ISDIR (fe1->st.st_mode); if (is_dir1) diff --git a/src/filemanager/achown.c b/src/filemanager/achown.c index a4ef1f5bb..7c98ab06f 100644 --- a/src/filemanager/achown.c +++ b/src/filemanager/achown.c @@ -1020,7 +1020,16 @@ advanced_chown_cmd (WPanel *panel) if (panel->marked != 0) fname = next_file (panel); /* next marked file */ else - fname = panel_current_entry (panel)->fname; /* single file */ + { + /* single file */ + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + break; + + fname = fe->fname; + } vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/chattr.c b/src/filemanager/chattr.c index 91159d4c4..27120346e 100644 --- a/src/filemanager/chattr.c +++ b/src/filemanager/chattr.c @@ -1227,7 +1227,16 @@ chattr_cmd (WPanel *panel) if (panel->marked != 0) fname = next_file (panel); /* next marked file */ else - fname = panel_current_entry (panel)->fname; /* single file */ + { + /* single file */ + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + break; + + fname = fe->fname; + } vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/chmod.c b/src/filemanager/chmod.c index 7467b4043..7c50baa92 100644 --- a/src/filemanager/chmod.c +++ b/src/filemanager/chmod.c @@ -552,7 +552,16 @@ chmod_cmd (WPanel *panel) if (panel->marked != 0) fname = next_file (panel); /* next marked file */ else - fname = panel_current_entry (panel)->fname; /* single file */ + { + /* single file */ + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + break; + + fname = fe->fname; + } vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/chown.c b/src/filemanager/chown.c index 174b93049..4182afc44 100644 --- a/src/filemanager/chown.c +++ b/src/filemanager/chown.c @@ -421,7 +421,16 @@ chown_cmd (WPanel *panel) if (panel->marked != 0) fname = next_file (panel); /* next marked file */ else - fname = panel_current_entry (panel)->fname; /* single file */ + { + /* single file */ + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + break; + + fname = fe->fname; + } vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c index b1fd21142..acc53db60 100644 --- a/src/filemanager/cmd.c +++ b/src/filemanager/cmd.c @@ -125,6 +125,8 @@ do_view_cmd (WPanel *panel, gboolean plain_view) const file_entry_t *fe; fe = panel_current_entry (panel); + if (fe == NULL) + return; /* Directories are viewed by changing to them */ if (S_ISDIR (fe->st.st_mode) || link_isdir (fe)) @@ -576,12 +578,16 @@ view_cmd (WPanel *panel) void view_file_cmd (const WPanel *panel) { + const file_entry_t *fe; char *filename; vfs_path_t *vpath; + fe = panel_current_entry (panel); + if (fe == NULL) + return; + filename = - input_expand_dialog (_("View file"), _("Filename:"), - MC_HISTORY_FM_VIEW_FILE, panel_current_entry (panel)->fname->str, + input_expand_dialog (_("View file"), _("Filename:"), MC_HISTORY_FM_VIEW_FILE, fe->fname->str, INPUT_COMPLETE_FILENAMES); if (filename == NULL) return; @@ -609,7 +615,15 @@ view_filtered_cmd (const WPanel *panel) const char *initial_command; if (input_is_empty (cmdline)) - initial_command = panel_current_entry (panel)->fname->str; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + initial_command = fe->fname->str; + } else initial_command = input_get_ctext (cmdline); @@ -673,9 +687,14 @@ edit_file_at_line (const vfs_path_t *what_vpath, gboolean internal, long start_l void edit_cmd (const WPanel *panel) { + const file_entry_t *fe; vfs_path_t *fname; - fname = vfs_path_from_str (panel_current_entry (panel)->fname->str); + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + fname = vfs_path_from_str (fe->fname->str); if (regex_command (fname, "Edit") == 0) do_edit (fname); vfs_path_free (fname, TRUE); @@ -687,9 +706,14 @@ edit_cmd (const WPanel *panel) void edit_cmd_force_internal (const WPanel *panel) { + const file_entry_t *fe; vfs_path_t *fname; - fname = vfs_path_from_str (panel_current_entry (panel)->fname->str); + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + fname = vfs_path_from_str (fe->fname->str); if (regex_command (fname, "Edit") == 0) edit_file_at_line (fname, TRUE, 1); vfs_path_free (fname, TRUE); @@ -736,6 +760,8 @@ mkdir_cmd (WPanel *panel) const char *name = ""; fe = panel_current_entry (panel); + if (fe == NULL) + return; /* If 'on' then automatically fills name with current item name */ if (auto_fill_mkdir_name && !DIR_IS_DOTDOT (fe->fname->str)) @@ -1055,11 +1081,11 @@ swap_cmd (void) void link_cmd (link_type_t link_type) { - const char *filename; + const file_entry_t *fe; - filename = panel_current_entry (current_panel)->fname->str; - if (filename != NULL) - do_link (link_type, filename); + fe = panel_current_entry (current_panel); + if (fe != NULL) + do_link (link_type, fe->fname->str); } /* --------------------------------------------------------------------------------------------- */ @@ -1071,6 +1097,9 @@ edit_symlink_cmd (void) const char *p; fe = panel_current_entry (current_panel); + if (fe == NULL) + return; + p = fe->fname->str; if (!S_ISLNK (fe->st.st_mode)) @@ -1218,7 +1247,8 @@ smart_dirsize_cmd (WPanel *panel) const file_entry_t *entry; entry = panel_current_entry (panel); - if ((S_ISDIR (entry->st.st_mode) && DIR_IS_DOTDOT (entry->fname->str)) || panel->dirs_marked) + if ((entry != NULL && S_ISDIR (entry->st.st_mode) && DIR_IS_DOTDOT (entry->fname->str)) + || panel->dirs_marked) dirsizes_cmd (panel); else single_dirsize_cmd (panel); @@ -1233,7 +1263,7 @@ single_dirsize_cmd (WPanel *panel) entry = panel_current_entry (panel); - if (S_ISDIR (entry->st.st_mode) && !DIR_IS_DOTDOT (entry->fname->str)) + if (entry != NULL && S_ISDIR (entry->st.st_mode) && !DIR_IS_DOTDOT (entry->fname->str)) { size_t dir_count = 0; size_t count = 0; diff --git a/src/filemanager/file.c b/src/filemanager/file.c index e1568095d..cc0696055 100644 --- a/src/filemanager/file.c +++ b/src/filemanager/file.c @@ -1751,6 +1751,8 @@ do_move_dir_dir (const WPanel *panel, file_op_total_context_t *tctx, file_op_con static const char * panel_get_file (const WPanel *panel) { + const file_entry_t *fe; + if (get_current_type () == view_tree) { WTree *tree; @@ -1770,7 +1772,9 @@ panel_get_file (const WPanel *panel) return panel->dir.list[i].fname->str; } - return panel_current_entry (panel)->fname->str; + fe = panel_current_entry (panel); + + return (fe == NULL ? NULL : fe->fname->str); } /* --------------------------------------------------------------------------------------------- */ @@ -1782,10 +1786,18 @@ check_single_entry (const WPanel *panel, gboolean force_single, struct stat *src gboolean ok; if (force_single) - source = panel_current_entry (panel)->fname->str; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + source = fe == NULL ? NULL : fe->fname->str; + } else source = panel_get_file (panel); + if (source == NULL) + return NULL; + ok = !DIR_IS_DOTDOT (source); if (!ok) @@ -3529,9 +3541,12 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl else #endif /* ENABLE_BACKGROUND */ { + const file_entry_t *fe; + if (operation == OP_DELETE) dialog_type = FILEGUI_DIALOG_DELETE_ITEM; - else if (single_entry && S_ISDIR (panel_current_entry (panel)->st.st_mode)) + else if (single_entry + && ((fe = panel_current_entry (panel)) == NULL ? FALSE : S_ISDIR (fe->st.st_mode))) dialog_type = FILEGUI_DIALOG_MULTI_ITEM; else if (single_entry || force_single) dialog_type = FILEGUI_DIALOG_ONE_ITEM; diff --git a/src/filemanager/filemanager.c b/src/filemanager/filemanager.c index b31dda570..7291b896e 100644 --- a/src/filemanager/filemanager.c +++ b/src/filemanager/filemanager.c @@ -150,9 +150,14 @@ stop_dialogs (void) static void treebox_cmd (void) { + const file_entry_t *fe; char *sel_dir; - sel_dir = tree_box (panel_current_entry (current_panel)->fname->str); + fe = panel_current_entry (current_panel); + if (fe == NULL) + return; + + sel_dir = tree_box (fe->fname->str); if (sel_dir != NULL) { vfs_path_t *sel_vdir; @@ -720,7 +725,7 @@ put_link (WPanel *panel) fe = panel_current_entry (panel); - if (S_ISLNK (fe->st.st_mode)) + if (fe != NULL && S_ISLNK (fe->st.st_mode)) { char buffer[MC_MAXPATHLEN]; vfs_path_t *vpath; @@ -761,8 +766,6 @@ put_other_link (void) static void put_current_selected (void) { - const char *tmp; - if (!command_prompt) return; @@ -773,12 +776,16 @@ put_current_selected (void) tree = (WTree *) get_panel_widget (get_current_index ()); selected_name = tree_selected_name (tree); - tmp = vfs_path_as_str (selected_name); + command_insert (cmdline, vfs_path_as_str (selected_name), TRUE); } else - tmp = panel_current_entry (current_panel)->fname->str; + { + const file_entry_t *fe; - command_insert (cmdline, tmp, TRUE); + fe = panel_current_entry (current_panel); + if (fe != NULL) + command_insert (cmdline, fe->fname->str, TRUE); + } } /* --------------------------------------------------------------------------------------------- */ @@ -792,7 +799,13 @@ put_tagged (WPanel *panel) input_disable_update (cmdline); if (panel->marked == 0) - command_insert (cmdline, panel_current_entry (panel)->fname->str, TRUE); + { + const file_entry_t *fe; + + fe = panel_current_entry (current_panel); + if (fe != NULL) + command_insert (cmdline, fe->fname->str, TRUE); + } else { int i; diff --git a/src/filemanager/info.c b/src/filemanager/info.c index 419820e09..c8570d8fb 100644 --- a/src/filemanager/info.c +++ b/src/filemanager/info.c @@ -138,6 +138,8 @@ info_show_info (WInfo *info) my_statfs (&myfs_stats, p_rp_cwd); fe = panel_current_entry (current_panel); + if (fe == NULL) + return; st = fe->st; diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c index 1f96c2dd1..43540ad21 100644 --- a/src/filemanager/layout.c +++ b/src/filemanager/layout.c @@ -1199,7 +1199,13 @@ create_panel (int num, panel_view_mode_t type) new_widget = WIDGET (mcview_new (&r, TRUE)); the_other_panel = PANEL (panels[the_other].widget); if (the_other_panel != NULL) - file_name = panel_current_entry (the_other_panel)->fname->str; + { + const file_entry_t *fe; + + fe = panel_current_entry (the_other_panel); + if (fe != NULL) + file_name = fe->fname->str; + } mcview_load ((WView *) new_widget, 0, file_name, 0, 0, 0); break; diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 4506cbff6..9200a88ea 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -837,7 +837,7 @@ format_file (WPanel *panel, int file_index, int width, file_attr_t attr, gboolea *field_length = 0; - if (file_index < panel->dir.len) + if (panel->dir.len != 0 && file_index < panel->dir.len) { fe = &panel->dir.list[file_index]; color = file_compute_color (attr, fe); @@ -1039,7 +1039,7 @@ display_mini_info (WPanel *panel) Widget *w = WIDGET (panel); const file_entry_t *fe; - if (!panels_options.show_mini_info || panel->current < 0) + if (!panels_options.show_mini_info) return; widget_gotoyx (w, panel_lines (panel) + 3, 1); @@ -1058,7 +1058,10 @@ display_mini_info (WPanel *panel) fe = panel_current_entry (panel); - if (S_ISLNK (fe->st.st_mode)) + if (fe == NULL) + /* NULL is in case of filter that doesn't match anything */ + repaint_status (panel); + else if (S_ISLNK (fe->st.st_mode)) { char link_target[MC_MAXPATHLEN]; vfs_path_t *lc_link_vpath; @@ -1375,8 +1378,8 @@ show_dir (const WPanel *panel) fe = panel_current_entry (panel); - /* Show size of curret file in the bottom of panel */ - if (S_ISREG (fe->st.st_mode)) + /* Show size of current file in the bottom of panel */ + if (fe != NULL && S_ISREG (fe->st.st_mode)) { char buffer[BUF_SMALL]; @@ -1408,25 +1411,21 @@ adjust_top_file (WPanel *panel) { int items; - /* Update panel->current to avoid out of range in panel->dir.list[panel->current] - * when panel is redrawing when directory is reloading, for example in path: - * dir_list_reload() -> mc_refresh() -> dialog_change_screen_size() -> - * midnight_callback (MSG_RESIZE) -> setup_panels() -> panel_callback(MSG_DRAW) -> - * display_mini_info() - */ - panel->current = CLAMP (panel->current, 0, panel->dir.len - 1); - items = panel_items (panel); - if (panel->dir.len <= items) + if (panel->dir.len <= items || panel->current < 0) { /* If all files fit, show them all. */ + /* panel->current < 0 is in case of filter that doesn't match anything, keep it. */ panel->top = 0; } else { int i; + /* Update panel->current to avoid out of range in panel->dir.list[panel->current]. */ + panel->current = CLAMP (panel->current, 0, panel->dir.len - 1); + /* top_file has to be in the range [current-items+1, current] so that the current file is visible. top_file should be in the range [0, count-items] so that there's @@ -2069,7 +2068,7 @@ maybe_cd (WPanel *panel, gboolean move_up_dir) fe = panel_current_entry (panel); - if (S_ISDIR (fe->st.st_mode) || link_isdir (fe)) + if (fe != NULL && (S_ISDIR (fe->st.st_mode) || link_isdir (fe))) { vfs_path_t *vpath; @@ -2100,11 +2099,14 @@ force_maybe_cd (WPanel *panel) /* --------------------------------------------------------------------------------------------- */ -static inline void +static void unselect_item (WPanel *panel) { + const file_entry_t *fe; + + fe = panel_current_entry (panel); repaint_file (panel, panel->current, - panel_current_entry (panel)->f.marked != 0 ? FATTR_MARKED : FATTR_NORMAL); + fe != NULL && fe->f.marked != 0 ? FATTR_MARKED : FATTR_NORMAL); } /* --------------------------------------------------------------------------------------------- */ @@ -2114,21 +2116,18 @@ static void panel_select_ext_cmd (WPanel *panel) { const file_entry_t *fe; - GString *filename; gboolean do_select; char *reg_exp, *cur_file_ext; mc_search_t *search; int i; fe = panel_current_entry (panel); - - filename = fe->fname; - if (filename == NULL) + if (fe == NULL) return; do_select = (fe->f.marked == 0); - cur_file_ext = str_regex_escape (extension (filename->str)); + cur_file_ext = str_regex_escape (extension (fe->fname->str)); if (cur_file_ext[0] != '\0') reg_exp = g_strconcat ("^.*\\.", cur_file_ext, "$", (char *) NULL); else @@ -2339,11 +2338,16 @@ goto_parent_dir (WPanel *panel) cd_up_dir (panel); else { + const file_entry_t *fe; GString *fname; const char *bname; vfs_path_t *dname_vpath; - fname = panel_current_entry (panel)->fname; + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + fname = fe->fname; if (g_path_is_absolute (fname->str)) fname = mc_g_string_dup (fname); @@ -2411,7 +2415,7 @@ goto_child_dir (WPanel *panel) fe = panel_current_entry (panel); - if (S_ISDIR (fe->st.st_mode) || link_isdir (fe)) + if (fe != NULL && (S_ISDIR (fe->st.st_mode) || link_isdir (fe))) { vfs_path_t *vpath; @@ -2525,7 +2529,13 @@ move_end (WPanel *panel) static void do_mark_file (WPanel *panel, mark_act_t do_move) { - do_file_mark (panel, panel->current, panel_current_entry (panel)->f.marked ? 0 : 1); + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + do_file_mark (panel, panel->current, fe->f.marked ? 0 : 1); if ((panels_options.mark_moves_down && do_move == MARK_DOWN) || do_move == MARK_FORCE_DOWN) move_down (panel); @@ -2565,7 +2575,15 @@ mark_file_right (WPanel *panel) int lines; if (state_mark < 0) - state_mark = panel_current_entry (panel)->f.marked ? 0 : 1; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + state_mark = fe->f.marked ? 0 : 1; + } lines = panel_lines (panel); lines = MIN (lines, panel->dir.len - panel->current - 1); @@ -2585,7 +2603,15 @@ mark_file_left (WPanel *panel) int lines; if (state_mark < 0) - state_mark = panel_current_entry (panel)->f.marked ? 0 : 1; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + state_mark = fe->f.marked ? 0 : 1; + } lines = panel_lines (panel); lines = MIN (lines, panel->current + 1); @@ -2921,7 +2947,7 @@ stop_search (WPanel *panel) /** Return TRUE if the Enter key has been processed, FALSE otherwise */ static gboolean -do_enter_on_file_entry (WPanel *panel, file_entry_t *fe) +do_enter_on_file_entry (WPanel *panel, const file_entry_t *fe) { const char *fname = fe->fname->str; char *fname_quoted; @@ -2999,7 +3025,11 @@ do_enter_on_file_entry (WPanel *panel, file_entry_t *fe) static inline gboolean do_enter (WPanel *panel) { - return do_enter_on_file_entry (panel, panel_current_entry (panel)); + const file_entry_t *fe; + + fe = panel_current_entry (panel); + + return (fe == NULL ? FALSE : do_enter_on_file_entry (panel, fe)); } /* --------------------------------------------------------------------------------------------- */ @@ -3024,6 +3054,8 @@ chdir_other_panel (WPanel *panel) WPanel *p; entry = panel_current_entry (panel); + if (entry == NULL) + return; if (get_other_type () != view_listing) create_panel (get_other_index (), view_listing); @@ -3065,7 +3097,13 @@ panel_sync_other (const WPanel *panel) /* try to set current filename on the other panel */ if (!panel->is_panelized) - panel_set_current_by_name (other_panel, panel_current_entry (panel)->fname->str); + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe != NULL) + panel_set_current_by_name (other_panel, fe->fname->str); + } } /* --------------------------------------------------------------------------------------------- */ @@ -3087,7 +3125,7 @@ chdir_to_readlink (WPanel *panel) fe = panel_current_entry (panel); - if (!S_ISLNK (fe->st.st_mode)) + if (fe == NULL || !S_ISLNK (fe->st.st_mode)) return; i = readlink (fe->fname->str, buffer, MC_MAXPATHLEN - 1); @@ -3870,9 +3908,15 @@ panel_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *dat static void mouse_toggle_mark (WPanel *panel) { - do_mark_file (panel, MARK_DONT_MOVE); - mouse_marking = (panel_current_entry (panel)->f.marked != 0); - mouse_mark_panel = current_panel; + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe != NULL) + { + do_mark_file (panel, MARK_DONT_MOVE); + mouse_marking = fe->f.marked != 0; + mouse_mark_panel = current_panel; + } } /* --------------------------------------------------------------------------------------------- */ @@ -3885,11 +3929,13 @@ mouse_set_mark (WPanel *panel) const file_entry_t *fe; fe = panel_current_entry (panel); - - if (mouse_marking && fe->f.marked == 0) - do_mark_file (panel, MARK_DONT_MOVE); - else if (!mouse_marking && fe->f.marked != 0) - do_mark_file (panel, MARK_DONT_MOVE); + if (fe != NULL) + { + if (mouse_marking && fe->f.marked == 0) + do_mark_file (panel, MARK_DONT_MOVE); + else if (!mouse_marking && fe->f.marked != 0) + do_mark_file (panel, MARK_DONT_MOVE); + } } } @@ -4188,10 +4234,11 @@ update_one_panel_widget (WPanel *panel, panel_update_flags_t flags, const char * if (free_pointer) { - const GString *fname; + const file_entry_t *fe; - fname = panel_current_entry (panel)->fname; - my_current_file = g_strndup (fname->str, fname->len); + fe = panel_current_entry (panel); + if (fe != NULL) + my_current_file = g_strndup (fe->fname->str, fe->fname->len); current_file = my_current_file; } @@ -4268,8 +4315,13 @@ panel_save_current_file_to_clip_file (const gchar *event_group_name, const gchar (void) data; if (current_panel->marked == 0) - mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", - (gpointer) panel_current_entry (current_panel)->fname->str); + { + const file_entry_t *fe; + + fe = panel_current_entry (current_panel); + if (fe != NULL) + mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", (gpointer) fe->fname->str); + } else { int i; @@ -4371,6 +4423,21 @@ panel_dir_list_callback (dir_list_cb_state_t state, void *data) /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ +file_entry_t * +panel_current_entry (const WPanel *panel) +{ + file_entry_t *fe; + + if (panel->dir.len == 0 || panel->current < 0 || panel->current >= panel->dir.len) + return NULL; + + fe = &(panel->dir.list[panel->current]); + + return fe->fname == NULL ? NULL : fe; +} + +/* --------------------------------------------------------------------------------------------- */ + void panel_set_current_by_name (WPanel *panel, const char *name) { @@ -4879,6 +4946,9 @@ panel_re_sort (WPanel *panel) return; fe = panel_current_entry (panel); + if (fe == NULL) + return; + filename = g_strndup (fe->fname->str, fe->fname->len); unselect_item (panel); dir_list_sort (&panel->dir, panel->sort_field->sort_routine, &panel->sort_info); @@ -4910,11 +4980,12 @@ panel_set_sort_order (WPanel *panel, const panel_field_t *sort_order) /* The directory is already sorted, we have to load the unsorted stuff */ if (sort_order->sort_routine == (GCompareFunc) unsorted) { - char *current_file; - const GString *fname; + const file_entry_t *fe; + char *current_file = NULL; - fname = panel_current_entry (panel)->fname; - current_file = g_strndup (fname->str, fname->len); + fe = panel_current_entry (panel); + if (fe != NULL) + current_file = g_strndup (fe->fname->str, fe->fname->len); panel_reload (panel); panel_set_current_by_name (panel, current_file); g_free (current_file); diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h index 2f4d8d549..eca00581d 100644 --- a/src/filemanager/panel.h +++ b/src/filemanager/panel.h @@ -171,6 +171,7 @@ int set_panel_formats (WPanel * p); void panel_set_filter (WPanel * panel, const file_filter_t * filter); +file_entry_t *panel_current_entry (const WPanel *panel); void panel_set_current_by_name (WPanel * panel, const char *name); void unmark_files (WPanel * panel); @@ -275,12 +276,4 @@ panel_sized_new (const char *panel_name, const WRect *r) /* --------------------------------------------------------------------------------------------- */ -static inline file_entry_t * -panel_current_entry (const WPanel *panel) -{ - return &(panel->dir.list[panel->current]); -} - -/* --------------------------------------------------------------------------------------------- */ - #endif /* MC__PANEL_H */ diff --git a/src/usermenu.c b/src/usermenu.c index 5bfa99901..1ec961153 100644 --- a/src/usermenu.c +++ b/src/usermenu.c @@ -173,10 +173,15 @@ extract_arg (char *p, char *arg, int size) static gboolean test_type (WPanel *panel, char *arg) { + const file_entry_t *fe; int result = 0; /* False by default */ mode_t st_mode; - st_mode = panel_current_entry (panel)->st.st_mode; + fe = panel_current_entry (panel); + if (fe == NULL) + return FALSE; + + st_mode = fe->st.st_mode; for (; *arg != '\0'; arg++) { @@ -268,9 +273,18 @@ test_condition (const Widget *edit_widget, char *p, gboolean *condition) } else #endif - *condition = panel != NULL && - mc_search (arg, DEFAULT_CHARSET, panel_current_entry (panel)->fname->str, - search_type); + { + if (panel == NULL) + *condition = FALSE; + else + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + *condition = fe != NULL + && mc_search (arg, DEFAULT_CHARSET, fe->fname->str, search_type); + } + } break; case 'y': /* syntax pattern */ #ifdef USE_INTERNAL_EDIT @@ -784,6 +798,8 @@ expand_format (const Widget *edit_widget, char c, gboolean do_quote) else #endif { + const file_entry_t *fe; + if (g_ascii_islower ((gchar) c)) panel = current_panel; else @@ -793,7 +809,8 @@ expand_format (const Widget *edit_widget, char c, gboolean do_quote) panel = other_panel; } - fname = panel_current_entry (panel)->fname->str; + fe = panel_current_entry (panel); + fname = fe == NULL ? NULL : fe->fname->str; } break; diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c index b09808604..265224695 100644 --- a/src/viewer/actions_cmd.c +++ b/src/viewer/actions_cmd.c @@ -168,6 +168,7 @@ mcview_hook (void *v) { WView *view = (WView *) v; WPanel *panel; + const file_entry_t *fe; /* If the user is busy typing, wait until he finishes to update the screen */ @@ -187,9 +188,13 @@ mcview_hook (void *v) else return; + fe = panel_current_entry (panel); + if (fe == NULL) + return; + mcview_done (view); mcview_init (view); - mcview_load (view, 0, panel_current_entry (panel)->fname->str, 0, 0, 0); + mcview_load (view, 0, fe->fname->str, 0, 0, 0); mcview_display (view); }