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:
M | src/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);