summaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c254
1 files changed, 131 insertions, 123 deletions
diff --git a/src/parser.c b/src/parser.c
index 969c3e4f..ddeb590c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,13 +1,19 @@
-/**
+/*
* XML Security Library (http://www.aleksey.com/xmlsec).
*
- * XML Parser transform and utility functions.
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
*
* Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
*/
+/**
+ * SECTION:parser
+ * @Short_description: XML parser functions and the XML parser transform implementation.
+ * @Stability: Stable
+ *
+ */
+
#include "globals.h"
#include <stdlib.h>
@@ -87,6 +93,7 @@ static xmlSecTransformKlass xmlSecParserKlass = {
NULL, /* void* reserved1; */
};
+
/**
* xmlSecTransformXmlParserGetKlass:
*
@@ -125,6 +132,10 @@ xmlSecParserFinalize(xmlSecTransformPtr transform) {
xmlSecAssert(ctx != NULL);
if(ctx->parserCtx != NULL) {
+ if(ctx->parserCtx->myDoc != NULL) {
+ xmlFreeDoc(ctx->parserCtx->myDoc);
+ ctx->parserCtx->myDoc = NULL;
+ }
xmlFreeParserCtxt(ctx->parserCtx);
}
memset(ctx, 0, sizeof(xmlSecParserCtx));
@@ -148,11 +159,7 @@ xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
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);
+ xmlSecXmlError("xmlCreatePushParserCtxt", xmlSecTransformGetName(transform));
return(-1);
}
@@ -165,11 +172,7 @@ xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
} else if(transform->status == xmlSecTransformStatusFinished) {
return(0);
} else if(transform->status != xmlSecTransformStatusWorking) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
+ xmlSecInvalidTransfromStatusError(transform);
return(-1);
}
xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1);
@@ -179,11 +182,9 @@ xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
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);
+ xmlSecXmlParserError2("xmlParseChunk", ctx->parserCtx,
+ xmlSecTransformGetName(transform),
+ "size=%lu", (unsigned long)dataSize);
return(-1);
}
}
@@ -192,11 +193,8 @@ xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
if(final != 0) {
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);
+ xmlSecXmlParserError("xmlParseChunk", ctx->parserCtx,
+ xmlSecTransformGetName(transform));
return(-1);
}
@@ -204,11 +202,8 @@ xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
transform->outNodes = xmlSecNodeSetCreate(ctx->parserCtx->myDoc,
NULL, xmlSecNodeSetTree);
if(transform->outNodes == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecNodeSetCreate",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecNodeSetCreate",
+ xmlSecTransformGetName(transform));
xmlFreeDoc(ctx->parserCtx->myDoc);
ctx->parserCtx->myDoc = NULL;
return(-1);
@@ -220,11 +215,8 @@ xmlSecParserPushBin(xmlSecTransformPtr transform, const xmlSecByte* data,
if(transform->next != NULL) {
ret = xmlSecTransformPushXml(transform->next, transform->outNodes, transformCtx);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecTransformPushXml",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecTransformPushXml",
+ xmlSecTransformGetName(transform));
return(-1);
}
}
@@ -264,53 +256,38 @@ xmlSecParserPopXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr* nodes,
(*nodes) = NULL;
return(0);
default:
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_STATUS,
- "status=%d", transform->status);
+ xmlSecInvalidTransfromStatusError(transform);
return(-1);
}
xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1);
/* prepare parser context */
if(transform->prev == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- NULL,
- XMLSEC_ERRORS_R_INVALID_TRANSFORM,
- "prev transform is null");
+ xmlSecInvalidTransfromError2(transform,
+ "prev transform=\"%s\"",
+ xmlSecErrorsSafeString(transform->prev));
return(-1);
}
buf = xmlSecTransformCreateInputBuffer(transform->prev, transformCtx);
if(buf == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecTransformCreateInputBuffer",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecTransformCreateInputBuffer",
+ xmlSecTransformGetName(transform));
return(-1);
}
ctxt = xmlNewParserCtxt();
if (ctxt == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlNewParserCtxt",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlError("xmlNewParserCtxt",
+ xmlSecTransformGetName(transform));
xmlFreeParserInputBuffer(buf);
return(-1);
}
input = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
if(input == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlNewParserCtxt",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlParserError("xmlNewParserCtxt", ctxt,
+ xmlSecTransformGetName(transform));
xmlFreeParserCtxt(ctxt);
xmlFreeParserInputBuffer(buf);
return(-1);
@@ -318,12 +295,13 @@ xmlSecParserPopXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr* nodes,
ret = inputPush(ctxt, input);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "inputPush",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlParserError("inputPush", ctxt,
+ xmlSecTransformGetName(transform));
xmlFreeInputStream(input);
+ if(ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
xmlFreeParserCtxt(ctxt);
return(-1);
}
@@ -335,11 +313,8 @@ xmlSecParserPopXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr* nodes,
/* finaly do the parsing */
ret = xmlParseDocument(ctxt);
if(ret < 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlParseDocument",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlParserError("xmlParseDocument", ctxt,
+ xmlSecTransformGetName(transform));
if(ctxt->myDoc != NULL) {
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
@@ -356,11 +331,8 @@ xmlSecParserPopXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr* nodes,
/* return result to the caller */
(*nodes) = xmlSecNodeSetCreate(doc, NULL, xmlSecNodeSetTree);
if((*nodes) == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
- "xmlSecNodeSetCreate",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecInternalError("xmlSecNodeSetCreate",
+ xmlSecTransformGetName(transform));
xmlFreeDoc(doc);
return(-1);
}
@@ -394,15 +366,18 @@ typedef struct _xmlSecExtMemoryParserCtx {
*/
xmlDocPtr
xmlSecParseFile(const char *filename) {
- xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
+ xmlDocPtr res = NULL;
char *directory = NULL;
+ int ret;
xmlSecAssert2(filename != NULL, NULL);
xmlInitParser();
ctxt = xmlCreateFileParserCtxt(filename);
if (ctxt == NULL) {
+ xmlSecXmlError2("xmlCreateFileParserCtxt", NULL,
+ "filename=%s", xmlSecErrorsSafeString(filename));
return(NULL);
}
@@ -410,26 +385,56 @@ xmlSecParseFile(const char *filename) {
/* crashes on x64 xmlCtxtUseOptions (ctxt, XML_PARSE_HUGE); */
/* todo: set directories from current doc? */
- if ((ctxt->directory == NULL) && (directory == NULL))
+ if ((ctxt->directory == NULL) && (directory == NULL)) {
directory = xmlParserGetDirectory(filename);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
+ if(directory == NULL) {
+ xmlSecXmlError2("xmlParserGetDirectory", NULL,
+ "filename=%s", xmlSecErrorsSafeString(filename));
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
+ }
+ if ((ctxt->directory == NULL) && (directory != NULL)) {
+ ctxt->directory = (char *) xmlStrdup(BAD_CAST directory);
+ if(ctxt->directory == NULL) {
+ xmlSecStrdupError(BAD_CAST directory, NULL);
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
+ }
/* required for c14n! */
ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
ctxt->replaceEntities = 1;
- xmlParseDocument(ctxt);
+ ret = xmlParseDocument(ctxt);
+ if(ret < 0) {
+ xmlSecXmlParserError2("xmlParseDocument", ctxt, NULL,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ if(ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
- if(ctxt->wellFormed) {
- ret = ctxt->myDoc;
- } else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
+ if(!ctxt->wellFormed) {
+ xmlSecInternalError("document is not well formed", NULL);
+ if(ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
}
+
+ /* done */
+ res = ctxt->myDoc;
+ ctxt->myDoc = NULL;
xmlFreeParserCtxt(ctxt);
- return(ret);
+ return(res);
}
@@ -457,11 +462,7 @@ xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
/* create context */
ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
if(ctxt == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlCreatePushParserCtxt",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlError("xmlCreatePushParserCtxt", NULL);
goto done;
}
@@ -473,11 +474,9 @@ xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
if((prefix != NULL) && (prefixSize > 0)) {
ret = xmlParseChunk(ctxt, (const char*)prefix, prefixSize, 0);
if(ret != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlParseChunk",
- XMLSEC_ERRORS_R_XML_FAILED,
- "prefixSize=%d", prefixSize);
+ xmlSecXmlParserError2("xmlParseChunk", ctxt, NULL,
+ "chunkSize=%d", prefixSize);
+
goto done;
}
}
@@ -486,11 +485,9 @@ xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
if((buffer != NULL) && (bufferSize > 0)) {
ret = xmlParseChunk(ctxt, (const char*)buffer, bufferSize, 0);
if(ret != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlParseChunk",
- XMLSEC_ERRORS_R_XML_FAILED,
- "bufferSize=%d", bufferSize);
+ xmlSecXmlParserError2("xmlParseChunk", ctxt, NULL,
+ "chunkSize=%d", bufferSize);
+
goto done;
}
}
@@ -499,11 +496,9 @@ xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
if((postfix != NULL) && (postfixSize > 0)) {
ret = xmlParseChunk(ctxt, (const char*)postfix, postfixSize, 0);
if(ret != 0) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlParseChunk",
- XMLSEC_ERRORS_R_XML_FAILED,
- "postfixSize=%d", postfixSize);
+ xmlSecXmlParserError2("xmlParseChunk", ctxt, NULL,
+ "chunkSize=%d", postfixSize);
+
goto done;
}
}
@@ -511,17 +506,18 @@ xmlSecParseMemoryExt(const xmlSecByte *prefix, xmlSecSize prefixSize,
/* finishing */
ret = xmlParseChunk(ctxt, NULL, 0, 1);
if((ret != 0) || (ctxt->myDoc == NULL)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlParseChunk",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlParserError("xmlParseChunk", ctxt, NULL);
goto done;
}
doc = ctxt->myDoc;
+ ctxt->myDoc = NULL;
done:
if(ctxt != NULL) {
+ if(ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
xmlFreeParserCtxt(ctxt);
}
return(doc);
@@ -541,18 +537,15 @@ done:
*/
xmlDocPtr
xmlSecParseMemory(const xmlSecByte *buffer, xmlSecSize size, int recovery) {
- xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
+ xmlDocPtr res = NULL;
+ int ret;
xmlSecAssert2(buffer != NULL, NULL);
ctxt = xmlCreateMemoryParserCtxt((char*)buffer, size);
if (ctxt == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlCreateMemoryParserCtxt",
- XMLSEC_ERRORS_R_XML_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXmlError("xmlCreateMemoryParserCtxt", NULL);
return(NULL);
}
@@ -560,16 +553,31 @@ xmlSecParseMemory(const xmlSecByte *buffer, xmlSecSize size, int recovery) {
ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
ctxt->replaceEntities = 1;
- xmlParseDocument(ctxt);
+ ret = xmlParseDocument(ctxt);
+ if(ret < 0) {
+ xmlSecXmlParserError("xmlParseDocument", ctxt, NULL);
+ if(ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
+ }
- if((ctxt->wellFormed) || recovery) {
- ret = ctxt->myDoc;
- } else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
+ if(!(ctxt->wellFormed) && !recovery) {
+ xmlSecInternalError("document is not well formed", NULL);
+ if(ctxt->myDoc != NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+ xmlFreeParserCtxt(ctxt);
+ return(NULL);
}
+
+ /* done */
+ res = ctxt->myDoc;
+ ctxt->myDoc = NULL;
xmlFreeParserCtxt(ctxt);
- return(ret);
+ return(res);
}