Annotation of embedaddon/libxml2/testC14N.c, revision 1.1.1.1

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

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