fixed many memory leaks

Sun, 08 Feb 2015 16:36:32 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 08 Feb 2015 16:36:32 +0100
changeset 74
da079dc0724c
parent 73
41e88442ad4e
child 75
56962faf2b42

fixed many memory leaks

dav/config.c file | annotate | diff | comparison | revisions
dav/config.h file | annotate | diff | comparison | revisions
dav/main.c file | annotate | diff | comparison | revisions
dav/optparser.c file | annotate | diff | comparison | revisions
dav/optparser.h file | annotate | diff | comparison | revisions
libidav/davql.c file | annotate | diff | comparison | revisions
libidav/methods.c file | annotate | diff | comparison | revisions
libidav/resource.c file | annotate | diff | comparison | revisions
libidav/session.c file | annotate | diff | comparison | revisions
libidav/utils.c file | annotate | diff | comparison | revisions
libidav/webdav.c file | annotate | diff | comparison | revisions
suncc.mk file | annotate | diff | comparison | revisions
--- a/dav/config.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/dav/config.c	Sun Feb 08 16:36:32 2015 +0100
@@ -109,6 +109,33 @@
     xmlFreeDoc(doc);
 }
 
+void free_config() {
+    UcxMapIterator i = ucx_map_iterator(repos);
+    UcxKey k;
+    Repository *repo;
+    UCX_MAP_FOREACH(k, repo, i) {
+        if(repo->default_key) {
+            free(repo->default_key);
+        }
+        if(repo->name) {
+            free(repo->name);
+        }
+        if(repo->password) {
+            free(repo->password);
+        }
+        if(repo->url) {
+            free(repo->url);
+        }
+        if(repo->user) {
+            free(repo->user);
+        }
+        free(repo);
+    }
+    ucx_map_free(repos);
+    
+    ucx_map_free(keys);
+}
+
 void load_repository(xmlNode *reponode) {
     xmlNode *node = reponode->children;
     Repository *repo = calloc(1, sizeof(Repository));
--- a/dav/config.h	Thu Jan 29 11:43:41 2015 +0100
+++ b/dav/config.h	Sun Feb 08 16:36:32 2015 +0100
@@ -73,6 +73,7 @@
 };
     
 void load_config(DavContext *ctx);
+void free_config();
 void load_repository(xmlNode *reponode);
 void load_key(xmlNode *keynode);
 void load_proxy(xmlNode *proxynode, int type);
--- a/dav/main.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/dav/main.c	Sun Feb 08 16:36:32 2015 +0100
@@ -61,7 +61,6 @@
     ctx = dav_context_new();
     load_config(ctx);
     //dav_add_namespace(ctx, "U", "http://www.uap-core.de/");
-    
     //test();
     
     memcpy(ctx->http_proxy, get_http_proxy(), sizeof(Proxy));
@@ -77,6 +76,7 @@
     CmdArgs *args = cmd_parse_args(argc - 2, argv + 2);
     if(!args) {
         print_usage(argv[0]);
+        cmd_args_free(args);
         return -1;
     }
     
@@ -104,7 +104,12 @@
     } else {
         print_usage(argv[0]);
     }
+    
     dav_context_destroy(ctx);
+    cmd_args_free(args);
+    free_config();
+    xmlCleanupParser();
+    curl_global_cleanup();
     
     return ret;
 }
@@ -364,6 +369,8 @@
     free(path);
     //free(base);
     
+    dav_session_destroy(sn);
+    
     return ret;
 }
 
@@ -585,6 +592,7 @@
     
     int ret = get_resource(repo, res, a, outfile);
     
+    free(path);
     return ret;
 }
 
@@ -677,6 +685,7 @@
         ret = put_entry(repo, a, sn, path, file); 
     }
     
+    free(path);
     return ret;
 }
 
@@ -756,9 +765,9 @@
     } else if(res->iscollection) {
         // TODO: free res
         char *newpath = util_concat_path(path, name);
-        free(path);
         path = newpath;
         res = dav_resource_new(sn, path);
+        free(newpath);
         int ret = put_file(repo, a, sn, res->path, NULL, in);
         // TODO: free res
         return ret;
@@ -805,6 +814,7 @@
         return -1;
     }
     
+    free(path);
     return 0;
 }
 
@@ -849,6 +859,7 @@
         return -1;
     }
     
+    free(path);
     return 0;
 }
 
@@ -888,6 +899,7 @@
         } else {
             return -1;
         }
+        free(path);
         return 0;
     } else {
         fprintf(stderr, "Too many arguments\n");
@@ -936,6 +948,7 @@
         ret = -1;
     }
     
+    free(path);
     return ret;
 }
 
@@ -975,6 +988,7 @@
         return -1;
     }
     
+    free(path);
     return 0;
 }
 
--- a/dav/optparser.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/dav/optparser.c	Sun Feb 08 16:36:32 2015 +0100
@@ -35,6 +35,7 @@
 void cmd_args_free(CmdArgs *args) {
     ucx_map_free(args->options);
     free(args->argv);
+    free(args);
 }
 
 CmdArgs* cmd_parse_args(int argc, char **argv) {
--- a/dav/optparser.h	Thu Jan 29 11:43:41 2015 +0100
+++ b/dav/optparser.h	Sun Feb 08 16:36:32 2015 +0100
@@ -44,6 +44,8 @@
 CmdArgs* cmd_parse_args(int argc, char **argv);
 char* cmd_getoption(CmdArgs *arg, char *name);
 
+void cmd_args_free(CmdArgs *args);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/libidav/davql.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/davql.c	Sun Feb 08 16:36:32 2015 +0100
@@ -76,7 +76,7 @@
     int depth = 1;
        
     // insert variable values
-    UcxBuffer *fbuf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND);
+    UcxBuffer *fbuf = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
     int var = 0;
     for(int i=0;i<from_query.length;i++) {
         char c = from_query.ptr[i];
@@ -137,7 +137,7 @@
     
     DavGetQuery *getquery = malloc(sizeof(DavGetQuery));
     getquery->properties = sstrdup(property_query);
-    getquery->from = sstrn(fbuf->space, fbuf->pos);
+    getquery->from = sstrdup(sstrn(fbuf->space, fbuf->pos));
     getquery->depth = depth;
     if(condition) {
         getquery->condition = condition;
@@ -146,12 +146,17 @@
         getquery->condition = NULL;
         getquery->condlen = 0;
     }
+    
+    ucx_buffer_free(fbuf);
     return getquery;
 }
 
 void free_get_query(DavGetQuery *q) {
     free(q->from.ptr);
     free(q->properties.ptr);
+    if(q->condition) {
+        free(q->condition);
+    }
     free(q);
 }
 
--- a/libidav/methods.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/methods.c	Sun Feb 08 16:36:32 2015 +0100
@@ -63,7 +63,9 @@
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
     
     ucx_buffer_seek(request, 0, SEEK_SET);
-    return curl_easy_perform(handle);
+    CURLcode ret = curl_easy_perform(handle);
+    curl_slist_free_all(headers);
+    return ret;
 }
 
 UcxBuffer* create_allprop_propfind_request() {
@@ -188,6 +190,7 @@
     s = S("</D:prop>\n</D:propfind>\n");
     ucx_buffer_write(s.ptr, 1, s.length, buf);
     
+    ucx_map_free(namespaces);
     return buf;
 }
 
@@ -248,9 +251,9 @@
                 parse_response_tag(root, node, cond, len);
             }
         }
-        
         node = node->next;
     }
+    xmlFreeDoc(doc);
     
     return root;
 }
@@ -395,6 +398,7 @@
             resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, text);
         }
     }
+    ucx_list_free(properties);
     
     set_davprops(res);
     if(res != resource) {
@@ -450,7 +454,9 @@
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
     
     ucx_buffer_seek(request, 0, SEEK_SET);
-    return curl_easy_perform(handle);
+    CURLcode ret = curl_easy_perform(handle);
+    curl_slist_free_all(headers);
+    return ret;
 }
 
 UcxBuffer* create_proppatch_request(DavResourceData *data) {
@@ -619,7 +625,6 @@
         read_func = (dav_read_func)ucx_buffer_read;
         curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)length);
     } else if(length == 0) {
-        struct curl_slist *headers = NULL;
         headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
         curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)1);
         curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
@@ -634,6 +639,7 @@
     curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
     
     CURLcode ret = curl_easy_perform(handle);
+    curl_slist_free_all(headers);
     if(buf) {
         ucx_buffer_free(buf);
     }
--- a/libidav/resource.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/resource.c	Sun Feb 08 16:36:32 2015 +0100
@@ -90,7 +90,6 @@
     
     char *path = util_concat_path(parent_path, name); 
     res->path = dav_session_strdup(sn, path);
-    free(path);
     
     res->href = href;
     
@@ -101,6 +100,7 @@
     if(href) {
         dav_session_cache_path(sn, sstr(path), sstr(href));
     }
+    free(path);
     
     return res;
 }
@@ -488,6 +488,7 @@
         }
     }
     
+    curl_easy_setopt(handle, CURLOPT_HTTPHEADER, NULL);
     curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, NULL);
     curl_easy_setopt(handle, CURLOPT_PUT, 0L);
--- a/libidav/session.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/session.c	Sun Feb 08 16:36:32 2015 +0100
@@ -158,7 +158,7 @@
     // remove session from context
     UcxList *sessions = sn->context->sessions;
     ssize_t i = ucx_list_find(sessions, sn, ucx_ptrcmp, NULL);
-    if(i > 0)  {
+    if(i >= 0)  {
         UcxList *elm = ucx_list_get(sessions, i);
         if(elm) {
             sn->context->sessions = ucx_list_remove(sessions, elm);
@@ -245,7 +245,7 @@
         UcxBuffer *rqbuf = create_basic_propfind_request();
         
         sstr_t remaining = sstrsubs(p, start);
-        size_t nelm = 0;
+        ssize_t nelm = 0;
         sstr_t *elms = sstrsplit(remaining, S("/"), &nelm);
         DavResource *res = root;
         ucx_buffer_puts(pbuf, res->path);
--- a/libidav/utils.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/utils.c	Sun Feb 08 16:36:32 2015 +0100
@@ -204,7 +204,7 @@
     ucx_buffer_seek(url, -1, SEEK_CUR);
     
     sstr_t p = sstr(path);
-    size_t ntk = 0;
+    ssize_t ntk = 0;
     sstr_t *tks = sstrsplit(p, S("/"), &ntk);
     
     for(int i=0;i<ntk;i++) {
@@ -214,8 +214,8 @@
             ucx_buffer_putc(url, '/');
             ucx_buffer_write(esc, 1, strlen(esc), url);
             curl_free(esc);
-            free(node.ptr);
         }
+        free(node.ptr);
     }
     free(tks);
     if(path[p.length-1] == '/') {
--- a/libidav/webdav.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/webdav.c	Sun Feb 08 16:36:32 2015 +0100
@@ -41,68 +41,140 @@
 
 
 DavContext* dav_context_new() {
-    DavContext *context = malloc(sizeof(DavContext));
+    // initialize
+    DavContext *context = calloc(1, sizeof(DavContext));
     if(!context) {
         return NULL;
     }
     context->sessions = NULL;
     context->http_proxy = calloc(1, sizeof(DavProxy));
+    if(!context->http_proxy) {
+        dav_context_destroy(context);
+        return NULL;
+    }
     context->https_proxy = calloc(1, sizeof(DavProxy));
+    if(!context->https_proxy) {
+        dav_context_destroy(context);
+        return NULL;
+    }
     context->namespaces = ucx_map_new(16);
     if(!context->namespaces) {
-        free(context);
+        dav_context_destroy(context);
         return NULL;
     }
     context->keys = ucx_map_new(16);
-    DavNamespace *davns = malloc(sizeof(DavNamespace));
-    if(!davns) {
-        ucx_map_free(context->namespaces);
-        free(context);
-        return NULL;
-    }
-    davns->prefix = "D";
-    davns->name = "DAV:";
-    if(ucx_map_cstr_put(context->namespaces, "D", davns)) {
-        free(davns);
-        ucx_map_free(context->namespaces);
-        free(context);
+    if(!context->keys) {
+        dav_context_destroy(context);
         return NULL;
     }
     
-    DavNamespace *idavns = malloc(sizeof(DavNamespace));
-    if(!idavns) {
+    // add DAV: namespace
+    DavNamespace *davns = malloc(sizeof(DavNamespace));
+    if(!davns) {
         free(davns);
-        ucx_map_free(context->namespaces);
-        free(context);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    davns->prefix = strdup("D");
+    if(!davns->prefix) {
+        free(davns);
+        dav_context_destroy(context);
         return NULL;
     }
-    idavns->prefix = "idav";
-    idavns->name = DAV_NS;
-    if(ucx_map_cstr_put(context->namespaces, "idav", idavns)) {
+    davns->name = strdup("DAV:");
+    if(!davns->name) {
+        free(davns->prefix);
         free(davns);
-        free(idavns);
-        ucx_map_free(context->namespaces);
-        free(context);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    if(ucx_map_cstr_put(context->namespaces, "D", davns)) {
+        free(davns->prefix);
+        free(davns->name);
+        free(davns);
+        dav_context_destroy(context);
         return NULL;
     }
     
+    // add idav namespace
+    DavNamespace *idavns = malloc(sizeof(DavNamespace));
+    if(!idavns) {
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    idavns->prefix = strdup("idav");
+    if(!idavns->prefix) {
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    idavns->name = strdup(DAV_NS);
+    if(!idavns->name) {
+        free(idavns->prefix);
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    if(ucx_map_cstr_put(context->namespaces, "idav", idavns)) {
+        free(idavns->prefix);
+        free(idavns->name);
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
     
     return context;
 }
 
 void dav_context_destroy(DavContext *ctx) {
     // destroy all sessions assoziated with this context
-    UCX_FOREACH(elm, ctx->sessions) {
-        dav_session_destroy(elm->data);
+    UcxList *elm = ctx->sessions;
+    while(elm) {
+        DavSession *sn = elm->data;
+        elm = elm->next;
+        dav_session_destroy(sn);
     }
-    free(ctx->http_proxy);
-    free(ctx->https_proxy);
+    if(ctx->http_proxy) {
+        free(ctx->http_proxy);
+    }
+    if(ctx->https_proxy) {
+        free(ctx->https_proxy);
+    }
     
-    UcxMapIterator i = ucx_map_iterator(ctx->namespaces);
-    UcxKey k;
-    DavNamespace *ns;
-    // TODO: free map elements
-    ucx_map_free(ctx->namespaces);
+    if(ctx->namespaces) {
+        UcxMapIterator i = ucx_map_iterator(ctx->namespaces);
+        UcxKey k;
+        DavNamespace *ns;
+        UCX_MAP_FOREACH(k, ns, i) {
+            if(!ns) continue;
+            if(ns->prefix) {
+                free(ns->prefix);
+            }
+            if(ns->name) {
+                free(ns->name);
+            }
+            free(ns);
+        }
+        ucx_map_free(ctx->namespaces);
+    }
+    if(ctx->keys) {
+        UcxMapIterator i = ucx_map_iterator(ctx->keys);
+        UcxKey k;
+        DavKey *key;
+        UCX_MAP_FOREACH(k, key, i) {
+            if(!key) continue;
+            if(key->name) {
+                free(key->name);
+            }
+            if(key->data) {
+                free(key->data);
+            }
+            free(key);
+        }
+        ucx_map_free(ctx->keys);
+    }    
+    
     free(ctx);
 }
 
@@ -195,12 +267,19 @@
 int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, DavQOp *cond, size_t len) {
     // clean resource properties
     DavResourceData *data = root->data;
-    if(data->properties->count > 0) {
+    size_t pcount = data->properties->count;
+    if(pcount > 0) {
         UcxKey key;
         void *value;
         UcxMapIterator i = ucx_map_iterator(data->properties);
+        UcxKey mkeys[pcount];
+        int index = 0;
         UCX_MAP_FOREACH(key, value, i) {
-            ucx_map_remove(data->properties, key);
+            mkeys[index] = key;
+            index++;
+        }
+        for(int j=0;j<index;j++) {
+            ucx_map_remove(data->properties, mkeys[j]);
         }
     }
     
@@ -255,6 +334,12 @@
     } else {
         UcxList *proplist = parse_properties_string(sn->context, ps);
         rqbuf = create_propfind_request(sn, proplist);
+        UCX_FOREACH(elm, proplist) {
+            DavProperty *prop = elm->data;
+            free(prop->name);
+            free(prop);
+        }
+        ucx_list_free(proplist);
     }
     
     //fwrite(rqbuf->space, 1, rqbuf->size, stdout);
@@ -290,7 +375,7 @@
 
 UcxList* parse_properties_string(DavContext *context, sstr_t str) {
     UcxList *proplist = NULL;
-    size_t nprops = 0;
+    ssize_t nprops = 0;
     sstr_t *props = sstrsplit(str, S(","), &nprops);
     for(int i=0;i<nprops;i++) {
         sstr_t s = props[i];
--- a/suncc.mk	Thu Jan 29 11:43:41 2015 +0100
+++ b/suncc.mk	Sun Feb 08 16:36:32 2015 +0100
@@ -43,5 +43,5 @@
 APP_EXT =
 
 DAV_CFLAGS = `curl-config --cflags` `pkg-config --cflags openssl libxml-2.0`
-DAV_LDFLAGS = `curl-config --libs` `pkg-config --libs openssl libxml-2.0`
+DAV_LDFLAGS = `pkg-config --libs openssl libxml-2.0` `curl-config --libs` 
 

mercurial