commit 74bea526c558fb385ffcbb01e4e271523cebb168 from: Mark Jamsek date: Mon Dec 30 10:06:42 2024 UTC fix NULL deref with T keymap on log view worktree entry When the log view T keymap is used, the selected_entry is passed to browse_commit_tree() to open a tree view of the repository as at the selected commit, which passes the selected_entry->id member to open_tree_view() to open the commit. The id member, which is a NULL pointer in work tree entries, is dereferenced so we segfault. If the T keymap is used on a work tree entry, use the base commit id instead, which we must have if a work tree entry is selected. ok stsp@ commit - d999c1e562c0fe06cd9b18c002f65fec062018b4 commit + 74bea526c558fb385ffcbb01e4e271523cebb168 blob - 8ba0b402891597607aa828b626aea058f21769eb blob + ce0e59563dca13d6cbb9942f09da18f0433fbab0 --- tog/tog.c +++ tog/tog.c @@ -3833,12 +3833,23 @@ browse_commit_tree(struct tog_view **new_view, int beg const struct got_error *err = NULL; struct tog_tree_view_state *s; struct tog_view *tree_view; + struct got_commit_object *commit = NULL; + struct got_object_id *commit_id; + *new_view = NULL; + + if (entry->id != NULL) + commit_id = entry->id; + else if (entry->worktree_entry) + commit_id = tog_base_commit.id; + else /* cannot happen */ + return got_error(GOT_ERR_NOT_WORKTREE); + tree_view = view_open(0, 0, begin_y, begin_x, TOG_VIEW_TREE); if (tree_view == NULL) return got_error_from_errno("view_open"); - err = open_tree_view(tree_view, entry->id, head_ref_name, repo); + err = open_tree_view(tree_view, commit_id, head_ref_name, repo); if (err) return err; s = &tree_view->state.tree; @@ -3848,7 +3859,22 @@ browse_commit_tree(struct tog_view **new_view, int beg if (got_path_is_root_dir(path)) return NULL; - return tree_view_walk_path(s, entry->commit, path); + if (entry->worktree_entry) { + err = got_object_open_as_commit(&commit, repo, commit_id); + if (err != NULL) + goto done; + } + + err = tree_view_walk_path(s, commit ? commit : entry->commit, path); + +done: + if (commit != NULL) + got_object_commit_close(commit); + if (err != NULL) { + view_close(tree_view); + *new_view = NULL; + } + return err; } /*