agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Andrey Chernyy <[email protected]>
Subject: [PATCH v2 4/4] xml2: Avoid libxml leaks in pgxml_xpath() error paths
Date: Tue, 2 Jun 2026 01:41:38 +0300
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(-)
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--
view thread (1049+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v2 4/4] xml2: Avoid libxml leaks in pgxml_xpath() error paths
In-Reply-To: <no-message-id-458027@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox