aboutsummaryrefslogtreecommitdiff
path: root/contrib/xml2
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/xml2')
-rw-r--r--contrib/xml2/xpath.c421
-rw-r--r--contrib/xml2/xslt_proc.c26
2 files changed, 296 insertions, 151 deletions
diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c
index 23d3f332dba..3f733405ec6 100644
--- a/contrib/xml2/xpath.c
+++ b/contrib/xml2/xpath.c
@@ -51,10 +51,10 @@ static text *pgxml_result_to_text(xmlXPathObjectPtr res, xmlChar *toptag,
static xmlChar *pgxml_texttoxmlchar(text *textstring);
-static xmlXPathObjectPtr pgxml_xpath(text *document, xmlChar *xpath,
- xpath_workspace *workspace);
+static xpath_workspace *pgxml_xpath(text *document, xmlChar *xpath,
+ PgXmlErrorContext *xmlerrcxt);
-static void cleanup_workspace(xpath_workspace *workspace);
+static void cleanup_workspace(volatile xpath_workspace *workspace);
/*
@@ -89,18 +89,40 @@ xml_encode_special_chars(PG_FUNCTION_ARGS)
{
text *tin = PG_GETARG_TEXT_PP(0);
text *tout;
- xmlChar *ts,
- *tt;
+ volatile xmlChar *tt = NULL;
+ PgXmlErrorContext *xmlerrcxt;
+
+ xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
+
+ PG_TRY();
+ {
+ xmlChar *ts;
- ts = pgxml_texttoxmlchar(tin);
+ ts = pgxml_texttoxmlchar(tin);
+
+ tt = xmlEncodeSpecialChars(NULL, ts);
+ if (tt == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xmlChar");
+ pfree(ts);
+
+ tout = cstring_to_text((char *) tt);
+ }
+ PG_CATCH();
+ {
+ if (tt != NULL)
+ xmlFree((xmlChar *) tt);
- tt = xmlEncodeSpecialChars(NULL, ts);
+ pg_xml_done(xmlerrcxt, true);
- pfree(ts);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- tout = cstring_to_text((char *) tt);
+ if (tt != NULL)
+ xmlFree((xmlChar *) tt);
- xmlFree(tt);
+ pg_xml_done(xmlerrcxt, false);
PG_RETURN_TEXT_P(tout);
}
@@ -122,62 +144,90 @@ pgxmlNodeSetToText(xmlNodeSetPtr nodeset,
xmlChar *septagname,
xmlChar *plainsep)
{
- xmlBufferPtr buf;
+ volatile xmlBufferPtr buf = NULL;
xmlChar *result;
int i;
+ PgXmlErrorContext *xmlerrcxt;
- buf = xmlBufferCreate();
+ /* spin some error handling */
+ xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
- if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
- {
- xmlBufferWriteChar(buf, "<");
- xmlBufferWriteCHAR(buf, toptagname);
- xmlBufferWriteChar(buf, ">");
- }
- if (nodeset != NULL)
+ PG_TRY();
{
- for (i = 0; i < nodeset->nodeNr; i++)
- {
- if (plainsep != NULL)
- {
- xmlBufferWriteCHAR(buf,
- xmlXPathCastNodeToString(nodeset->nodeTab[i]));
+ buf = xmlBufferCreate();
- /* If this isn't the last entry, write the plain sep. */
- if (i < (nodeset->nodeNr) - 1)
- xmlBufferWriteChar(buf, (char *) plainsep);
- }
- else
+ if (buf == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate xmlBuffer");
+
+ if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
+ {
+ xmlBufferWriteChar(buf, "<");
+ xmlBufferWriteCHAR(buf, toptagname);
+ xmlBufferWriteChar(buf, ">");
+ }
+ if (nodeset != NULL)
+ {
+ for (i = 0; i < nodeset->nodeNr; i++)
{
- if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
+ if (plainsep != NULL)
{
- xmlBufferWriteChar(buf, "<");
- xmlBufferWriteCHAR(buf, septagname);
- xmlBufferWriteChar(buf, ">");
- }
- xmlNodeDump(buf,
- nodeset->nodeTab[i]->doc,
- nodeset->nodeTab[i],
- 1, 0);
+ xmlBufferWriteCHAR(buf,
+ xmlXPathCastNodeToString(nodeset->nodeTab[i]));
- if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
+ /* If this isn't the last entry, write the plain sep. */
+ if (i < (nodeset->nodeNr) - 1)
+ xmlBufferWriteChar(buf, (char *) plainsep);
+ }
+ else
{
- xmlBufferWriteChar(buf, "</");
- xmlBufferWriteCHAR(buf, septagname);
- xmlBufferWriteChar(buf, ">");
+ if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
+ {
+ xmlBufferWriteChar(buf, "<");
+ xmlBufferWriteCHAR(buf, septagname);
+ xmlBufferWriteChar(buf, ">");
+ }
+ xmlNodeDump(buf,
+ nodeset->nodeTab[i]->doc,
+ nodeset->nodeTab[i],
+ 1, 0);
+
+ if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
+ {
+ xmlBufferWriteChar(buf, "</");
+ xmlBufferWriteCHAR(buf, septagname);
+ xmlBufferWriteChar(buf, ">");
+ }
}
}
}
- }
- if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
+ if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
+ {
+ xmlBufferWriteChar(buf, "</");
+ xmlBufferWriteCHAR(buf, toptagname);
+ xmlBufferWriteChar(buf, ">");
+ }
+
+ result = xmlStrdup(buf->content);
+ if (result == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate result");
+ }
+ PG_CATCH();
{
- xmlBufferWriteChar(buf, "</");
- xmlBufferWriteCHAR(buf, toptagname);
- xmlBufferWriteChar(buf, ">");
+ if (buf)
+ xmlBufferFree(buf);
+
+ pg_xml_done(xmlerrcxt, true);
+
+ PG_RE_THROW();
}
- result = xmlStrdup(buf->content);
+ PG_END_TRY();
+
xmlBufferFree(buf);
+ pg_xml_done(xmlerrcxt, false);
+
return result;
}
@@ -208,16 +258,29 @@ xpath_nodeset(PG_FUNCTION_ARGS)
xmlChar *septag = pgxml_texttoxmlchar(PG_GETARG_TEXT_PP(3));
xmlChar *xpath;
text *xpres;
- xmlXPathObjectPtr res;
- xpath_workspace workspace;
+ volatile xpath_workspace *workspace;
+ PgXmlErrorContext *xmlerrcxt;
xpath = pgxml_texttoxmlchar(xpathsupp);
+ xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);
- res = pgxml_xpath(document, xpath, &workspace);
+ PG_TRY();
+ {
+ workspace = pgxml_xpath(document, xpath, xmlerrcxt);
+ xpres = pgxml_result_to_text(workspace->res, toptag, septag, NULL);
+ }
+ PG_CATCH();
+ {
+ if (workspace)
+ cleanup_workspace(workspace);
- xpres = pgxml_result_to_text(res, toptag, septag, NULL);
+ pg_xml_done(xmlerrcxt, true);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- cleanup_workspace(&workspace);
+ cleanup_workspace(workspace);
+ pg_xml_done(xmlerrcxt, false);
pfree(xpath);
@@ -240,16 +303,29 @@ xpath_list(PG_FUNCTION_ARGS)
xmlChar *plainsep = pgxml_texttoxmlchar(PG_GETARG_TEXT_PP(2));
xmlChar *xpath;
text *xpres;
- xmlXPathObjectPtr res;
- xpath_workspace workspace;
+ volatile xpath_workspace *workspace;
+ PgXmlErrorContext *xmlerrcxt;
xpath = pgxml_texttoxmlchar(xpathsupp);
+ xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);
- res = pgxml_xpath(document, xpath, &workspace);
+ PG_TRY();
+ {
+ workspace = pgxml_xpath(document, xpath, xmlerrcxt);
+ xpres = pgxml_result_to_text(workspace->res, NULL, NULL, plainsep);
+ }
+ PG_CATCH();
+ {
+ if (workspace)
+ cleanup_workspace(workspace);
- xpres = pgxml_result_to_text(res, NULL, NULL, plainsep);
+ pg_xml_done(xmlerrcxt, true);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- cleanup_workspace(&workspace);
+ cleanup_workspace(workspace);
+ pg_xml_done(xmlerrcxt, false);
pfree(xpath);
@@ -269,8 +345,8 @@ xpath_string(PG_FUNCTION_ARGS)
xmlChar *xpath;
int32 pathsize;
text *xpres;
- xmlXPathObjectPtr res;
- xpath_workspace workspace;
+ volatile xpath_workspace *workspace;
+ PgXmlErrorContext *xmlerrcxt;
pathsize = VARSIZE_ANY_EXHDR(xpathsupp);
@@ -286,11 +362,25 @@ xpath_string(PG_FUNCTION_ARGS)
xpath[pathsize + 7] = ')';
xpath[pathsize + 8] = '\0';
- res = pgxml_xpath(document, xpath, &workspace);
+ xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);
+
+ PG_TRY();
+ {
+ workspace = pgxml_xpath(document, xpath, xmlerrcxt);
+ xpres = pgxml_result_to_text(workspace->res, NULL, NULL, NULL);
+ }
+ PG_CATCH();
+ {
+ if (workspace)
+ cleanup_workspace(workspace);
- xpres = pgxml_result_to_text(res, NULL, NULL, NULL);
+ pg_xml_done(xmlerrcxt, true);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- cleanup_workspace(&workspace);
+ cleanup_workspace(workspace);
+ pg_xml_done(xmlerrcxt, false);
pfree(xpath);
@@ -308,24 +398,38 @@ xpath_number(PG_FUNCTION_ARGS)
text *document = PG_GETARG_TEXT_PP(0);
text *xpathsupp = PG_GETARG_TEXT_PP(1); /* XPath expression */
xmlChar *xpath;
- float4 fRes;
- xmlXPathObjectPtr res;
- xpath_workspace workspace;
+ float4 fRes = 0.0;
+ bool isNull = false;
+ volatile xpath_workspace *workspace = NULL;
+ PgXmlErrorContext *xmlerrcxt;
xpath = pgxml_texttoxmlchar(xpathsupp);
+ xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);
- res = pgxml_xpath(document, xpath, &workspace);
-
- pfree(xpath);
+ PG_TRY();
+ {
+ workspace = pgxml_xpath(document, xpath, xmlerrcxt);
+ pfree(xpath);
- if (res == NULL)
- PG_RETURN_NULL();
+ if (workspace->res == NULL)
+ isNull = true;
+ else
+ fRes = xmlXPathCastToNumber(workspace->res);
+ }
+ PG_CATCH();
+ {
+ if (workspace)
+ cleanup_workspace(workspace);
- fRes = xmlXPathCastToNumber(res);
+ pg_xml_done(xmlerrcxt, true);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- cleanup_workspace(&workspace);
+ cleanup_workspace(workspace);
+ pg_xml_done(xmlerrcxt, false);
- if (xmlXPathIsNaN(fRes))
+ if (isNull || xmlXPathIsNaN(fRes))
PG_RETURN_NULL();
PG_RETURN_FLOAT4(fRes);
@@ -341,21 +445,34 @@ xpath_bool(PG_FUNCTION_ARGS)
text *xpathsupp = PG_GETARG_TEXT_PP(1); /* XPath expression */
xmlChar *xpath;
int bRes;
- xmlXPathObjectPtr res;
- xpath_workspace workspace;
+ volatile xpath_workspace *workspace = NULL;
+ PgXmlErrorContext *xmlerrcxt;
xpath = pgxml_texttoxmlchar(xpathsupp);
+ xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);
- res = pgxml_xpath(document, xpath, &workspace);
-
- pfree(xpath);
+ PG_TRY();
+ {
+ workspace = pgxml_xpath(document, xpath, xmlerrcxt);
+ pfree(xpath);
- if (res == NULL)
- PG_RETURN_BOOL(false);
+ if (workspace->res == NULL)
+ bRes = 0;
+ else
+ bRes = xmlXPathCastToBoolean(workspace->res);
+ }
+ PG_CATCH();
+ {
+ if (workspace)
+ cleanup_workspace(workspace);
- bRes = xmlXPathCastToBoolean(res);
+ pg_xml_done(xmlerrcxt, true);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- cleanup_workspace(&workspace);
+ cleanup_workspace(workspace);
+ pg_xml_done(xmlerrcxt, false);
PG_RETURN_BOOL(bRes);
}
@@ -364,62 +481,44 @@ xpath_bool(PG_FUNCTION_ARGS)
/* Core function to evaluate XPath query */
-static xmlXPathObjectPtr
-pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
+static xpath_workspace *
+pgxml_xpath(text *document, xmlChar *xpath, PgXmlErrorContext *xmlerrcxt)
{
int32 docsize = VARSIZE_ANY_EXHDR(document);
- PgXmlErrorContext *xmlerrcxt;
xmlXPathCompExprPtr comppath;
+ xpath_workspace *workspace = (xpath_workspace *)
+ palloc0(sizeof(xpath_workspace));
workspace->doctree = NULL;
workspace->ctxt = NULL;
workspace->res = NULL;
- xmlerrcxt = pgxml_parser_init(PG_XML_STRICTNESS_LEGACY);
-
- PG_TRY();
+ workspace->doctree = xmlReadMemory((char *) VARDATA_ANY(document),
+ docsize, NULL, NULL,
+ XML_PARSE_NOENT);
+ if (workspace->doctree != NULL)
{
- workspace->doctree = xmlReadMemory((char *) VARDATA_ANY(document),
- docsize, NULL, NULL,
- XML_PARSE_NOENT);
- if (workspace->doctree != NULL)
- {
- workspace->ctxt = xmlXPathNewContext(workspace->doctree);
- workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);
-
- /* compile the path */
- comppath = xmlXPathCtxtCompile(workspace->ctxt, xpath);
- if (comppath == NULL)
- xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
- "XPath Syntax Error");
+ workspace->ctxt = xmlXPathNewContext(workspace->doctree);
+ workspace->ctxt->node = xmlDocGetRootElement(workspace->doctree);
- /* Now evaluate the path expression. */
- workspace->res = xmlXPathCompiledEval(comppath, workspace->ctxt);
+ /* 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");
- xmlXPathFreeCompExpr(comppath);
- }
- }
- PG_CATCH();
- {
- cleanup_workspace(workspace);
-
- pg_xml_done(xmlerrcxt, true);
+ /* Now evaluate the path expression. */
+ workspace->res = xmlXPathCompiledEval(comppath, workspace->ctxt);
- PG_RE_THROW();
+ xmlXPathFreeCompExpr(comppath);
}
- PG_END_TRY();
- if (workspace->res == NULL)
- cleanup_workspace(workspace);
-
- pg_xml_done(xmlerrcxt, false);
-
- return workspace->res;
+ return workspace;
}
/* Clean up after processing the result of pgxml_xpath() */
static void
-cleanup_workspace(xpath_workspace *workspace)
+cleanup_workspace(volatile xpath_workspace *workspace)
{
if (workspace->res)
xmlXPathFreeObject(workspace->res);
@@ -438,34 +537,59 @@ pgxml_result_to_text(xmlXPathObjectPtr res,
xmlChar *septag,
xmlChar *plainsep)
{
- xmlChar *xpresstr;
+ volatile xmlChar *xpresstr = NULL;
+ PgXmlErrorContext *xmlerrcxt;
text *xpres;
if (res == NULL)
return NULL;
- switch (res->type)
- {
- case XPATH_NODESET:
- xpresstr = pgxmlNodeSetToText(res->nodesetval,
- toptag,
- septag, plainsep);
- break;
+ /* spin some error handling */
+ xmlerrcxt = pg_xml_init(PG_XML_STRICTNESS_ALL);
- case XPATH_STRING:
- xpresstr = xmlStrdup(res->stringval);
- break;
+ PG_TRY();
+ {
+ switch (res->type)
+ {
+ case XPATH_NODESET:
+ xpresstr = pgxmlNodeSetToText(res->nodesetval,
+ toptag,
+ septag, plainsep);
+ break;
+
+ case XPATH_STRING:
+ xpresstr = xmlStrdup(res->stringval);
+ if (xpresstr == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate result");
+ break;
+
+ default:
+ elog(NOTICE, "unsupported XQuery result: %d", res->type);
+ xpresstr = xmlStrdup((const xmlChar *) "<unsupported/>");
+ if (xpresstr == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate result");
+ }
- default:
- elog(NOTICE, "unsupported XQuery result: %d", res->type);
- xpresstr = xmlStrdup((const xmlChar *) "<unsupported/>");
+ /* Now convert this result back to text */
+ xpres = cstring_to_text((char *) xpresstr);
}
+ PG_CATCH();
+ {
+ if (xpresstr != NULL)
+ xmlFree((xmlChar *) xpresstr);
- /* Now convert this result back to text */
- xpres = cstring_to_text((char *) xpresstr);
+ pg_xml_done(xmlerrcxt, true);
+
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
/* Free various storage */
- xmlFree(xpresstr);
+ xmlFree((xmlChar *) xpresstr);
+
+ pg_xml_done(xmlerrcxt, false);
return xpres;
}
@@ -648,11 +772,16 @@ xpath_table(PG_FUNCTION_ARGS)
for (j = 0; j < numpaths; j++)
{
ctxt = xmlXPathNewContext(doctree);
+ if (ctxt == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt,
+ ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate XPath context");
+
ctxt->node = xmlDocGetRootElement(doctree);
/* compile the path */
comppath = xmlXPathCtxtCompile(ctxt, xpaths[j]);
- if (comppath == NULL)
+ if (comppath == NULL || pg_xml_error_occurred(xmlerrcxt))
xml_ereport(xmlerrcxt, ERROR,
ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
"XPath Syntax Error");
@@ -671,6 +800,10 @@ xpath_table(PG_FUNCTION_ARGS)
rownr < res->nodesetval->nodeNr)
{
resstr = xmlXPathCastNodeToString(res->nodesetval->nodeTab[rownr]);
+ if (resstr == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt,
+ ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate result");
had_values = true;
}
else
@@ -680,11 +813,19 @@ xpath_table(PG_FUNCTION_ARGS)
case XPATH_STRING:
resstr = xmlStrdup(res->stringval);
+ if (resstr == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt,
+ ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate result");
break;
default:
elog(NOTICE, "unsupported XQuery result: %d", res->type);
resstr = xmlStrdup((const xmlChar *) "<unsupported/>");
+ if (resstr == NULL || pg_xml_error_occurred(xmlerrcxt))
+ xml_ereport(xmlerrcxt,
+ ERROR, ERRCODE_OUT_OF_MEMORY,
+ "could not allocate result");
}
/*
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index b720d89f754..c8e7dd45ed5 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -58,7 +58,7 @@ xslt_process(PG_FUNCTION_ARGS)
volatile xsltSecurityPrefsPtr xslt_sec_prefs = NULL;
volatile xsltTransformContextPtr xslt_ctxt = NULL;
volatile int resstat = -1;
- xmlChar *resstr = NULL;
+ volatile xmlChar *resstr = NULL;
int reslen = 0;
if (fcinfo->nargs == 3)
@@ -86,7 +86,7 @@ xslt_process(PG_FUNCTION_ARGS)
VARSIZE_ANY_EXHDR(doct), NULL, NULL,
XML_PARSE_NOENT);
- if (doctree == NULL)
+ if (doctree == NULL || pg_xml_error_occurred(xmlerrcxt))
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
"error parsing XML document");
@@ -95,14 +95,14 @@ xslt_process(PG_FUNCTION_ARGS)
VARSIZE_ANY_EXHDR(ssheet), NULL, NULL,
XML_PARSE_NOENT);
- if (ssdoc == NULL)
+ if (ssdoc == NULL || pg_xml_error_occurred(xmlerrcxt))
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
"error parsing stylesheet as XML document");
/* After this call we need not free ssdoc separately */
stylesheet = xsltParseStylesheetDoc(ssdoc);
- if (stylesheet == NULL)
+ if (stylesheet == NULL || pg_xml_error_occurred(xmlerrcxt))
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
"failed to parse stylesheet");
@@ -137,11 +137,15 @@ xslt_process(PG_FUNCTION_ARGS)
restree = xsltApplyStylesheetUser(stylesheet, doctree, params,
NULL, NULL, xslt_ctxt);
- if (restree == NULL)
+ if (restree == NULL || pg_xml_error_occurred(xmlerrcxt))
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
"failed to apply stylesheet");
- resstat = xsltSaveResultToString(&resstr, &reslen, restree, stylesheet);
+ resstat = xsltSaveResultToString((xmlChar **) &resstr, &reslen,
+ restree, stylesheet);
+
+ if (resstat >= 0)
+ result = cstring_to_text_with_len((char *) resstr, reslen);
}
PG_CATCH();
{
@@ -155,6 +159,8 @@ xslt_process(PG_FUNCTION_ARGS)
xsltFreeStylesheet(stylesheet);
if (doctree != NULL)
xmlFreeDoc(doctree);
+ if (resstr != NULL)
+ xmlFree((xmlChar *) resstr);
xsltCleanupGlobals();
pg_xml_done(xmlerrcxt, true);
@@ -170,17 +176,15 @@ xslt_process(PG_FUNCTION_ARGS)
xmlFreeDoc(doctree);
xsltCleanupGlobals();
+ if (resstr)
+ xmlFree((xmlChar *) resstr);
+
pg_xml_done(xmlerrcxt, false);
/* XXX this is pretty dubious, really ought to throw error instead */
if (resstat < 0)
PG_RETURN_NULL();
- result = cstring_to_text_with_len((char *) resstr, reslen);
-
- if (resstr)
- xmlFree(resstr);
-
PG_RETURN_TEXT_P(result);
#else /* !USE_LIBXSLT */