Fri, 17 Jan 2020 17:42:10 +0100
remove nsdef from WebdavProperty
--- a/src/server/public/webdav.h Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/public/webdav.h Fri Jan 17 17:42:10 2020 +0100 @@ -100,8 +100,6 @@ struct WebdavProperty { WSNamespace *namespace; - WebdavNSList *nsdef; - const char *name; char *lang; @@ -295,6 +293,12 @@ */ int webdav_getdepth(Request *rq); +int webdav_plist_add( + pool_handle_t *pool, + WebdavPList **begin, + WebdavPList **end, + WebdavProperty *prop); + WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list); size_t webdav_plist_size(WebdavPList *list); @@ -313,12 +317,6 @@ pool_handle_t *pool, char *value); -int webdav_property_add_nsdef( - WebdavProperty *p, - pool_handle_t *pool, - const char *prefix, - const char *nsuri); - WebdavVFSProperties webdav_vfs_properties( WebdavPropfindRequest *rq, WSBool removefromlist,
--- a/src/server/test/webdav.c Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/test/webdav.c Fri Jan 17 17:42:10 2020 +0100 @@ -709,9 +709,41 @@ WebdavProperty p[16]; const char *names[] = {"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9"}; + WSNamespace ns1; + ZERO(&ns1, sizeof(WSNamespace)); + WSNamespace ns2; + ZERO(&ns2, sizeof(WSNamespace)); + ns1.prefix = (xmlChar*)"x1"; + ns1.href = (xmlChar*)"http://example.com/test/"; + ns2.prefix = (xmlChar*)"x2"; + ns2.href = (xmlChar*)"http://example.com/test/"; + + WebdavProperty dp1; + ZERO(&dp1, sizeof(WebdavProperty)); + dp1.name = "dup"; + dp1.namespace = &ns1; + dp1.value.text.str = "Hello"; + dp1.value.text.length = 5; + dp1.vtype = WS_VALUE_TEXT; + + WebdavProperty dp2; + ZERO(&dp2, sizeof(WebdavProperty)); + dp2.name = "dup"; + dp2.namespace = &ns1; + dp2.value.text.str = "Hello"; + dp2.value.text.length = 5; + dp2.vtype = WS_VALUE_TEXT; + + WebdavProperty dp3; + ZERO(&dp3, sizeof(WebdavProperty)); + dp3.name = "dup"; + dp3.namespace = &ns2; + dp3.value.text.str = "Hello"; + dp3.value.text.length = 5; + dp3.vtype = WS_VALUE_TEXT; + // init test data p1.namespace = webdav_dav_namespace(); - p1.nsdef = NULL; p1.lang = NULL; p1.name = "test1"; p1.value.data = NULL; @@ -719,7 +751,6 @@ for(int i=0;i<8;i++) { p[i].namespace = webdav_dav_namespace(); - p[i].nsdef = NULL; p[i].name = names[i]; p[i].lang = NULL; p[i].value.node = NULL; @@ -751,6 +782,26 @@ UCX_TEST_ASSERT(ucx_list_size(r->errors->next->begin) == 4, "403 list size != 4"); UCX_TEST_ASSERT(ucx_list_size(r->errors->next->next->begin) == 1, "500 list size != 1"); + // new resource for prop duplication tests + r = (MSResponse*)ms->response.addresource((WebdavResponse*)ms, "/test"); + UCX_TEST_ASSERT(r, "cannot create second response"); + + r->resource.addproperty((WebdavResource*)r, &dp1, 200); + UCX_TEST_ASSERT(r->plist_begin, "adding dp1 failed"); + UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: list size not 1"); + + r->resource.addproperty((WebdavResource*)r, &dp2, 200); + UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: adding dp2 should not work"); + + r->resource.addproperty((WebdavResource*)r, &dp2, 404); + UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: adding dp2 with different status should not work (1)"); + if(r->errors) { + UCX_TEST_ASSERT(ucx_list_size(r->errors->begin) == 0, "dp1: error list not empty"); + } + + r->resource.addproperty((WebdavResource*)r, &dp3, 200); + UCX_TEST_ASSERT(!r->plist_begin->next, "dp1: adding dp3 should not work"); + UCX_TEST_END; }
--- a/src/server/webdav/multistatus.c Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/webdav/multistatus.c Fri Jan 17 17:42:10 2020 +0100 @@ -117,6 +117,7 @@ int status) { MSResponse *response = (MSResponse*)res; + Session *sn = response->multistatus->sn; if(response->resource.isclosed) { log_ereport( LOG_WARN, @@ -135,18 +136,9 @@ property->name); return 1; } - if(property->nsdef) { - // error: nsdef MUST be NULL, only fill nsdef in this func - log_ereport( - LOG_FAILURE, - "%s", - "webdav: property '%s': nsdef must be null", - property->name); - return 1; - } // check if the property was already added to the resource - UcxAllocator *a = session_get_allocator(response->multistatus->sn); + UcxAllocator *a = session_get_allocator(sn); sstr_t key = sstrcat_a( a, 3, @@ -162,97 +154,20 @@ } a->free(a->pool, key.ptr); - // add namespace of this property to the namespace map - // the namespace map will be used for global namespace definitions - if(property->namespace->prefix) { - char *ns = ucx_map_cstr_get( - response->multistatus->namespaces, - (const char*)property->namespace->prefix); - if(!ns) { - // prefix is not in use -> we can add the namespace to the ns map - int err = ucx_map_cstr_put( - response->multistatus->namespaces, - (const char*)property->namespace->prefix, - property->namespace->href); - if(err) { - return 1; // OOM - } - } else if(strcmp((char*)property->namespace->href, ns)) { - // global namespace != local namespace - // therefore we need a namespace definition in this element - - if(webdav_property_add_nsdef( - property, - response->multistatus->sn->pool, - (const char*)property->namespace->prefix, - (const char*)property->namespace->href)) - { - return 1; // OOM - } - } - } - // error properties will be added to a separate list if(status != 200) { return msresponse_addproperror(response, property, status); } - // add all namespaces used by this property to the nsdef list - WebdavNSList *nslist = NULL; - if(property->vtype == WS_VALUE_XML_NODE) { - // iterate over xml tree and collect all namespaces - int err = 0; - WebdavNSList *nsdef = wsxml_get_required_namespaces( - response->multistatus->sn->pool, - property->value.node, - &err); - if(err) { - return 1; // OOM - } - nslist = nsdef; - } else if(property->vtype == WS_VALUE_XML_DATA) { - // xml data contains a list of all used namespaces - nslist = property->value.data->namespaces; - } // other value types don't contain xml namespaces - - while(nslist) { - // only add the namespace to the definitions list, if it isn't a - // property namespace, because the prop ns is already added - // to the element's def list or global definitions list - if(strcmp( - (const char*)nslist->namespace->prefix, - (const char*)property->namespace->prefix)) - { - // ns-prefix != property-prefix -> add ns to nsdef - if(webdav_property_add_nsdef( - property, - response->multistatus->sn->pool, - (const char*)nslist->namespace->prefix, - (const char*)nslist->namespace->href)) - { - return 1; // OOM - } - } - nslist = nslist->next; - } - // add property to the list - WebdavPList *listelm = pool_malloc( - response->multistatus->sn->pool, - sizeof(WebdavPList)); - if(!listelm) { + if(webdav_plist_add( + sn->pool, + &response->plist_begin, + &response->plist_end, + property)) + { return 1; } - - listelm->property = property; - listelm->next = NULL; - - if(response->plist_end) { - response->plist_end->next = listelm; - } else { - response->plist_begin = listelm; - } - response->plist_end = listelm; return 0; }
--- a/src/server/webdav/multistatus.h Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/webdav/multistatus.h Fri Jan 17 17:42:10 2020 +0100 @@ -77,8 +77,6 @@ WebdavPList *plist_begin; WebdavPList *plist_end; - UcxMap *nsdef; - MSResponse *next; WSBool closing; };
--- a/src/server/webdav/requestparser.c Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/webdav/requestparser.c Fri Jan 17 17:42:10 2020 +0100 @@ -38,33 +38,6 @@ #define xstreq(a, b) !strcmp((const char*)a, (const char*)b) -// TODO: make function public -int proplist_add( - pool_handle_t *pool, - WebdavPList **begin, - WebdavPList **end, - WebdavProperty *prop) -{ - WebdavPList *elm = pool_malloc(pool, sizeof(WebdavPList)); - if(!elm) { - return 1; - } - elm->prev = *end; - elm->next = NULL; - elm->property = prop; - - if(!*begin) { - *begin = elm; - *end = elm; - return 0; - } - - (*end)->next = elm; - *end = elm; - - return 0; -} - void proplist_free(pool_handle_t *pool, WebdavPList *list) { while(list) { WebdavPList *next = list->next; @@ -134,7 +107,7 @@ prop->vtype = WS_VALUE_XML_NODE; } if(prop) { - if(proplist_add(sn->pool, plist_begin, plist_end, prop)) { + if(webdav_plist_add(sn->pool, plist_begin, plist_end, prop)) { *error = proppatch ? PROPPATCH_PARSER_OOM : PROPFIND_PARSER_OOM; }
--- a/src/server/webdav/requestparser.h Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/webdav/requestparser.h Fri Jan 17 17:42:10 2020 +0100 @@ -59,12 +59,7 @@ #define LOCK_PARSER_UNKNOWN_ELEMENT 3 #define LOCK_PARSER_OOM 4 #define LOCK_PARSER_ERROR 5 - -int proplist_add( - pool_handle_t *pool, - WebdavPList **begin, - WebdavPList **end, - WebdavProperty *prop); + WebdavProperty* prop_create( pool_handle_t *pool,
--- a/src/server/webdav/webdav.c Thu Jan 16 22:28:22 2020 +0100 +++ b/src/server/webdav/webdav.c Fri Jan 17 17:42:10 2020 +0100 @@ -460,6 +460,32 @@ return depth; } +int webdav_plist_add( + pool_handle_t *pool, + WebdavPList **begin, + WebdavPList **end, + WebdavProperty *prop) +{ + WebdavPList *elm = pool_malloc(pool, sizeof(WebdavPList)); + if(!elm) { + return 1; + } + elm->prev = *end; + elm->next = NULL; + elm->property = prop; + + if(!*begin) { + *begin = elm; + *end = elm; + return 0; + } + + (*end)->next = elm; + *end = elm; + + return 0; +} + WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list) { WebdavPList *new_list = NULL; // start of the new list WebdavPList *new_list_end = NULL; // end of the new list @@ -573,44 +599,6 @@ return 0; } -int webdav_property_add_nsdef( - WebdavProperty *property, - pool_handle_t *pool, - const char *prefix, - const char *nsuri) -{ - // because we're using a memory pool, we don't free in case stuff in - // case of an error (OOM) - stuff will be freed by destroyinig the pool - - WebdavNSList *new_def = pool_malloc(pool, sizeof(WebdavNSList)); - if(!new_def) { - return 1; - } - WSNamespace *new_ns = pool_malloc(pool, sizeof(WSNamespace)); - if(!new_ns) { - return 1; - } - ZERO(new_ns, sizeof(WSNamespace)); - - new_ns->prefix = (xmlChar*)pool_strdup(pool, prefix); - new_ns->href = (xmlChar*)pool_strdup(pool, nsuri); - if(!new_ns->prefix || !new_ns->href) { - return 1; - } - - new_def->namespace = new_ns; - new_def->prev = NULL; - new_def->next = NULL; - - if(property->nsdef) { - property->nsdef->prev = new_def; - new_def->next = property->nsdef; - } - property->nsdef = new_def; - - return 0; -} - WebdavVFSProperties webdav_vfs_properties( WebdavPropfindRequest *rq, WSBool removefromlist,