serious changes on Result Value Trees and NodeSets w.r.t. deallocation and
* xpath.c: serious changes on Result Value Trees and NodeSets
w.r.t. deallocation and collect operations. Probably not
100% clean (merge of allocated trees smells like a problem).
Seems sufficient to close #58943
Daniel
diff --git a/xpath.c b/xpath.c
index 2de4e1d..2228ff5 100644
--- a/xpath.c
+++ b/xpath.c
@@ -1737,7 +1737,7 @@
if (obj == NULL) return;
for (i = 0;i < obj->nodeNr;i++)
- if (obj->nodeTab[i] != NULL)
+ if (obj->nodeTab[i] != NULL)
xmlFreeNodeList(obj->nodeTab[i]);
if (obj->nodeTab != NULL) {
@@ -1834,6 +1834,8 @@
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
ret->type = XPATH_XSLT_TREE;
+ ret->boolval = 1;
+ ret->user = (void *) val;
ret->nodesetval = xmlXPathNodeSetCreate(val);
return(ret);
}
@@ -2824,14 +2826,19 @@
break;
case XPATH_XSLT_TREE:
if ((val->nodesetval != NULL) &&
- (val->nodesetval->nodeTab != NULL))
+ (val->nodesetval->nodeTab != NULL)) {
+ ret->boolval = 1;
+ ret->user = xmlCopyNode(val->nodesetval->nodeTab[0], 1);
ret->nodesetval = xmlXPathNodeSetCreate(
- xmlCopyNode(val->nodesetval->nodeTab[0], 1));
- else
+ (xmlNodePtr) ret->user);
+ } else
ret->nodesetval = xmlXPathNodeSetCreate(NULL);
+ /* Deallocate the copied tree value */
break;
case XPATH_NODESET:
ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
+ /* Do not deallocate the copied tree value */
+ ret->boolval = 0;
break;
case XPATH_LOCATIONSET:
#ifdef LIBXML_XPTR_ENABLED
@@ -2860,10 +2867,12 @@
void
xmlXPathFreeObject(xmlXPathObjectPtr obj) {
if (obj == NULL) return;
- if (obj->type == XPATH_NODESET) {
+ if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
if (obj->boolval) {
- obj->type = XPATH_XSLT_TREE;
- if (obj->nodesetval != NULL)
+ if (obj->user != NULL) {
+ xmlFreeNodeList((xmlNodePtr) obj->user);
+ xmlXPathFreeNodeSet(obj->nodesetval);
+ } else if (obj->nodesetval != NULL)
xmlXPathFreeValueTree(obj->nodesetval);
} else {
if (obj->nodesetval != NULL)
@@ -2877,9 +2886,6 @@
} else if (obj->type == XPATH_STRING) {
if (obj->stringval != NULL)
xmlFree(obj->stringval);
- } else if (obj->type == XPATH_XSLT_TREE) {
- if (obj->nodesetval != NULL)
- xmlXPathFreeValueTree(obj->nodesetval);
}
xmlFree(obj);
@@ -8402,8 +8408,14 @@
"\nExamined %d nodes, found %d nodes at that step\n",
t, n);
#endif
- xmlXPathFreeObject(obj);
valuePush(ctxt, xmlXPathWrapNodeSet(ret));
+ if ((obj->boolval) && (obj->user != NULL)) {
+ ctxt->value->boolval = 1;
+ ctxt->value->user = obj->user;
+ obj->user = NULL;
+ obj->boolval = 0;
+ }
+ xmlXPathFreeObject(obj);
return(t);
}
@@ -8780,8 +8792,14 @@
"\nExamined %d nodes, found %d nodes at that step\n",
t, list->nodeNr);
#endif
- xmlXPathFreeObject(obj);
valuePush(ctxt, xmlXPathWrapNodeSet(list));
+ if ((obj->boolval) && (obj->user != NULL)) {
+ ctxt->value->boolval = 1;
+ ctxt->value->user = obj->user;
+ obj->user = NULL;
+ obj->boolval = 0;
+ }
+ xmlXPathFreeObject(obj);
return(t);
}