summaryrefslogtreecommitdiff
path: root/src/xslt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xslt.c')
-rw-r--r--src/xslt.c695
1 files changed, 397 insertions, 298 deletions
diff --git a/src/xslt.c b/src/xslt.c
index e5e52685..0353a251 100644
--- a/src/xslt.c
+++ b/src/xslt.c
@@ -1,11 +1,11 @@
-/**
+/**
* XML Security Library (http://www.aleksey.com/xmlsec).
*
* XSLT Transform (http://www.w3.org/TR/xmldsig-core/#sec-XSLT)
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
- *
+ *
* Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
*/
#include "globals.h"
@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <string.h>
-
+
#include <libxml/tree.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
@@ -28,122 +28,173 @@
#include <xmlsec/keys.h>
#include <xmlsec/parser.h>
#include <xmlsec/errors.h>
+#include <xmlsec/private/xslt.h>
/**************************************************************************
*
* Internal xslt ctx
*
*****************************************************************************/
-typedef struct _xmlSecXsltCtx xmlSecXsltCtx, *xmlSecXsltCtxPtr;
+typedef struct _xmlSecXsltCtx xmlSecXsltCtx, *xmlSecXsltCtxPtr;
struct _xmlSecXsltCtx {
- xsltStylesheetPtr xslt;
- xmlParserCtxtPtr parserCtx;
-};
+ xsltStylesheetPtr xslt;
+ xmlParserCtxtPtr parserCtx;
+};
/****************************************************************************
*
* XSLT transform
*
* xmlSecXsltCtx is located after xmlSecTransform
- *
+ *
***************************************************************************/
-#define xmlSecXsltSize \
- (sizeof(xmlSecTransform) + sizeof(xmlSecXsltCtx))
+#define xmlSecXsltSize \
+ (sizeof(xmlSecTransform) + sizeof(xmlSecXsltCtx))
#define xmlSecXsltGetCtx(transform) \
((xmlSecXsltCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
-static int xmlSecXsltInitialize (xmlSecTransformPtr transform);
-static void xmlSecXsltFinalize (xmlSecTransformPtr transform);
-static int xmlSecXsltReadNode (xmlSecTransformPtr transform,
- xmlNodePtr node,
- xmlSecTransformCtxPtr transformCtx);
-static int xmlSecXsltPushBin (xmlSecTransformPtr transform,
- const xmlSecByte* data,
- xmlSecSize dataSize,
- int final,
- xmlSecTransformCtxPtr transformCtx);
-static int xmlSecXsltExecute (xmlSecTransformPtr transform,
- int last,
- xmlSecTransformCtxPtr transformCtx);
-static int xmlSecXslProcess (xmlSecBufferPtr in,
- xmlSecBufferPtr out,
- xsltStylesheetPtr stylesheet);
+static int xmlSecXsltInitialize (xmlSecTransformPtr transform);
+static void xmlSecXsltFinalize (xmlSecTransformPtr transform);
+static int xmlSecXsltReadNode (xmlSecTransformPtr transform,
+ xmlNodePtr node,
+ xmlSecTransformCtxPtr transformCtx);
+static int xmlSecXsltPushBin (xmlSecTransformPtr transform,
+ const xmlSecByte* data,
+ xmlSecSize dataSize,
+ int final,
+ xmlSecTransformCtxPtr transformCtx);
+static int xmlSecXsltExecute (xmlSecTransformPtr transform,
+ int last,
+ xmlSecTransformCtxPtr transformCtx);
+static int xmlSecXslProcess (xmlSecXsltCtxPtr ctx,
+ xmlSecBufferPtr in,
+ xmlSecBufferPtr out);
+static xmlDocPtr xmlSecXsApplyStylesheet (xmlSecXsltCtxPtr ctx,
+ xmlDocPtr doc);
+
static xmlSecTransformKlass xmlSecXsltKlass = {
/* klass/object sizes */
- sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
- xmlSecXsltSize, /* xmlSecSize objSize */
-
- xmlSecNameXslt, /* const xmlChar* name; */
- xmlSecHrefXslt, /* const xmlChar* href; */
- xmlSecTransformUsageDSigTransform, /* xmlSecAlgorithmUsage usage; */
-
- xmlSecXsltInitialize, /* xmlSecTransformInitializeMethod initialize; */
- xmlSecXsltFinalize, /* xmlSecTransformFinalizeMethod finalize; */
- xmlSecXsltReadNode, /* xmlSecTransformNodeReadMethod readNode; */
- NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
- NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
- NULL, /* xmlSecTransformSetKeyMethod setKey; */
- NULL, /* xmlSecTransformValidateMethod validate; */
- xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
- xmlSecXsltPushBin, /* xmlSecTransformPushBinMethod pushBin; */
- xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
- NULL, /* xmlSecTransformPushXmlMethod pushXml; */
- NULL, /* xmlSecTransformPopXmlMethod popXml; */
- xmlSecXsltExecute, /* xmlSecTransformExecuteMethod execute; */
-
- NULL, /* void* reserved0; */
- NULL, /* void* reserved1; */
+ sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
+ xmlSecXsltSize, /* xmlSecSize objSize */
+
+ xmlSecNameXslt, /* const xmlChar* name; */
+ xmlSecHrefXslt, /* const xmlChar* href; */
+ xmlSecTransformUsageDSigTransform, /* xmlSecAlgorithmUsage usage; */
+
+ xmlSecXsltInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecXsltFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ xmlSecXsltReadNode, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ NULL, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
+ xmlSecXsltPushBin, /* xmlSecTransformPushBinMethod pushBin; */
+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
+ xmlSecXsltExecute, /* xmlSecTransformExecuteMethod execute; */
+
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
};
+
+#define XMLSEC_XSLT_COPY_SEC_PREF(src, dst, pref) \
+ xsltSetSecurityPrefs((dst), (pref), xsltGetSecurityPrefs((src), (pref)))
+
+static xsltSecurityPrefsPtr g_xslt_default_security_prefs = NULL;
+
+void xmlSecTransformXsltInitialize(void) {
+ xmlSecAssert(g_xslt_default_security_prefs == NULL);
+
+ g_xslt_default_security_prefs = xsltNewSecurityPrefs();
+ xmlSecAssert(g_xslt_default_security_prefs != NULL);
+ xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
+ xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
+ xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
+ xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
+ xsltSetSecurityPrefs(g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
+}
+
+void xmlSecTransformXsltShutdown(void) {
+ if(g_xslt_default_security_prefs != NULL) {
+ xsltFreeSecurityPrefs(g_xslt_default_security_prefs);
+ g_xslt_default_security_prefs = NULL;
+ }
+}
+
+/**
+ * xmlSecTransformXsltSetDefaultSecurityPrefs:
+ * @sec: the new security preferences
+ *
+ * Sets the new default security preferences. The xmlsec default security policy is
+ * to disable everything.
+ */
+XMLSEC_EXPORT void
+xmlSecTransformXsltSetDefaultSecurityPrefs(xsltSecurityPrefsPtr sec) {
+ xmlSecAssert(sec != NULL);
+ xmlSecAssert(g_xslt_default_security_prefs != NULL);
+
+ /* copy prefs */
+ XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_READ_FILE);
+ XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_FILE);
+ XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_CREATE_DIRECTORY);
+ XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_READ_NETWORK);
+ XMLSEC_XSLT_COPY_SEC_PREF(sec, g_xslt_default_security_prefs, XSLT_SECPREF_WRITE_NETWORK);
+}
+
/**
* xmlSecTransformXsltGetKlass:
*
* XSLT transform klass (http://www.w3.org/TR/xmldsig-core/#sec-XSLT):
*
- * The normative specification for XSL Transformations is [XSLT].
- * Specification of a namespace-qualified stylesheet element, which MUST be
- * the sole child of the Transform element, indicates that the specified style
- * sheet should be used. Whether this instantiates in-line processing of local
- * XSLT declarations within the resource is determined by the XSLT processing
- * model; the ordered application of multiple stylesheet may require multiple
- * Transforms. No special provision is made for the identification of a remote
- * stylesheet at a given URI because it can be communicated via an xsl:include
+ * The normative specification for XSL Transformations is [XSLT].
+ * Specification of a namespace-qualified stylesheet element, which MUST be
+ * the sole child of the Transform element, indicates that the specified style
+ * sheet should be used. Whether this instantiates in-line processing of local
+ * XSLT declarations within the resource is determined by the XSLT processing
+ * model; the ordered application of multiple stylesheet may require multiple
+ * Transforms. No special provision is made for the identification of a remote
+ * stylesheet at a given URI because it can be communicated via an xsl:include
* or xsl:import within the stylesheet child of the Transform.
*
- * This transform requires an octet stream as input. If the actual input is an
- * XPath node-set, then the signature application should attempt to convert it
- * to octets (apply Canonical XML]) as described in the Reference Processing
+ * This transform requires an octet stream as input. If the actual input is an
+ * XPath node-set, then the signature application should attempt to convert it
+ * to octets (apply Canonical XML]) as described in the Reference Processing
* Model (section 4.3.3.2).]
*
- * The output of this transform is an octet stream. The processing rules for
+ * The output of this transform is an octet stream. The processing rules for
* the XSL style sheet or transform element are stated in the XSLT specification
- * [XSLT]. We RECOMMEND that XSLT transform authors use an output method of xml
- * for XML and HTML. As XSLT implementations do not produce consistent
- * serializations of their output, we further RECOMMEND inserting a transform
- * after the XSLT transform to canonicalize the output. These steps will help
- * to ensure interoperability of the resulting signatures among applications
- * that support the XSLT transform. Note that if the output is actually HTML,
+ * [XSLT]. We RECOMMEND that XSLT transform authors use an output method of xml
+ * for XML and HTML. As XSLT implementations do not produce consistent
+ * serializations of their output, we further RECOMMEND inserting a transform
+ * after the XSLT transform to canonicalize the output. These steps will help
+ * to ensure interoperability of the resulting signatures among applications
+ * that support the XSLT transform. Note that if the output is actually HTML,
* then the result of these steps is logically equivalent [XHTML].
*
* Returns: pointer to XSLT transform klass.
*/
-xmlSecTransformId
+xmlSecTransformId
xmlSecTransformXsltGetKlass(void) {
return(&xmlSecXsltKlass);
}
-
-static int
-xmlSecXsltInitialize(xmlSecTransformPtr transform) {
+
+static int
+xmlSecXsltInitialize(xmlSecTransformPtr transform) {
xmlSecXsltCtxPtr ctx;
-
+
xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXsltId), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecXsltSize), -1);
ctx = xmlSecXsltGetCtx(transform);
xmlSecAssert2(ctx != NULL, -1);
-
+
/* initialize context */
memset(ctx, 0, sizeof(xmlSecXsltCtx));
+
+ /* done */
return(0);
}
@@ -156,12 +207,12 @@ xmlSecXsltFinalize(xmlSecTransformPtr transform) {
ctx = xmlSecXsltGetCtx(transform);
xmlSecAssert(ctx != NULL);
-
+
if(ctx->xslt != NULL) {
- xsltFreeStylesheet(ctx->xslt);
+ xsltFreeStylesheet(ctx->xslt);
}
if(ctx->parserCtx != NULL) {
- xmlFreeParserCtxt(ctx->parserCtx);
+ xmlFreeParserCtxt(ctx->parserCtx);
}
memset(ctx, 0, sizeof(xmlSecXsltCtx));
}
@@ -172,70 +223,70 @@ xmlSecXsltReadNode(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransfor
xmlBufferPtr buffer;
xmlDocPtr doc;
xmlNodePtr cur;
-
+
xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXsltId), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecXsltSize), -1);
- xmlSecAssert2(node != NULL, -1);
- xmlSecAssert2(transformCtx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(transformCtx != NULL, -1);
ctx = xmlSecXsltGetCtx(transform);
xmlSecAssert2(ctx != NULL, -1);
xmlSecAssert2(ctx->xslt == NULL, -1);
- /* read content in the buffer */
+ /* read content in the buffer */
buffer = xmlBufferCreate();
if(buffer == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlBufferCreate",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlBufferCreate",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
cur = node->children;
while(cur != NULL) {
- xmlNodeDump(buffer, cur->doc, cur, 0, 0);
- cur = cur->next;
+ xmlNodeDump(buffer, cur->doc, cur, 0, 0);
+ cur = cur->next;
}
-
+
/* parse the buffer */
- doc = xmlSecParseMemory(xmlBufferContent(buffer),
- xmlBufferLength(buffer), 1);
+ doc = xmlSecParseMemory(xmlBufferContent(buffer),
+ xmlBufferLength(buffer), 1);
if(doc == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecParseMemory",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlBufferFree(buffer);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecParseMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlBufferFree(buffer);
+ return(-1);
}
- /* pre-process stylesheet */
+ /* pre-process stylesheet */
ctx->xslt = xsltParseStylesheetDoc(doc);
if(ctx->xslt == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xsltParseStylesheetDoc",
- XMLSEC_ERRORS_R_XSLT_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- /* after parsing stylesheet doc is assigned
- * to it and will be freed by xsltFreeStylesheet() */
- xmlFreeDoc(doc);
- xmlBufferFree(buffer);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xsltParseStylesheetDoc",
+ XMLSEC_ERRORS_R_XSLT_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ /* after parsing stylesheet doc is assigned
+ * to it and will be freed by xsltFreeStylesheet() */
+ xmlFreeDoc(doc);
+ xmlBufferFree(buffer);
+ return(-1);
}
-
+
xmlBufferFree(buffer);
return(0);
}
-static int
+static int
xmlSecXsltPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
- xmlSecSize dataSize, int final, xmlSecTransformCtxPtr transformCtx) {
+ xmlSecSize dataSize, int final, xmlSecTransformCtxPtr transformCtx) {
xmlSecXsltCtxPtr ctx;
int ret;
-
+
xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXsltId), -1);
xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecXsltSize), -1);
xmlSecAssert2(transformCtx != NULL, -1);
@@ -246,136 +297,136 @@ xmlSecXsltPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
/* check/update current transform status */
if(transform->status == xmlSecTransformStatusNone) {
- xmlSecAssert2(ctx->parserCtx == NULL, -1);
-
- ctx->parserCtx = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
- if(ctx->parserCtx == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlCreatePushParserCtxt",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
+ xmlSecAssert2(ctx->parserCtx == NULL, -1);
+
+ ctx->parserCtx = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
+ if(ctx->parserCtx == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlCreatePushParserCtxt",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
/* required for c14n! */
- ctx->parserCtx->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
- ctx->parserCtx->replaceEntities = 1;
+ ctx->parserCtx->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+ ctx->parserCtx->replaceEntities = 1;
- transform->status = xmlSecTransformStatusWorking;
+ transform->status = xmlSecTransformStatusWorking;
} else if(transform->status == xmlSecTransformStatusFinished) {
- return(0);
+ return(0);
} else if(transform->status != xmlSecTransformStatusWorking) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_STATUS,
+ "status=%d", transform->status);
+ return(-1);
}
xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1);
xmlSecAssert2(ctx->parserCtx != NULL, -1);
-
+
/* push data to the input buffer */
if((data != NULL) && (dataSize > 0)) {
- ret = xmlParseChunk(ctx->parserCtx, (const char*)data, dataSize, 0);
- if(ret != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlParseChunk",
- XMLSEC_ERRORS_R_XML_FAILED,
- "size=%d", dataSize);
- return(-1);
- }
- }
-
+ ret = xmlParseChunk(ctx->parserCtx, (const char*)data, dataSize, 0);
+ if(ret != 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlParseChunk",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "size=%d", dataSize);
+ return(-1);
+ }
+ }
+
/* finish parsing, apply xslt transforms and push to next in the chain */
if(final != 0) {
xmlDocPtr docIn;
xmlDocPtr docOut;
xmlOutputBufferPtr output;
- /* finalize */
- ret = xmlParseChunk(ctx->parserCtx, NULL, 0, 1);
- if((ret != 0) || (ctx->parserCtx->myDoc == NULL)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlParseChunk",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
-
- /* todo: check that document is well formed? */
- docIn = ctx->parserCtx->myDoc;
- ctx->parserCtx->myDoc = NULL;
-
- docOut = xsltApplyStylesheet(ctx->xslt, docIn, NULL);
- if(docOut == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xsltApplyStylesheet",
- XMLSEC_ERRORS_R_XSLT_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlFreeDoc(docIn);
- return(-1);
- }
- xmlFreeDoc(docIn);
-
- if(transform->next != NULL) {
- output = xmlSecTransformCreateOutputBuffer(transform->next, transformCtx);
- if(output == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecTransformCreateOutputBuffer",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlFreeDoc(docOut);
- return(-1);
- }
- } else {
- output = xmlSecBufferCreateOutputBuffer(&(transform->outBuf));
- if(output == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferCreateOutputBuffer",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlFreeDoc(docOut);
- return(-1);
- }
- }
-
- ret = xsltSaveResultTo(output, docOut, ctx->xslt);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xsltSaveResultTo",
- XMLSEC_ERRORS_R_XSLT_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlOutputBufferClose(output);
- xmlFreeDoc(docOut);
- return(-1);
- }
- ret = xmlOutputBufferClose(output);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlOutputBufferClose",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlFreeDoc(docOut);
- return(-1);
- }
- xmlFreeDoc(docOut);
-
- transform->status = xmlSecTransformStatusFinished;
+ /* finalize */
+ ret = xmlParseChunk(ctx->parserCtx, NULL, 0, 1);
+ if((ret != 0) || (ctx->parserCtx->myDoc == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlParseChunk",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* todo: check that document is well formed? */
+ docIn = ctx->parserCtx->myDoc;
+ ctx->parserCtx->myDoc = NULL;
+
+ docOut = xmlSecXsApplyStylesheet(ctx, docIn);
+ if(docOut == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecXsApplyStylesheet",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFreeDoc(docIn);
+ return(-1);
+ }
+ xmlFreeDoc(docIn);
+
+ if(transform->next != NULL) {
+ output = xmlSecTransformCreateOutputBuffer(transform->next, transformCtx);
+ if(output == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecTransformCreateOutputBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFreeDoc(docOut);
+ return(-1);
+ }
+ } else {
+ output = xmlSecBufferCreateOutputBuffer(&(transform->outBuf));
+ if(output == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferCreateOutputBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFreeDoc(docOut);
+ return(-1);
+ }
+ }
+
+ ret = xsltSaveResultTo(output, docOut, ctx->xslt);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xsltSaveResultTo",
+ XMLSEC_ERRORS_R_XSLT_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlOutputBufferClose(output);
+ xmlFreeDoc(docOut);
+ return(-1);
+ }
+ ret = xmlOutputBufferClose(output);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlOutputBufferClose",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFreeDoc(docOut);
+ return(-1);
+ }
+ xmlFreeDoc(docOut);
+
+ transform->status = xmlSecTransformStatusFinished;
}
return(0);
}
-static int
+static int
xmlSecXsltExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
xmlSecXsltCtxPtr ctx;
xmlSecBufferPtr in, out;
@@ -393,57 +444,57 @@ xmlSecXsltExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr
in = &(transform->inBuf);
out = &(transform->outBuf);
inSize = xmlSecBufferGetSize(in);
- outSize = xmlSecBufferGetSize(out);
-
+ outSize = xmlSecBufferGetSize(out);
+
if(transform->status == xmlSecTransformStatusNone) {
- transform->status = xmlSecTransformStatusWorking;
- }
-
+ transform->status = xmlSecTransformStatusWorking;
+ }
+
if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) {
- /* just do nothing */
- xmlSecAssert2(outSize == 0, -1);
+ /* just do nothing */
+ xmlSecAssert2(outSize == 0, -1);
} else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
- xmlSecAssert2(outSize == 0, -1);
-
- ret = xmlSecXslProcess(in, out, ctx->xslt);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecXslProcess",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
- }
-
- ret = xmlSecBufferRemoveHead(in, inSize);
- if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecBufferRemoveHead",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "size=%d", inSize);
- return(-1);
- }
-
- transform->status = xmlSecTransformStatusFinished;
+ xmlSecAssert2(outSize == 0, -1);
+
+ ret = xmlSecXslProcess(ctx, in, out);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecXslProcess",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecBufferRemoveHead(in, inSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ "xmlSecBufferRemoveHead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", inSize);
+ return(-1);
+ }
+
+ transform->status = xmlSecTransformStatusFinished;
} else if(transform->status == xmlSecTransformStatusFinished) {
- /* the only way we can get here is if there is no input */
- xmlSecAssert2(inSize == 0, -1);
+ /* the only way we can get here is if there is no input */
+ xmlSecAssert2(inSize == 0, -1);
} else {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_STATUS,
+ "status=%d", transform->status);
+ return(-1);
}
return(0);
}
/* TODO: create PopBin method instead */
-static int
-xmlSecXslProcess(xmlSecBufferPtr in, xmlSecBufferPtr out, xsltStylesheetPtr stylesheet) {
+static int
+xmlSecXslProcess(xmlSecXsltCtxPtr ctx, xmlSecBufferPtr in, xmlSecBufferPtr out) {
xmlDocPtr docIn = NULL;
xmlDocPtr docOut = NULL;
xmlOutputBufferPtr output = NULL;
@@ -452,67 +503,115 @@ xmlSecXslProcess(xmlSecBufferPtr in, xmlSecBufferPtr out, xsltStylesheetPtr sty
xmlSecAssert2(in != NULL, -1);
xmlSecAssert2(out != NULL, -1);
- xmlSecAssert2(stylesheet != NULL, -1);
+ xmlSecAssert2(ctx != NULL, -1);
docIn = xmlSecParseMemory(xmlSecBufferGetData(in), xmlSecBufferGetSize(in), 1);
if(docIn == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecParseMemory",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecParseMemory",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
}
- docOut = xsltApplyStylesheet(stylesheet, docIn, NULL);
+ docOut = xmlSecXsApplyStylesheet(ctx, docIn);
if(docOut == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xsltApplyStylesheet",
- XMLSEC_ERRORS_R_XSLT_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXsApplyStylesheet",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
}
output = xmlSecBufferCreateOutputBuffer(out);
if(output == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecBufferCreateOutputBuffer",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBufferCreateOutputBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
}
- ret = xsltSaveResultTo(output, docOut, stylesheet);
+ ret = xsltSaveResultTo(output, docOut, ctx->xslt);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xsltSaveResultTo",
- XMLSEC_ERRORS_R_XSLT_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto done;
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xsltSaveResultTo",
+ XMLSEC_ERRORS_R_XSLT_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
}
ret = xmlOutputBufferClose(output);
output = NULL;
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlOutputBufferClose",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlOutputBufferClose",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
}
res = 0;
-done:
+done:
if(output != NULL) xmlOutputBufferClose(output);
if(docIn != NULL) xmlFreeDoc(docIn);
if(docOut != NULL) xmlFreeDoc(docOut);
- return(res);
+ return(res);
+}
+
+
+static xmlDocPtr
+xmlSecXsApplyStylesheet(xmlSecXsltCtxPtr ctx, xmlDocPtr doc) {
+ xsltTransformContextPtr xsltCtx = NULL;
+ xmlDocPtr res = NULL;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, NULL);
+ xmlSecAssert2(ctx->xslt != NULL, NULL);
+ xmlSecAssert2(doc != NULL, NULL);
+
+ xsltCtx = xsltNewTransformContext(ctx->xslt, doc);
+ if(xsltCtx == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xsltNewTransformContext",
+ XMLSEC_ERRORS_R_XSLT_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* set security prefs */
+ ret = xsltSetCtxtSecurityPrefs(g_xslt_default_security_prefs, xsltCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xsltSetCtxtSecurityPrefs",
+ XMLSEC_ERRORS_R_XSLT_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ res = xsltApplyStylesheetUser(ctx->xslt, doc, NULL, NULL, NULL, xsltCtx);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xsltApplyStylesheetUser",
+ XMLSEC_ERRORS_R_XSLT_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+done:
+ if(xsltCtx != NULL) xsltFreeTransformContext(xsltCtx);
+ return res;
}
+
#endif /* XMLSEC_NO_XSLT */