Saturday, August 30, 2025

Re: libxslt patches

OK aja

On Fri, Aug 29, 2025 at 04:56:09PM +0200, Theo Buehler wrote:
> There's been a bit of noise about this recently so I looked and noticed
> we have not yet pulled in the available patches. It doesn't sound like a
> big deal since it appears untrusted style sheets are involved. Still,
> it seems like something we want to patch.
>
> https://vuxml.freebsd.org/freebsd/b0a3466f-5efc-11f0-ae84-99047d0a6bcc.html
>
> lists four issues, three of which are public and have patches from apple
> and google.
>
> Two of them are for libxslt and apply cleanly. Those are included below:
>
> https://gitlab.gnome.org/GNOME/libxslt/-/issues/139
> https://gitlab.gnome.org/GNOME/libxslt/-/issues/144
>
> Regress still passes.
>
> The third one is quite confusing since part of it seems to be about
> libxml2 and some of the fixes implicate binary compatibility. The apple
> patch doesn't apply cleanly to our port:
>
> https://gitlab.gnome.org/GNOME/libxslt/-/issues/140
>
> I leave that one to the maintainer to sort out.
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/textproc/libxslt/Makefile,v
> diff -u -p -r1.110 Makefile
> --- Makefile 15 Mar 2025 09:34:42 -0000 1.110
> +++ Makefile 29 Aug 2025 13:17:48 -0000
> @@ -2,7 +2,7 @@ COMMENT= XSLT C Library for GNOME
>
> GNOME_VERSION= 1.1.43
> GNOME_PROJECT= libxslt
> -REVISION= 0
> +REVISION= 1
>
> SHARED_LIBS += xslt 4.2 # 2.43
> SHARED_LIBS += exslt 9.8 # 8.24
> Index: patches/patch-libxslt_functions_c
> ===================================================================
> RCS file: patches/patch-libxslt_functions_c
> diff -N patches/patch-libxslt_functions_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libxslt_functions_c 29 Aug 2025 13:17:48 -0000
> @@ -0,0 +1,55 @@
> +https://gitlab.gnome.org/GNOME/libxslt/-/issues/139
> +
> +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.
> +
> +Index: libxslt/functions.c
> +--- libxslt/functions.c.orig
> ++++ 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
> +@@ -125,7 +126,20 @@ xsltDocumentFunctionLoadDocument(xmlXPathParserContext
> + /*
> + * 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 {
> + goto out_fragment;
> + }
> Index: patches/patch-libxslt_transformInternals_h
> ===================================================================
> RCS file: patches/patch-libxslt_transformInternals_h
> diff -N patches/patch-libxslt_transformInternals_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libxslt_transformInternals_h 29 Aug 2025 13:17:48 -0000
> @@ -0,0 +1,35 @@
> +https://gitlab.gnome.org/GNOME/libxslt/-/issues/139
> +
> +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.
> +
> +Index: libxslt/transformInternals.h
> +--- libxslt/transformInternals.h.orig
> ++++ 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);
> Index: patches/patch-libxslt_transform_c
> ===================================================================
> RCS file: patches/patch-libxslt_transform_c
> diff -N patches/patch-libxslt_transform_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-libxslt_transform_c 29 Aug 2025 13:17:48 -0000
> @@ -0,0 +1,258 @@
> +https://gitlab.gnome.org/GNOME/libxslt/-/issues/139
> +https://gitlab.gnome.org/GNOME/libxslt/-/issues/144
> +
> +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.
> +
> +From f94e7e9796edeb6f3bedd3fdb1099e9b556aea21 Mon Sep 17 00:00:00 2001
> +From: Daniel Cheng <dcheng@chromium.org>
> +Date: Sat, 31 May 2025 00:15:24 -0700
> +Subject: [PATCH] Use a dedicated node type to maintain the list of cached RVTs
> +
> +While evaluating a stylesheet, result value trees (result tree fragments
> +in the XSLT spec) are represented as xmlDocs and cached on the transform
> +context in a linked list, using xmlDoc's prev and next pointers to
> +maintain the list.
> +
> +However, XPath evaluations can inadvertently traverse these links, which
> +are an implementation detail and do not reflect the actual document
> +structure. Using a dedicated node type avoids these unintended
> +traversals.
> +
> +Index: libxslt/transform.c
> +--- libxslt/transform.c.orig
> ++++ 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"
> +@@ -518,19 +519,20 @@ xsltTransformCacheFree(xsltTransformCachePtr cache)
> + /*
> + * 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);
> + }
> + }
> + /*
> +@@ -2263,38 +2265,40 @@ xsltLocalVariablePush(xsltTransformContextPtr ctxt,
> + * 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;
> ++ /* Reset localRVTList early because some RVTs might be registered again. */
> ++ ctxt->localRVTList = base;
> + if (base != NULL)
> + base->prev = NULL;
> +
> + 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);
> + }
> +@@ -2322,7 +2326,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr c
> + xmlNodePtr oldInsert, oldInst, oldCurInst, oldContextNode;
> + xmlNodePtr cur, insert, copy = NULL;
> + int level = 0, oldVarsNr;
> +- xmlDocPtr oldLocalFragmentTop;
> ++ xsltRVTListPtr oldLocalFragmentTop;
> +
> + #ifdef XSLT_REFACTORED
> + xsltStylePreCompPtr info;
> +@@ -2368,7 +2372,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr c
> + }
> + ctxt->depth++;
> +
> +- oldLocalFragmentTop = ctxt->localRVT;
> ++ oldLocalFragmentTop = ctxt->localRVTList;
> + oldInsert = insert = ctxt->insert;
> + oldInst = oldCurInst = ctxt->inst;
> + oldContextNode = ctxt->node;
> +@@ -2602,7 +2606,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr c
> + /*
> + * Cleanup temporary tree fragments.
> + */
> +- if (oldLocalFragmentTop != ctxt->localRVT)
> ++ if (oldLocalFragmentTop != ctxt->localRVTList)
> + xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
> +
> + ctxt->insert = oldInsert;
> +@@ -2697,7 +2701,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr c
> + /*
> + * Cleanup temporary tree fragments.
> + */
> +- if (oldLocalFragmentTop != ctxt->localRVT)
> ++ if (oldLocalFragmentTop != ctxt->localRVTList)
> + xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
> +
> + ctxt->insert = oldInsert;
> +@@ -2763,7 +2767,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr c
> + /*
> + * Cleanup temporary tree fragments.
> + */
> +- if (oldLocalFragmentTop != ctxt->localRVT)
> ++ if (oldLocalFragmentTop != ctxt->localRVTList)
> + xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
> +
> + ctxt->insert = oldInsert;
> +@@ -2893,7 +2897,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr c
> + /*
> + * Cleanup temporary tree fragments.
> + */
> +- if (oldLocalFragmentTop != ctxt->localRVT)
> ++ if (oldLocalFragmentTop != ctxt->localRVTList)
> + xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
> +
> + ctxt->insert = oldInsert;
> +@@ -3072,7 +3076,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
> + int oldVarsBase = 0;
> + xmlNodePtr cur;
> + xsltStackElemPtr tmpParam = NULL;
> +- xmlDocPtr oldUserFragmentTop;
> ++ xsltRVTListPtr oldUserFragmentTop;
> + #ifdef WITH_PROFILER
> + long start = 0;
> +

No comments:

Post a Comment