gmni

a gemini line mode client
git clone https://git.clttr.info/gmni.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

commit 1dfc0cca7219a31955550c8eb51b46d98839a1ba
parent 2c97d4a27d12ba94793e33b17cc5f23f81056cd9
Author: Ondřej Fiala <ofiala@airmail.cc>
Date:   Thu, 11 Apr 2024 13:52:06 +0200

gmnlm: fix memory leaks in display_document

fixes cba4dfd017893694d030202b0c538ce7313dd7ff

Diffstat:
Msrc/gmnlm.c | 64+++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 35 insertions(+), 29 deletions(-)

diff --git a/src/gmnlm.c b/src/gmnlm.c @@ -885,6 +885,32 @@ wrap(FILE *f, char *s, struct winsize *ws, int *row, int *col) return fprintf(f, "%s\n", s) - 1; } +static void +headings_free(struct browser *browser) +{ + struct headings *head = browser->headings; + while (head) { + struct headings *next = head->next; + free(head->title); + free(head); + head = next; + } + browser->headings = NULL; +} + +static void +links_free(struct browser *browser) +{ + struct link *link = browser->links; + while (link) { + struct link *next = link->next; + free(link->url); + free(link); + link = next; + } + browser->links = NULL; +} + static bool display_document(struct browser *browser, struct gemini_response *resp, int (*parser_next)(struct gemini_parser *, struct gemini_token *)) @@ -894,6 +920,8 @@ display_document(struct browser *browser, struct gemini_response *resp, gemini_parser_init(&p, resp->body); free(browser->page_title); browser->page_title = NULL; + links_free(browser); + headings_free(browser); struct gemini_token tok; struct link **nextlnk = &browser->links; @@ -979,10 +1007,8 @@ repeat: } break; case GEMINI_PREFORMATTED_BEGIN: - gemini_token_finish(&tok); - /* fallthrough */ case GEMINI_PREFORMATTED_END: - continue; // Not used + goto next; case GEMINI_PREFORMATTED_TEXT: if (text == NULL) { text = tok.preformatted; @@ -1030,14 +1056,13 @@ repeat: break; } - if (browser->target_heading) { - text = NULL; - continue; - } + if (browser->target_heading) goto next; if (text && searching) { int r = regexec(&browser->regex, text, 0, NULL, 0); if (r != 0) { +next: text = NULL; + gemini_token_finish(&tok); continue; } else { assert(out != browser->tty); @@ -1086,10 +1111,7 @@ repeat: break; case PROMPT_QUIT: browser->running = false; - if (text != NULL) { - gemini_token_finish(&tok); - } - return true; + /* fall-through */ case PROMPT_ANSWERED: if (text != NULL) { gemini_token_finish(&tok); @@ -1332,24 +1354,6 @@ again:; } } gemini_response_finish(&resp); - - struct link *link = browser.links; - while (link) { - struct link *next = link->next; - free(link->url); - free(link); - link = next; - } - browser.links = NULL; - - struct headings *head = browser.headings; - while (head) { - struct headings *next = head->next; - free(head->title); - free(head); - head = next; - } - browser.headings = NULL; } gemini_tofu_finish(&browser.tofu); @@ -1358,6 +1362,8 @@ again:; hist = hist->prev; } history_free(hist); + links_free(&browser); + headings_free(&browser); curl_url_cleanup(browser.url); free(browser.page_title); free(browser.plain_url);