From 155d08ac4c8872607b156e78a77667eb8877858f Mon Sep 17 00:00:00 2001 From: sergiotarxz Date: Mon, 22 Nov 2021 01:02:00 +0100 Subject: [PATCH] More memory cleanup. --- src/backend/readmng.c | 118 +++++++++++++++++++++++++---------- src/chapter.c | 11 +++- src/manga.c | 38 ++++++++++- src/util/regex.c | 1 + src/util/soup.c | 4 +- src/util/xml.c | 10 ++- src/view/chapter_view.c | 5 ++ src/view/detail_manga.c | 7 ++- src/view/list_view_chapter.c | 6 +- src/view/list_view_manga.c | 4 +- src/view/picture.c | 5 +- 11 files changed, 163 insertions(+), 46 deletions(-) diff --git a/src/backend/readmng.c b/src/backend/readmng.c index 95363d7..52a5337 100644 --- a/src/backend/readmng.c +++ b/src/backend/readmng.c @@ -1,6 +1,11 @@ #include #include +#ifndef PCRE2_CODE_UNIT_WIDTH +#define PCRE2_CODE_UNIT_WIDTH 8 +#include +#endif + #include #include @@ -179,14 +184,16 @@ mg_backend_readmng_parse_page (MgBackendReadmng *self, node_set = xpath_result->nodesetval; if (!node_set) { fprintf(stderr, "No match for images.\n"); - return images; + goto cleanup_mg_backend_readmng_parse_page; } for (int i = 0; i < node_set->nodeNr; i++) { xmlNodePtr node = node_set->nodeTab[i]; - const char *image_url = mg_util_xml_get_attr (xml_utils, node, "src"); - gtk_string_list_append (GTK_STRING_LIST (images), (void *)image_url); + char *image_url = mg_util_xml_get_attr (xml_utils, node, "src"); + gtk_string_list_append (GTK_STRING_LIST (images), image_url); + g_free (image_url); } - +cleanup_mg_backend_readmng_parse_page: + xmlXPathFreeObject(xpath_result); return images; } @@ -205,13 +212,18 @@ mg_backend_readmng_fetch_page_url (MgBackendReadmng *self, snprintf (concated_url, concat_all_pages_len + 1, "%s/all-pages", url); - const char *html_response = mg_util_soup_get_request (util_soup, concated_url, + char *html_response = mg_util_soup_get_request (util_soup, concated_url, &response_len); - return htmlReadMemory (html_response, response_len, + + g_clear_object (&util_soup); + g_free (url); + g_free (concated_url); + xmlDocPtr document = htmlReadMemory (html_response, response_len, NULL, NULL, HTML_PARSE_RECOVER | HTML_PARSE_NODEFDTD | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING ); - + g_free (html_response); + return document; } @@ -260,13 +272,20 @@ mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self, node, movie_detail, "movie-detail", &movie_detail_len); } if (movie_detail) { - mg_manga_set_description (manga, - (char *) xmlNodeGetContent (movie_detail[0])); + char *description = (char *) xmlNodeGetContent (movie_detail[0]); + mg_manga_set_description (manga, description); + g_free (description); } manga_chapters = mg_backend_readmng_recover_chapter_list (self, html_document); mg_manga_set_chapter_list (manga, manga_chapters); mg_manga_details_recovered (manga); cleanup_mg_backend_readmng_retrieve_manga_details: + for (size_t i = 0; i < movie_detail_len; i++) { + xmlFreeNode (movie_detail[i]); + } + if (xpath_result) { + xmlXPathFreeObject(xpath_result); + } if (movie_detail) { g_free (movie_detail); } @@ -310,6 +329,9 @@ mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self, } } cleanup_mg_backend_readmng_recover_chapter_list: + if (xpath_result) { + xmlXPathFreeObject(xpath_result); + } if (uls) { g_free (uls); } @@ -321,6 +343,7 @@ mg_backend_readmng_loop_li_chapter ( MgBackendReadmng *self, xmlNodePtr li) { MgUtilXML *xml_utils = self->xml_utils; + MgMangaChapter *chapter = NULL; xmlNodePtr a = mg_backend_readmng_get_a_for_chapter ( self, li); if (!a) return NULL; @@ -332,12 +355,27 @@ mg_backend_readmng_loop_li_chapter ( xmlNodePtr *val = mg_util_xml_find_class (xml_utils, a, "val", &val_len, NULL, 1); xmlNodePtr *dte = mg_util_xml_find_class (xml_utils, a, "dte", &dte_len, NULL, 1); if (val_len && dte_len) { - return mg_manga_chapter_new ( - (char *) xmlNodeGetContent (val[0]), - (char *) xmlNodeGetContent(dte[0]), - url); + char *val_str = (char *) xmlNodeGetContent (val[0]); + char *dte_str = (char *) xmlNodeGetContent (dte[0]); + + chapter = mg_manga_chapter_new (val_str, dte_str, url); + + g_free (val_str); + g_free (dte_str); } - return NULL; + if (url) { + g_free (url); + } + if (val) { + g_free (val); + val = NULL; + } + if (dte) { + g_free (dte); + dte = NULL; + } + + return chapter; } static xmlNodePtr @@ -375,11 +413,15 @@ mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self, char *html_response = mg_util_soup_get_request (util_soup, request_url, &response_len); + g_free (request_url); + request_url = NULL; g_clear_object (&util_soup); g_clear_object (&string_util); - return htmlReadMemory (html_response, response_len, NULL, NULL, + xmlDocPtr document = htmlReadMemory (html_response, response_len, NULL, NULL, HTML_PARSE_RECOVER | HTML_PARSE_NODEFDTD | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING ); + g_free (html_response); + return document; } static xmlDocPtr @@ -387,13 +429,14 @@ mg_backend_readmng_fetch_xml_main_page (MgBackendReadmng *self) { size_t size_response_text = 0; const char *html_response = mg_backend_readmng_get_main_page (self, &size_response_text); - return htmlReadMemory (html_response, + xmlDocPtr document = htmlReadMemory (html_response, size_response_text, NULL, NULL, HTML_PARSE_RECOVER | HTML_PARSE_NODEFDTD | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING ); + return document; } static const char * @@ -402,7 +445,7 @@ mg_backend_readmng_get_main_page (MgBackendReadmng *self, size_t *len) { MgUtilSoup *util_soup = mg_util_soup_new (); self->main_page_html = mg_util_soup_get_request (util_soup, self->base_url, &self->main_page_html_len); - g_object_unref (util_soup); + g_clear_object (&util_soup); } if (len) { *len = self->main_page_html_len; @@ -423,7 +466,8 @@ mg_backend_readmng_parse_main_page (MgBackendReadmng *self, const xmlDocPtr html xmlNodePtr current_li = li[i]; mg_backend_readmng_extract_manga_info_from_current_li (self, mangas, current_li); - + xmlFreeNode (current_li); + li[i] = NULL; } g_free (li); return mangas; @@ -475,10 +519,10 @@ mg_backend_readmng_retrieve_slides (MgBackendReadmng *self, const xmlDocPtr html if (nodes) { slides = nodes[0]; } +cleanup_mg_backend_readmng_retrieve_slides: if (xpath_result) { xmlXPathFreeObject(xpath_result); } -cleanup_mg_backend_readmng_retrieve_slides: if (nodes) { g_free (nodes); } @@ -505,9 +549,15 @@ static xmlNodePtr mg_backend_readmng_retrieve_title_from_li (MgBackendReadmng *self, xmlNodePtr li) { size_t title_len = 0; MgUtilXML *xml_utils = self->xml_utils; + xmlNodePtr return_value = NULL; xmlNodePtr *title = mg_util_xml_find_class (xml_utils, li, "title", &title_len, NULL, 1); - if (title_len) return title[0]; - return NULL; + if (title_len) { + return_value = title[0]; + } + if (title) { + g_free (title); + } + return return_value; } static xmlNodePtr @@ -522,11 +572,16 @@ mg_backend_readmng_find_a_link_chapter (MgBackendReadmng *self, } static char * -mg_backend_get_id_manga_link (MgBackendReadmng *self, xmlNodePtr a) { +mg_backend_readmng_get_id_manga_link (MgBackendReadmng *self, xmlNodePtr a) { char *re_str = "readmng\\.com/([^/]+)"; MgUtilXML *xml_utils = self->xml_utils; MgUtilRegex *regex_util = mg_util_regex_new (); - return mg_util_regex_match_1 (regex_util, re_str, mg_util_xml_get_attr (xml_utils, a, "href")); + char *href = mg_util_xml_get_attr (xml_utils, a, "href"); + char *result = mg_util_regex_match_1 (regex_util, re_str, href); + + g_free (href); + g_clear_object (®ex_util); + return result; } static void @@ -542,17 +597,14 @@ mg_backend_readmng_extract_manga_info_from_current_li (MgBackendReadmng *self, if (thumbnail && title && (img = mg_backend_readmng_retrieve_img_from_thumbnail (self, thumbnail)) - && a && (id_manga = mg_backend_get_id_manga_link (self, a))) { - g_list_store_append (mangas, - mg_manga_new (mg_util_xml_get_attr (xml_utils, img, "src"), - (char *)xmlNodeGetContent (title), id_manga)); - } + && a && (id_manga = mg_backend_readmng_get_id_manga_link (self, a))) { + char *src = mg_util_xml_get_attr (xml_utils, img, "src"); + char *title_string = (char *)xmlNodeGetContent (title); + g_list_store_append (mangas, mg_manga_new (src, title_string, id_manga)); - if (thumbnail) { - xmlFreeNode (thumbnail); - } - if (title) { - xmlFreeNode (title); + g_free (src); + g_free (title_string); + pcre2_substring_free ((PCRE2_UCHAR8 *) id_manga); } } diff --git a/src/chapter.c b/src/chapter.c index 1fedbec..854e0b6 100644 --- a/src/chapter.c +++ b/src/chapter.c @@ -67,6 +67,7 @@ mg_manga_chapter_new (const char *const title, strlen(published_text) + 1, 0, strlen (published_text)); + g_clear_object (&string_util); return self; } @@ -156,15 +157,21 @@ mg_manga_chapter_set_property (GObject *object, char * mg_manga_chapter_get_title (MgMangaChapter *self) { GValue value = G_VALUE_INIT; + char *return_value = NULL; g_value_init (&value, G_TYPE_STRING); g_object_get_property (G_OBJECT (self), "title", &value); - return g_value_dup_string (&value); + return_value = g_value_dup_string (&value); + g_value_unset (&value); + return return_value; } char * mg_manga_chapter_get_url (MgMangaChapter *self) { GValue value = G_VALUE_INIT; + char *return_value = NULL; g_value_init (&value, G_TYPE_STRING); g_object_get_property (G_OBJECT (self), "url", &value); - return g_value_dup_string (&value); + return_value = g_value_dup_string (&value); + g_value_unset (&value); + return return_value; } diff --git a/src/manga.c b/src/manga.c index 470fd96..8971639 100644 --- a/src/manga.c +++ b/src/manga.c @@ -41,11 +41,15 @@ mg_manga_get_property (GObject *object, GValue *value, GParamSpec *pspec); +static void +mg_manga_dispose (GObject *object); + static void mg_manga_class_init (MgMangaClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->set_property = mg_manga_set_property; object_class->get_property = mg_manga_get_property; + object_class->dispose = mg_manga_dispose; manga_properties[MG_MANGA_IMAGE_URL] = g_param_spec_string ("image_url", "ImageURL", @@ -86,6 +90,29 @@ mg_manga_init (MgManga *self) { self->has_details = 0; } +static void +mg_manga_dispose (GObject *object) { + MgManga *self = MG_MANGA (object); + if (self->description) { + g_free (self->description); + self->description = NULL; + } + if (self->title) { + g_free (self->title); + self->title = NULL; + } + if (self->id) { + g_free (self->id); + self->id = NULL; + } + if (self->image_url) { + g_free (self->image_url); + self->image_url = NULL; + } + + g_clear_object (&(self->chapter_list)); +} + int mg_manga_has_details (MgManga *self) { return self->has_details; @@ -138,11 +165,14 @@ mg_manga_get_title (MgManga *self) { char * mg_manga_get_description (MgManga *self) { GValue value = G_VALUE_INIT; + char *result; g_value_init (&value, G_TYPE_STRING); g_object_get_property (G_OBJECT (self), "description", &value); - return g_value_dup_string (&value); + result = g_value_dup_string (&value); + g_value_unset (&value); + return result; } GListStore * @@ -159,6 +189,8 @@ mg_manga_get_chapter_list (MgManga *self) { "chapter_list", &value); return_value = G_LIST_STORE (g_value_peek_pointer (&value)); + g_object_ref (G_OBJECT (return_value)); + g_value_unset (&value); return return_value; } @@ -169,14 +201,17 @@ mg_manga_set_description (MgManga *self, const char *description) { g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, description); g_object_set_property (G_OBJECT (self), "description", &value); + g_value_unset (&value); } void mg_manga_set_chapter_list (MgManga *self, GListStore *chapter_list) { GValue value = G_VALUE_INIT; + g_object_ref (G_OBJECT (chapter_list)); g_value_init (&value, G_TYPE_LIST_STORE); g_value_set_instance (&value, chapter_list); g_object_set_property (G_OBJECT (self), "chapter_list", &value); + g_value_unset (&value); } static void @@ -260,5 +295,6 @@ mg_manga_new (const char *const image_url, const char *const title, const char * title, self->title, strlen(title) + 1, 0, strlen (title)); mg_util_string_copy_substring (string_util, id, self->id, strlen(id) + 1, 0, strlen (id)); + g_clear_object (&string_util); return self; } diff --git a/src/util/regex.c b/src/util/regex.c index d61d43b..078ec7c 100644 --- a/src/util/regex.c +++ b/src/util/regex.c @@ -125,6 +125,7 @@ mg_util_regex_iterate_string_to_split (MgUtilRegex *self, *offset += 1; cleanup_iterate_string_to_split: + g_clear_object (&string_util); pcre2_match_data_free (match_data); } diff --git a/src/util/soup.c b/src/util/soup.c index e273a05..429480c 100644 --- a/src/util/soup.c +++ b/src/util/soup.c @@ -48,8 +48,8 @@ mg_util_soup_get_request (MgUtilSoup *self, const char *url, gsize *size_respons char *return_value = mg_util_soup_copy_binary_data(self, html_response, *size_response_text); g_value_unset (&response); - g_object_unref (soup_session); - g_object_unref (msg); + g_clear_object (&soup_session); + g_clear_object (&msg); return return_value; } diff --git a/src/util/xml.c b/src/util/xml.c index a1465c8..73d81dc 100644 --- a/src/util/xml.c +++ b/src/util/xml.c @@ -86,6 +86,7 @@ mg_util_xml_get_attr (MgUtilXML *self, xmlNodePtr const node, const char *attr_n break; } } + g_clear_object (&string_util); return return_value; } @@ -120,6 +121,7 @@ mg_util_xml_has_class (MgUtilXML *self, cleanup_has_class: mg_util_regex_splitted_string_free (regex_util, classes); + g_clear_object (®ex_util); return return_value; } @@ -161,6 +163,7 @@ mg_util_xml_get_title_text (MgUtilXML *self, xmlNodePtr text_content = NULL; xmlDocSetRootElement (document, root_node); char *size_text = NULL; + char *result; size_text = g_malloc (sizeof *size_text * 2000); text_content = xmlNewText ((xmlChar *) text); @@ -168,7 +171,12 @@ mg_util_xml_get_title_text (MgUtilXML *self, snprintf (size_text, 2000, "%d", 30 * PANGO_SCALE); xmlNewProp (root_node, (xmlChar *) "size", (xmlChar *) size_text); - return mg_util_xml_get_as_char_node (self, root_node, document); + result = mg_util_xml_get_as_char_node (self, root_node, document); + + g_free (size_text); + xmlFreeDoc (document); + + return result; } static char * diff --git a/src/view/chapter_view.c b/src/view/chapter_view.c index cc5efa9..c109ab9 100644 --- a/src/view/chapter_view.c +++ b/src/view/chapter_view.c @@ -80,6 +80,8 @@ setup_chapter_view (MgMangaChapter *chapter, AdwLeaflet *views_leaflet) { add_controls_overlay (overlay, chapter_visor_data); gtk_box_append (chapter_view_container, GTK_WIDGET (overlay)); append_chapter_view_leaflet (views_leaflet, chapter_view_container); + + g_clear_object (&readmng); } static void @@ -141,6 +143,9 @@ set_image_zoomable_picture_container (ChapterVisorData *chapter_visor_data) { g_signal_connect (G_OBJECT (current_picture), "map", G_CALLBACK (image_page_show), views_leaflet); gtk_scrolled_window_set_child (zoomable_picture_container, GTK_WIDGET (current_picture)); + + g_free (url_image); + g_clear_object (&string_util); } static void diff --git a/src/view/detail_manga.c b/src/view/detail_manga.c index 7f9544d..b816338 100644 --- a/src/view/detail_manga.c +++ b/src/view/detail_manga.c @@ -29,7 +29,7 @@ reverse_list (GtkButton *reverse_button, GtkSingleSelection *new_selection = gtk_single_selection_new (G_LIST_MODEL (new_model)); gtk_list_view_set_model (list_view, GTK_SELECTION_MODEL (new_selection)); - g_object_unref (G_OBJECT (model)); + g_clear_object (&model); } static void @@ -62,8 +62,8 @@ create_detail_view (MgManga *manga, AdwLeaflet *views_leaflet) { GtkButton *reverse_list_button = GTK_BUTTON (gtk_button_new_from_icon_name ("network-transmit-receive-symbolic")); GtkListView *chapter_list = NULL; - GtkPicture *manga_image = create_picture_from_url ( - mg_manga_get_image_url(manga), 200); + char *url_image = mg_manga_get_image_url(manga); + GtkPicture *manga_image = create_picture_from_url (url_image, 200); char *manga_title_text = mg_manga_get_title (manga); char *title_text = mg_util_xml_get_title_text ( xml_util, manga_title_text); @@ -105,6 +105,7 @@ create_detail_view (MgManga *manga, AdwLeaflet *views_leaflet) { gtk_box_append (detail_view, GTK_WIDGET (reverse_list_button)); g_clear_object (&readmng); + g_free (url_image); g_free (manga_title_text); g_free (title_text); g_free (description_text); diff --git a/src/view/list_view_chapter.c b/src/view/list_view_chapter.c index 3344662..3789f25 100644 --- a/src/view/list_view_chapter.c +++ b/src/view/list_view_chapter.c @@ -44,8 +44,8 @@ setup_list_view_chapter_list (GtkSignalListItemFactory *factory, gpointer user_data) { MgMangaChapter *manga_chapter = gtk_list_item_get_item (list_item); GtkBox *box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); - g_object_ref (G_OBJECT (box)); - GtkLabel *title = GTK_LABEL (gtk_label_new (mg_manga_chapter_get_title (manga_chapter))); + char *title_string = mg_manga_chapter_get_title (manga_chapter); + GtkLabel *title = GTK_LABEL (gtk_label_new (title_string)); GtkImage *icon = GTK_IMAGE (gtk_image_new_from_icon_name ( "weather-clear-night-symbolic")); gtk_image_set_icon_size (icon, GTK_ICON_SIZE_LARGE); @@ -53,6 +53,8 @@ setup_list_view_chapter_list (GtkSignalListItemFactory *factory, gtk_box_append (box, GTK_WIDGET (icon)); gtk_box_append (box, GTK_WIDGET (title)); gtk_list_item_set_child (list_item, GTK_WIDGET (box)); + + g_free (title_string); } static void diff --git a/src/view/list_view_manga.c b/src/view/list_view_manga.c index 1ba754e..829ec38 100644 --- a/src/view/list_view_manga.c +++ b/src/view/list_view_manga.c @@ -51,15 +51,17 @@ setup_list_view_mangas (GtkSignalListItemFactory *factory, MgManga *manga = gtk_list_item_get_item (list_item); GtkBox *box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); char *manga_title = mg_manga_get_title (manga); + char *image_url = mg_manga_get_image_url (manga); GtkWidget *label = gtk_label_new (manga_title); GtkWidget *picture = GTK_WIDGET ( - create_picture_from_url (mg_manga_get_image_url(manga), 200)); + create_picture_from_url (image_url, 200)); gtk_box_append (box, picture); gtk_box_append (box, label); gtk_list_item_set_child (list_item, GTK_WIDGET (box)); g_free (manga_title); + g_free (image_url); } GtkListView * diff --git a/src/view/picture.c b/src/view/picture.c index 0fcb8ae..fa93a5d 100644 --- a/src/view/picture.c +++ b/src/view/picture.c @@ -21,13 +21,14 @@ create_picture_from_url (char *url, gint picture_height) { tmp_image = g_file_new_tmp ("mangareadertmpfileXXXXXX", &iostream, &error); if (error) { fprintf (stderr, "Unable to read file: %s\n", error->message); + g_clear_error (&error); goto cleanup_create_picture_from_url; } - error = NULL; g_output_stream_write (g_io_stream_get_output_stream (G_IO_STREAM (iostream)), downloaded_image, size_downloaded_image, NULL, &error); if (error) { fprintf (stderr, "Unable to write file: %s\n", error->message); + g_clear_error (&error); goto cleanup_create_picture_from_url; } picture = GTK_PICTURE (gtk_picture_new_for_file (tmp_image)); @@ -36,5 +37,7 @@ create_picture_from_url (char *url, gint picture_height) { cleanup_create_picture_from_url: g_free (downloaded_image); g_clear_object (&util_soup); + g_clear_object (&iostream); + g_clear_object (&tmp_image); return picture; }