diff options
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 254 |
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); } |