File libxslt-CVE-2025-10911.patch of Package libxslt
Index: libxslt-1.1.43/libxslt/transform.c
===================================================================
--- libxslt-1.1.43.orig/libxslt/transform.c
+++ libxslt-1.1.43/libxslt/transform.c
@@ -519,19 +519,20 @@ xsltTransformCacheFree(xsltTransformCach
/*
* Free tree fragments.
*/
- if (cache->RVT) {
- xmlDocPtr tmp, cur = cache->RVT;
+ if (cache->rvtList) {
+ xsltRVTListPtr tmp, cur = cache->rvtList;
while (cur) {
tmp = cur;
- cur = (xmlDocPtr) cur->next;
- if (tmp->_private != NULL) {
+ cur = cur->next;
+ if (tmp->RVT->_private != NULL) {
/*
- * Tree the document info.
+ * Free the document info.
*/
- xsltFreeDocumentKeys((xsltDocumentPtr) tmp->_private);
- xmlFree(tmp->_private);
+ xsltFreeDocumentKeys((xsltDocumentPtr) tmp->RVT->_private);
+ xmlFree(tmp->RVT->_private);
}
- xmlFreeDoc(tmp);
+ xmlFreeDoc(tmp->RVT);
+ xmlFree(tmp);
}
}
/*
@@ -2264,38 +2265,36 @@ xsltLocalVariablePush(xsltTransformConte
* are preserved; all other fragments are freed/cached.
*/
static void
-xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
+xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xsltRVTListPtr base)
{
- xmlDocPtr cur = ctxt->localRVT, tmp;
+ xsltRVTListPtr cur = ctxt->localRVTList, tmp;
if (cur == base)
return;
- if (cur->prev != NULL)
- xsltTransformError(ctxt, NULL, NULL, "localRVT not head of list\n");
- /* Reset localRVT early because some RVTs might be registered again. */
- ctxt->localRVT = base;
- if (base != NULL)
- base->prev = NULL;
+ /* Reset localRVTList early because some RVTs might be registered again. */
+ ctxt->localRVTList = base;
do {
tmp = cur;
- cur = (xmlDocPtr) cur->next;
- if (tmp->compression == XSLT_RVT_LOCAL) {
- xsltReleaseRVT(ctxt, tmp);
- } else if (tmp->compression == XSLT_RVT_GLOBAL) {
- xsltRegisterPersistRVT(ctxt, tmp);
- } else if (tmp->compression == XSLT_RVT_FUNC_RESULT) {
+ cur = cur->next;
+ if (tmp->RVT->compression == XSLT_RVT_LOCAL) {
+ xsltReleaseRVTList(ctxt, tmp);
+ } else if (tmp->RVT->compression == XSLT_RVT_GLOBAL) {
+ xsltRegisterPersistRVT(ctxt, tmp->RVT);
+ xmlFree(tmp);
+ } else if (tmp->RVT->compression == XSLT_RVT_FUNC_RESULT) {
/*
* This will either register the RVT again or move it to the
* context variable.
*/
- xsltRegisterLocalRVT(ctxt, tmp);
- tmp->compression = XSLT_RVT_FUNC_RESULT;
+ xsltRegisterLocalRVT(ctxt, tmp->RVT);
+ tmp->RVT->compression = XSLT_RVT_FUNC_RESULT;
+ xmlFree(tmp);
} else {
xmlGenericError(xmlGenericErrorContext,
- "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n",
- tmp->psvi);
+ "xsltReleaseLocalRVTs: Unexpected RVT flag %d\n",
+ tmp->RVT->compression);
}
} while (cur != base);
}
@@ -2323,7 +2322,7 @@ xsltApplySequenceConstructor(xsltTransfo
xmlNodePtr oldInsert, oldInst, oldCurInst, oldContextNode;
xmlNodePtr cur, insert, copy = NULL;
int level = 0, oldVarsNr;
- xmlDocPtr oldLocalFragmentTop;
+ xsltRVTListPtr oldLocalFragmentTop;
#ifdef XSLT_REFACTORED
xsltStylePreCompPtr info;
@@ -2369,7 +2368,7 @@ xsltApplySequenceConstructor(xsltTransfo
}
ctxt->depth++;
- oldLocalFragmentTop = ctxt->localRVT;
+ oldLocalFragmentTop = ctxt->localRVTList;
oldInsert = insert = ctxt->insert;
oldInst = oldCurInst = ctxt->inst;
oldContextNode = ctxt->node;
@@ -2603,7 +2602,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -2698,7 +2697,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -2764,7 +2763,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -2894,7 +2893,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -3073,7 +3072,7 @@ xsltApplyXSLTTemplate(xsltTransformConte
int oldVarsBase = 0;
xmlNodePtr cur;
xsltStackElemPtr tmpParam = NULL;
- xmlDocPtr oldUserFragmentTop;
+ xsltRVTListPtr oldUserFragmentTop;
#ifdef WITH_PROFILER
long start = 0;
#endif
@@ -3121,8 +3120,8 @@ xsltApplyXSLTTemplate(xsltTransformConte
return;
}
- oldUserFragmentTop = ctxt->tmpRVT;
- ctxt->tmpRVT = NULL;
+ oldUserFragmentTop = ctxt->tmpRVTList;
+ ctxt->tmpRVTList = NULL;
/*
* Initiate a distinct scope of local params/variables.
@@ -3233,16 +3232,16 @@ xsltApplyXSLTTemplate(xsltTransformConte
* user code should now use xsltRegisterLocalRVT() instead
* of the obsolete xsltRegisterTmpRVT().
*/
- if (ctxt->tmpRVT) {
- xmlDocPtr curdoc = ctxt->tmpRVT, tmp;
+ if (ctxt->tmpRVTList) {
+ xsltRVTListPtr curRVTList = ctxt->tmpRVTList, tmp;
- while (curdoc != NULL) {
- tmp = curdoc;
- curdoc = (xmlDocPtr) curdoc->next;
- xsltReleaseRVT(ctxt, tmp);
+ while (curRVTList != NULL) {
+ tmp = curRVTList;
+ curRVTList = curRVTList->next;
+ xsltReleaseRVTList(ctxt, tmp);
}
}
- ctxt->tmpRVT = oldUserFragmentTop;
+ ctxt->tmpRVTList = oldUserFragmentTop;
/*
* Pop the xsl:template declaration from the stack.
@@ -5320,7 +5319,7 @@ xsltIf(xsltTransformContextPtr ctxt, xml
#ifdef XSLT_FAST_IF
{
- xmlDocPtr oldLocalFragmentTop = ctxt->localRVT;
+ xsltRVTListPtr oldLocalFragmentTop = ctxt->localRVTList;
res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp);
@@ -5328,7 +5327,7 @@ xsltIf(xsltTransformContextPtr ctxt, xml
* Cleanup fragments created during evaluation of the
* "select" expression.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
}
Index: libxslt-1.1.43/libxslt/variables.c
===================================================================
--- libxslt-1.1.43.orig/libxslt/variables.c
+++ libxslt-1.1.43/libxslt/variables.c
@@ -47,6 +47,21 @@ static const xmlChar *xsltComputingGloba
#define XSLT_VAR_IN_SELECT (1<<1)
#define XSLT_TCTXT_VARIABLE(c) ((xsltStackElemPtr) (c)->contextVariable)
+static xsltRVTListPtr
+xsltRVTListCreate(void)
+{
+ xsltRVTListPtr ret;
+
+ ret = (xsltRVTListPtr) xmlMalloc(sizeof(xsltRVTList));
+ if (ret == NULL) {
+ xsltTransformError(NULL, NULL, NULL,
+ "xsltRVTListCreate: malloc failed\n");
+ return(NULL);
+ }
+ memset(ret, 0, sizeof(xsltRVTList));
+ return(ret);
+}
+
/************************************************************************
* *
* Result Value Tree (Result Tree Fragment) interfaces *
@@ -64,6 +79,7 @@ static const xmlChar *xsltComputingGloba
xmlDocPtr
xsltCreateRVT(xsltTransformContextPtr ctxt)
{
+ xsltRVTListPtr rvtList;
xmlDocPtr container;
/*
@@ -76,12 +92,11 @@ xsltCreateRVT(xsltTransformContextPtr ct
/*
* Reuse a RTF from the cache if available.
*/
- if (ctxt->cache->RVT) {
- container = ctxt->cache->RVT;
- ctxt->cache->RVT = (xmlDocPtr) container->next;
- /* clear the internal pointers */
- container->next = NULL;
- container->prev = NULL;
+ if (ctxt->cache->rvtList) {
+ rvtList = ctxt->cache->rvtList;
+ container = ctxt->cache->rvtList->RVT;
+ ctxt->cache->rvtList = rvtList->next;
+ xmlFree(rvtList);
if (ctxt->cache->nbRVT > 0)
ctxt->cache->nbRVT--;
#ifdef XSLT_DEBUG_PROFILE_CACHE
@@ -119,11 +134,16 @@ xsltCreateRVT(xsltTransformContextPtr ct
int
xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
{
+ xsltRVTListPtr list;
+
if ((ctxt == NULL) || (RVT == NULL))
return(-1);
- RVT->prev = NULL;
+ list = xsltRVTListCreate();
+ if (list == NULL) return(-1);
+
RVT->compression = XSLT_RVT_LOCAL;
+ list->RVT = RVT;
/*
* We'll restrict the lifetime of user-created fragments
@@ -131,15 +151,13 @@ xsltRegisterTmpRVT(xsltTransformContextP
* var/param itself.
*/
if (ctxt->contextVariable != NULL) {
- RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
- XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
+ list->next = XSLT_TCTXT_VARIABLE(ctxt)->fragment;
+ XSLT_TCTXT_VARIABLE(ctxt)->fragment = list;
return(0);
}
- RVT->next = (xmlNodePtr) ctxt->tmpRVT;
- if (ctxt->tmpRVT != NULL)
- ctxt->tmpRVT->prev = (xmlNodePtr) RVT;
- ctxt->tmpRVT = RVT;
+ list->next = ctxt->tmpRVTList;
+ ctxt->tmpRVTList = list;
return(0);
}
@@ -159,11 +177,16 @@ int
xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
xmlDocPtr RVT)
{
+ xsltRVTListPtr list;
+
if ((ctxt == NULL) || (RVT == NULL))
return(-1);
- RVT->prev = NULL;
+ list = xsltRVTListCreate();
+ if (list == NULL) return(-1);
+
RVT->compression = XSLT_RVT_LOCAL;
+ list->RVT = RVT;
/*
* When evaluating "select" expressions of xsl:variable
@@ -174,8 +197,8 @@ xsltRegisterLocalRVT(xsltTransformContex
if ((ctxt->contextVariable != NULL) &&
(XSLT_TCTXT_VARIABLE(ctxt)->flags & XSLT_VAR_IN_SELECT))
{
- RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
- XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
+ list->next = XSLT_TCTXT_VARIABLE(ctxt)->fragment;
+ XSLT_TCTXT_VARIABLE(ctxt)->fragment = list;
return(0);
}
/*
@@ -183,10 +206,8 @@ xsltRegisterLocalRVT(xsltTransformContex
* If not reference by a returning instruction (like EXSLT's function),
* then this fragment will be freed, when the instruction exits.
*/
- RVT->next = (xmlNodePtr) ctxt->localRVT;
- if (ctxt->localRVT != NULL)
- ctxt->localRVT->prev = (xmlNodePtr) RVT;
- ctxt->localRVT = RVT;
+ list->next = ctxt->localRVTList;
+ ctxt->localRVTList = list;
return(0);
}
@@ -344,8 +365,9 @@ xsltFlagRVTs(xsltTransformContextPtr ctx
* @ctxt: an XSLT transformation context
* @RVT: a result value tree (Result Tree Fragment)
*
- * Either frees the RVT (which is an xmlDoc) or stores
- * it in the context's cache for later reuse.
+ * Either frees the RVT (which is an xmlDoc) or stores it in the context's
+ * cache for later reuse. Preserved for ABI/API compatibility; internal use
+ * has all migrated to xsltReleaseRVTList().
*/
void
xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
@@ -353,36 +375,64 @@ xsltReleaseRVT(xsltTransformContextPtr c
if (RVT == NULL)
return;
+ xsltRVTListPtr list = xsltRVTListCreate();
+ if (list == NULL) {
+ if (RVT->_private != NULL) {
+ xsltFreeDocumentKeys((xsltDocumentPtr) RVT->_private);
+ xmlFree(RVT->_private);
+ }
+ xmlFreeDoc(RVT);
+ return;
+ }
+
+ xsltReleaseRVTList(ctxt, list);
+}
+
+/**
+ * xsltReleaseRVTList:
+ * @ctxt: an XSLT transformation context
+ * @list: a list node containing a result value tree (Result Tree Fragment)
+ *
+ * Either frees the list node or stores it in the context's cache for later
+ * reuse. Optimization to avoid adding a fallible allocation path when the
+ * caller already has a RVT list node.
+ */
+void
+xsltReleaseRVTList(xsltTransformContextPtr ctxt, xsltRVTListPtr list)
+{
+ if (list == NULL)
+ return;
+
if (ctxt && (ctxt->cache->nbRVT < 40)) {
/*
* Store the Result Tree Fragment.
* Free the document info.
*/
- if (RVT->_private != NULL) {
- xsltFreeDocumentKeys((xsltDocumentPtr) RVT->_private);
- xmlFree(RVT->_private);
- RVT->_private = NULL;
+ if (list->RVT->_private != NULL) {
+ xsltFreeDocumentKeys((xsltDocumentPtr) list->RVT->_private);
+ xmlFree(list->RVT->_private);
+ list->RVT->_private = NULL;
}
/*
* Clear the document tree.
*/
- if (RVT->children != NULL) {
- xmlFreeNodeList(RVT->children);
- RVT->children = NULL;
- RVT->last = NULL;
- }
- if (RVT->ids != NULL) {
- xmlFreeIDTable((xmlIDTablePtr) RVT->ids);
- RVT->ids = NULL;
+ if (list->RVT->children != NULL) {
+ xmlFreeNodeList(list->RVT->children);
+ list->RVT->children = NULL;
+ list->RVT->last = NULL;
+ }
+ if (list->RVT->ids != NULL) {
+ xmlFreeIDTable((xmlIDTablePtr) list->RVT->ids);
+ list->RVT->ids = NULL;
}
/*
* Reset the ownership information.
*/
- RVT->compression = 0;
+ list->RVT->compression = 0;
- RVT->next = (xmlNodePtr) ctxt->cache->RVT;
- ctxt->cache->RVT = RVT;
+ list->next = ctxt->cache->rvtList;
+ ctxt->cache->rvtList = list;
ctxt->cache->nbRVT++;
@@ -394,11 +444,12 @@ xsltReleaseRVT(xsltTransformContextPtr c
/*
* Free it.
*/
- if (RVT->_private != NULL) {
- xsltFreeDocumentKeys((xsltDocumentPtr) RVT->_private);
- xmlFree(RVT->_private);
+ if (list->RVT->_private != NULL) {
+ xsltFreeDocumentKeys((xsltDocumentPtr) list->RVT->_private);
+ xmlFree(list->RVT->_private);
}
- xmlFreeDoc(RVT);
+ xmlFreeDoc(list->RVT);
+ xmlFree(list);
}
/**
@@ -416,14 +467,17 @@ xsltReleaseRVT(xsltTransformContextPtr c
int
xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
{
+ xsltRVTListPtr list;
+
if ((ctxt == NULL) || (RVT == NULL)) return(-1);
+ list = xsltRVTListCreate();
+ if (list == NULL) return(-1);
+
RVT->compression = XSLT_RVT_GLOBAL;
- RVT->prev = NULL;
- RVT->next = (xmlNodePtr) ctxt->persistRVT;
- if (ctxt->persistRVT != NULL)
- ctxt->persistRVT->prev = (xmlNodePtr) RVT;
- ctxt->persistRVT = RVT;
+ list->RVT = RVT;
+ list->next = ctxt->persistRVTList;
+ ctxt->persistRVTList = list;
return(0);
}
@@ -438,52 +492,55 @@ xsltRegisterPersistRVT(xsltTransformCont
void
xsltFreeRVTs(xsltTransformContextPtr ctxt)
{
- xmlDocPtr cur, next;
+ xsltRVTListPtr cur, next;
if (ctxt == NULL)
return;
/*
* Local fragments.
*/
- cur = ctxt->localRVT;
+ cur = ctxt->localRVTList;
while (cur != NULL) {
- next = (xmlDocPtr) cur->next;
- if (cur->_private != NULL) {
- xsltFreeDocumentKeys(cur->_private);
- xmlFree(cur->_private);
+ next = cur->next;
+ if (cur->RVT->_private != NULL) {
+ xsltFreeDocumentKeys(cur->RVT->_private);
+ xmlFree(cur->RVT->_private);
}
- xmlFreeDoc(cur);
+ xmlFreeDoc(cur->RVT);
+ xmlFree(cur);
cur = next;
}
- ctxt->localRVT = NULL;
+ ctxt->localRVTList = NULL;
/*
* User-created per-template fragments.
*/
- cur = ctxt->tmpRVT;
+ cur = ctxt->tmpRVTList;
while (cur != NULL) {
- next = (xmlDocPtr) cur->next;
- if (cur->_private != NULL) {
- xsltFreeDocumentKeys(cur->_private);
- xmlFree(cur->_private);
+ next = cur->next;
+ if (cur->RVT->_private != NULL) {
+ xsltFreeDocumentKeys(cur->RVT->_private);
+ xmlFree(cur->RVT->_private);
}
- xmlFreeDoc(cur);
+ xmlFreeDoc(cur->RVT);
+ xmlFree(cur);
cur = next;
}
- ctxt->tmpRVT = NULL;
+ ctxt->tmpRVTList = NULL;
/*
* Global fragments.
*/
- cur = ctxt->persistRVT;
+ cur = ctxt->persistRVTList;
while (cur != NULL) {
- next = (xmlDocPtr) cur->next;
- if (cur->_private != NULL) {
- xsltFreeDocumentKeys(cur->_private);
- xmlFree(cur->_private);
+ next = cur->next;
+ if (cur->RVT->_private != NULL) {
+ xsltFreeDocumentKeys(cur->RVT->_private);
+ xmlFree(cur->RVT->_private);
}
- xmlFreeDoc(cur);
+ xmlFreeDoc(cur->RVT);
+ xmlFree(cur);
cur = next;
}
- ctxt->persistRVT = NULL;
+ ctxt->persistRVTList = NULL;
}
/************************************************************************
@@ -571,21 +628,22 @@ xsltFreeStackElem(xsltStackElemPtr elem)
* Release the list of temporary Result Tree Fragments.
*/
if (elem->context) {
- xmlDocPtr cur;
+ xsltRVTListPtr cur;
while (elem->fragment != NULL) {
cur = elem->fragment;
- elem->fragment = (xmlDocPtr) cur->next;
+ elem->fragment = cur->next;
- if (cur->compression == XSLT_RVT_LOCAL) {
- xsltReleaseRVT(elem->context, cur);
- } else if (cur->compression == XSLT_RVT_FUNC_RESULT) {
- xsltRegisterLocalRVT(elem->context, cur);
- cur->compression = XSLT_RVT_FUNC_RESULT;
+ if (cur->RVT->compression == XSLT_RVT_LOCAL) {
+ xsltReleaseRVTList(elem->context, cur);
+ } else if (cur->RVT->compression == XSLT_RVT_FUNC_RESULT) {
+ xsltRegisterLocalRVT(elem->context, cur->RVT);
+ cur->RVT->compression = XSLT_RVT_FUNC_RESULT;
+ xmlFree(cur);
} else {
xmlGenericError(xmlGenericErrorContext,
"xsltFreeStackElem: Unexpected RVT flag %d\n",
- cur->compression);
+ cur->RVT->compression);
}
}
}
@@ -944,6 +1002,7 @@ xsltEvalVariable(xsltTransformContextPtr
} else {
if (variable->tree) {
xmlDocPtr container;
+ xsltRVTListPtr rvtList;
xmlNodePtr oldInsert;
xmlDocPtr oldOutput;
const xmlChar *oldLastText;
@@ -968,7 +1027,11 @@ xsltEvalVariable(xsltTransformContextPtr
* when the variable is freed, it will also free
* the Result Tree Fragment.
*/
- variable->fragment = container;
+ rvtList = xsltRVTListCreate();
+ if (rvtList == NULL)
+ goto error;
+ rvtList->RVT = container;
+ variable->fragment = rvtList;
container->compression = XSLT_RVT_LOCAL;
oldOutput = ctxt->output;
@@ -2361,5 +2424,3 @@ local_variable_found:
return(valueObj);
}
-
-
Index: libxslt-1.1.43/libxslt/xsltInternals.h
===================================================================
--- libxslt-1.1.43.orig/libxslt/xsltInternals.h
+++ libxslt-1.1.43/libxslt/xsltInternals.h
@@ -1410,6 +1410,8 @@ struct _xsltStylePreComp {
#endif /* XSLT_REFACTORED */
+typedef struct _xsltRVTList xsltRVTList;
+typedef xsltRVTList *xsltRVTListPtr;
/*
* The in-memory structure corresponding to an XSLT Variable
@@ -1427,7 +1429,7 @@ struct _xsltStackElem {
xmlNodePtr tree; /* the sequence constructor if no eval
string or the location */
xmlXPathObjectPtr value; /* The value if computed */
- xmlDocPtr fragment; /* The Result Tree Fragments (needed for XSLT 1.0)
+ xsltRVTListPtr fragment; /* The Result Tree Fragments (needed for XSLT 1.0)
which are bound to the variable's lifetime. */
int level; /* the depth in the tree;
-1 if persistent (e.g. a given xsl:with-param) */
@@ -1639,10 +1641,15 @@ struct _xsltStylesheet {
unsigned long opCount;
};
+struct _xsltRVTList {
+ xmlDocPtr RVT;
+ xsltRVTListPtr next;
+};
+
typedef struct _xsltTransformCache xsltTransformCache;
typedef xsltTransformCache *xsltTransformCachePtr;
struct _xsltTransformCache {
- xmlDocPtr RVT;
+ xsltRVTListPtr rvtList;
int nbRVT;
xsltStackElemPtr stackItems;
int nbStackItems;
@@ -1749,8 +1756,8 @@ struct _xsltTransformContext {
* handling of temporary Result Value Tree
* (XSLT 1.0 term: "Result Tree Fragment")
*/
- xmlDocPtr tmpRVT; /* list of RVT without persistance */
- xmlDocPtr persistRVT; /* list of persistant RVTs */
+ xsltRVTListPtr tmpRVTList; /* list of RVT without persistance */
+ xsltRVTListPtr persistRVTList; /* list of persistant RVTs */
int ctxtflags; /* context processing flags */
/*
@@ -1783,7 +1790,7 @@ struct _xsltTransformContext {
xmlDocPtr initialContextDoc;
xsltTransformCachePtr cache;
void *contextVariable; /* the current variable item */
- xmlDocPtr localRVT; /* list of local tree fragments; will be freed when
+ xsltRVTListPtr localRVTList; /* list of local tree fragments; will be freed when
the instruction which created the fragment
exits */
xmlDocPtr localRVTBase; /* Obsolete */
@@ -1932,8 +1939,11 @@ XSLTPUBFUN int XSLTCALL
XSLTPUBFUN void XSLTCALL
xsltFreeRVTs (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL
- xsltReleaseRVT (xsltTransformContextPtr ctxt,
+ xsltReleaseRVT (xsltTransformContextPtr ctxt,
xmlDocPtr RVT);
+XSLTPUBFUN void XSLTCALL
+ xsltReleaseRVTList (xsltTransformContextPtr ctxt,
+ xsltRVTListPtr list);
/*
* Extra functions for Attribute Value Templates
*/
@@ -1992,4 +2002,3 @@ XSLTPUBFUN int XSLTCALL
#endif
#endif /* __XML_XSLT_H__ */
-