From bda2f34a970dc7542d4def69e08abc6c82c4e959 Mon Sep 17 00:00:00 2001 From: Michael Rasmussen Date: Sun, 27 Jan 2019 12:21:37 +0100 Subject: [PATCH] Refactor http class to prevent memory leak Signed-off-by: Michael Rasmussen --- src/plugins/litehtml_viewer/http.cpp | 20 +++++++++++--------- src/plugins/litehtml_viewer/http.h | 3 ++- src/plugins/litehtml_viewer/lh_widget.cpp | 11 ++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/plugins/litehtml_viewer/http.cpp b/src/plugins/litehtml_viewer/http.cpp index 7472bd7ab..bed56383c 100644 --- a/src/plugins/litehtml_viewer/http.cpp +++ b/src/plugins/litehtml_viewer/http.cpp @@ -22,11 +22,13 @@ http::http() curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http::curl_write_data); + stream = NULL; } http::~http() { curl_easy_cleanup(curl); + destroy_giostream(); } size_t http::curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_ptr) { @@ -48,12 +50,12 @@ size_t http::curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_pt return realsize; } -void http::destroy_giostream(gpointer data) { - GInputStream* gio; - if (data) { - gio = G_INPUT_STREAM(data); - g_input_stream_close(gio, NULL, NULL); - gio = NULL; +void http::destroy_giostream() { + debug_print("destroy_giostream called.\n"); + if (stream) { + debug_print("Freeing input_stream\n"); + g_input_stream_close(stream, NULL, NULL); + g_object_unref(stream); } } @@ -63,7 +65,6 @@ GInputStream *http::load_url(const gchar *url, GError **error) CURLcode res = CURLE_OK; gsize len; gchar* content; - GInputStream* stream = NULL; struct Data data; data.memory = (char *) g_malloc(1); @@ -72,7 +73,7 @@ GInputStream *http::load_url(const gchar *url, GError **error) if (!strncmp(url, "file:///", 8) || g_file_test(url, G_FILE_TEST_EXISTS)) { gchar* newurl = g_filename_from_uri(url, NULL, NULL); if (g_file_get_contents(newurl ? newurl : url, &content, &len, &_error)) { - stream = g_memory_input_stream_new_from_data(content, len, http::destroy_giostream); + stream = g_memory_input_stream_new_from_data(content, len, NULL); } else { debug_print("Got error: %s\n", _error->message); } @@ -86,7 +87,8 @@ GInputStream *http::load_url(const gchar *url, GError **error) _error = g_error_new_literal(G_FILE_ERROR, res, curl_easy_strerror(res)); } else { debug_print("Image size: %d\n", data.size); - stream = g_memory_input_stream_new_from_data(g_memdup(data.memory, data.size), data.size, http::destroy_giostream); + stream = g_memory_input_stream_new_from_data( + g_memdup(data.memory, data.size), data.size, NULL); g_free(data.memory); } } diff --git a/src/plugins/litehtml_viewer/http.h b/src/plugins/litehtml_viewer/http.h index c8c3bee64..d0ae4c84c 100644 --- a/src/plugins/litehtml_viewer/http.h +++ b/src/plugins/litehtml_viewer/http.h @@ -11,6 +11,7 @@ class http { CURL* curl; + GInputStream* stream; public: http(); @@ -20,7 +21,7 @@ public: private: static size_t curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_ptr); - static void destroy_giostream(gpointer data); + void destroy_giostream(); }; diff --git a/src/plugins/litehtml_viewer/lh_widget.cpp b/src/plugins/litehtml_viewer/lh_widget.cpp index c561e9c29..8db070cf3 100644 --- a/src/plugins/litehtml_viewer/lh_widget.cpp +++ b/src/plugins/litehtml_viewer/lh_widget.cpp @@ -92,7 +92,6 @@ lh_widget::lh_widget() GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); - } lh_widget::~lh_widget() @@ -153,6 +152,7 @@ GdkPixbuf *lh_widget::get_image(const litehtml::tchar_t* url, bool redraw_on_rea { GError *error = NULL; GdkPixbuf *pixbuf = NULL; + http* http_loader = NULL; if (!lh_prefs_get()->enable_remote_content) { debug_print("blocking download of image from '%s'\n", url); @@ -164,8 +164,8 @@ GdkPixbuf *lh_widget::get_image(const litehtml::tchar_t* url, bool redraw_on_rea lh_widget_statusbar_push(msg); g_free(msg); - http http_loader; - GInputStream *image = http_loader.load_url(url, &error); + http_loader = new http(); + GInputStream *image = http_loader->load_url(url, &error); if (error || !image) { if (error) { @@ -178,11 +178,9 @@ GdkPixbuf *lh_widget::get_image(const litehtml::tchar_t* url, bool redraw_on_rea pixbuf = gdk_pixbuf_new_from_stream(image, NULL, &error); if (error) { g_warning("lh_widget::get_image: Could not create pixbuf %s", error->message); - //g_object_unref(pixbuf); pixbuf = NULL; g_clear_error(&error); } - g_input_stream_close(image, NULL, NULL); /* if (redraw_on_ready) { redraw(); @@ -190,6 +188,9 @@ GdkPixbuf *lh_widget::get_image(const litehtml::tchar_t* url, bool redraw_on_rea statusbar_pop: lh_widget_statusbar_pop(); + if (http_loader) { + delete http_loader; + } return pixbuf; } -- 2.25.1