aboutsummaryrefslogtreecommitdiff
path: root/contrib/xml2/xslt_proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/xml2/xslt_proc.c')
-rw-r--r--contrib/xml2/xslt_proc.c79
1 files changed, 58 insertions, 21 deletions
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 90232eb0a1d..6e4bf550517 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -26,6 +26,7 @@
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
+#include <libxslt/security.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#endif /* USE_LIBXSLT */
@@ -62,7 +63,10 @@ xslt_process(PG_FUNCTION_ARGS)
xsltStylesheetPtr stylesheet = NULL;
xmlDocPtr doctree;
xmlDocPtr restree;
- xmlDocPtr ssdoc = NULL;
+ xmlDocPtr ssdoc;
+ xsltSecurityPrefsPtr xslt_sec_prefs;
+ bool xslt_sec_prefs_error;
+ xsltTransformContextPtr xslt_ctxt;
xmlChar *resstr;
int resstat;
int reslen;
@@ -79,34 +83,27 @@ xslt_process(PG_FUNCTION_ARGS)
/* Setup parser */
pgxml_parser_init();
- /* Check to see if document is a file or a literal */
-
- if (VARDATA(doct)[0] == '<')
- doctree = xmlParseMemory((char *) VARDATA(doct), VARSIZE(doct) - VARHDRSZ);
- else
- doctree = xmlParseFile(text_to_cstring(doct));
+ /* Parse document */
+ doctree = xmlParseMemory((char *) VARDATA(doct),
+ VARSIZE(doct) - VARHDRSZ);
if (doctree == NULL)
xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
"error parsing XML document");
/* Same for stylesheet */
- if (VARDATA(ssheet)[0] == '<')
- {
- ssdoc = xmlParseMemory((char *) VARDATA(ssheet),
- VARSIZE(ssheet) - VARHDRSZ);
- if (ssdoc == NULL)
- {
- xmlFreeDoc(doctree);
- xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
- "error parsing stylesheet as XML document");
- }
+ ssdoc = xmlParseMemory((char *) VARDATA(ssheet),
+ VARSIZE(ssheet) - VARHDRSZ);
- stylesheet = xsltParseStylesheetDoc(ssdoc);
+ if (ssdoc == NULL)
+ {
+ xmlFreeDoc(doctree);
+ xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+ "error parsing stylesheet as XML document");
}
- else
- stylesheet = xsltParseStylesheetFile((xmlChar *) text_to_cstring(ssheet));
+ /* After this call we need not free ssdoc separately */
+ stylesheet = xsltParseStylesheetDoc(ssdoc);
if (stylesheet == NULL)
{
@@ -116,12 +113,50 @@ xslt_process(PG_FUNCTION_ARGS)
"failed to parse stylesheet");
}
- restree = xsltApplyStylesheet(stylesheet, doctree, params);
+ xslt_ctxt = xsltNewTransformContext(stylesheet, doctree);
+
+ xslt_sec_prefs_error = false;
+ if ((xslt_sec_prefs = xsltNewSecurityPrefs()) == NULL)
+ xslt_sec_prefs_error = true;
+
+ if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_READ_FILE,
+ xsltSecurityForbid) != 0)
+ xslt_sec_prefs_error = true;
+ if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_WRITE_FILE,
+ xsltSecurityForbid) != 0)
+ xslt_sec_prefs_error = true;
+ if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_CREATE_DIRECTORY,
+ xsltSecurityForbid) != 0)
+ xslt_sec_prefs_error = true;
+ if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_READ_NETWORK,
+ xsltSecurityForbid) != 0)
+ xslt_sec_prefs_error = true;
+ if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_WRITE_NETWORK,
+ xsltSecurityForbid) != 0)
+ xslt_sec_prefs_error = true;
+ if (xsltSetCtxtSecurityPrefs(xslt_sec_prefs, xslt_ctxt) != 0)
+ xslt_sec_prefs_error = true;
+
+ if (xslt_sec_prefs_error)
+ {
+ xsltFreeStylesheet(stylesheet);
+ xmlFreeDoc(doctree);
+ xsltFreeSecurityPrefs(xslt_sec_prefs);
+ xsltFreeTransformContext(xslt_ctxt);
+ xsltCleanupGlobals();
+ xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+ "could not set libxslt security preferences");
+ }
+
+ restree = xsltApplyStylesheetUser(stylesheet, doctree, params,
+ NULL, NULL, xslt_ctxt);
if (restree == NULL)
{
xsltFreeStylesheet(stylesheet);
xmlFreeDoc(doctree);
+ xsltFreeSecurityPrefs(xslt_sec_prefs);
+ xsltFreeTransformContext(xslt_ctxt);
xsltCleanupGlobals();
xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
"failed to apply stylesheet");
@@ -132,6 +167,8 @@ xslt_process(PG_FUNCTION_ARGS)
xsltFreeStylesheet(stylesheet);
xmlFreeDoc(restree);
xmlFreeDoc(doctree);
+ xsltFreeSecurityPrefs(xslt_sec_prefs);
+ xsltFreeTransformContext(xslt_ctxt);
xsltCleanupGlobals();