# HG changeset patch # User Olaf Wintermann # Date 1423409792 -3600 # Node ID da079dc0724c7f241b3f500cbc456e34680b30bd # Parent 41e88442ad4e1984cb7b1ad970f8874db9e91f34 fixed many memory leaks diff -r 41e88442ad4e -r da079dc0724c dav/config.c --- 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)); diff -r 41e88442ad4e -r da079dc0724c dav/config.h --- 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); diff -r 41e88442ad4e -r da079dc0724c dav/main.c --- 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; } diff -r 41e88442ad4e -r da079dc0724c dav/optparser.c --- 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) { diff -r 41e88442ad4e -r da079dc0724c dav/optparser.h --- 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 diff -r 41e88442ad4e -r da079dc0724c libidav/davql.c --- 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;iproperties = 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); } diff -r 41e88442ad4e -r da079dc0724c libidav/methods.c --- 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("\n\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); } diff -r 41e88442ad4e -r da079dc0724c libidav/resource.c --- 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); diff -r 41e88442ad4e -r da079dc0724c libidav/session.c --- 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); diff -r 41e88442ad4e -r da079dc0724c libidav/utils.c --- 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;isessions = 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;jproperties, 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