pg.ddx.io pgsql-hackers@postgresql.org mailing list archive
help / color / mirror / Atom feed[PATCH v2 4/4] xml2: Avoid libxml leaks in pgxml_xpath() error paths
1+ messages / 1 participants
[nested] [flat]
* [PATCH v2 4/4] xml2: Avoid libxml leaks in pgxml_xpath() error paths
@ 2026-06-01 22:41 Andrey Chernyy <andrey.cherny@tantorlabs.com>
0 siblings, 0 replies; 1+ messages in thread
From: Andrey Chernyy @ 2026-06-01 22:41 UTC (permalink / raw)
pgxml_xpath() builds an xpath_workspace before returning it to
callers. If an ERROR is thrown before the function returns, callers
have not received the workspace pointer yet and cannot run
cleanup_workspace().
Add local error cleanup for the partially built workspace and the
compiled XPath expression. Also check xmlXPathNewContext() before
dereferencing the returned context.
---
contrib/xml2/xpath.c | 51 +++++++++++++++++++++++++++-----------------
1 file changed, 32 insertions(+), 19 deletions(-)
inline patch 1: contrib/xml2/xpath.c (+32/-19 lines) download inline-1.patch
diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c
index 9fe75cb5ff4..283bb51178d 100644
--- a/contrib/xml2/xpath.c
+++ b/contrib/xml2/xpath.c
@@ -497,36 +497,49 @@ static xpath_workspace *
pgxml_xpath(text *document, xmlChar *xpath, PgXmlErrorContext *xmlerrcxt)
{
int32 docsize = VARSIZE_ANY_EXHDR(document);
- xmlXPathCompExprPtr comppath;
+ xmlXPathCompExprPtr volatile comppath = NULL;
xpath_workspace *workspace = palloc0_object(xpath_workspace);
workspace->doctree = NULL;
workspace->ctxt = NULL;
workspace->res = NULL;
- workspace->doctree = xmlReadMemory((char *) VARDATA_ANY(document),
- docsize, NULL, NULL,
- XML_PARSE_NOENT);
- if (workspace->doctree != NULL)
+ PG_TRY();
{
- workspace->ctxt = xmlXPathNewContext(workspace->doctree);
- workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);
-
- /* compile the path */
- comppath = xmlXPathCtxtCompile(workspace->ctxt, xpath);
- if (comppath == NULL || pg_xml_error_occurred(xmlerrcxt))
+ workspace->doctree = xmlReadMemory((char *) VARDATA_ANY(document),
+ docsize, NULL, NULL,
+ XML_PARSE_NOENT);
+ if (workspace->doctree != NULL)
{
- if (comppath != NULL)
- xmlXPathFreeCompExpr(comppath);
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
- "XPath Syntax Error");
- }
+ workspace->ctxt = xmlXPathNewContext(workspace->doctree);
+ if (workspace->ctxt == NULL)
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate XPath context");
- /* Now evaluate the path expression. */
- workspace->res = xmlXPathCompiledEval(comppath, workspace->ctxt);
+ workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);
+
+ /* compile the path */
+ comppath = xmlXPathCtxtCompile(workspace->ctxt, xpath);
+ if (comppath == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
+ "XPath Syntax Error");
+
+ /* Now evaluate the path expression. */
+ workspace->res = xmlXPathCompiledEval(comppath, workspace->ctxt);
+
+ xmlXPathFreeCompExpr(comppath);
+ comppath = NULL;
+ }
+ }
+ PG_CATCH();
+ {
+ if (comppath != NULL)
+ xmlXPathFreeCompExpr(comppath);
+ cleanup_workspace(workspace);
- xmlXPathFreeCompExpr(comppath);
+ PG_RE_THROW();
}
+ PG_END_TRY();
return workspace;
}
--
2.54.0
--MP_/LMSk9=uMhuQ1QiIJDarDO8G--
^ permalink raw reply [nested|flat] 1+ messages in thread
only message in thread
Thread overview: 1+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-06-01 22:41 [PATCH v2 4/4] xml2: Avoid libxml leaks in pgxml_xpath() error paths Andrey Chernyy <andrey.cherny@tantorlabs.com>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox