diff options
Diffstat (limited to 'src/xmltree.c')
-rw-r--r-- | src/xmltree.c | 951 |
1 files changed, 495 insertions, 456 deletions
diff --git a/src/xmltree.c b/src/xmltree.c index 3ef7f977..df99931d 100644 --- a/src/xmltree.c +++ b/src/xmltree.c @@ -1,20 +1,24 @@ -/** +/* * XML Security Library (http://www.aleksey.com/xmlsec). * - * Common XML Doc 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:xmltree + * @Short_description: XML tree functions. + * @Stability: Stable + * + */ + #include "globals.h" #include <stdlib.h> #include <string.h> #include <ctype.h> -#include <time.h> -#include <errno.h> #include <libxml/tree.h> #include <libxml/valid.h> @@ -28,6 +32,61 @@ #include <xmlsec/base64.h> #include <xmlsec/errors.h> +static const xmlChar* g_xmlsec_xmltree_default_linefeed = xmlSecStringCR; + +/** + * xmlSecGetDefaultLineFeed: + * + * Gets the current default linefeed. + * + * Returns: the current default linefeed. + */ +const xmlChar* +xmlSecGetDefaultLineFeed(void) +{ + return g_xmlsec_xmltree_default_linefeed; +} + +/** + * xmlSecSetDefaultLineFeed: + * @linefeed: default linefeed. + * + * Sets the current default linefeed. The caller must ensure that the linefeed + * string exists for the lifetime of the program or until the new linefeed is set. + */ +void +xmlSecSetDefaultLineFeed(const xmlChar *linefeed) +{ + g_xmlsec_xmltree_default_linefeed = linefeed; +} + +/** + * xmlSecFindSibling: + * @cur: the pointer to XML node. + * @name: the name. + * @ns: the namespace href (may be NULL). + * + * Searches @cur and the next siblings of the @cur node having given name and + * namespace href. + * + * Returns: the pointer to the found node or NULL if an error occurs or + * node is not found. + */ +xmlNodePtr +xmlSecFindSibling(const xmlNodePtr cur, const xmlChar *name, const xmlChar *ns) { + xmlNodePtr tmp; + xmlSecAssert2(name != NULL, NULL); + + for(tmp = cur; tmp != NULL; tmp = tmp->next) { + if(tmp->type == XML_ELEMENT_NODE) { + if(xmlSecCheckNodeName(tmp, name, ns)) { + return(tmp); + } + } + } + return(NULL); +} + /** * xmlSecFindChild: * @parent: the pointer to XML node. @@ -42,21 +101,10 @@ */ xmlNodePtr xmlSecFindChild(const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) { - xmlNodePtr cur; - xmlSecAssert2(parent != NULL, NULL); xmlSecAssert2(name != NULL, NULL); - cur = parent->children; - while(cur != NULL) { - if(cur->type == XML_ELEMENT_NODE) { - if(xmlSecCheckNodeName(cur, name, ns)) { - return(cur); - } - } - cur = cur->next; - } - return(NULL); + return(xmlSecFindSibling(parent->children, name, ns)); } /** @@ -185,13 +233,9 @@ xmlSecAddChild(xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) { if(parent->children == NULL) { /* TODO: add indents */ - text = xmlNewText(xmlSecStringCR); + text = xmlNewText(xmlSecGetDefaultLineFeed()); if(text == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewText", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewText", NULL); return(NULL); } xmlAddChild(parent, text); @@ -199,11 +243,7 @@ xmlSecAddChild(xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) { cur = xmlNewChild(parent, NULL, name, NULL); if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewChild", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewChild", NULL); return(NULL); } @@ -215,18 +255,18 @@ xmlSecAddChild(xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) { nsPtr = xmlSearchNsByHref(cur->doc, cur, ns); if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) { nsPtr = xmlNewNs(cur, ns, NULL); + if(nsPtr == NULL) { + xmlSecXmlError("xmlNewNs", NULL); + return(NULL); + } } xmlSetNs(cur, nsPtr); } /* TODO: add indents */ - text = xmlNewText(xmlSecStringCR); + text = xmlNewText(xmlSecGetDefaultLineFeed()); if(text == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewText", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewText", NULL); return(NULL); } xmlAddChild(parent, text); @@ -252,13 +292,9 @@ xmlSecAddChildNode(xmlNodePtr parent, xmlNodePtr child) { if(parent->children == NULL) { /* TODO: add indents */ - text = xmlNewText(xmlSecStringCR); + text = xmlNewText(xmlSecGetDefaultLineFeed()); if(text == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewText", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewText", NULL); return(NULL); } xmlAddChild(parent, text); @@ -267,13 +303,9 @@ xmlSecAddChildNode(xmlNodePtr parent, xmlNodePtr child) { xmlAddChild(parent, child); /* TODO: add indents */ - text = xmlNewText(xmlSecStringCR); + text = xmlNewText(xmlSecGetDefaultLineFeed()); if(text == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewText", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewText", NULL); return(NULL); } xmlAddChild(parent, text); @@ -282,6 +314,52 @@ xmlSecAddChildNode(xmlNodePtr parent, xmlNodePtr child) { } /** + * xmlSecEnsureEmptyChild: + * @parent: the pointer to XML node. + * @name: the name. + * @ns: the namespace href (may be NULL). + * + * Searches a direct child of the @parent node having given name and + * namespace href. If not found then element node with given name / namespace + * is added. + * + * Returns: the pointer to the found or created node; or NULL if an error occurs. + */ +xmlNodePtr +xmlSecEnsureEmptyChild(xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) { + xmlNodePtr cur = NULL; + xmlNodePtr tmp; + + xmlSecAssert2(parent != NULL, NULL); + xmlSecAssert2(name != NULL, NULL); + + /* try to find an empty node first */ + tmp = xmlSecFindNode(parent, name, ns); + while(tmp != NULL) { + cur = tmp; + if(xmlSecIsEmptyNode(cur) == 1) { + return(cur); + } + tmp = xmlSecFindSibling(cur->next, name, ns); + } + + /* if not found then either add next or add at the end */ + if(cur == NULL) { + cur = xmlSecAddChild(parent, name, ns); + } else if((cur->next != NULL) && (cur->next->type == XML_TEXT_NODE)) { + cur = xmlSecAddNextSibling(cur->next, name, ns); + } else { + cur = xmlSecAddNextSibling(cur, name, ns); + } + if(cur == NULL) { + xmlSecInternalError2("xmlSecAddChild or xmlSecAddNextSibling", NULL, + "node=%s", xmlSecErrorsSafeString(name)); + return(NULL); + } + return(cur); +} + +/** * xmlSecAddNextSibling * @node: the pointer to an XML node. * @name: the new node name. @@ -301,11 +379,7 @@ xmlSecAddNextSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) { cur = xmlNewNode(NULL, name); if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewNode", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewNode", NULL); return(NULL); } xmlAddNextSibling(node, cur); @@ -323,13 +397,9 @@ xmlSecAddNextSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) { } /* TODO: add indents */ - text = xmlNewText(xmlSecStringCR); + text = xmlNewText(xmlSecGetDefaultLineFeed()); if(text == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewText", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewText", NULL); return(NULL); } xmlAddNextSibling(node, text); @@ -357,11 +427,7 @@ xmlSecAddPrevSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) { cur = xmlNewNode(NULL, name); if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewNode", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewNode", NULL); return(NULL); } xmlAddPrevSibling(node, cur); @@ -379,13 +445,9 @@ xmlSecAddPrevSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) { } /* TODO: add indents */ - text = xmlNewText(xmlSecStringCR); + text = xmlNewText(xmlSecGetDefaultLineFeed()); if(text == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewText", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewText", NULL); return(NULL); } xmlAddPrevSibling(node, text); @@ -453,11 +515,7 @@ xmlSecReplaceNodeAndReturn(xmlNodePtr node, xmlNodePtr newNode, xmlNodePtr* repl oldNode = xmlReplaceNode(node, newNode); if(oldNode == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlReplaceNode", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlReplaceNode", NULL); return(-1); } @@ -565,17 +623,15 @@ int xmlSecReplaceNodeBufferAndReturn(xmlNodePtr node, const xmlSecByte *buffer, xmlSecSize size, xmlNodePtr *replaced) { xmlNodePtr results = NULL; xmlNodePtr next = NULL; + int ret; xmlSecAssert2(node != NULL, -1); xmlSecAssert2(node->parent != NULL, -1); /* parse buffer in the context of node's parent */ - if(xmlParseInNodeContext(node->parent, (const char*)buffer, size, XML_PARSE_NODICT, &results) != XML_ERR_OK) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlParseInNodeContext", - XMLSEC_ERRORS_R_XML_FAILED, - "Failed to parse content"); + ret = xmlParseInNodeContext(node->parent, (const char*)buffer, size, XML_PARSE_NODICT, &results); + if(ret != XML_ERR_OK) { + xmlSecXmlError("xmlParseInNodeContext", NULL); return(-1); } @@ -615,24 +671,17 @@ xmlSecNodeEncodeAndSetContent(xmlNodePtr node, const xmlChar * buffer) { xmlSecAssert2(node->doc != NULL, -1); if(buffer != NULL) { - xmlChar * tmp; - + xmlChar * tmp; tmp = xmlEncodeSpecialChars(node->doc, buffer); if (tmp == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlEncodeSpecialChars", - XMLSEC_ERRORS_R_XML_FAILED, - "Failed to encode special characters"); + xmlSecXmlError("xmlEncodeSpecialChars", NULL); return(-1); } - xmlNodeSetContent(node, tmp); xmlFree(tmp); } else { xmlNodeSetContent(node, NULL); } - return(0); } @@ -667,12 +716,7 @@ xmlSecAddIDs(xmlDocPtr doc, xmlNodePtr cur, const xmlChar** ids) { if(tmp == NULL) { xmlAddID(NULL, doc, name, attr); } else if(tmp != attr) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "id=%s already defined", - xmlSecErrorsSafeString(name)); + xmlSecInvalidStringDataError("id", name, "unique id (id already defined)", NULL); } xmlFree(name); } @@ -694,172 +738,9 @@ xmlSecAddIDs(xmlDocPtr doc, xmlNodePtr cur, const xmlChar** ids) { } /** - * xmlSecGenerateAndAddID: - * @node: the node to ID attr to. - * @attrName: the ID attr name. - * @prefix: the prefix to add to the generated ID (can be NULL). - * @len: the length of ID. - * - * Generates a unique ID in the format <@prefix>base64-encoded(@len random bytes) - * and puts it in the attribute @attrName. - * - * Returns: 0 on success or a negative value if an error occurs. - */ -int -xmlSecGenerateAndAddID(xmlNodePtr node, const xmlChar* attrName, const xmlChar* prefix, xmlSecSize len) { - xmlChar* id; - int count; - - xmlSecAssert2(node != NULL, -1); - xmlSecAssert2(attrName != NULL, -1); - - /* we will try 5 times before giving up */ - for(count = 0; count < 5; count++) { - id = xmlSecGenerateID(prefix, len); - if(id == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGenerateID", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - if((node->doc == NULL) || (xmlGetID(node->doc, id) == NULL)) { - /* this is a unique ID in the document and we can use it */ - if(xmlSetProp(node, attrName, id) == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSetProp", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlFree(id); - return(-1); - } - - xmlFree(id); - return(0); - } - xmlFree(id); - } - - return(-1); -} - -/** - * xmlSecGenerateID: - * @prefix: the prefix to add to the generated ID (can be NULL). - * @len: the length of ID. - * - * Generates a unique ID in the format <@prefix>base64-encoded(@len random bytes). - * The caller is responsible for freeing returned string using @xmlFree function. - * - * Returns: pointer to generated ID string or NULL if an error occurs. - */ -xmlChar* -xmlSecGenerateID(const xmlChar* prefix, xmlSecSize len) { - xmlSecBuffer buffer; - xmlSecSize i, binLen; - xmlChar* res; - xmlChar* p; - int ret; - - xmlSecAssert2(len > 0, NULL); - - /* we will do base64 decoding later */ - binLen = (3 * len + 1) / 4; - - ret = xmlSecBufferInitialize(&buffer, binLen + 1); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferInitialize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); - } - xmlSecAssert2(xmlSecBufferGetData(&buffer) != NULL, NULL); - xmlSecAssert2(xmlSecBufferGetMaxSize(&buffer) >= binLen, NULL); - - ret = xmlSecBufferSetSize(&buffer, binLen); - if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlSecBufferFinalize(&buffer); - return(NULL); - } - xmlSecAssert2(xmlSecBufferGetSize(&buffer) == binLen, NULL); - - /* create random bytes */ - unsigned int seed = time(NULL); - for(i = 0; i < binLen; i++) { - (xmlSecBufferGetData(&buffer)) [i] = (xmlSecByte) (256.0 * rand_r(&seed) / (RAND_MAX + 1.0)); - } - - /* base64 encode random bytes */ - res = xmlSecBase64Encode(xmlSecBufferGetData(&buffer), xmlSecBufferGetSize(&buffer), 0); - if((res == NULL) || (xmlStrlen(res) == 0)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBase64Encode", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlSecBufferFinalize(&buffer); - return(NULL); - } - xmlSecBufferFinalize(&buffer); - - /* truncate the generated id attribute if needed */ - if(xmlStrlen(res) > (int)len) { - res[len] = '\0'; - } - - /* we need to cleanup base64 encoded id because ID attr can't have '+' or '/' characters */ - for(p = res; (*p) != '\0'; p++) { - if(((*p) == '+') || ((*p) == '/')) { - (*p) = '_'; - } - } - - /* add prefix if exist */ - if(prefix) { - xmlChar* tmp; - xmlSecSize tmpLen; - - tmpLen = xmlStrlen(prefix) + xmlStrlen(res) + 1; - tmp = xmlMalloc(tmpLen + 1); - if(tmp == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlMalloc", - XMLSEC_ERRORS_R_MALLOC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - xmlFree(res); - return(NULL); - } - - xmlSecStrPrintf(tmp, tmpLen, "%s%s", prefix, res); - xmlFree(res); - res = tmp; - } else { - /* no prefix: check that ID attribute starts from a letter */ - if(!(((res[0] >= 'A') && (res[0] <= 'Z')) || - ((res[0] >= 'a') && (res[0] <= 'z')))) { - res[0] = 'A'; - } - } - - return(res); -} - - -/** * xmlSecCreateTree: * @rootNodeName: the root node name. - * @rootNodeNs: the root node namespace (otpional). + * @rootNodeNs: the root node namespace (optional). * * Creates a new XML tree with one root node @rootNodeName. * @@ -876,22 +757,15 @@ xmlSecCreateTree(const xmlChar* rootNodeName, const xmlChar* rootNodeNs) { /* create doc */ doc = xmlNewDoc(BAD_CAST "1.0"); if(doc == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewDoc", - XMLSEC_ERRORS_R_XML_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecXmlError("xmlNewDoc", NULL); return(NULL); } /* create root node */ root = xmlNewDocNode(doc, NULL, rootNodeName, NULL); if(root == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewDocNode", - XMLSEC_ERRORS_R_XML_FAILED, - "node=Keys"); + xmlSecXmlError2("xmlNewDocNode", NULL, + "node=%s", rootNodeName); xmlFreeDoc(doc); return(NULL); } @@ -900,12 +774,8 @@ xmlSecCreateTree(const xmlChar* rootNodeName, const xmlChar* rootNodeNs) { /* and set root node namespace */ ns = xmlNewNs(root, rootNodeNs, NULL); if(ns == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewNs", - XMLSEC_ERRORS_R_XML_FAILED, - "ns=%s", - xmlSecErrorsSafeString(rootNodeNs)); + xmlSecXmlError2("xmlNewNs", NULL, + "ns=%s", xmlSecErrorsSafeString(rootNodeNs)); xmlFreeDoc(doc); return(NULL); } @@ -918,7 +788,7 @@ xmlSecCreateTree(const xmlChar* rootNodeName, const xmlChar* rootNodeNs) { * xmlSecIsEmptyNode: * @node: the node to check * - * Checks whethere the @node is empty (i.e. has only whitespaces children). + * Checks whether the @node is empty (i.e. has only whitespaces children). * * Returns: 1 if @node is empty, 0 otherwise or a negative value if an error occurs. */ @@ -947,7 +817,7 @@ xmlSecIsEmptyNode(xmlNodePtr node) { * xmlSecIsEmptyString: * @str: the string to check * - * Checks whethere the @str is empty (i.e. has only whitespaces children). + * Checks whether the @str is empty (i.e. has only whitespaces children). * * Returns: 1 if @str is empty, 0 otherwise or a negative value if an error occurs. */ @@ -980,12 +850,8 @@ xmlSecPrintXmlString(FILE * fd, const xmlChar * str) { xmlChar * encoded_str = NULL; encoded_str = xmlEncodeSpecialChars(NULL, str); if(encoded_str == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlEncodeSpecialChars", - XMLSEC_ERRORS_R_XML_FAILED, - "string=%s", - xmlSecErrorsSafeString(str)); + xmlSecXmlError2("xmlEncodeSpecialChars", NULL, + "string=%s", xmlSecErrorsSafeString(str)); return(-1); } @@ -996,12 +862,7 @@ xmlSecPrintXmlString(FILE * fd, const xmlChar * str) { } if(res < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "fprintf", - XMLSEC_ERRORS_R_IO_FAILED, - "res=%d,errno=%d", - res, errno); + xmlSecIOError("fprintf", NULL, NULL); return(-1); } return(res); @@ -1023,6 +884,7 @@ xmlChar* xmlSecGetQName(xmlNodePtr node, const xmlChar* href, const xmlChar* local) { xmlChar* qname; xmlNsPtr ns; + int ret; xmlSecAssert2(node != NULL, NULL); xmlSecAssert2(local != NULL, NULL); @@ -1031,13 +893,8 @@ xmlSecGetQName(xmlNodePtr node, const xmlChar* href, const xmlChar* local) { * it might cause collisions */ ns = xmlSearchNsByHref(node->doc, node, href); if((ns == NULL) && (href != NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSearchNsByHref", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s,href=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(href)); + xmlSecXmlError2("xmlSearchNsByHref", NULL, + "node=%s", xmlSecErrorsSafeString(node->name)); return(NULL); } @@ -1045,26 +902,22 @@ xmlSecGetQName(xmlNodePtr node, const xmlChar* href, const xmlChar* local) { xmlSecSize len; len = xmlStrlen(local) + xmlStrlen(ns->prefix) + 4; - qname = xmlMalloc(len); + qname = (xmlChar *)xmlMalloc(len); if(qname == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlMalloc", - XMLSEC_ERRORS_R_MALLOC_FAILED, - "node=%s", - xmlSecErrorsSafeString(node->name)); + xmlSecMallocError(len, NULL); + return(NULL); + } + + ret = xmlStrPrintf(qname, len, "%s:%s", ns->prefix, local); + if(ret < 0) { + xmlSecXmlError("xmlStrPrintf", NULL); + xmlFree(qname); return(NULL); } - xmlSecStrPrintf(qname, len, "%s:%s", ns->prefix, local); } else { qname = xmlStrdup(local); if(qname == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlStrdup", - XMLSEC_ERRORS_R_MALLOC_FAILED, - "node=%s", - xmlSecErrorsSafeString(node->name)); + xmlSecStrdupError(local, NULL); return(NULL); } } @@ -1164,15 +1017,9 @@ xmlSecQName2IntegerGetIntegerFromString(xmlSecQName2IntegerInfoConstPtr info, qnameLocalPart = xmlStrchr(qname, ':'); if(qnameLocalPart != NULL) { - qnamePrefix = xmlStrndup(qname, qnameLocalPart - qname); + qnamePrefix = xmlStrndup(qname, (int)(qnameLocalPart - qname)); if(qnamePrefix == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlStrndup", - XMLSEC_ERRORS_R_MALLOC_FAILED, - "node=%s,value=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(qname)); + xmlSecStrdupError(qname, NULL); return(-1); } qnameLocalPart++; @@ -1184,13 +1031,8 @@ xmlSecQName2IntegerGetIntegerFromString(xmlSecQName2IntegerInfoConstPtr info, /* search namespace href */ ns = xmlSearchNs(node->doc, node, qnamePrefix); if((ns == NULL) && (qnamePrefix != NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSearchNs", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s,qnamePrefix=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(qnamePrefix)); + xmlSecXmlError2("xmlSearchNs", NULL, + "node=%s", xmlSecErrorsSafeString(node->name)); if(qnamePrefix != NULL) { xmlFree(qnamePrefix); } @@ -1201,14 +1043,11 @@ xmlSecQName2IntegerGetIntegerFromString(xmlSecQName2IntegerInfoConstPtr info, /* and finally search for integer */ ret = xmlSecQName2IntegerGetInteger(info, qnameHref, qnameLocalPart, intValue); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2IntegerGetInteger", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,qnameLocalPart=%s,qnameHref=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(qnameLocalPart), - xmlSecErrorsSafeString(qnameHref)); + xmlSecInternalError4("xmlSecQName2IntegerGetInteger", NULL, + "node=%s,qnameLocalPart=%s,qnameHref=%s", + xmlSecErrorsSafeString(node->name), + xmlSecErrorsSafeString(qnameLocalPart), + xmlSecErrorsSafeString(qnameHref)); if(qnamePrefix != NULL) { xmlFree(qnamePrefix); } @@ -1243,13 +1082,10 @@ xmlSecQName2IntegerGetStringFromInteger(xmlSecQName2IntegerInfoConstPtr info, qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue); if(qnameInfo == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2IntegerGetInfo", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,intValue=%d", - xmlSecErrorsSafeString(node->name), - intValue); + xmlSecInternalError3("xmlSecQName2IntegerGetInfo", NULL, + "node=%s,intValue=%d", + xmlSecErrorsSafeString(node->name), + intValue); return(NULL); } @@ -1278,25 +1114,18 @@ xmlSecQName2IntegerNodeRead(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr nod content = xmlNodeGetContent(node); if(content == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNodeGetContent", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s", - xmlSecErrorsSafeString(node->name)); + xmlSecXmlError2("xmlNodeGetContent", NULL, + "node=%s", xmlSecErrorsSafeString(node->name)); return(-1); } /* todo: trim content? */ ret = xmlSecQName2IntegerGetIntegerFromString(info, node, content, intValue); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2IntegerGetIntegerFromString", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,value=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(content)); + xmlSecInternalError3("xmlSecQName2IntegerGetIntegerFromString", NULL, + "node=%s,value=%s", + xmlSecErrorsSafeString(node->name), + xmlSecErrorsSafeString(content)); xmlFree(content); return(-1); } @@ -1330,25 +1159,19 @@ xmlSecQName2IntegerNodeWrite(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr no /* find and build qname */ qname = xmlSecQName2IntegerGetStringFromInteger(info, node, intValue); if(qname == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2IntegerGetStringFromInteger", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,intValue=%d", - xmlSecErrorsSafeString(node->name), - intValue); + xmlSecInternalError3("xmlSecQName2IntegerGetStringFromInteger", NULL, + "node=%s,intValue=%d", + xmlSecErrorsSafeString(node->name), + intValue); return(-1); } cur = xmlSecAddChild(node, nodeName, nodeNs); if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChild", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,intValue=%d", - xmlSecErrorsSafeString(nodeName), - intValue); + xmlSecInternalError3("xmlSecAddChild", NULL, + "node=%s,intValue=%d", + xmlSecErrorsSafeString(nodeName), + intValue); xmlFree(qname); return(-1); } @@ -1383,27 +1206,19 @@ xmlSecQName2IntegerAttributeRead(xmlSecQName2IntegerInfoConstPtr info, xmlNodePt attrValue = xmlGetProp(node, attrName); if(attrValue == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlGetProp", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s,attrValue=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(attrName)); + xmlSecXmlError2("xmlGetProp", NULL, + "node=%s", xmlSecErrorsSafeString(node->name)); return(-1); } /* todo: trim value? */ ret = xmlSecQName2IntegerGetIntegerFromString(info, node, attrValue, intValue); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2IntegerGetIntegerFromString", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,attrName=%s,attrValue=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(attrName), - xmlSecErrorsSafeString(attrValue)); + xmlSecInternalError4("xmlSecQName2IntegerGetIntegerFromString", NULL, + "node=%s,attrName=%s,attrValue=%s", + xmlSecErrorsSafeString(node->name), + xmlSecErrorsSafeString(attrName), + xmlSecErrorsSafeString(attrValue)); xmlFree(attrValue); return(-1); } @@ -1437,27 +1252,21 @@ xmlSecQName2IntegerAttributeWrite(xmlSecQName2IntegerInfoConstPtr info, xmlNodeP /* find and build qname */ qname = xmlSecQName2IntegerGetStringFromInteger(info, node, intValue); if(qname == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2IntegerGetStringFromInteger", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,attrName=%s,intValue=%d", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(attrName), - intValue); + xmlSecInternalError4("xmlSecQName2IntegerGetStringFromInteger", NULL, + "node=%s,attrName=%s,intValue=%d", + xmlSecErrorsSafeString(node->name), + xmlSecErrorsSafeString(attrName), + intValue); return(-1); } attr = xmlSetProp(node, attrName, qname); if(attr == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChildNode", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,attrName=%s,intValue=%d", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(attrName), - intValue); + xmlSecInternalError4("xmlSetProp", NULL, + "node=%s,attrName=%s,intValue=%d", + xmlSecErrorsSafeString(node->name), + xmlSecErrorsSafeString(attrName), + intValue); xmlFree(qname); return(-1); } @@ -1612,15 +1421,9 @@ xmlSecQName2BitMaskGetBitMaskFromString(xmlSecQName2BitMaskInfoConstPtr info, qnameLocalPart = xmlStrchr(qname, ':'); if(qnameLocalPart != NULL) { - qnamePrefix = xmlStrndup(qname, qnameLocalPart - qname); + qnamePrefix = xmlStrndup(qname, (int)(qnameLocalPart - qname)); if(qnamePrefix == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlStrndup", - XMLSEC_ERRORS_R_MALLOC_FAILED, - "node=%s,value=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(qname)); + xmlSecStrdupError(qname, NULL); return(-1); } qnameLocalPart++; @@ -1632,13 +1435,8 @@ xmlSecQName2BitMaskGetBitMaskFromString(xmlSecQName2BitMaskInfoConstPtr info, /* search namespace href */ ns = xmlSearchNs(node->doc, node, qnamePrefix); if((ns == NULL) && (qnamePrefix != NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSearchNs", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s,qnamePrefix=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(qnamePrefix)); + xmlSecXmlError2("xmlSearchNs", NULL, + "node=%s", xmlSecErrorsSafeString(node->name)); if(qnamePrefix != NULL) { xmlFree(qnamePrefix); } @@ -1649,14 +1447,11 @@ xmlSecQName2BitMaskGetBitMaskFromString(xmlSecQName2BitMaskInfoConstPtr info, /* and finally search for integer */ ret = xmlSecQName2BitMaskGetBitMask(info, qnameHref, qnameLocalPart, mask); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2BitMaskGetBitMask", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,qnameLocalPart=%s,qnameHref=%s", - xmlSecErrorsSafeString(node->name), - xmlSecErrorsSafeString(qnameLocalPart), - xmlSecErrorsSafeString(qnameHref)); + xmlSecInternalError4("xmlSecQName2BitMaskGetBitMask", NULL, + "node=%s,qnameLocalPart=%s,qnameHref=%s", + xmlSecErrorsSafeString(node->name), + xmlSecErrorsSafeString(qnameLocalPart), + xmlSecErrorsSafeString(qnameHref)); if(qnamePrefix != NULL) { xmlFree(qnamePrefix); } @@ -1691,13 +1486,10 @@ xmlSecQName2BitMaskGetStringFromBitMask(xmlSecQName2BitMaskInfoConstPtr info, qnameInfo = xmlSecQName2BitMaskGetInfo(info, mask); if(qnameInfo == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2BitMaskGetInfo", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s,mask=%d", - xmlSecErrorsSafeString(node->name), - mask); + xmlSecInternalError3("xmlSecQName2BitMaskGetInfo", NULL, + "node=%s,mask=%d", + xmlSecErrorsSafeString(node->name), + mask); return(NULL); } @@ -1738,23 +1530,15 @@ xmlSecQName2BitMaskNodesRead(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr* n while((cur != NULL) && (xmlSecCheckNodeName(cur, nodeName, nodeNs))) { content = xmlNodeGetContent(cur); if(content == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNodeGetContent", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s", - xmlSecErrorsSafeString(cur->name)); + xmlSecXmlError2("xmlNodeGetContent", NULL, + "node=%s", xmlSecErrorsSafeString(cur->name)); return(-1); } ret = xmlSecQName2BitMaskGetBitMaskFromString(info, cur, content, &tmp); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2BitMaskGetBitMaskFromString", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "value=%s", - xmlSecErrorsSafeString(content)); + xmlSecInternalError2("xmlSecQName2BitMaskGetBitMaskFromString", NULL, + "value=%s", xmlSecErrorsSafeString(content)); xmlFree(content); return(-1); } @@ -1762,12 +1546,8 @@ xmlSecQName2BitMaskNodesRead(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr* n if((stopOnUnknown != 0) && (tmp == 0)) { /* todo: better error */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecQName2BitMaskGetBitMaskFromString", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "value=%s", - xmlSecErrorsSafeString(content)); + xmlSecInternalError2("xmlSecQName2BitMaskGetBitMaskFromString", NULL, + "value=%s", xmlSecErrorsSafeString(content)); return(-1); } @@ -1810,23 +1590,15 @@ xmlSecQName2BitMaskNodesWrite(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr n qname = xmlSecGetQName(node, info[ii].qnameHref, info[ii].qnameLocalPart); if(qname == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGetQName", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s", - xmlSecErrorsSafeString(nodeName)); + xmlSecXmlError2("xmlSecGetQName", NULL, + "node=%s", xmlSecErrorsSafeString(nodeName)); return(-1); } cur = xmlSecAddChild(node, nodeName, nodeNs); if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChild", - XMLSEC_ERRORS_R_XML_FAILED, - "node=%s", - xmlSecErrorsSafeString(nodeName)); + xmlSecXmlError2("xmlSecAddChild", NULL, + "node=%s", xmlSecErrorsSafeString(nodeName)); xmlFree(qname); return(-1); } @@ -1905,6 +1677,273 @@ xmlSecQName2BitMaskDebugXmlDump(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitM fprintf(output, "</%sList>\n", name); } +/************************************************************************* + * + * Windows string conversions + * + ************************************************************************/ +#ifdef WIN32 + +/** + * xmlSecWin32ConvertUtf8ToUnicode: + * @str: the string to convert. + * + * Converts input string from UTF8 to Unicode. + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +LPWSTR +xmlSecWin32ConvertUtf8ToUnicode(const xmlChar* str) { + LPWSTR res = NULL; + int len; + int ret; + + xmlSecAssert2(str != NULL, NULL); + + /* call MultiByteToWideChar first to get the buffer size */ + ret = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)str, -1, NULL, 0); + if(ret <= 0) { + return(NULL); + } + len = ret + 1; + + /* allocate buffer */ + res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len); + if(res == NULL) { + xmlSecMallocError(sizeof(WCHAR) * len, NULL); + return(NULL); + } + + /* convert */ + ret = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)str, -1, res, len); + if(ret <= 0) { + xmlFree(res); + return(NULL); + } + + /* done */ + return(res); +} + +/** + * xmlSecWin32ConvertUnicodeToUtf8: + * @str: the string to convert. + * + * Converts input string from Unicode to UTF8. + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +xmlChar* +xmlSecWin32ConvertUnicodeToUtf8(LPCWSTR str) { + xmlChar * res = NULL; + int len; + int ret; + + xmlSecAssert2(str != NULL, NULL); + + /* call WideCharToMultiByte first to get the buffer size */ + ret = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); + if(ret <= 0) { + return(NULL); + } + len = ret + 1; + + /* allocate buffer */ + res = (xmlChar*)xmlMalloc(sizeof(xmlChar) * len); + if(res == NULL) { + xmlSecMallocError(sizeof(xmlChar) * len, NULL); + return(NULL); + } + + /* convert */ + ret = WideCharToMultiByte(CP_UTF8, 0, str, -1, (LPSTR)res, len, NULL, NULL); + if(ret <= 0) { + xmlFree(res); + return(NULL); + } + + /* done */ + return(res); +} + +/** + * xmlSecWin32ConvertLocaleToUnicode: + * @str: the string to convert. + * + * Converts input string from current system locale to Unicode. + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +LPWSTR +xmlSecWin32ConvertLocaleToUnicode(const char* str) { + LPWSTR res = NULL; + int len; + int ret; + + xmlSecAssert2(str != NULL, NULL); + + /* call MultiByteToWideChar first to get the buffer size */ + ret = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + if(ret <= 0) { + return(NULL); + } + len = ret; + + /* allocate buffer */ + res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len); + if(res == NULL) { + xmlSecMallocError(sizeof(WCHAR) * len, NULL); + return(NULL); + } + + /* convert */ + ret = MultiByteToWideChar(CP_ACP, 0, str, -1, res, len); + if(ret <= 0) { + xmlFree(res); + return(NULL); + } + + /* done */ + return(res); +} + +/** + * xmlSecWin32ConvertLocaleToUtf8: + * @str: the string to convert. + * + * Converts input string from locale to UTF8. + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +xmlChar* +xmlSecWin32ConvertLocaleToUtf8(const char * str) { + LPWSTR strW = NULL; + xmlChar * res = NULL; + int len; + int ret; + + xmlSecAssert2(str != NULL, NULL); + + strW = xmlSecWin32ConvertLocaleToUnicode(str); + if(strW == NULL) { + return(NULL); + } + + /* call WideCharToMultiByte first to get the buffer size */ + ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, NULL, 0, NULL, NULL); + if(ret <= 0) { + xmlFree(strW); + return(NULL); + } + len = ret + 1; + + /* allocate buffer */ + res = (xmlChar*)xmlMalloc(sizeof(xmlChar) * len); + if(res == NULL) { + xmlSecMallocError(sizeof(xmlChar) * len, NULL); + xmlFree(strW); + return(NULL); + } + + /* convert */ + ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, (LPSTR)res, len, NULL, NULL); + if(ret <= 0) { + xmlFree(strW); + xmlFree(res); + return(NULL); + } + + /* done */ + xmlFree(strW); + return(res); +} + +/** + * xmlSecWin32ConvertUtf8ToLocale: + * @str: the string to convert. + * + * Converts input string from UTF8 to locale. + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +char * +xmlSecWin32ConvertUtf8ToLocale(const xmlChar* str) { + LPWSTR strW = NULL; + char * res = NULL; + int len; + int ret; + + xmlSecAssert2(str != NULL, NULL); + + strW = xmlSecWin32ConvertUtf8ToUnicode(str); + if(strW == NULL) { + return(NULL); + } + + /* call WideCharToMultiByte first to get the buffer size */ + ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, NULL, 0, NULL, NULL); + if(ret <= 0) { + xmlFree(strW); + return(NULL); + } + len = ret + 1; + + /* allocate buffer */ + res = (char*)xmlMalloc(sizeof(char) * len); + if(res == NULL) { + xmlSecMallocError(sizeof(char) * len, NULL); + xmlFree(strW); + return(NULL); + } + + /* convert */ + ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, res, len, NULL, NULL); + if(ret <= 0) { + xmlFree(strW); + xmlFree(res); + return(NULL); + } + + /* done */ + xmlFree(strW); + return(res); +} + +/** + * xmlSecWin32ConvertTstrToUtf8: + * @str: the string to convert. + * + * Converts input string from TSTR (locale or Unicode) to UTF8. + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +xmlChar* +xmlSecWin32ConvertTstrToUtf8(LPCTSTR str) { +#ifdef UNICODE + return xmlSecWin32ConvertUnicodeToUtf8(str); +#else /* UNICODE */ + return xmlSecWin32ConvertLocaleToUtf8(str); +#endif /* UNICODE */ +} + +/** + * xmlSecWin32ConvertUtf8ToTstr: + * @str: the string to convert. + * + * Converts input string from UTF8 to TSTR (locale or Unicode). + * + * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. + */ +LPTSTR +xmlSecWin32ConvertUtf8ToTstr(const xmlChar* str) { +#ifdef UNICODE + return xmlSecWin32ConvertUtf8ToUnicode(str); +#else /* UNICODE */ + return xmlSecWin32ConvertUtf8ToLocale(str); +#endif /* UNICODE */ +} + +#endif /* WIN32 */ |