mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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 483bdb2af.
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
			
			
This commit is contained in:
		@@ -642,7 +642,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
 | 
				
			|||||||
	volatile xmlBufferPtr buf = NULL;
 | 
						volatile xmlBufferPtr buf = NULL;
 | 
				
			||||||
	volatile xmlSaveCtxtPtr ctxt = NULL;
 | 
						volatile xmlSaveCtxtPtr ctxt = NULL;
 | 
				
			||||||
	ErrorSaveContext escontext = {T_ErrorSaveContext};
 | 
						ErrorSaveContext escontext = {T_ErrorSaveContext};
 | 
				
			||||||
	PgXmlErrorContext *xmlerrcxt;
 | 
						PgXmlErrorContext *volatile xmlerrcxt = NULL;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
 | 
						if (xmloption_arg != XMLOPTION_DOCUMENT && !indent)
 | 
				
			||||||
@@ -683,13 +683,18 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
 | 
				
			|||||||
		return (text *) data;
 | 
							return (text *) data;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Otherwise, we gotta spin up some error handling. */
 | 
						/*
 | 
				
			||||||
	xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
 | 
						 * Otherwise, we gotta spin up some error handling.  Unlike most other
 | 
				
			||||||
 | 
						 * routines in this module, we already have a libxml "doc" structure to
 | 
				
			||||||
 | 
						 * free, so we need to call pg_xml_init() inside the PG_TRY and be
 | 
				
			||||||
 | 
						 * prepared for it to fail (typically due to palloc OOM).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	PG_TRY();
 | 
						PG_TRY();
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		size_t		decl_len = 0;
 | 
							size_t		decl_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* The serialized data will go into this buffer. */
 | 
							/* The serialized data will go into this buffer. */
 | 
				
			||||||
		buf = xmlBufferCreate();
 | 
							buf = xmlBufferCreate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -817,10 +822,10 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
 | 
				
			|||||||
			xmlSaveClose(ctxt);
 | 
								xmlSaveClose(ctxt);
 | 
				
			||||||
		if (buf)
 | 
							if (buf)
 | 
				
			||||||
			xmlBufferFree(buf);
 | 
								xmlBufferFree(buf);
 | 
				
			||||||
		if (doc)
 | 
							xmlFreeDoc(doc);
 | 
				
			||||||
			xmlFreeDoc(doc);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pg_xml_done(xmlerrcxt, true);
 | 
							if (xmlerrcxt)
 | 
				
			||||||
 | 
								pg_xml_done(xmlerrcxt, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PG_RE_THROW();
 | 
							PG_RE_THROW();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user