Download raw body.
tog: fix use after free of reference name
Another problem found during testing:
run tog log
type 'r' to open a ref view
hit Enter on refs/heads/main
type Ctrl-L
tog exits with: tog: reference <garbage> not found
Where <garbage> corresponds to memory that has been freed.
It could display as an empty string, an unrelated reference name,
actual garbage in the terminal, etc.
This patch fixes the issue for me. ok?
deep-copy reference names in the log and tree views to prevent use-after-free
diff 36464f21ee78a3b85d0ab903434431af52021e5c d67a9c03480788ee66943922f80d961fa841532e
blob - ba062af0078c93a3bbbfc65a63c8e30b0bdfa7f9
blob + 86a18f384a1e940617fee4f6e7a3f2df79853ac0
--- tog/tog.c
+++ tog/tog.c
@@ -301,7 +301,7 @@ struct tog_log_view_state {
struct commit_queue_entry *selected_entry;
int selected;
char *in_repo_path;
- const char *head_ref_name;
+ char *head_ref_name;
int log_branches;
struct got_repository *repo;
struct got_reflist_head refs;
@@ -396,7 +396,7 @@ struct tog_tree_view_state {
int ndisplayed, selected, show_ids;
struct tog_parent_trees parents;
struct got_object_id *commit_id;
- const char *head_ref_name;
+ char *head_ref_name;
struct got_repository *repo;
struct got_tree_entry *matched_entry;
struct tog_colors colors;
@@ -2110,6 +2110,8 @@ close_log_view(struct tog_view *view)
s->in_repo_path = NULL;
free(s->start_id);
s->start_id = NULL;
+ free(s->head_ref_name);
+ s->head_ref_name = NULL;
got_ref_list_free(&s->refs);
return err;
}
@@ -2257,7 +2259,11 @@ open_log_view(struct tog_view *view, struct got_object
goto done;
s->repo = repo;
- s->head_ref_name = head_ref_name;
+ s->head_ref_name = strdup(head_ref_name);
+ if (s->head_ref_name == NULL) {
+ err = got_error_from_errno("strdup");
+ goto done;
+ }
s->start_id = got_object_id_dup(start_id);
if (s->start_id == NULL) {
err = got_error_from_errno("got_object_id_dup");
@@ -5072,7 +5078,11 @@ open_tree_view(struct tog_view *view, struct got_tree_
err = got_error_from_errno("got_object_id_dup");
goto done;
}
- s->head_ref_name = head_ref_name;
+ s->head_ref_name = strdup(head_ref_name);
+ if (s->head_ref_name == NULL) {
+ err = got_error_from_errno("strdup");
+ goto done;
+ }
s->repo = repo;
SIMPLEQ_INIT(&s->colors);
@@ -5137,6 +5147,8 @@ close_tree_view(struct tog_view *view)
s->tree_label = NULL;
free(s->commit_id);
s->commit_id = NULL;
+ free(s->head_ref_name);
+ s->head_ref_name = NULL;
while (!TAILQ_EMPTY(&s->parents)) {
struct tog_parent_tree *parent;
parent = TAILQ_FIRST(&s->parents);
tog: fix use after free of reference name