postgres.git / summary / log / commit / refs

commit    9ec568b3eb6a8e8aad9041078e4c7bfedf293ca8
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Fri Jun 05 05:29:27 2026 +0000

    xml2: Fix stylesheet document leak in xslt_process()
    
    xslt_process() parses the stylesheet text into an xmlDoc before passing it
    to xsltParseStylesheetDoc().  On success, the returned stylesheet owns
    that document and frees it through xsltFreeStylesheet(), calling
    xmlFreeDoc() at its end.  On failure, libxslt leaves the caller
    responsible for the xmlDoc.  In xml2, this would cause the memory
    allocated for the xmlDoc to pile up across calls of xslt_process() when
    failing to create a sheet.
    
    While on it, I have double-checked the code of xml2 with libxslt, and it
    seems that we are in the clear now, hopefully..  This leak exists for a
    long time.  732061150b0 has made the fix introduced in this commit
    easier to implement.
    
    Author: Andrey Chernyy <andrey.cherny@tantorlabs.com>
    Discussion: https://postgr.es/m/20260605024642.5a1b6518@andrnote


contrib/xml2/xslt_proc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c index 8ceb8c46494..c42469cfaa3 100644 --- a/contrib/xml2/xslt_proc.c +++ b/contrib/xml2/xslt_proc.c @@ -55,6 +55,7 @@ xslt_process(PG_FUNCTION_ARGS) PgXmlErrorContext *xmlerrcxt; volatile xsltStylesheetPtr stylesheet = NULL; volatile xmlDocPtr doctree = NULL; + volatile xmlDocPtr ssdoc = NULL; volatile xmlDocPtr restree = NULL; volatile xsltSecurityPrefsPtr xslt_sec_prefs = NULL; volatile xsltTransformContextPtr xslt_ctxt = NULL; @@ -78,7 +79,6 @@ xslt_process(PG_FUNCTION_ARGS) PG_TRY(); { - xmlDocPtr ssdoc; bool xslt_sec_prefs_error; int reslen = 0; @@ -100,8 +100,13 @@ xslt_process(PG_FUNCTION_ARGS) xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT, "error parsing stylesheet as XML document"); - /* After this call we need not free ssdoc separately */ + /* + * On success, the stylesheet owns ssdoc, with xsltFreeStylesheet() + * calling xmlFreeDoc() on its associated doc. + */ stylesheet = xsltParseStylesheetDoc(ssdoc); + if (stylesheet != NULL) + ssdoc = NULL; if (stylesheet == NULL || pg_xml_error_occurred(xmlerrcxt)) xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY, @@ -167,6 +172,8 @@ xslt_process(PG_FUNCTION_ARGS) xsltFreeSecurityPrefs(xslt_sec_prefs); if (stylesheet != NULL) xsltFreeStylesheet(stylesheet); + if (ssdoc != NULL) + xmlFreeDoc(ssdoc); if (doctree != NULL) xmlFreeDoc(doctree); if (resstr != NULL)