Skip to content

Commit e03c952

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 aa39b4e commit e03c952

File tree

1 file changed

+13
-8
lines changed
  • src/backend/utils/adt

1 file changed

+13
-8
lines changed

src/backend/utils/adt/xml.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ xmltext(PG_FUNCTION_ARGS)
532532
volatile xmlChar *xmlbuf = NULL;
533533
PgXmlErrorContext *xmlerrcxt;
534534

535-
/* Otherwise, we gotta spin up some error handling. */
535+
/* First we gotta spin up some error handling. */
536536
xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
537537

538538
PG_TRY();
@@ -685,7 +685,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
685685
volatile xmlBufferPtr buf = NULL;
686686
volatile xmlSaveCtxtPtr ctxt = NULL;
687687
ErrorSaveContext escontext = {T_ErrorSaveContext};
688-
PgXmlErrorContext *xmlerrcxt;
688+
PgXmlErrorContext *volatile xmlerrcxt = NULL;
689689
#endif
690690

691691
if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
@@ -726,13 +726,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
726726
return (text *) data;
727727
}
728728

729-
/* Otherwise, we gotta spin up some error handling. */
730-
xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
731-
729+
/*
730+
* Otherwise, we gotta spin up some error handling. Unlike most other
731+
* routines in this module, we already have a libxml "doc" structure to
732+
* free, so we need to call pg_xml_init() inside the PG_TRY and be
733+
* prepared for it to fail (typically due to palloc OOM).
734+
*/
732735
PG_TRY();
733736
{
734737
size_t decl_len = 0;
735738

739+
xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
740+
736741
/* The serialized data will go into this buffer. */
737742
buf = xmlBufferCreate();
738743

@@ -863,10 +868,10 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
863868
xmlSaveClose(ctxt);
864869
if (buf)
865870
xmlBufferFree(buf);
866-
if (doc)
867-
xmlFreeDoc(doc);
871+
xmlFreeDoc(doc);
868872

869-
pg_xml_done(xmlerrcxt, true);
873+
if (xmlerrcxt)
874+
pg_xml_done(xmlerrcxt, true);
870875

871876
PG_RE_THROW();
872877
}

0 commit comments

Comments
 (0)