File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / testC14N.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:22:20 2013 UTC (10 years, 11 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_8_0p0, v2_8_0, HEAD
2.8.0

    1: /*
    2:  * Canonical XML implementation test program
    3:  * (http://www.w3.org/TR/2001/REC-xml-c14n-20010315)
    4:  *
    5:  * See Copyright for the status of this software.
    6:  * 
    7:  * Author: Aleksey Sanin <aleksey@aleksey.com>
    8:  */
    9: #include "libxml.h"
   10: #if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
   11: 
   12: #include <stdio.h>
   13: #include <string.h>
   14: #ifdef HAVE_UNISTD_H
   15: #include <unistd.h>
   16: #else
   17: #define STDOUT_FILENO fileno(stdout)
   18: #endif /* HAVE_UNISTD_H */
   19: #ifdef HAVE_STDLIB_H
   20: #include <stdlib.h>
   21: #endif
   22: 
   23: #include <libxml/xmlmemory.h>
   24: #include <libxml/parser.h>
   25: #include <libxml/xpath.h>
   26: #include <libxml/xpathInternals.h>
   27: 
   28: #include <libxml/c14n.h>
   29: 
   30: 
   31: static void usage(const char *name) {
   32:     fprintf(stderr,
   33: 	"Usage: %s <mode> <xml-file> [<xpath-expr>] [<inclusive-ns-list>]\n",
   34: 	    name);
   35:     fprintf(stderr, "where <mode> is one of following:\n");
   36:     fprintf(stderr,
   37: 	"--with-comments       \t XML file canonicalization v1.0 w comments \n");
   38:     fprintf(stderr,
   39: 	"--without-comments    \t XML file canonicalization v1.0 w/o comments\n");
   40:     fprintf(stderr,
   41: 	"--1-1-with-comments       \t XML file canonicalization v1.1 w comments\n");
   42:     fprintf(stderr,
   43: 	"--1-1-without-comments    \t XML file canonicalization v1.1 w/o comments\n");
   44:     fprintf(stderr,
   45:     "--exc-with-comments   \t Exclusive XML file canonicalization v1.0 w comments\n");
   46:     fprintf(stderr,
   47:     "--exc-without-comments\t Exclusive XML file canonicalization v1.0 w/o comments\n");
   48: }
   49: 
   50: static xmlXPathObjectPtr
   51: load_xpath_expr (xmlDocPtr parent_doc, const char* filename);
   52: 
   53: static xmlChar **parse_list(xmlChar *str);
   54: 
   55: /* static void print_xpath_nodes(xmlNodeSetPtr nodes); */
   56: 
   57: static int 
   58: test_c14n(const char* xml_filename, int with_comments, int mode,
   59: 	const char* xpath_filename, xmlChar **inclusive_namespaces) {
   60:     xmlDocPtr doc;
   61:     xmlXPathObjectPtr xpath = NULL; 
   62:     xmlChar *result = NULL;
   63:     int ret;
   64: 
   65:     /*
   66:      * build an XML tree from a the file; we need to add default
   67:      * attributes and resolve all character and entities references
   68:      */
   69:     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
   70:     xmlSubstituteEntitiesDefault(1);
   71: 
   72:     doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
   73:     if (doc == NULL) {
   74: 	fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
   75: 	return(-1);
   76:     }
   77:     
   78:     /*
   79:      * Check the document is of the right kind
   80:      */    
   81:     if(xmlDocGetRootElement(doc) == NULL) {
   82:         fprintf(stderr,"Error: empty document for file \"%s\"\n", xml_filename);
   83: 	xmlFreeDoc(doc);
   84: 	return(-1);
   85:     }
   86: 
   87:     /* 
   88:      * load xpath file if specified 
   89:      */
   90:     if(xpath_filename) {
   91: 	xpath = load_xpath_expr(doc, xpath_filename);
   92: 	if(xpath == NULL) {
   93: 	    fprintf(stderr,"Error: unable to evaluate xpath expression\n");
   94: 	    xmlFreeDoc(doc); 
   95: 	    return(-1);
   96: 	}
   97:     }
   98: 
   99:     /*
  100:      * Canonical form
  101:      */      
  102:     /* fprintf(stderr,"File \"%s\" loaded: start canonization\n", xml_filename); */
  103:     ret = xmlC14NDocDumpMemory(doc, 
  104: 	    (xpath) ? xpath->nodesetval : NULL, 
  105: 	    mode, inclusive_namespaces,
  106: 	    with_comments, &result);
  107:     if(ret >= 0) {
  108: 	if(result != NULL) {
  109: 	    if (write(STDOUT_FILENO, result, ret) == -1) {
  110: 		fprintf(stderr, "Can't write data\n");
  111: 	    }
  112: 	    xmlFree(result);
  113: 	}
  114:     } else {
  115: 	fprintf(stderr,"Error: failed to canonicalize XML file \"%s\" (ret=%d)\n", xml_filename, ret);
  116: 	if(result != NULL) xmlFree(result);
  117: 	xmlFreeDoc(doc); 
  118: 	return(-1);
  119:     }
  120:         
  121:     /*
  122:      * Cleanup
  123:      */ 
  124:     if(xpath != NULL) xmlXPathFreeObject(xpath);
  125:     xmlFreeDoc(doc);    
  126: 
  127:     return(ret);
  128: }
  129: 
  130: int main(int argc, char **argv) {
  131:     int ret = -1;
  132:     
  133:     /*
  134:      * Init libxml
  135:      */     
  136:     xmlInitParser();
  137:     LIBXML_TEST_VERSION
  138: 
  139:     /*
  140:      * Parse command line and process file
  141:      */
  142:     if( argc < 3 ) {
  143: 	fprintf(stderr, "Error: wrong number of arguments.\n");
  144: 	usage(argv[0]);
  145:     } else if(strcmp(argv[1], "--with-comments") == 0) {
  146: 	ret = test_c14n(argv[2], 1, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
  147:     } else if(strcmp(argv[1], "--without-comments") == 0) {
  148: 	ret = test_c14n(argv[2], 0, XML_C14N_1_0, (argc > 3) ? argv[3] : NULL, NULL);
  149:     } else if(strcmp(argv[1], "--1-1-with-comments") == 0) {
  150: 	ret = test_c14n(argv[2], 1, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
  151:     } else if(strcmp(argv[1], "--1-1-without-comments") == 0) {
  152: 	ret = test_c14n(argv[2], 0, XML_C14N_1_1, (argc > 3) ? argv[3] : NULL, NULL);
  153:     } else if(strcmp(argv[1], "--exc-with-comments") == 0) {
  154: 	xmlChar **list;
  155: 	
  156: 	/* load exclusive namespace from command line */
  157: 	list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
  158: 	ret = test_c14n(argv[2], 1, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
  159: 	if(list != NULL) xmlFree(list);
  160:     } else if(strcmp(argv[1], "--exc-without-comments") == 0) {
  161: 	xmlChar **list;
  162: 	
  163: 	/* load exclusive namespace from command line */
  164: 	list = (argc > 4) ? parse_list((xmlChar *)argv[4]) : NULL;
  165: 	ret = test_c14n(argv[2], 0, XML_C14N_EXCLUSIVE_1_0, (argc > 3) ? argv[3] : NULL, list);
  166: 	if(list != NULL) xmlFree(list);
  167:     } else {
  168: 	fprintf(stderr, "Error: bad option.\n");
  169: 	usage(argv[0]);
  170:     }
  171: 
  172:     /* 
  173:      * Shutdown libxml
  174:      */
  175:     xmlCleanupParser();
  176:     xmlMemoryDump();
  177: 
  178:     return((ret >= 0) ? 0 : 1);
  179: }
  180: 
  181: /*
  182:  * Macro used to grow the current buffer.
  183:  */
  184: #define growBufferReentrant() {						\
  185:     buffer_size *= 2;							\
  186:     buffer = (xmlChar **)						\
  187: 		xmlRealloc(buffer, buffer_size * sizeof(xmlChar*));	\
  188:     if (buffer == NULL) {						\
  189: 	perror("realloc failed");					\
  190: 	return(NULL);							\
  191:     }									\
  192: }
  193: 
  194: static xmlChar **
  195: parse_list(xmlChar *str) {
  196:     xmlChar **buffer;
  197:     xmlChar **out = NULL;
  198:     int buffer_size = 0;
  199:     int len;
  200: 
  201:     if(str == NULL) {
  202: 	return(NULL);
  203:     }
  204: 
  205:     len = xmlStrlen(str);
  206:     if((str[0] == '\'') && (str[len - 1] == '\'')) {
  207: 	str[len - 1] = '\0';
  208: 	str++;
  209:     }
  210:     /*
  211:      * allocate an translation buffer.
  212:      */
  213:     buffer_size = 1000;
  214:     buffer = (xmlChar **) xmlMalloc(buffer_size * sizeof(xmlChar*));
  215:     if (buffer == NULL) {
  216: 	perror("malloc failed");
  217: 	return(NULL);
  218:     }
  219:     out = buffer;
  220: 
  221:     while(*str != '\0') {
  222: 	if (out - buffer > buffer_size - 10) {
  223: 	    int indx = out - buffer;
  224: 
  225: 	    growBufferReentrant();
  226: 	    out = &buffer[indx];
  227: 	}
  228: 	(*out++) = str;
  229: 	while(*str != ',' && *str != '\0') ++str;
  230: 	if(*str == ',') *(str++) = '\0';
  231:     }
  232:     (*out) = NULL;
  233:     return buffer;
  234: }
  235: 
  236: static xmlXPathObjectPtr
  237: load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {
  238:     xmlXPathObjectPtr xpath; 
  239:     xmlDocPtr doc;
  240:     xmlChar *expr;
  241:     xmlXPathContextPtr ctx; 
  242:     xmlNodePtr node;
  243:     xmlNsPtr ns;
  244:     
  245:     /*
  246:      * load XPath expr as a file
  247:      */
  248:     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
  249:     xmlSubstituteEntitiesDefault(1);
  250: 
  251:     doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
  252:     if (doc == NULL) {
  253: 	fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
  254: 	return(NULL);
  255:     }
  256:     
  257:     /*
  258:      * Check the document is of the right kind
  259:      */    
  260:     if(xmlDocGetRootElement(doc) == NULL) {
  261:         fprintf(stderr,"Error: empty document for file \"%s\"\n", filename);
  262: 	xmlFreeDoc(doc);
  263: 	return(NULL);
  264:     }
  265: 
  266:     node = doc->children;
  267:     while(node != NULL && !xmlStrEqual(node->name, (const xmlChar *)"XPath")) {
  268: 	node = node->next;
  269:     }
  270:     
  271:     if(node == NULL) {   
  272:         fprintf(stderr,"Error: XPath element expected in the file  \"%s\"\n", filename);
  273: 	xmlFreeDoc(doc);
  274: 	return(NULL);
  275:     }
  276: 
  277:     expr = xmlNodeGetContent(node);
  278:     if(expr == NULL) {
  279:         fprintf(stderr,"Error: XPath content element is NULL \"%s\"\n", filename);
  280: 	xmlFreeDoc(doc);
  281: 	return(NULL);
  282:     }
  283: 
  284:     ctx = xmlXPathNewContext(parent_doc);
  285:     if(ctx == NULL) {
  286:         fprintf(stderr,"Error: unable to create new context\n");
  287:         xmlFree(expr); 
  288:         xmlFreeDoc(doc); 
  289:         return(NULL);
  290:     }
  291: 
  292:     /*
  293:      * Register namespaces
  294:      */
  295:     ns = node->nsDef;
  296:     while(ns != NULL) {
  297: 	if(xmlXPathRegisterNs(ctx, ns->prefix, ns->href) != 0) {
  298: 	    fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", ns->prefix, ns->href);
  299:     	    xmlFree(expr); 
  300: 	    xmlXPathFreeContext(ctx); 
  301: 	    xmlFreeDoc(doc); 
  302: 	    return(NULL);
  303: 	}
  304: 	ns = ns->next;
  305:     }
  306: 
  307:     /*  
  308:      * Evaluate xpath
  309:      */
  310:     xpath = xmlXPathEvalExpression(expr, ctx);
  311:     if(xpath == NULL) {
  312:         fprintf(stderr,"Error: unable to evaluate xpath expression\n");
  313:     	xmlFree(expr); 
  314:         xmlXPathFreeContext(ctx); 
  315:         xmlFreeDoc(doc); 
  316:         return(NULL);
  317:     }
  318: 
  319:     /* print_xpath_nodes(xpath->nodesetval); */
  320: 
  321:     xmlFree(expr); 
  322:     xmlXPathFreeContext(ctx); 
  323:     xmlFreeDoc(doc); 
  324:     return(xpath);
  325: }
  326: 
  327: /*
  328: static void
  329: print_xpath_nodes(xmlNodeSetPtr nodes) {
  330:     xmlNodePtr cur;
  331:     int i;
  332:     
  333:     if(nodes == NULL ){ 
  334: 	fprintf(stderr, "Error: no nodes set defined\n");
  335: 	return;
  336:     }
  337:     
  338:     fprintf(stderr, "Nodes Set:\n-----\n");
  339:     for(i = 0; i < nodes->nodeNr; ++i) {
  340: 	if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
  341: 	    xmlNsPtr ns;
  342: 	    
  343: 	    ns = (xmlNsPtr)nodes->nodeTab[i];
  344: 	    cur = (xmlNodePtr)ns->next;
  345: 	    fprintf(stderr, "namespace \"%s\"=\"%s\" for node %s:%s\n", 
  346: 		    ns->prefix, ns->href,
  347: 		    (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name);
  348: 	} else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
  349: 	    cur = nodes->nodeTab[i];    
  350: 	    fprintf(stderr, "element node \"%s:%s\"\n", 
  351: 		    (cur->ns) ? cur->ns->prefix : BAD_CAST "", cur->name);
  352: 	} else {
  353: 	    cur = nodes->nodeTab[i];    
  354: 	    fprintf(stderr, "node \"%s\": type %d\n", cur->name, cur->type);
  355: 	}
  356:     }
  357: }
  358: */
  359: 
  360: #else
  361: #include <stdio.h>
  362: int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
  363:     printf("%s : XPath/Canonicalization and output support not compiled in\n", argv[0]);
  364:     return(0);
  365: }
  366: #endif /* LIBXML_C14N_ENABLED */
  367: 
  368: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>