--- a/src/server/webdav/xml.c Tue Jan 14 22:05:34 2020 +0100 +++ b/src/server/webdav/xml.c Thu Jan 16 19:14:53 2020 +0100 @@ -30,12 +30,12 @@ #include <stdlib.h> #include <string.h> - #include "xml.h" typedef struct StackElm { WSXmlNode *node; // list of nodes - WSXmlNode *parent; // if not NULL, call endcb after node->next is NULL + //WSXmlNode *parent; // if not NULL, call endcb after node->next is NULL + int endonly; struct StackElm *next; } StackElm; @@ -58,7 +58,8 @@ } stack->next = NULL; stack->node = node; - stack->parent = NULL; + stack->endonly = 0; + //stack->parent = NULL; int ret = 0; int br = 0; @@ -68,7 +69,7 @@ stack = cur->next; // and remove it cur->next = NULL; - while(xmlnode) { + while(xmlnode && !cur->endonly) { // element begin callback if(begincb(xmlnode, udata)) { br = 1; @@ -88,20 +89,37 @@ newelm->node = xmlnode->children; // setting the parent will make sure endcb will be called // for the current xmlnode after all children are processed - newelm->parent = xmlnode; + //newelm->parent = xmlnode; + newelm->endonly = 0; // if xmlnode->next is not NULL, there are still nodes at // this level, therefore we have to put these also on the // stack // this way, the remaining nodes are processed after all - // children of the current node are processed + // children and the end tag are processed if(xmlnode->next) { - // reuse current StackElm - cur->node = xmlnode->next; - STACK_PUSH(stack, cur); - cur = NULL; + StackElm *nextelm = pool_malloc(pool, sizeof(StackElm)); + if(!nextelm) { + ret = 1; + br = 1; + break; + } + nextelm->node = xmlnode->next; + nextelm->next = NULL; + nextelm->endonly = 0; + STACK_PUSH(stack, nextelm); } + // we have to put the end tag of the current element + // on the stack to ensure endcb is called for the current + // element, after all children are processed + // reuse cur + cur->node = xmlnode; + cur->endonly = 1; + STACK_PUSH(stack, cur); + + cur = NULL; + // now we can put the children on the stack STACK_PUSH(stack, newelm); // break, because we don't want to process xmlnode->next now @@ -109,6 +127,7 @@ } else { // no children means, the end callback can be called directly // after the begin callback (no intermediate nodes) + cur->node = NULL; if(endcb(xmlnode, udata)) { br = 1; break; @@ -122,11 +141,11 @@ break; // break because of an error } - if(cur) { - if(cur->parent) { - if(endcb(cur->parent, udata)) { - break; - } + if(cur && cur->node) { + //xmlNode *endNode = cur->parent ? cur->parent : cur->node; + xmlNode *endNode = cur->node; + if(endcb(endNode, udata)) { + break; } pool_free(pool, cur); }