Compare commits

4 Commits
main ... 1.1

10 changed files with 1029 additions and 156 deletions

BIN
libxslt-1.1.38.tar.xz LFS Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,42 @@
From 46041b65f2fbddf5c284ee1a1332fa2c515c0515 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 5 Dec 2024 12:43:19 +0100
Subject: [PATCH] [CVE-2024-55549] Fix UAF related to excluded namespaces
Definitions of excluded namespaces could be deleted in
xsltParseTemplateContent. Store excluded namespace URIs in the
stylesheet's dictionary instead of referencing the namespace definition.
Thanks to Ivan Fratric for the report!
Fixes #127.
---
libxslt/xslt.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
Index: libxslt-1.1.38/libxslt/xslt.c
===================================================================
--- libxslt-1.1.38.orig/libxslt/xslt.c
+++ libxslt-1.1.38/libxslt/xslt.c
@@ -147,10 +147,20 @@ xsltParseContentError(xsltStylesheetPtr
* in case of error
*/
static int
-exclPrefixPush(xsltStylesheetPtr style, xmlChar * value)
+exclPrefixPush(xsltStylesheetPtr style, xmlChar * orig)
{
+ xmlChar *value;
int i;
+ /*
+ * orig can come from a namespace definition on a node which
+ * could be deleted later, for example in xsltParseTemplateContent.
+ * Store the string in stylesheet's dict to avoid use after free.
+ */
+ value = (xmlChar *) xmlDictLookup(style->dict, orig, -1);
+ if (value == NULL)
+ return(-1);
+
/* do not push duplicates */
for (i = 0;i < style->exclPrefixNr;i++) {
if (xmlStrEqual(style->exclPrefixTab[i], value))

View File

@@ -0,0 +1,681 @@
Index: libxslt-1.1.38/libxslt/transform.c
===================================================================
--- libxslt-1.1.38.orig/libxslt/transform.c
+++ libxslt-1.1.38/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);
}
}
/*
@@ -2250,38 +2251,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);
}
@@ -2309,7 +2308,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;
@@ -2355,7 +2354,7 @@ xsltApplySequenceConstructor(xsltTransfo
}
ctxt->depth++;
- oldLocalFragmentTop = ctxt->localRVT;
+ oldLocalFragmentTop = ctxt->localRVTList;
oldInsert = insert = ctxt->insert;
oldInst = oldCurInst = ctxt->inst;
oldContextNode = ctxt->node;
@@ -2589,7 +2588,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -2684,7 +2683,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -2750,7 +2749,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -2880,7 +2879,7 @@ xsltApplySequenceConstructor(xsltTransfo
/*
* Cleanup temporary tree fragments.
*/
- if (oldLocalFragmentTop != ctxt->localRVT)
+ if (oldLocalFragmentTop != ctxt->localRVTList)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
ctxt->insert = oldInsert;
@@ -3059,7 +3058,7 @@ xsltApplyXSLTTemplate(xsltTransformConte
int oldVarsBase = 0;
xmlNodePtr cur;
xsltStackElemPtr tmpParam = NULL;
- xmlDocPtr oldUserFragmentTop;
+ xsltRVTListPtr oldUserFragmentTop;
#ifdef WITH_PROFILER
long start = 0;
#endif
@@ -3107,8 +3106,8 @@ xsltApplyXSLTTemplate(xsltTransformConte
return;
}
- oldUserFragmentTop = ctxt->tmpRVT;
- ctxt->tmpRVT = NULL;
+ oldUserFragmentTop = ctxt->tmpRVTList;
+ ctxt->tmpRVTList = NULL;
/*
* Initiate a distinct scope of local params/variables.
@@ -3219,16 +3218,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.
@@ -5306,7 +5305,7 @@ xsltIf(xsltTransformContextPtr ctxt, xml
#ifdef XSLT_FAST_IF
{
- xmlDocPtr oldLocalFragmentTop = ctxt->localRVT;
+ xsltRVTListPtr oldLocalFragmentTop = ctxt->localRVTList;
res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp);
@@ -5314,7 +5313,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.38/libxslt/variables.c
===================================================================
--- libxslt-1.1.38.orig/libxslt/variables.c
+++ libxslt-1.1.38/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);
}
}
}
@@ -955,6 +1013,7 @@ xsltEvalVariable(xsltTransformContextPtr
} else {
if (variable->tree) {
xmlDocPtr container;
+ xsltRVTListPtr rvtList;
xmlNodePtr oldInsert;
xmlDocPtr oldOutput;
const xmlChar *oldLastText;
@@ -979,7 +1038,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;
@@ -2375,5 +2438,3 @@ local_variable_found:
return(valueObj);
}
-
-
Index: libxslt-1.1.38/libxslt/xsltInternals.h
===================================================================
--- libxslt-1.1.38.orig/libxslt/xsltInternals.h
+++ libxslt-1.1.38/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) */
@@ -1636,10 +1638,15 @@ struct _xsltStylesheet {
xmlXPathContextPtr xpathCtxt;
};
+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;
@@ -1746,8 +1753,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 */
/*
@@ -1780,7 +1787,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 */
@@ -1929,8 +1936,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
*/
@@ -1989,4 +1999,3 @@ XSLTPUBFUN int XSLTCALL
#endif
#endif /* __XML_XSLT_H__ */
-

View File

@@ -0,0 +1,33 @@
From fe508f201efb9ea37bfbe95413b8b28251497de3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org>
Date: Wed, 27 Aug 2025 14:28:40 +0300
Subject: [PATCH] End function node ancestor search at document
Avoids dereferencing a non-existent ->ns property on an
XML_DOCUMENT_NODE pointer.
Fixes #151.
---
libexslt/functions.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
Index: libxslt-1.1.38/libexslt/functions.c
===================================================================
--- libxslt-1.1.38.orig/libexslt/functions.c
+++ libxslt-1.1.38/libexslt/functions.c
@@ -615,8 +615,13 @@ exsltFuncResultComp (xsltStylesheetPtr s
* instanciation of a func:result element.
*/
for (test = inst->parent; test != NULL; test = test->parent) {
- if (IS_XSLT_ELEM(test) &&
- IS_XSLT_NAME(test, "stylesheet")) {
+ if (/* Traversal has reached the top-level document without
+ * finding a func:function ancestor. */
+ (test != NULL && test->type == XML_DOCUMENT_NODE) ||
+ /* Traversal reached a stylesheet-namespace node,
+ * and has left the function namespace. */
+ (IS_XSLT_ELEM(test) &&
+ IS_XSLT_NAME(test, "stylesheet"))) {
xsltGenericError(xsltGenericErrorContext,
"func:result element not a descendant "
"of a func:function\n");

View File

@@ -0,0 +1,130 @@
From c7c7f1f78dd202a053996fcefe57eb994aec8ef2 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 17 Dec 2024 15:56:21 +0100
Subject: [PATCH] [CVE-2025-24855] Fix use-after-free of XPath context node
There are several places where the XPath context node isn't restored
after modifying it, leading to use-after-free errors with nested XPath
evaluations and dynamically allocated context nodes.
Restore XPath context node in
- xsltNumberFormatGetValue
- xsltEvalXPathPredicate
- xsltEvalXPathStringNs
- xsltComputeSortResultInternal
In some places, the transformation context node was saved and restored
which shouldn't be necessary.
Thanks to Ivan Fratric for the report!
Fixes #128.
---
libxslt/numbers.c | 5 +++++
libxslt/templates.c | 9 ++++++---
libxslt/xsltutils.c | 4 ++--
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 0e1fa136..741124d1 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -733,9 +733,12 @@ xsltNumberFormatGetValue(xmlXPathContextPtr context,
int amount = 0;
xmlBufferPtr pattern;
xmlXPathObjectPtr obj;
+ xmlNodePtr oldNode;
pattern = xmlBufferCreate();
if (pattern != NULL) {
+ oldNode = context->node;
+
xmlBufferCCat(pattern, "number(");
xmlBufferCat(pattern, value);
xmlBufferCCat(pattern, ")");
@@ -748,6 +751,8 @@ xsltNumberFormatGetValue(xmlXPathContextPtr context,
xmlXPathFreeObject(obj);
}
xmlBufferFree(pattern);
+
+ context->node = oldNode;
}
return amount;
}
diff --git a/libxslt/templates.c b/libxslt/templates.c
index f08b9bda..1c8d96e2 100644
--- a/libxslt/templates.c
+++ b/libxslt/templates.c
@@ -61,6 +61,7 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
int oldNsNr;
xmlNsPtr *oldNamespaces;
xmlNodePtr oldInst;
+ xmlNodePtr oldNode;
int oldProximityPosition, oldContextSize;
if ((ctxt == NULL) || (ctxt->inst == NULL)) {
@@ -69,6 +70,7 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
return(0);
}
+ oldNode = ctxt->xpathCtxt->node;
oldContextSize = ctxt->xpathCtxt->contextSize;
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
oldNsNr = ctxt->xpathCtxt->nsNr;
@@ -96,8 +98,9 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
ctxt->state = XSLT_STATE_STOPPED;
ret = 0;
}
- ctxt->xpathCtxt->nsNr = oldNsNr;
+ ctxt->xpathCtxt->node = oldNode;
+ ctxt->xpathCtxt->nsNr = oldNsNr;
ctxt->xpathCtxt->namespaces = oldNamespaces;
ctxt->inst = oldInst;
ctxt->xpathCtxt->contextSize = oldContextSize;
@@ -137,7 +140,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
}
oldInst = ctxt->inst;
- oldNode = ctxt->node;
+ oldNode = ctxt->xpathCtxt->node;
oldPos = ctxt->xpathCtxt->proximityPosition;
oldSize = ctxt->xpathCtxt->contextSize;
oldNsNr = ctxt->xpathCtxt->nsNr;
@@ -167,7 +170,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
"xsltEvalXPathString: returns %s\n", ret));
#endif
ctxt->inst = oldInst;
- ctxt->node = oldNode;
+ ctxt->xpathCtxt->node = oldNode;
ctxt->xpathCtxt->contextSize = oldSize;
ctxt->xpathCtxt->proximityPosition = oldPos;
ctxt->xpathCtxt->nsNr = oldNsNr;
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
index 0e9dc62f..a20da961 100644
--- a/libxslt/xsltutils.c
+++ b/libxslt/xsltutils.c
@@ -1065,8 +1065,8 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort,
return(NULL);
}
- oldNode = ctxt->node;
oldInst = ctxt->inst;
+ oldNode = ctxt->xpathCtxt->node;
oldPos = ctxt->xpathCtxt->proximityPosition;
oldSize = ctxt->xpathCtxt->contextSize;
oldNsNr = ctxt->xpathCtxt->nsNr;
@@ -1137,8 +1137,8 @@ xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort,
results[i] = NULL;
}
}
- ctxt->node = oldNode;
ctxt->inst = oldInst;
+ ctxt->xpathCtxt->node = oldNode;
ctxt->xpathCtxt->contextSize = oldSize;
ctxt->xpathCtxt->proximityPosition = oldPos;
ctxt->xpathCtxt->nsNr = oldNsNr;
--
GitLab

View File

@@ -0,0 +1,95 @@
From 345d6826d0eae6f0a962456b8ed6f6a1bad0877d Mon Sep 17 00:00:00 2001
From: David Kilzer <ddkilzer@apple.com>
Date: Sat, 24 May 2025 15:06:42 -0700
Subject: [PATCH] libxslt: Type confusion in xmlNode.psvi between stylesheet
and source nodes
* libxslt/functions.c:
(xsltDocumentFunctionLoadDocument):
- Implement fix suggested by Ivan Fratric. This copies the xmlDoc,
calls xsltCleanupSourceDoc() to remove pvsi fields, then adds the
xmlDoc to tctxt->docList.
- Add error handling for functions that may return NULL.
* libxslt/transform.c:
- Remove static keyword so this can be called from
xsltDocumentFunctionLoadDocument().
* libxslt/transformInternals.h: Add.
(xsltCleanupSourceDoc): Add declaration.
Fixes #139.
---
libxslt/functions.c | 16 +++++++++++++++-
libxslt/transform.c | 3 ++-
libxslt/transformInternals.h | 9 +++++++++
3 files changed, 26 insertions(+), 2 deletions(-)
create mode 100644 libxslt/transformInternals.h
Index: libxslt-1.1.38/libxslt/functions.c
===================================================================
--- libxslt-1.1.38.orig/libxslt/functions.c
+++ libxslt-1.1.38/libxslt/functions.c
@@ -34,6 +34,7 @@
#include "numbersInternals.h"
#include "keys.h"
#include "documents.h"
+#include "transformInternals.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_FUNCTION
@@ -145,7 +146,20 @@ xsltDocumentFunctionLoadDocument(xmlXPat
/*
* This selects the stylesheet's doc itself.
*/
- doc = tctxt->style->doc;
+ doc = xmlCopyDoc(tctxt->style->doc, 1);
+ if (doc == NULL) {
+ xsltTransformError(tctxt, NULL, NULL,
+ "document() : failed to copy style doc\n");
+ goto out_fragment;
+ }
+ xsltCleanupSourceDoc(doc); /* Remove psvi fields. */
+ idoc = xsltNewDocument(tctxt, doc);
+ if (idoc == NULL) {
+ xsltTransformError(tctxt, NULL, NULL,
+ "document() : failed to create xsltDocument\n");
+ xmlFreeDoc(doc);
+ goto out_fragment;
+ }
} else {
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
Index: libxslt-1.1.38/libxslt/transform.c
===================================================================
--- libxslt-1.1.38.orig/libxslt/transform.c
+++ libxslt-1.1.38/libxslt/transform.c
@@ -43,6 +43,7 @@
#include "xsltlocale.h"
#include "pattern.h"
#include "transform.h"
+#include "transformInternals.h"
#include "variables.h"
#include "numbersInternals.h"
#include "namespaces.h"
@@ -5743,7 +5744,7 @@ xsltCountKeys(xsltTransformContextPtr ct
*
* Resets source node flags and ids stored in 'psvi' member.
*/
-static void
+void
xsltCleanupSourceDoc(xmlDocPtr doc) {
xmlNodePtr cur = (xmlNodePtr) doc;
void **psviPtr;
Index: libxslt-1.1.38/libxslt/transformInternals.h
===================================================================
--- /dev/null
+++ libxslt-1.1.38/libxslt/transformInternals.h
@@ -0,0 +1,9 @@
+/*
+ * Summary: set of internal interfaces for the XSLT engine transformation part.
+ *
+ * Copy: See Copyright for the status of this software.
+ *
+ * Author: David Kilzer <ddkilzer@apple.com>
+ */
+
+void xsltCleanupSourceDoc(xmlDocPtr doc);

View File

@@ -8,7 +8,7 @@ Index: libxslt-v1.1.36/libexslt/math.c
===================================================================
--- libxslt-v1.1.36.orig/libexslt/math.c
+++ libxslt-v1.1.36/libexslt/math.c
@@ -12,6 +12,12 @@
@@ -12,6 +12,14 @@
#include <math.h>
#include <stdlib.h>
@@ -16,7 +16,9 @@ Index: libxslt-v1.1.36/libexslt/math.c
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
#include "exslt.h"

View File

@@ -1,159 +1,39 @@
-------------------------------------------------------------------
Fri Mar 14 15:00:15 UTC 2025 - Pedro Monreal <pmonreal@suse.com>
Wed Oct 15 08:17:24 UTC 2025 - pgajdos@suse.com
- Update to 1.1.43:
* Major changes:
- The non-standard EXSLT crypto extensions and support for dynamically
loaded plugins are now disabled by default. These features can be
enabled by passing --with-crypto or --with-plugins to configure.
In a future release, these features will be removed.
- Debug output and the debugger are disabled by default and can be
enabled by passing --with-debug or --with-debugger.
* Security:
- [bsc#1239625, CVE-2025-24855] Fix use-after-free of XPath context node
- [bsc#1239637, CVE-2024-55549] Fix UAF related to excluded namespaces
* Bug fixes:
- variables: Fix non-deterministic generated IDs
* libxml2 related cleanup:
- python: Don't use removed libxml2 macro
- tests: Skip test_bad.xsl with libxml2 before 2.13
- python: Don't include nanoftp.h and nanohttp.h
- tests: Avoid namespace warning on Windows
- numbers: Stop using libxml2 XPath axis API
- numbers: Use private copy of xmlCopyCharMultiByte
- documents: Use xmlCtxtParseDocument if available
- tests: Make runtest compile with older libxml2 versions
- utils: Account for libxml2 change
- tests: Make bug-219.xsl compatible with older libxml2
- extensions: always include stdlib.h (Hugo Beauzée-Luyssen)
- extensions: Don't use libxml2's "modules" feature
* Code cleanup:
- numbers: Make static variables const
- variables: Remove debug code
* Portability:
- python: Declare init func with PyMODINIT_FUNC
- exslt: Use C99 NAN macro
* Build:
- cmake: Always build Python module as shared library
- cmake: Fix compatibility in package version file
- configure.ac: Find libgcrypt via pkg-config (Alessandro Astone)
* Remove patches fixed in the update:
- libxslt-reproducible.patch
- libxslt-test-compile-with-older-libxml2-versions.patch
- security update
- added patches
CVE-2025-11731 [bsc#1251979], type confusion in exsltFuncResultCompfunction leading to denial of service
* libxslt-CVE-2025-11731.patch
-------------------------------------------------------------------
Sat Jan 18 10:20:18 UTC 2025 - Pedro Monreal <pmonreal@suse.com>
Thu Oct 2 13:19:06 UTC 2025 - pgajdos@suse.com
- Remove the test_bad regression test that fails with old libxml2
as suggested by upstream devs:
* https://gitlab.gnome.org/GNOME/libxslt/-/issues/126
- security update
- added patches
CVE-2025-10911 [bsc#1250553], use-after-free with key data stored cross-RVT
* libxslt-CVE-2025-10911.patch
-------------------------------------------------------------------
Sat Jan 18 10:00:30 UTC 2025 - Pedro Monreal <pmonreal@suse.com>
Thu Jul 17 09:41:58 UTC 2025 - pgajdos@suse.com
- Allow building with older libxml2 versions:
* tests: Make runtest compile with older libxml2 versions
* https://gitlab.gnome.org/GNOME/libxslt/issues/125
* Add libxslt-test-compile-with-older-libxml2-versions.patch
- security update
- added patches
CVE-2025-7424 [bsc#1246360], Type confusion in xmlNode.psvi between stylesheet and source nodes
+ libxslt-CVE-2025-7424.patch
-------------------------------------------------------------------
Fri Jan 17 15:53:19 UTC 2025 - Pedro Monreal <pmonreal@suse.com>
Wed Mar 19 13:45:27 UTC 2025 - Pedro Monreal <pmonreal@suse.com>
- Update to 1.1.42:
* Regressions:
- extensions: Readd call to xmlCheckFilename with older libxml2
* Improvments:
- utils: Don't use deprecated xmlCharEncodingHandler member
- transform: Handle filesystem paths after libxml2 changes
- locale: Work around issue with FreeBSD's strxfrm_l
* Build systems:
- cmake: Add LIBXSLT_WITH_PROGRAMS option (Don Olmstead)
- cmake: Fix HAVE_GCRYPT check
- Update to 1.1.41:
* Removals:
- autotools: Stop installing libxslt.m4
- autotools: Remove RPM build
* Improvements:
- libxslt: Set _FILE_OFFSET_BITS to 64
- xsltproc: Remove unneeded includes
- include: Don't define ATTRIBUTE_UNUSED in public header
- xsltproc: Make "-" read from stdin
* Build systems:
- cmake: Adjust paths for UNIX or UNIX-like target systems (Daniel E)
* Tests:
- cmake: Link testplugin with libxml2
- tests: Link testplugin with libxml2
- tests: Fix expected error after libxml2 change
- runtest: Switch to xmlFormatError
- fuzz: Avoid accessing internal struct members
- Update to 1.1.40:
* Removals:
- xsltproc: remove maxparserdepth option (Mike Dalessio)
* Improvements:
- functions: xmlXPtrNewContext is deprecated
- xsltproc: Stop calling xmlMemoryDump
- xsltproc: Prefer XML_PARSE_NONET over xmlNoNetEntityLoader
- functions: Fix build if libxml2 modules are disabled
- extensions: Don't call deprecated xmlCheckFilename
- documents: Don't set ctxt->directory
- exslt: Fix EXSLT functions without parameters
* Build systems:
- build: Remove mem-debug option
* Remove patches upstream:
- gcc14-runtest-no-const.patch
- 0001-tests-Fix-build-with-older-libxml2.patch
-------------------------------------------------------------------
Fri Sep 20 14:27:35 UTC 2024 - Bernhard Wiedemann <bwiedemann@suse.com>
- Add libxslt-reproducible.patch to make xml output deterministic (boo#1062303)
-------------------------------------------------------------------
Fri May 24 16:14:39 UTC 2024 - Christophe Marin <christophe@krop.fr>
- Add upstream build fix:
* 0001-tests-Fix-build-with-older-libxml2.patch
-------------------------------------------------------------------
Sun May 5 16:26:10 UTC 2024 - Bruno Pitrus <brunopitrus@hotmail.com>
- Fix ftbfs with GCC14 (bsc#1220571)
* correct libxslt-random-seed.patch to include time.h unconditionally
* add gcc14-runtest-no-const.patch
-------------------------------------------------------------------
Fri Nov 24 20:53:10 UTC 2023 - Bjørn Lie <bjorn.lie@gmail.com>
- Update to version 1.1.39:
* Bug fixes: extensions: Don't search imports for extension
prefixes
* Improvements:
- transform: Check maximum depth when processing default
templates
- build:
. Add more missing include
. Add missing includes
- python: Don't set deprecated global
- imports: Limit nesting depth
- extensions: Report top-level elements in
xsltDebugDumpExtensions
- Add extern "C" { } block to xsltlocale.h
* Portability:
- python: Make it compatible with python3.12
- date:
. Fix check for localtime_s
. Fix check for gmtime_s
* Build systems:
- pkg-config files include cflags for static builds
- Handle NOCONFIG case when setting locations from CMake target
properties
- autotools: Make xslt-config executable
* Tests:
- tests: Structured error handler now passes a const xmlError
- python: Fix tests on MinGW
- fuzz: Fix xmlFuzzEntityLoader after recent libxml2 changes
- Security fixes:
* Fix use-after-free of XPath context node [bsc#1239625, CVE-2025-24855]
* Fix UAF related to excluded namespaces [bsc#1239637, CVE-2024-55549]
* Make generate-id() deterministic [bsc#1238591, CVE-2023-40403]
Just adding the reference here as this CVE was already fixed
in 0009-Make-generate-id-deterministic.patch
* Add patches:
- libxslt-CVE-2024-55549.patch
- libxslt-CVE-2025-24855.patch
-------------------------------------------------------------------
Tue May 9 16:09:17 UTC 2023 - David Anes <david.anes@suse.com>

View File

@@ -1,7 +1,7 @@
#
# spec file for package libxslt
#
# Copyright (c) 2025 SUSE LLC
# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
%define libexver 0
Name: libxslt
Version: 1.1.43
Version: 1.1.38
Release: 0
Summary: XSL Transformation Library
License: GPL-2.0-or-later AND MIT
@@ -40,6 +40,16 @@ Patch0: libxslt-1.1.24-no-net-autobuild.patch
# Initialize the random seed to ensure libxslt's math.random() function
# produces unpredictable outputs.
Patch1: libxslt-random-seed.patch
# PATCH-FIX-UPSTREAM bsc#1239625 CVE-2025-24855 Fix use-after-free of XPath context node
Patch2: libxslt-CVE-2024-55549.patch
# PATCH-FIX-UPSTREAM bsc#1239637 CVE-2024-55549 Fix UAF related to excluded namespaces
Patch3: libxslt-CVE-2025-24855.patch
# CVE-2025-7424 [bsc#1246360], Type confusion in xmlNode.psvi between stylesheet and source nodes
Patch4: libxslt-CVE-2025-7424.patch
# CVE-2025-10911 [bsc#1250553], use-after-free with key data stored cross-RVT
Patch5: libxslt-CVE-2025-10911.patch
# CVE-2025-11731 [bsc#1251979], type confusion in exsltFuncResultCompfunction leading to denial of service
Patch6: libxslt-CVE-2025-11731.patch
#
### SUSE patches starts on 1000
# PATCH-FIX-SUSE
@@ -128,7 +138,6 @@ xtend the
%make_build
%check
find -type f -name "test_bad*" -delete -print
%make_build check
%install
@@ -148,21 +157,21 @@ find %{buildroot} -type f -name "*.la" -delete -print
%ldconfig_scriptlets -n libexslt%{libexver}
%files -n libxslt%{libver}
%license Copyright
%license COPYING* Copyright
%{_libdir}/libxslt.so.%{libver}*
%files -n libexslt%{libexver}
%license Copyright
%license COPYING* Copyright
%{_libdir}/libexslt.so.%{libexver}*
%files tools
%license Copyright
%license COPYING* Copyright
%doc AUTHORS NEWS TODO FEATURES
%{_bindir}/xsltproc
%{_mandir}/man1/xsltproc.1%{?ext_man}
%files devel
%license Copyright
%license COPYING* Copyright
%{_libdir}/libxslt.so
%{_libdir}/libexslt.so
%{_libdir}/*.sh
@@ -172,6 +181,7 @@ find %{buildroot} -type f -name "*.la" -delete -print
%{_libdir}/cmake/libxslt/FindGcrypt.cmake
%{_libdir}/cmake/libxslt/libxslt-config.cmake
%{_includedir}/*
%{_datadir}/aclocal/*
%{_bindir}/xslt-config
%{_mandir}/man1/xslt-config.1%{?ext_man}
%{_mandir}/man3/*