Mon, 09 Aug 2021 17:22:21 +0200
fix dav-sync push creating finfo elements without using the mempool, which could lead to crashes
dav/finfo.c | file | annotate | diff | comparison | revisions | |
dav/version.h | file | annotate | diff | comparison | revisions | |
libidav/resource.c | file | annotate | diff | comparison | revisions | |
libidav/webdav.h | file | annotate | diff | comparison | revisions | |
libidav/xml.c | file | annotate | diff | comparison | revisions | |
test/bin-test/test-dav-sync-metadata1.sh | file | annotate | diff | comparison | revisions |
--- a/dav/finfo.c Sun Aug 08 16:50:36 2021 +0200 +++ b/dav/finfo.c Mon Aug 09 17:22:21 2021 +0200 @@ -101,7 +101,7 @@ char str[32]; struct tm *date = gmtime(&s->st_mtime); strftime(str, 32, "%a, %d %b %Y %H:%M:%S GMT", date); - DavXmlNode *mtime = dav_xml_createnode_with_text(DAV_PROPS_NS, "mtime", str); + DavXmlNode *mtime = dav_text_element(res->session, DAV_PROPS_NS, "mtime", str); content = mtime; last = mtime; } @@ -113,7 +113,7 @@ mode_t mode = s->st_mode & 07777; char str[32]; snprintf(str, 32, "%o", (int)mode); - DavXmlNode *xmode = dav_xml_createnode_with_text(DAV_PROPS_NS, "mode", str); + DavXmlNode *xmode = dav_text_element(res->session, DAV_PROPS_NS, "mode", str); if(last) { last->next = xmode; } else {
--- a/dav/version.h Sun Aug 08 16:50:36 2021 +0200 +++ b/dav/version.h Mon Aug 09 17:22:21 2021 +0200 @@ -27,6 +27,6 @@ */ #ifndef DAV_VERSION -#define DAV_VERSION "1.3.0" +#define DAV_VERSION "2.0 dev" #endif
--- a/libidav/resource.c Sun Aug 08 16:50:36 2021 +0200 +++ b/libidav/resource.c Mon Aug 09 17:22:21 2021 +0200 @@ -153,7 +153,7 @@ dav_session_free(sn, p->ns); dav_session_free(sn, p->name); - dav_session_free(sn, p->value); + dav_free_xml_node_sn(sn, p->value); dav_session_free(sn, p); } @@ -600,7 +600,9 @@ DavResourceData *data = res->data; DavProperty *property = createprop(sn, ns, name); - property->value = value; // TODO: copy node? + // TODO: this function should copy the value + // but we also need a function, that doesn't create a copy + property->value = value; if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) { data->crypto_set = ucx_list_append_a(a, data->crypto_set, property);
--- a/libidav/webdav.h Sun Aug 08 16:50:36 2021 +0200 +++ b/libidav/webdav.h Mon Aug 09 17:22:21 2021 +0200 @@ -362,10 +362,14 @@ char* dav_xml_getstring(DavXmlNode *node); DavBool dav_xml_isstring(DavXmlNode *node); DavXmlNode* dav_xml_nextelm(DavXmlNode *node); -DavXmlNode* dav_text_node(DavSession *sn, char *text); +DavXmlNode* dav_text_node(DavSession *sn, const char *text); +DavXmlNode* dav_text_element(DavSession *sn, const char *ns, const char *name, const char *text); DavXmlNode* dav_copy_node(DavXmlNode *node); +void dav_free_xml_node_sn(DavSession *sn, DavXmlNode *node); +void dav_free_xml_node(DavXmlNode *node); + DavXmlNode* dav_xml_createnode(const char *ns, const char *name); DavXmlNode* dav_xml_createnode_with_text(const char *ns, const char *name, const char *text); DavXmlNode* dav_xml_createtextnode(const char *text);
--- a/libidav/xml.c Sun Aug 08 16:50:36 2021 +0200 +++ b/libidav/xml.c Mon Aug 09 17:22:21 2021 +0200 @@ -240,16 +240,52 @@ return NULL; } -DavXmlNode* dav_text_node(DavSession *sn, char *text) { +DavXmlNode* dav_text_node(DavSession *sn, const char *text) { UcxMempool *mp = sn->mp; DavXmlNode *newxn = ucx_mempool_calloc(mp, 1, sizeof(DavXmlNode)); newxn->type = DAV_XML_TEXT; - sstr_t content = sstrdup_a(mp->allocator, sstr(text)); + sstr_t content = scstrdup_a(mp->allocator, scstr(text)); newxn->content = content.ptr; newxn->contentlength = content.length; return newxn; } +DavXmlNode* dav_text_element(DavSession *sn, const char *ns, const char *name, const char *text) { + UcxMempool *mp = sn->mp; + DavXmlNode *newelm = ucx_mempool_calloc(mp, 1, sizeof(DavXmlNode)); + newelm->type = DAV_XML_ELEMENT; + newelm->namespace = scstrdup_a(mp->allocator, scstr(ns)).ptr; + newelm->name = scstrdup_a(mp->allocator, scstr(name)).ptr; + newelm->children = dav_text_node(sn, text); + return newelm; +} + +static void dav_free_xml_node_a(UcxAllocator *a, DavXmlNode *node) { + if(node->name) alfree(a, node->name); + if(node->namespace) alfree(a, node->namespace); + if(node->content) alfree(a, node->content); + DavXmlAttr *attr = node->attributes; + while(attr) { + if(attr->name) alfree(a, attr->name); + if(attr->value) alfree(a, attr->value); + attr = attr->next; + } + DavXmlNode *children = node->children; + while(children) { + DavXmlNode *next_ch = children->next; + dav_free_xml_node_a(a, children); + children = next_ch; + } + alfree(a, node); +} + +void dav_free_xml_node_sn(DavSession *sn, DavXmlNode *node) { + dav_free_xml_node_a(sn->mp->allocator, node); +} + +void dav_free_xml_node(DavXmlNode *node) { + dav_free_xml_node_a(ucx_default_allocator(), node); +} DavXmlAttr* dav_copy_xml_attr(DavXmlAttr *attr) { if(!attr) {
--- a/test/bin-test/test-dav-sync-metadata1.sh Sun Aug 08 16:50:36 2021 +0200 +++ b/test/bin-test/test-dav-sync-metadata1.sh Mon Aug 09 17:22:21 2021 +0200 @@ -38,6 +38,14 @@ exit 1 fi +TEST=`uname | grep BSD` +if [ $? -eq 0 ]; +then + alias stat_="stat -f %m" +else + alias stat_="stat -c %Y" +fi + XATTR=../../build/xattrtool # checks if tmp-sync/out.txt contains a specific text @@ -151,11 +159,11 @@ check_tmpout "0 conflicts" "test 2: wrong conflict counter (pull)" check_tmpout "0 errors" "test 2: wrong error counter (pull)" -MTIMEA1=`stat -c %Y tmp-sync/test4a/file1` -MTIMEB1=`stat -c %Y tmp-sync/test4b/file1` +MTIMEA1=`stat_ tmp-sync/test4a/file1` +MTIMEB1=`stat_ tmp-sync/test4b/file1` -MTIMEA2=`stat -c %Y tmp-sync/test4a/dir1/file2` -MTIMEB2=`stat -c %Y tmp-sync/test4b/dir1/file2` +MTIMEA2=`stat_ tmp-sync/test4a/dir1/file2` +MTIMEB2=`stat_ tmp-sync/test4b/dir1/file2` if [ $MTIMEA1 != $MTIMEB1 ]; then echo "file1: mtime not synced" @@ -183,8 +191,8 @@ check_tmpout "0 conflicts" "test 3: wrong conflict counter (pull)" check_tmpout "0 errors" "test 3: wrong error counter (pull)" -MTIMEA1=`stat -c %Y tmp-sync/test4a/file1` -MTIMEB1=`stat -c %Y tmp-sync/test4b/file1` +MTIMEA1=`stat_ tmp-sync/test4a/file1` +MTIMEB1=`stat_ tmp-sync/test4b/file1` if [ $MTIMEA1 != $MTIMEB1 ]; then echo "file1: mtime not synced"