diff -r 60870dbac94f -r a9b9344875aa src/server/webdav/xml.c --- a/src/server/webdav/xml.c Sat Apr 30 20:44:38 2022 +0200 +++ b/src/server/webdav/xml.c Sun May 01 10:48:20 2022 +0200 @@ -35,6 +35,7 @@ #include #include "../util/util.h" +#include "../util/pool.h" #include "xml.h" @@ -314,7 +315,7 @@ } -static ssize_t buf_writefunc(void *buf, const void *s, size_t len) { +static ssize_t buf_writefunc(void *buf, const char *s, size_t len) { int w = ucx_buffer_write(s, 1, len, buf); return w == 0 ? IO_ERROR : w; } @@ -357,6 +358,131 @@ return data; } +char* wsxml_nslist2string(pool_handle_t *pool, WebdavNSList *nslist) { + if(!nslist) return NULL; + + // get required string length + size_t len = 0; + WebdavNSList *elm = nslist; + while(elm) { + WSNamespace *ns = elm->namespace; + if(ns) { + if(ns->prefix) len += strlen((const char*)ns->prefix); + if(ns->href) len += strlen((const char*)ns->href); + len += 2; // 1 char for ':', 1 char for \n or \0 + } + elm = elm->next; + } + + // alloc string + char *str = pool_malloc(pool, len); + if(!str) { + return NULL; + } + char *pos = str; + + // copy namespace definitions to the string + elm = nslist; + while(elm) { + WSNamespace *ns = elm->namespace; + if(ns) { + if(ns->prefix) { + size_t prefixlen = strlen((const char*)ns->prefix); + memcpy(pos, ns->prefix, prefixlen); + pos[prefixlen] = ':'; + pos += prefixlen + 1; + } else { + pos[0] = ':'; + pos++; + } + if(ns->href) { + size_t hreflen = strlen((const char*)ns->href); + memcpy(pos, ns->href, hreflen); + pos[hreflen] = elm->next ? '\n' : '\0'; + pos += hreflen + 1; + } else { + pos[0] = elm->next ? '\n' : '\0'; + pos++; + } + } + elm = elm->next; + } + + return str; +} + +WebdavNSList* wsxml_string2nslist(pool_handle_t *pool, char *nsliststr) { + if(!nsliststr) return NULL; + size_t len = strlen(nsliststr); + WebdavNSList *list_start = NULL; + WebdavNSList *list_current = NULL; + + char *prefix = nsliststr; + size_t prefix_start = 0; + size_t prefix_len = 0; + char *href = NULL; + size_t href_start = len; + size_t i; + for(i=0;i<=len;i++) { + char c = nsliststr[i]; + if(c == '\n' || c == '\0') { + if(i > href_start) { + WebdavNSList *elm = pool_malloc(pool, sizeof(WebdavNSList)); + if(!elm) { + break; + } + elm->prev = list_current; + elm->next = NULL; + WSNamespace *ns = pool_malloc(pool, sizeof(WSNamespace)); + elm->namespace = ns; + if(!ns) { + break; + } + memset(ns, 0, sizeof(WSNamespace)); + ns->prefix = prefix_len > 0 ? (xmlChar*)sstrdup_pool(pool, sstrn(prefix, prefix_len)).ptr : NULL; + ns->href = (xmlChar*)sstrdup_pool(pool, sstrn(href, i-href_start)).ptr; + if(list_current) { + list_current->next = elm; + } else { + list_start = elm; + } + list_current = elm; + } + prefix_start = i + 1; + prefix = nsliststr + prefix_start; + prefix_len = 0; + href_start = len; + href = NULL; + } else if(!href && c == ':') { + prefix_len = i - prefix_start; + href_start = i + 1; + href = nsliststr + href_start; + } + } + + if(i < len) { + // error, cleanup + while(list_start) { + if(list_start->namespace) { + WSNamespace *ns = list_start->namespace; + if(ns->prefix) { + pool_free(pool, (char*)ns->prefix); + } + if(ns->href) { + pool_free(pool, (char*)ns->href); + } + pool_free(pool, ns); + } + WebdavNSList *next = list_start->next; + pool_free(pool, list_start); + list_start = next; + } + list_start = NULL; + } + + return list_start; +} + /***************************************************************************** * Non public functions *****************************************************************************/