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