Skip to content

Commit 95cf1a1

Browse files
committed
Fix low-probability memory leak in XMLSERIALIZE(... INDENT).
xmltotext_with_options() did not consider the possibility that pg_xml_init() could fail --- most likely due to OOM. If that happened, the already-parsed xmlDoc structure would be leaked. Oversight in commit 483bdb2. Bug: #18981 Author: Dmitry Kovalenko <d.kovalenko@postgrespro.ru> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/18981-9bc3c80f107ae925@postgresql.org Backpatch-through: 16
1 parent a553a22 commit 95cf1a1

File tree

1 file changed

+12
-7
lines changed
  • src/backend/utils/adt

1 file changed

+12
-7
lines changed

src/backend/utils/adt/xml.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
663663
volatile xmlBufferPtr buf = NULL;
664664
volatile xmlSaveCtxtPtr ctxt = NULL;
665665
ErrorSaveContext escontext = {T_ErrorSaveContext};
666-
PgXmlErrorContext *xmlerrcxt;
666+
PgXmlErrorContext *volatile xmlerrcxt = NULL;
667667
#endif
668668

669669
if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
@@ -704,13 +704,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
704704
return (text *) data;
705705
}
706706

707-
/* Otherwise, we gotta spin up some error handling. */
708-
xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
709-
707+
/*
708+
* Otherwise, we gotta spin up some error handling. Unlike most other
709+
* routines in this module, we already have a libxml "doc" structure to
710+
* free, so we need to call pg_xml_init() inside the PG_TRY and be
711+
* prepared for it to fail (typically due to palloc OOM).
712+
*/
710713
PG_TRY();
711714
{
712715
size_t decl_len = 0;
713716

717+
xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
718+
714719
/* The serialized data will go into this buffer. */
715720
buf = xmlBufferCreate();
716721

@@ -838,10 +843,10 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
838843
xmlSaveClose(ctxt);
839844
if (buf)
840845
xmlBufferFree(buf);
841-
if (doc)
842-
xmlFreeDoc(doc);
846+
xmlFreeDoc(doc);
843847

844-
pg_xml_done(xmlerrcxt, true);
848+
if (xmlerrcxt)
849+
pg_xml_done(xmlerrcxt, true);
845850

846851
PG_RE_THROW();
847852
}

0 commit comments

Comments
 (0)