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

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

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