Cleaner code a fix memory leak
authorMichael Rasmussen <mir@datanom.net>
Wed, 7 Nov 2018 23:45:52 +0000 (00:45 +0100)
committerAndrej Kacian <ticho@claws-mail.org>
Tue, 12 Feb 2019 18:38:09 +0000 (19:38 +0100)
Signed-off-by: Michael Rasmussen <mir@datanom.net>
src/plugins/litehtml_viewer/http.cpp
src/plugins/litehtml_viewer/http.h

index 46882e1c37270f3d00b7908968552116536df37f..2a8709a1c0cf4f5934314b4486ad76cffbe6be3e 100644 (file)
@@ -1,5 +1,10 @@
 #include "http.h"
 
+struct Data {
+  char *memory;
+  size_t size;
+};
+
 http::http()
 {
     curl = curl_easy_init();
@@ -10,28 +15,30 @@ 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);
-    response_data = NULL;
-    response_size = 0;;
 }
 
 http::~http()
 {
     curl_easy_cleanup(curl);
-    if (response_data) {
-        g_free(response_data);
-    }
 }
 
-size_t http::curl_write_data(char* ptr, size_t size, size_t nmemb, void* data) {
-       if (!response_data)
-               response_data = (char *) malloc(size * nmemb);
-       else
-               response_data = (char *) realloc(response_data, response_size + size * nmemb);
-       if (response_data) {
-               memcpy(response_data + response_size, ptr, size * nmemb);
-               response_size += size * nmemb;
-       }
-       return size * nmemb;
+size_t http::curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_ptr) {
+    struct Data* data = (struct Data *) data_ptr;
+    size_t realsize = size * nmemb;
+    
+    char *input = (char *) realloc(data->memory, data->size + realsize + 1);
+    if(ptr == NULL) {
+        /* out of memory! */
+        g_log(NULL, G_LOG_LEVEL_ERROR, "not enough memory (realloc returned NULL)");
+        return 0;
+    }
+    
+    data->memory = input;
+    memcpy(&(data->memory[data->size]), ptr, realsize);
+    data->size += realsize;
+    data->memory[data->size] = 0;
+    
+    return realsize;
 }
 
 void http::destroy_giostream(gpointer data) {
@@ -50,8 +57,11 @@ GInputStream *http::load_url(const gchar *url, GError **error)
        gsize len;
        gchar* content;
     GInputStream* stream = NULL;
+    struct Data data;
 
-
+    data.memory = (char *) malloc(1);
+    data.size = 0;
+    
        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)) {
@@ -64,11 +74,13 @@ GInputStream *http::load_url(const gchar *url, GError **error)
                if (!curl) return NULL;
            curl_easy_setopt(curl, CURLOPT_URL, url);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_data);
+           curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&data);
            res = curl_easy_perform(curl);
            if (res != CURLE_OK) {
                    _error = g_error_new_literal(G_FILE_ERROR, res, curl_easy_strerror(res));
            } else {
-               stream = g_memory_input_stream_new_from_data(response_data, response_size, http::destroy_giostream);
+               stream = g_memory_input_stream_new_from_data(g_memdup(data.memory, data.size), data.size, http::destroy_giostream);
+               g_free(data.memory);
            }
        }
 
index 4c4b03f725171387d94003bc274b3e0204bcc4c3..c8c3bee6492aeb2189a63f18a797da9401561639 100644 (file)
@@ -11,8 +11,6 @@
 class http
 {
     CURL*           curl;
-    static gchar*   response_data;
-    static size_t   response_size;
 
 public:
     http();
@@ -21,7 +19,7 @@ public:
     GInputStream *load_url(const gchar *url, GError **error);
 
 private:
-    static size_t curl_write_data(char* ptr, size_t size, size_t nmemb, void* data);
+    static size_t curl_write_data(char* ptr, size_t size, size_t nmemb, void* data_ptr);
     static void destroy_giostream(gpointer data);
 };