external/libxslt/77.patch.1                         |  706 ++++++++++++++++++++
 external/libxslt/UnpackedTarball_libxslt.mk         |    1 
 framework/source/fwe/helper/actiontriggerhelper.cxx |   13 
 sd/source/ui/view/DocumentRenderer.cxx              |    6 
 4 files changed, 717 insertions(+), 9 deletions(-)

New commits:
commit 4986c9c9cc556da7c97c3a41157885dcd1fb110a
Author:     Michael Stahl <[email protected]>
AuthorDate: Wed Oct 15 16:48:21 2025 +0200
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Nov 3 17:05:50 2025 +0100

    libxslt: add patch for CVE-2025-10911
    
    Change-Id: I951aad2bff3911f685f73390e4f42ed29fe49b41
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192444
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Stephan Bergmann <[email protected]>
    (cherry picked from commit fca876c2c369b26244413fafe506acafb9d3b5bf)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192864
    Reviewed-by: Michael Weghorn <[email protected]>
    Reviewed-by: Xisco Fauli <[email protected]>
    Tested-by: Ilmari Lauhakangas <[email protected]>

diff --git a/external/libxslt/77.patch.1 b/external/libxslt/77.patch.1
new file mode 100644
index 000000000000..a5d77a6a96e0
--- /dev/null
+++ b/external/libxslt/77.patch.1
@@ -0,0 +1,706 @@
+From a3139eabb3e204f62e42ae226c8eeea964611733 Mon Sep 17 00:00:00 2001
+From: Daniel Cheng <[email protected]>
+Date: Thu, 5 Jun 2025 09:43:53 -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.
+
+Fixes #144.
+---
+ libxslt/transform.c     |  87 ++++++++--------
+ libxslt/variables.c     | 219 +++++++++++++++++++++++++---------------
+ libxslt/xsltInternals.h |  23 +++--
+ 3 files changed, 199 insertions(+), 130 deletions(-)
+
+diff --git a/libxslt/transform.c b/libxslt/transform.c
+index 54ef821b..2d06ae77 100644
+--- a/libxslt/transform.c
++++ b/libxslt/transform.c
+@@ -518,19 +518,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 +2264,36 @@ 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
");
+ 
+-    /* 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
",
+-                    tmp->psvi);
++                    "xsltReleaseLocalRVTs: Unexpected RVT flag %d
",
++                    tmp->RVT->compression);
+         }
+     } while (cur != base);
+ }
+@@ -2322,7 +2321,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr 
ctxt,
+     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 +2367,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr 
ctxt,
+     }
+     ctxt->depth++;
+ 
+-    oldLocalFragmentTop = ctxt->localRVT;
++    oldLocalFragmentTop = ctxt->localRVTList;
+     oldInsert = insert = ctxt->insert;
+     oldInst = oldCurInst = ctxt->inst;
+     oldContextNode = ctxt->node;
+@@ -2602,7 +2601,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr 
ctxt,
+                   /*
+                   * Cleanup temporary tree fragments.
+                   */
+-                  if (oldLocalFragmentTop != ctxt->localRVT)
++                  if (oldLocalFragmentTop != ctxt->localRVTList)
+                       xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
+ 
+                   ctxt->insert = oldInsert;
+@@ -2697,7 +2696,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr 
ctxt,
+                   /*
+                   * Cleanup temporary tree fragments.
+                   */
+-                  if (oldLocalFragmentTop != ctxt->localRVT)
++                  if (oldLocalFragmentTop != ctxt->localRVTList)
+                       xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
+ 
+                   ctxt->insert = oldInsert;
+@@ -2763,7 +2762,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr 
ctxt,
+               /*
+               * Cleanup temporary tree fragments.
+               */
+-              if (oldLocalFragmentTop != ctxt->localRVT)
++              if (oldLocalFragmentTop != ctxt->localRVTList)
+                   xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
+ 
+                 ctxt->insert = oldInsert;
+@@ -2893,7 +2892,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr 
ctxt,
+               /*
+               * Cleanup temporary tree fragments.
+               */
+-              if (oldLocalFragmentTop != ctxt->localRVT)
++              if (oldLocalFragmentTop != ctxt->localRVTList)
+                   xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
+ 
+                 ctxt->insert = oldInsert;
+@@ -3072,7 +3071,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
+     int oldVarsBase = 0;
+     xmlNodePtr cur;
+     xsltStackElemPtr tmpParam = NULL;
+-    xmlDocPtr oldUserFragmentTop;
++    xsltRVTListPtr oldUserFragmentTop;
+ #ifdef WITH_PROFILER
+     long start = 0;
+ #endif
+@@ -3120,8 +3119,8 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
+         return;
+       }
+ 
+-    oldUserFragmentTop = ctxt->tmpRVT;
+-    ctxt->tmpRVT = NULL;
++    oldUserFragmentTop = ctxt->tmpRVTList;
++    ctxt->tmpRVTList = NULL;
+ 
+     /*
+     * Initiate a distinct scope of local params/variables.
+@@ -3232,16 +3231,16 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
+     * 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.
+@@ -5319,7 +5318,7 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr 
contextNode,
+ 
+ #ifdef XSLT_FAST_IF
+     {
+-      xmlDocPtr oldLocalFragmentTop = ctxt->localRVT;
++      xsltRVTListPtr oldLocalFragmentTop = ctxt->localRVTList;
+ 
+       res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp);
+ 
+@@ -5327,7 +5326,7 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr 
contextNode,
+       * Cleanup fragments created during evaluation of the
+       * "select" expression.
+       */
+-      if (oldLocalFragmentTop != ctxt->localRVT)
++      if (oldLocalFragmentTop != ctxt->localRVTList)
+           xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
+     }
+ 
+diff --git a/libxslt/variables.c b/libxslt/variables.c
+index eb98aab2..6696d9a1 100644
+--- a/libxslt/variables.c
++++ b/libxslt/variables.c
+@@ -47,6 +47,21 @@ static const xmlChar *xsltComputingGlobalVarMarker =
+ #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
");
++      return(NULL);
++    }
++    memset(ret, 0, sizeof(xsltRVTList));
++    return(ret);
++}
++
+ /************************************************************************
+  *                                                                    *
+  *  Result Value Tree (Result Tree Fragment) interfaces                       
*
+@@ -64,6 +79,7 @@ static const xmlChar *xsltComputingGlobalVarMarker =
+ xmlDocPtr
+ xsltCreateRVT(xsltTransformContextPtr ctxt)
+ {
++    xsltRVTListPtr rvtList;
+     xmlDocPtr container;
+ 
+     /*
+@@ -76,12 +92,11 @@ xsltCreateRVT(xsltTransformContextPtr ctxt)
+     /*
+     * 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 ctxt)
+ 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(xsltTransformContextPtr ctxt, 
xmlDocPtr RVT)
+     * 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(xsltTransformContextPtr ctxt,
+     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(xsltTransformContextPtr ctxt,
+     * 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 ctxt, 
xmlXPathObjectPtr obj, int val) {
+  * @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 ctxt, xmlDocPtr 
RVT)
+     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 (list->RVT->children != NULL) {
++          xmlFreeNodeList(list->RVT->children);
++          list->RVT->children = NULL;
++          list->RVT->last = NULL;
+       }
+-      if (RVT->ids != NULL) {
+-          xmlFreeIDTable((xmlIDTablePtr) RVT->ids);
+-          RVT->ids = 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 ctxt, xmlDocPtr 
RVT)
+     /*
+     * 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 ctxt, xmlDocPtr 
RVT)
+ 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(xsltTransformContextPtr ctxt, 
xmlDocPtr RVT)
+ 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;
+-
+-            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;
++          elem->fragment = cur->next;
++
++            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
",
+-                        cur->compression);
++                        cur->RVT->compression);
+             }
+       }
+     }
+@@ -944,6 +1002,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, 
xsltStackElemPtr variable,
+       } else {
+           if (variable->tree) {
+               xmlDocPtr container;
++                xsltRVTListPtr rvtList;
+               xmlNodePtr oldInsert;
+               xmlDocPtr  oldOutput;
+                 const xmlChar *oldLastText;
+@@ -968,7 +1027,11 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, 
xsltStackElemPtr variable,
+               * 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);
+ }
+-
+-
+diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
+index 6faa07db..ec84e1df 100644
+--- a/libxslt/xsltInternals.h
++++ b/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__ */
+-
+-- 
+GitLab
+
diff --git a/external/libxslt/UnpackedTarball_libxslt.mk 
b/external/libxslt/UnpackedTarball_libxslt.mk
index 06519e74ae4b..bd2417841e07 100644
--- a/external/libxslt/UnpackedTarball_libxslt.mk
+++ b/external/libxslt/UnpackedTarball_libxslt.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,libxslt,\
                external/libxslt/libxslt-msvc.patch.2) \
        external/libxslt/rpath.patch.0 \
        external/libxslt/gnome-libxslt-bug-139-apple-fix.diff.1 \
+       external/libxslt/77.patch.1 \
 ))
 
 # vim: set noet sw=4 ts=4:
commit 7d271f90984038127550ae70ac0b0deaee5c1255
Author:     Xisco Fauli <[email protected]>
AuthorDate: Thu Oct 23 10:34:40 2025 +0200
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Nov 3 17:05:45 2025 +0100

    tdf#169015: GetOutlinerParaObject might return nullptr
    
    Regression from
    commit 43e511e642a2ce7026b30ea5c212940ff3eb522e
    Author: Tibor Nagy <[email protected]>
    Date:   Fri Nov 29 02:10:21 2024 +0100
    
        tdf#88226 sd: fix cutting off the overflow text on the notes print page
    
    Change-Id: I4e25760afe4bd535d1accf8291f9cbb4457625ad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192895
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Jenkins
    Tested-by: Caolán McNamara <[email protected]>
    (cherry picked from commit 9a406c26e8b8d09b99c949192bc731ba6126cef0)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192907
    Reviewed-by: Michael Weghorn <[email protected]>
    Reviewed-by: Adolfo Jayme Barrientos <[email protected]>
    Reviewed-by: Xisco Fauli <[email protected]>
    Tested-by: Ilmari Lauhakangas <[email protected]>

diff --git a/sd/source/ui/view/DocumentRenderer.cxx 
b/sd/source/ui/view/DocumentRenderer.cxx
index 53b9737f5e8b..a7835759ad61 100644
--- a/sd/source/ui/view/DocumentRenderer.cxx
+++ b/sd/source/ui/view/DocumentRenderer.cxx
@@ -889,7 +889,8 @@ namespace {
                 pOut->SetPaperSize(aNotesSize);
                 pOut->SetUpdateLayout(true);
                 pOut->Clear();
-                pOut->SetText(*pNotesObj->GetOutlinerParaObject());
+                if (OutlinerParaObject* pOutlinerParaObject = 
pNotesObj->GetOutlinerParaObject())
+                    pOut->SetText(*pOutlinerParaObject);
 
                 bool bAutoGrow = 
pNotesObj->GetMergedItem(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue();
 
@@ -2523,7 +2524,8 @@ private:
                     pOut->SetPaperSize(nNotesObjSize);
                     pOut->SetUpdateLayout(true);
                     pOut->Clear();
-                    pOut->SetText(*pNotesObj->GetOutlinerParaObject());
+                    if (OutlinerParaObject* pOutlinerParaObject = 
pNotesObj->GetOutlinerParaObject())
+                        pOut->SetText(*pOutlinerParaObject);
 
                     sal_Int32 nFirstPageBottomMargin = 0;
                     ::tools::Long nNotesHeight = nNotesObjSize.Height();
commit 25a24b99856a9725567fde096e7e11f0a3539ce4
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Oct 29 22:45:15 2025 +0500
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Nov 3 17:05:37 2025 +0100

    tdf#168314: check if xGraphic is empty, not Any
    
    Regression after commit 9d6e1594a298c9d41f3dc64ad80edf4b9868c2e8
    (Deduplicate and unify using vcl::GetBitmap, 2024-11-08).
    
    An Any with an empty graphic is not itself empty; such an any caused
    the outer check to succeed, and therefore its 'else' branch never
    executed, when it ought to.
    
    Change-Id: I97115c7f7dbab4ec54b5e999e4b47ecdc8874e47
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193161
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>
    (cherry picked from commit a8216f500c223797b13976678924b76c5effec65)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193170
    Reviewed-by: Xisco Fauli <[email protected]>
    (cherry picked from commit da6b70633ac6bf78ce0a68022518396a2c650970)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193184
    Tested-by: Ilmari Lauhakangas <[email protected]>
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/framework/source/fwe/helper/actiontriggerhelper.cxx 
b/framework/source/fwe/helper/actiontriggerhelper.cxx
index e1ae01a4da28..00a2aed51661 100644
--- a/framework/source/fwe/helper/actiontriggerhelper.cxx
+++ b/framework/source/fwe/helper/actiontriggerhelper.cxx
@@ -65,7 +65,7 @@ static void GetMenuItemAttributes( const Reference< 
XPropertySet >& xActionTrigg
                             OUString& aMenuLabel,
                             OUString& aCommandURL,
                             OUString& aHelpURL,
-                            Any& rImage,
+                            Reference<css::graphic::XGraphic>& xGraphic,
                             Reference< XIndexContainer >& xSubContainer )
 {
     try
@@ -73,7 +73,7 @@ static void GetMenuItemAttributes( const Reference< 
XPropertySet >& xActionTrigg
         // mandatory properties
         xActionTriggerPropertySet->getPropertyValue(u"Text"_ustr) >>= 
aMenuLabel;
         xActionTriggerPropertySet->getPropertyValue(u"CommandURL"_ustr) >>= 
aCommandURL;
-        rImage = xActionTriggerPropertySet->getPropertyValue(u"Image"_ustr);
+        xGraphic = 
vcl::GetGraphic(xActionTriggerPropertySet->getPropertyValue(u"Image"_ustr));
         xActionTriggerPropertySet->getPropertyValue(u"SubContainer"_ustr) >>= 
xSubContainer;
     }
     catch (const Exception&)
@@ -117,11 +117,11 @@ static void InsertSubMenuItems(const 
Reference<XPopupMenu>& rSubMenu, sal_uInt16
                     OUString aLabel;
                     OUString aCommandURL;
                     OUString aHelpURL;
-                    Any aImage;
+                    Reference<css::graphic::XGraphic> xGraphic;
                     Reference< XIndexContainer > xSubContainer;
 
                     sal_uInt16 nNewItemId = nItemId++;
-                    GetMenuItemAttributes( xPropSet, aLabel, aCommandURL, 
aHelpURL, aImage, xSubContainer );
+                    GetMenuItemAttributes( xPropSet, aLabel, aCommandURL, 
aHelpURL, xGraphic, xSubContainer );
 
                     {
                         // insert new menu item
@@ -142,10 +142,9 @@ static void InsertSubMenuItems(const 
Reference<XPopupMenu>& rSubMenu, sal_uInt16
                         }
 
                         // handle bitmap
-                        if (aImage.hasValue())
+                        if (xGraphic)
                         {
-                            if (auto xGraphic = vcl::GetGraphic(aImage))
-                                rSubMenu->setItemImage(nNewItemId, xGraphic, 
false);
+                            rSubMenu->setItemImage(nNewItemId, xGraphic, 
false);
                         }
                         else
                         {

Reply via email to