fixed some memory leaks in dav-sync pull

Fri, 18 Mar 2016 19:54:36 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 18 Mar 2016 19:54:36 +0100
changeset 222
7b73058d782e
parent 221
e22c29b7ee2f
child 223
cbbdf207e67e

fixed some memory leaks in dav-sync pull

dav/config.c file | annotate | diff | comparison | revisions
dav/db.c file | annotate | diff | comparison | revisions
dav/db.h file | annotate | diff | comparison | revisions
dav/scfg.c file | annotate | diff | comparison | revisions
dav/sopt.c file | annotate | diff | comparison | revisions
dav/sopt.h file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
libidav/resource.c file | annotate | diff | comparison | revisions
libidav/session.c file | annotate | diff | comparison | revisions
--- a/dav/config.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/config.c	Fri Mar 18 19:54:36 2016 +0100
@@ -147,6 +147,9 @@
         if(repo->user) {
             free(repo->user);
         }
+        if(repo->cert) {
+            free(repo->cert);
+        }
         free(repo);
     }
     ucx_map_free(repos);
--- a/dav/db.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/db.c	Fri Mar 18 19:54:36 2016 +0100
@@ -325,3 +325,27 @@
     xmlFreeTextWriter(writer);
     return 0;
 }
+
+void destroy_db(SyncDatabase *db) {
+    ucx_map_free_content(db->resources, (ucx_destructor)local_resource_free);
+    ucx_map_free_content(db->conflict, (ucx_destructor)local_resource_free);
+    ucx_map_free(db->resources);
+    ucx_map_free(db->conflict);
+    free(db);
+}
+
+void local_resource_free(LocalResource *res) {
+    if(!res) {
+        return;
+    }
+    if(res->name) {
+        free(res->name);
+    }
+    if(res->path) {
+        free(res->path);
+    }
+    if(res->etag) {
+        free(res->etag);
+    }
+    free(res);
+}
--- a/dav/db.h	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/db.h	Fri Mar 18 19:54:36 2016 +0100
@@ -53,12 +53,14 @@
 
 struct SyncDatabase {
     UcxMap *resources;
-    //UcxMap *remove;
     UcxMap *conflict;
 };
 
 SyncDatabase* load_db(char *name);
 int store_db(SyncDatabase *db, char *name);
+void destroy_db(SyncDatabase *db);
+
+void local_resource_free(LocalResource *res);
 
 LocalResource* process_resource(xmlTextReaderPtr reader);
 LocalResource* process_conflict(xmlTextReaderPtr reader);
--- a/dav/scfg.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/scfg.c	Fri Mar 18 19:54:36 2016 +0100
@@ -79,12 +79,14 @@
                 perror("Cannot load sync.xml");
             }
         }
+        free(file);
         return 0;
     }
     
     xmlDoc *doc = xmlReadFile(file, NULL, 0);
     if(!doc) {
         fprintf(stderr, "Broken configuration file\n");
+        free(file);
         return -1;
     }
     
@@ -104,7 +106,7 @@
     }
     
     xmlFreeDoc(doc);
-    
+    free(file);
     return ret;
 }
 
--- a/dav/sopt.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/sopt.c	Fri Mar 18 19:54:36 2016 +0100
@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "optparser.h"
+#include "sopt.h"
 
 void cmd_args_free(CmdArgs *args) {
     if(args) {
--- a/dav/sopt.h	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/sopt.h	Fri Mar 18 19:54:36 2016 +0100
@@ -41,6 +41,7 @@
     int    argc;
 } CmdArgs;
 
+void cmd_args_free(CmdArgs *args);
 CmdArgs* cmd_parse_args(int argc, char **argv);
 char* cmd_getoption(CmdArgs *arg, char *name);
 
--- a/dav/sync.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/dav/sync.c	Fri Mar 18 19:54:36 2016 +0100
@@ -90,6 +90,8 @@
         memcpy(ctx->https_proxy, get_https_proxy(), sizeof(Proxy));
         
         if(load_sync_config()) {
+            cmd_args_free(args);
+            dav_context_destroy(ctx);
             return EXIT_FAILURE;
         }
     }
@@ -113,6 +115,10 @@
     }
     
     // TODO: cleanup sync config (don't forget to call regfree for regex)
+    cmd_args_free(args);
+    dav_context_destroy(ctx);
+    
+    free_config();
     
     return ret;
 }
@@ -208,6 +214,7 @@
     SyncDatabase *db = load_db(dir->database);
     if(!db) {
         fprintf(stderr, "Cannot load database file: %s\n", dir->database);
+        destroy_db(db);
         return -1;
     }
     remove_deleted_conflicts(dir, db);
@@ -217,6 +224,7 @@
         new_url = util_concat_path(repo->url, dir->collection);
     }
     DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url);
+    ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db);
     if(new_url) {
         free(new_url);
     }
@@ -400,6 +408,7 @@
             }
             if(!strcmp(e.ptr, local->etag)) {
                 // resource is already up-to-date on the client
+                free(local_path);
                 return 0;
             }
         }
@@ -491,7 +500,7 @@
                 free(local->etag);
             }
             // set metadata from stat
-            local->etag = etag;
+            local->etag = strdup(etag);
             local->last_modified = s.st_mtime;
             local->size = s.st_size;
         } else {
@@ -695,6 +704,7 @@
         new_url = util_concat_path(repo->url, dir->collection);
     }
     DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url);
+    ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db);
     if(new_url) {
         free(new_url);
     }
@@ -743,6 +753,7 @@
             if(res_isconflict(db, local_res)) {
                 printf("skip: %s\n", local_res->path);
                 sync_skipped++;
+                local_resource_free(local_res);
                 continue;
             }
             
@@ -766,6 +777,7 @@
                     if(cdt && remote_resource_is_changed(sn, dir, db, local_res)) {
                         printf("conflict: %s\n", local_res->path);
                         sync_skipped++;
+                        local_resource_free(local_res);
                         continue;
                     }
                     
@@ -783,7 +795,10 @@
             // remove every locally available resource from db->resource
             // the remaining elements are all deleted files
             ucx_map_cstr_put(lclres, local_res->path, local_res);
-            ucx_map_cstr_remove(db->resources, local_res->path); // TODO: element leaked
+            LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path);
+            if(lr) {
+                local_resource_free(lr);
+            }
         }
     }
     ucx_list_free(resources);
@@ -824,6 +839,7 @@
     
     // cleanup
     dav_session_destroy(sn);
+    ucx_list_free(resources); // content is already freed
     
     // Report
     if(ret == 0) {
@@ -1194,6 +1210,8 @@
     for(int i=0;i<numdc;i++) {
         ucx_map_cstr_remove(db->conflict, dc[i]);
     }
+    
+    free(dc);
 }
 
 int cmd_resolve_conflicts(CmdArgs *a) {
@@ -1214,6 +1232,8 @@
         return -1;
     }
     
+    int ret = 0;
+    
     // remove conflicts
     int num_conflict = db->conflict->count;
     //TODO: ucx_map_free_content(db->conflict, destr);
@@ -1223,14 +1243,17 @@
     if(store_db(db, dir->database)) {
         fprintf(stderr, "Cannot store sync db\n");
         fprintf(stderr, "Abort\n");
-        return -1; // TODO: don't return here
+        ret = -1;
     }
+    destroy_db(db);
     
     // Report
-    char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts";
-    printf("Result: %d %s resolved\n", num_conflict, str_conflict);
+    if(ret == 0) {
+        char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts";
+        printf("Result: %d %s resolved\n", num_conflict, str_conflict);
+    }
     
-    return 0;
+    return ret;
 }
 
 int cmd_delete_conflicts(CmdArgs *a) {
@@ -1254,6 +1277,8 @@
     int num_del = 0;
     int num_err = 0;
     
+    int ret = 0;
+    
     // delete all conflict files
     UcxMapIterator i = ucx_map_iterator(db->conflict);
     LocalResource *res;
@@ -1277,17 +1302,20 @@
     if(store_db(db, dir->database)) {
         fprintf(stderr, "Cannot store sync db\n");
         fprintf(stderr, "Abort\n");
-        return -1; // TODO: don't return here
+        ret = -1;
     }
+    destroy_db(db);
     
     // Report
-    char *str_delete = num_del == 1 ? "file" : "files";
-    char *str_error = num_err == 1 ? "error" : "errors";
-    printf("Result: %d conflict %s deleted, %d %s\n",
-            num_del, str_delete,
-            num_err, str_error);
+    if(ret == 0) {
+        char *str_delete = num_del == 1 ? "file" : "files";
+        char *str_error = num_err == 1 ? "error" : "errors";
+        printf("Result: %d conflict %s deleted, %d %s\n",
+                num_del, str_delete,
+                num_err, str_error);
+    }
     
-    return 0;
+    return ret;
 }
 
 
--- a/libidav/resource.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/libidav/resource.c	Fri Mar 18 19:54:36 2016 +0100
@@ -953,14 +953,18 @@
     //printf("%.*s\n\n", request->size, request->space);
     //printf("%.*s\n\n", response->size, response->space);
     
+    ucx_buffer_free(request);
+    
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && (status >= 200 && status < 300)) {
         LockDiscovery lock;
         if(parse_lock_response(sn, response, &lock)) {
             sn->error = DAV_ERROR;
+            ucx_buffer_free(response);
             return -1;
         }
+        ucx_buffer_free(response);
         
         DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout);
         free(lock.locktoken);
@@ -983,6 +987,7 @@
         }
     } else {
         dav_session_set_error(sn, ret, status);
+        ucx_buffer_free(response);
         return -1;
     }
 }
--- a/libidav/session.c	Fri Mar 18 15:08:30 2016 +0100
+++ b/libidav/session.c	Fri Mar 18 19:54:36 2016 +0100
@@ -57,7 +57,7 @@
         sstr_t url = sstrdup_a(sn->mp->allocator, sstr(base_url));
         sn->base_url = url.ptr;
     } else {
-        char *url_str = malloc(url.length + 2);
+        char *url_str = ucx_mempool_malloc(sn->mp, url.length + 2);
         memcpy(url_str, base_url, url.length);
         url_str[url.length]     = '/';
         url_str[url.length + 1] = '\0';

mercurial