Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * xmllint.c : a small tester program for XML input. |
3 | | * |
4 | | * See Copyright for the status of this software. |
5 | | * |
6 | | * Author: Daniel Veillard |
7 | | */ |
8 | | |
9 | | #include "libxml.h" |
10 | | |
11 | | #include <string.h> |
12 | | #include <stdarg.h> |
13 | | #include <stdio.h> |
14 | | #include <stdlib.h> |
15 | | #include <errno.h> |
16 | | #include <limits.h> |
17 | | #include <fcntl.h> |
18 | | |
19 | | #ifdef _WIN32 |
20 | | #include <io.h> |
21 | | #include <sys/timeb.h> |
22 | | #else |
23 | | #include <sys/time.h> |
24 | | #include <unistd.h> |
25 | | #endif |
26 | | |
27 | | #if HAVE_DECL_MMAP |
28 | | #include <sys/mman.h> |
29 | | #include <sys/stat.h> |
30 | | /* seems needed for Solaris */ |
31 | | #ifndef MAP_FAILED |
32 | | #define MAP_FAILED ((void *) -1) |
33 | | #endif |
34 | | #endif |
35 | | |
36 | | #include <libxml/xmlmemory.h> |
37 | | #include <libxml/parser.h> |
38 | | #include <libxml/parserInternals.h> |
39 | | #include <libxml/HTMLparser.h> |
40 | | #include <libxml/HTMLtree.h> |
41 | | #include <libxml/tree.h> |
42 | | #include <libxml/xpath.h> |
43 | | #include <libxml/xpathInternals.h> |
44 | | #include <libxml/debugXML.h> |
45 | | #include <libxml/xmlerror.h> |
46 | | #ifdef LIBXML_XINCLUDE_ENABLED |
47 | | #include <libxml/xinclude.h> |
48 | | #endif |
49 | | #ifdef LIBXML_CATALOG_ENABLED |
50 | | #include <libxml/catalog.h> |
51 | | #endif |
52 | | #include <libxml/xmlreader.h> |
53 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
54 | | #include <libxml/schematron.h> |
55 | | #endif |
56 | | #ifdef LIBXML_RELAXNG_ENABLED |
57 | | #include <libxml/relaxng.h> |
58 | | #endif |
59 | | #ifdef LIBXML_SCHEMAS_ENABLED |
60 | | #include <libxml/xmlschemas.h> |
61 | | #endif |
62 | | #ifdef LIBXML_PATTERN_ENABLED |
63 | | #include <libxml/pattern.h> |
64 | | #endif |
65 | | #ifdef LIBXML_C14N_ENABLED |
66 | | #include <libxml/c14n.h> |
67 | | #endif |
68 | | #ifdef LIBXML_OUTPUT_ENABLED |
69 | | #include <libxml/xmlsave.h> |
70 | | #endif |
71 | | |
72 | | #include "private/lint.h" |
73 | | |
74 | | #ifndef STDIN_FILENO |
75 | | #define STDIN_FILENO 0 |
76 | | #endif |
77 | | #ifndef STDOUT_FILENO |
78 | | #define STDOUT_FILENO 1 |
79 | | #endif |
80 | | |
81 | 0 | #define MAX_PATHS 64 |
82 | | |
83 | | #ifdef _WIN32 |
84 | | #define PATH_SEPARATOR ';' |
85 | | #else |
86 | 0 | #define PATH_SEPARATOR ':' |
87 | | #endif |
88 | | |
89 | | typedef enum { |
90 | | XMLLINT_RETURN_OK = 0, /* No error */ |
91 | | XMLLINT_ERR_UNCLASS = 1, /* Unclassified */ |
92 | | XMLLINT_ERR_DTD = 2, /* Error in DTD */ |
93 | | XMLLINT_ERR_VALID = 3, /* Validation error */ |
94 | | XMLLINT_ERR_RDFILE = 4, /* Wellformedness or IO error */ |
95 | | XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */ |
96 | | XMLLINT_ERR_OUT = 6, /* Error writing output */ |
97 | | XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */ |
98 | | /*XMLLINT_ERR_RDREGIS = 8,*/ |
99 | | XMLLINT_ERR_MEM = 9, /* Out of memory error */ |
100 | | XMLLINT_ERR_XPATH = 10, /* XPath evaluation error */ |
101 | | XMLLINT_ERR_XPATH_EMPTY = 11 /* XPath result is empty */ |
102 | | } xmllintReturnCode; |
103 | | |
104 | | #ifdef _WIN32 |
105 | | typedef __time64_t xmlSeconds; |
106 | | #else |
107 | | typedef time_t xmlSeconds; |
108 | | #endif |
109 | | |
110 | | typedef struct { |
111 | | xmlSeconds sec; |
112 | | int usec; |
113 | | } xmlTime; |
114 | | |
115 | | /* Boolean xmllint application options */ |
116 | | typedef enum { |
117 | | /** Do not build a tree but work just at the SAX level */ |
118 | | XML_LINT_SAX_ENABLED = (1 << 0), |
119 | | /** run a navigating shell */ |
120 | | XML_LINT_NAVIGATING_SHELL = (1 << 1), |
121 | | /** Show additional debug information */ |
122 | | XML_LINT_DEBUG_ENABLED = (1 << 2), |
123 | | /** Test the internal copy implementation */ |
124 | | XML_LINT_COPY_ENABLED = (1 << 3), |
125 | | /** Turn on gzip compression of output */ |
126 | | XML_LINT_ZLIB_COMPRESSION = (1 << 4), |
127 | | /** Save in W3C canonical format v1.0 (with comments) */ |
128 | | XML_LINT_CANONICAL_V1_0 = (1 << 5), |
129 | | /** Save in W3C canonical format v1.1 (with comments) */ |
130 | | XML_LINT_CANONICAL_V1_1 = (1 << 6), |
131 | | /** Save exclusive canonical format (with comments) */ |
132 | | XML_LINT_CANONICAL_EXE = (1 << 7), |
133 | | /** Do a posteriori validation, i.e after parsing */ |
134 | | XML_LINT_POST_VALIDATION = (1 << 8), |
135 | | /** Ad-hoc test for valid insertions */ |
136 | | XML_LINT_VALID_INSERTIONS = (1 << 9), |
137 | | /** Use the HTML parser */ |
138 | | XML_LINT_HTML_ENABLED = (1 << 10), |
139 | | /** Force to use the XML serializer when using XML_LINT_HTML_ENABLED */ |
140 | | XML_LINT_XML_OUT = (1 << 11), |
141 | | /** Use the push mode of the parser */ |
142 | | XML_LINT_PUSH_ENABLED = (1 << 12), |
143 | | /** Parse from memory */ |
144 | | XML_LINT_MEMORY = (1 << 13), |
145 | | /** Do XInclude processing */ |
146 | | XML_LINT_XINCLUDE = (1 << 14), |
147 | | /** Be quiet when succeeded */ |
148 | | XML_LINT_QUIET = (1 << 15), |
149 | | /** Print some timings */ |
150 | | XML_LINT_TIMINGS = (1 << 16), |
151 | | /** Generate a small doc on the fly */ |
152 | | XML_LINT_GENERATE = (1 << 17), |
153 | | /** Remove the DOCTYPE of the input docs */ |
154 | | XML_LINT_DROP_DTD = (1 << 18), |
155 | | /** Use the streaming interface to process very large files */ |
156 | | XML_LINT_USE_STREAMING = (1 << 19), |
157 | | /** Create a reader and walk though the resulting doc */ |
158 | | XML_LINT_USE_WALKER = (1 << 20), |
159 | | /** use SGML catalogs from $SGML_CATALOG_FILES */ |
160 | | XML_LINT_USE_CATALOGS = (1 << 21), |
161 | | /** Deactivate all catalogs */ |
162 | | XML_LINT_USE_NO_CATALOGS = (1 << 22), |
163 | | /** Print trace of all external entities loaded */ |
164 | | XML_LINT_USE_LOAD_TRACE = (1 << 23), |
165 | | /** Return application failure if document has any namespace errors */ |
166 | | XML_LINT_STRICT_NAMESPACE = (1 << 24) |
167 | | |
168 | | |
169 | | } xmllintAppOptions; |
170 | | |
171 | | typedef struct { |
172 | | FILE *errStream; |
173 | | xmlParserCtxtPtr ctxt; |
174 | | xmlResourceLoader defaultResourceLoader; |
175 | | |
176 | | int version; |
177 | | int maxmem; |
178 | | int callbacks; |
179 | | int noout; |
180 | | #ifdef LIBXML_OUTPUT_ENABLED |
181 | | const char *output; |
182 | | const char *encoding; |
183 | | const char *indentString; |
184 | | int format; |
185 | | #endif /* LIBXML_OUTPUT_ENABLED */ |
186 | | #ifdef LIBXML_VALID_ENABLED |
187 | | const char *dtdvalid; |
188 | | const char *dtdvalidfpi; |
189 | | #endif |
190 | | #ifdef LIBXML_RELAXNG_ENABLED |
191 | | const char *relaxng; |
192 | | xmlRelaxNGPtr relaxngschemas; |
193 | | #endif |
194 | | #ifdef LIBXML_SCHEMAS_ENABLED |
195 | | const char *schema; |
196 | | xmlSchemaPtr wxschemas; |
197 | | #endif |
198 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
199 | | const char *schematron; |
200 | | xmlSchematronPtr wxschematron; |
201 | | #endif |
202 | | int repeat; |
203 | | #ifdef LIBXML_HTML_ENABLED |
204 | | int htmlOptions; |
205 | | #endif |
206 | | #if HAVE_DECL_MMAP |
207 | | char *memoryData; |
208 | | size_t memorySize; |
209 | | #endif |
210 | | xmllintReturnCode progresult; |
211 | | #ifdef LIBXML_READER_ENABLED |
212 | | #ifdef LIBXML_PATTERN_ENABLED |
213 | | const char *pattern; |
214 | | xmlPatternPtr patternc; |
215 | | xmlStreamCtxtPtr patstream; |
216 | | #endif |
217 | | #endif /* LIBXML_READER_ENABLED */ |
218 | | #ifdef LIBXML_XPATH_ENABLED |
219 | | const char *xpathquery; |
220 | | #endif |
221 | | int parseOptions; |
222 | | unsigned appOptions; |
223 | | unsigned maxAmpl; |
224 | | |
225 | | xmlChar *paths[MAX_PATHS + 1]; |
226 | | int nbpaths; |
227 | | |
228 | | xmlTime begin; |
229 | | xmlTime end; |
230 | | } xmllintState; |
231 | | |
232 | | static int xmllintMaxmem; |
233 | | static int xmllintMaxmemReached; |
234 | | static int xmllintOom; |
235 | | |
236 | | /************************************************************************ |
237 | | * * |
238 | | * Entity loading control and customization. * |
239 | | * * |
240 | | ************************************************************************/ |
241 | | |
242 | | static void |
243 | 0 | parsePath(xmllintState *lint, const xmlChar *path) { |
244 | 0 | const xmlChar *cur; |
245 | |
|
246 | 0 | if (path == NULL) |
247 | 0 | return; |
248 | 0 | while (*path != 0) { |
249 | 0 | if (lint->nbpaths >= MAX_PATHS) { |
250 | 0 | fprintf(lint->errStream, "MAX_PATHS reached: too many paths\n"); |
251 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
252 | 0 | return; |
253 | 0 | } |
254 | 0 | cur = path; |
255 | 0 | while ((*cur == ' ') || (*cur == PATH_SEPARATOR)) |
256 | 0 | cur++; |
257 | 0 | path = cur; |
258 | 0 | while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR)) |
259 | 0 | cur++; |
260 | 0 | if (cur != path) { |
261 | 0 | lint->paths[lint->nbpaths] = xmlStrndup(path, cur - path); |
262 | 0 | if (lint->paths[lint->nbpaths] != NULL) |
263 | 0 | lint->nbpaths++; |
264 | 0 | path = cur; |
265 | 0 | } |
266 | 0 | } |
267 | 0 | } |
268 | | |
269 | | static xmlParserErrors |
270 | | xmllintResourceLoader(void *ctxt, const char *URL, |
271 | | const char *ID, xmlResourceType type, |
272 | 7.46k | xmlParserInputFlags flags, xmlParserInputPtr *out) { |
273 | 7.46k | xmllintState *lint = ctxt; |
274 | 7.46k | xmlParserErrors code; |
275 | 7.46k | int i; |
276 | 7.46k | const char *lastsegment = URL; |
277 | 7.46k | const char *iter = URL; |
278 | | |
279 | 7.46k | if ((lint->nbpaths > 0) && (iter != NULL)) { |
280 | 0 | while (*iter != 0) { |
281 | 0 | if (*iter == '/') |
282 | 0 | lastsegment = iter + 1; |
283 | 0 | iter++; |
284 | 0 | } |
285 | 0 | } |
286 | | |
287 | 7.46k | if (lint->defaultResourceLoader != NULL) |
288 | 7.46k | code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out); |
289 | 0 | else |
290 | 0 | code = xmlNewInputFromUrl(URL, flags, out); |
291 | 7.46k | if (code != XML_IO_ENOENT) { |
292 | 7.46k | if ((lint->appOptions & XML_LINT_USE_LOAD_TRACE) && (code == XML_ERR_OK)) { |
293 | 0 | fprintf(lint->errStream, "Loaded URL=\"%s\" ID=\"%s\"\n", |
294 | 0 | URL, ID ? ID : "(null)"); |
295 | 0 | } |
296 | 7.46k | return(code); |
297 | 7.46k | } |
298 | | |
299 | 0 | for (i = 0; i < lint->nbpaths; i++) { |
300 | 0 | xmlChar *newURL; |
301 | |
|
302 | 0 | newURL = xmlStrdup((const xmlChar *) lint->paths[i]); |
303 | 0 | newURL = xmlStrcat(newURL, (const xmlChar *) "/"); |
304 | 0 | newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment); |
305 | 0 | if (newURL != NULL) { |
306 | 0 | if (lint->defaultResourceLoader != NULL) |
307 | 0 | code = lint->defaultResourceLoader(NULL, (const char *) newURL, |
308 | 0 | ID, type, flags, out); |
309 | 0 | else |
310 | 0 | code = xmlNewInputFromUrl((const char *) newURL, flags, out); |
311 | 0 | if (code != XML_IO_ENOENT) { |
312 | 0 | if ((lint->appOptions & XML_LINT_USE_LOAD_TRACE) && (code == XML_ERR_OK)) { |
313 | 0 | fprintf(lint->errStream, "Loaded URL=\"%s\" ID=\"%s\"\n", |
314 | 0 | newURL, ID ? ID : "(null)"); |
315 | 0 | } |
316 | 0 | xmlFree(newURL); |
317 | 0 | return(code); |
318 | 0 | } |
319 | 0 | xmlFree(newURL); |
320 | 0 | } |
321 | 0 | } |
322 | | |
323 | 0 | return(XML_IO_ENOENT); |
324 | 0 | } |
325 | | |
326 | | /************************************************************************ |
327 | | * * |
328 | | * Core parsing functions * |
329 | | * * |
330 | | ************************************************************************/ |
331 | | |
332 | | static xmlDocPtr |
333 | 6.16k | parseXml(xmllintState *lint, const char *filename) { |
334 | 6.16k | xmlParserCtxtPtr ctxt = lint->ctxt; |
335 | 6.16k | xmlDocPtr doc; |
336 | | |
337 | 6.16k | #ifdef LIBXML_PUSH_ENABLED |
338 | 6.16k | if (lint->appOptions & XML_LINT_PUSH_ENABLED) { |
339 | 0 | FILE *f; |
340 | 0 | int res; |
341 | 0 | char chars[4096]; |
342 | |
|
343 | 0 | if ((filename[0] == '-') && (filename[1] == 0)) { |
344 | 0 | f = stdin; |
345 | 0 | } else { |
346 | 0 | f = fopen(filename, "rb"); |
347 | 0 | if (f == NULL) { |
348 | 0 | fprintf(lint->errStream, "Can't open %s\n", filename); |
349 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
350 | 0 | return(NULL); |
351 | 0 | } |
352 | 0 | } |
353 | | |
354 | 0 | while ((res = fread(chars, 1, 4096, f)) > 0) { |
355 | 0 | xmlParseChunk(ctxt, chars, res, 0); |
356 | 0 | } |
357 | 0 | xmlParseChunk(ctxt, chars, 0, 1); |
358 | 0 | doc = xmlCtxtGetDocument(ctxt); |
359 | |
|
360 | 0 | if (f != stdin) |
361 | 0 | fclose(f); |
362 | |
|
363 | 0 | return(doc); |
364 | 0 | } |
365 | 6.16k | #endif /* LIBXML_PUSH_ENABLED */ |
366 | | |
367 | 6.16k | #if HAVE_DECL_MMAP |
368 | 6.16k | if (lint->appOptions & XML_LINT_MEMORY) { |
369 | 0 | xmlParserInputPtr input; |
370 | |
|
371 | 0 | input = xmlNewInputFromMemory(filename, |
372 | 0 | lint->memoryData, lint->memorySize, |
373 | 0 | XML_INPUT_BUF_STATIC); |
374 | 0 | if (input == NULL) { |
375 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
376 | 0 | return(NULL); |
377 | 0 | } |
378 | 0 | doc = xmlCtxtParseDocument(ctxt, input); |
379 | 0 | return(doc); |
380 | 0 | } |
381 | 6.16k | #endif |
382 | | |
383 | 6.16k | if (strcmp(filename, "-") == 0) |
384 | 0 | doc = xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, |
385 | 0 | lint->parseOptions | XML_PARSE_UNZIP); |
386 | 6.16k | else |
387 | 6.16k | doc = xmlCtxtReadFile(ctxt, filename, NULL, |
388 | 6.16k | lint->parseOptions | XML_PARSE_UNZIP); |
389 | | |
390 | 6.16k | return(doc); |
391 | 6.16k | } |
392 | | |
393 | | #ifdef LIBXML_HTML_ENABLED |
394 | | static xmlDocPtr |
395 | 1.30k | parseHtml(xmllintState *lint, const char *filename) { |
396 | 1.30k | xmlParserCtxtPtr ctxt = lint->ctxt; |
397 | 1.30k | xmlDocPtr doc; |
398 | | |
399 | 1.30k | #ifdef LIBXML_PUSH_ENABLED |
400 | 1.30k | if (lint->appOptions & XML_LINT_PUSH_ENABLED) { |
401 | 0 | FILE *f; |
402 | 0 | int res; |
403 | 0 | char chars[4096]; |
404 | |
|
405 | 0 | if ((filename[0] == '-') && (filename[1] == 0)) { |
406 | 0 | f = stdin; |
407 | 0 | } else { |
408 | 0 | f = fopen(filename, "rb"); |
409 | 0 | if (f == NULL) { |
410 | 0 | fprintf(lint->errStream, "Can't open %s\n", filename); |
411 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
412 | 0 | return(NULL); |
413 | 0 | } |
414 | 0 | } |
415 | | |
416 | 0 | while ((res = fread(chars, 1, 4096, f)) > 0) { |
417 | 0 | htmlParseChunk(ctxt, chars, res, 0); |
418 | 0 | } |
419 | 0 | htmlParseChunk(ctxt, chars, 0, 1); |
420 | 0 | doc = xmlCtxtGetDocument(ctxt); |
421 | |
|
422 | 0 | if (f != stdin) |
423 | 0 | fclose(f); |
424 | |
|
425 | 0 | return(doc); |
426 | 0 | } |
427 | 1.30k | #endif /* LIBXML_PUSH_ENABLED */ |
428 | | |
429 | 1.30k | #if HAVE_DECL_MMAP |
430 | 1.30k | if (lint->appOptions & XML_LINT_MEMORY) { |
431 | 0 | xmlParserInputPtr input; |
432 | |
|
433 | 0 | input = xmlNewInputFromMemory(filename, |
434 | 0 | lint->memoryData, lint->memorySize, |
435 | 0 | XML_INPUT_BUF_STATIC); |
436 | 0 | if (input == NULL) { |
437 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
438 | 0 | return(NULL); |
439 | 0 | } |
440 | 0 | doc = htmlCtxtParseDocument(ctxt, input); |
441 | 0 | return(doc); |
442 | 0 | } |
443 | 1.30k | #endif |
444 | | |
445 | 1.30k | if (strcmp(filename, "-") == 0) |
446 | 0 | doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, |
447 | 0 | lint->htmlOptions); |
448 | 1.30k | else |
449 | 1.30k | doc = htmlCtxtReadFile(ctxt, filename, NULL, lint->htmlOptions); |
450 | | |
451 | 1.30k | return(doc); |
452 | 1.30k | } |
453 | | #endif /* LIBXML_HTML_ENABLED */ |
454 | | |
455 | | /************************************************************************ |
456 | | * * |
457 | | * Memory allocation consumption debugging * |
458 | | * * |
459 | | ************************************************************************/ |
460 | | |
461 | | #define XMLLINT_ABORT_ON_FAILURE 0 |
462 | | |
463 | | static void |
464 | 390 | myFreeFunc(void *mem) { |
465 | 390 | xmlMemFree(mem); |
466 | 390 | } |
467 | | |
468 | | static void * |
469 | 430 | myMallocFunc(size_t size) { |
470 | 430 | void *ret; |
471 | | |
472 | 430 | if (xmlMemUsed() + size > (size_t) xmllintMaxmem) { |
473 | | #if XMLLINT_ABORT_ON_FAILURE |
474 | | abort(); |
475 | | #endif |
476 | 430 | xmllintMaxmemReached = 1; |
477 | 430 | xmllintOom = 1; |
478 | 430 | return(NULL); |
479 | 430 | } |
480 | | |
481 | 0 | ret = xmlMemMalloc(size); |
482 | 0 | if (ret == NULL) |
483 | 0 | xmllintOom = 1; |
484 | |
|
485 | 0 | return(ret); |
486 | 430 | } |
487 | | |
488 | | static void * |
489 | 0 | myReallocFunc(void *mem, size_t size) { |
490 | 0 | void *ret; |
491 | 0 | size_t oldsize = xmlMemSize(mem); |
492 | |
|
493 | 0 | if (xmlMemUsed() + size - oldsize > (size_t) xmllintMaxmem) { |
494 | | #if XMLLINT_ABORT_ON_FAILURE |
495 | | abort(); |
496 | | #endif |
497 | 0 | xmllintMaxmemReached = 1; |
498 | 0 | xmllintOom = 1; |
499 | 0 | return(NULL); |
500 | 0 | } |
501 | | |
502 | 0 | ret = xmlMemRealloc(mem, size); |
503 | 0 | if (ret == NULL) |
504 | 0 | xmllintOom = 1; |
505 | |
|
506 | 0 | return(ret); |
507 | 0 | } |
508 | | |
509 | | static char * |
510 | 7.53k | myStrdupFunc(const char *str) { |
511 | 7.53k | size_t size; |
512 | 7.53k | char *ret; |
513 | | |
514 | 7.53k | if (str == NULL) |
515 | 0 | return(NULL); |
516 | | |
517 | 7.53k | size = strlen(str) + 1; |
518 | 7.53k | if (xmlMemUsed() + size > (size_t) xmllintMaxmem) { |
519 | | #if XMLLINT_ABORT_ON_FAILURE |
520 | | abort(); |
521 | | #endif |
522 | 7.53k | xmllintMaxmemReached = 1; |
523 | 7.53k | xmllintOom = 1; |
524 | 7.53k | return(NULL); |
525 | 7.53k | } |
526 | | |
527 | 0 | ret = xmlMemMalloc(size); |
528 | 0 | if (ret == NULL) { |
529 | 0 | xmllintOom = 1; |
530 | 0 | return(NULL); |
531 | 0 | } |
532 | | |
533 | 0 | memcpy(ret, str, size); |
534 | |
|
535 | 0 | return(ret); |
536 | 0 | } |
537 | | |
538 | | /************************************************************************ |
539 | | * * |
540 | | * Internal timing routines to remove the necessity to have * |
541 | | * unix-specific function calls. * |
542 | | * * |
543 | | ************************************************************************/ |
544 | | |
545 | | static void |
546 | 20.5k | getTime(xmlTime *time) { |
547 | | #ifdef _WIN32 |
548 | | struct __timeb64 timebuffer; |
549 | | |
550 | | _ftime64(&timebuffer); |
551 | | time->sec = timebuffer.time; |
552 | | time->usec = timebuffer.millitm * 1000; |
553 | | #else /* _WIN32 */ |
554 | 20.5k | struct timeval tv; |
555 | | |
556 | 20.5k | gettimeofday(&tv, NULL); |
557 | 20.5k | time->sec = tv.tv_sec; |
558 | 20.5k | time->usec = tv.tv_usec; |
559 | 20.5k | #endif /* _WIN32 */ |
560 | 20.5k | } |
561 | | |
562 | | /* |
563 | | * startTimer: call where you want to start timing |
564 | | */ |
565 | | static void |
566 | | startTimer(xmllintState *lint) |
567 | 10.9k | { |
568 | 10.9k | getTime(&lint->begin); |
569 | 10.9k | } |
570 | | |
571 | | /* |
572 | | * endTimer: call where you want to stop timing and to print out a |
573 | | * message about the timing performed; format is a printf |
574 | | * type argument |
575 | | */ |
576 | | static void LIBXML_ATTR_FORMAT(2,3) |
577 | | endTimer(xmllintState *lint, const char *fmt, ...) |
578 | 9.60k | { |
579 | 9.60k | xmlSeconds msec; |
580 | 9.60k | va_list ap; |
581 | | |
582 | 9.60k | getTime(&lint->end); |
583 | 9.60k | msec = lint->end.sec - lint->begin.sec; |
584 | 9.60k | msec *= 1000; |
585 | 9.60k | msec += (lint->end.usec - lint->begin.usec) / 1000; |
586 | | |
587 | 9.60k | va_start(ap, fmt); |
588 | 9.60k | vfprintf(lint->errStream, fmt, ap); |
589 | 9.60k | va_end(ap); |
590 | | |
591 | 9.60k | fprintf(lint->errStream, " took %ld ms\n", (long) msec); |
592 | 9.60k | } |
593 | | |
594 | | /************************************************************************ |
595 | | * * |
596 | | * SAX based tests * |
597 | | * * |
598 | | ************************************************************************/ |
599 | | |
600 | | /* |
601 | | * empty SAX block |
602 | | */ |
603 | | static const xmlSAXHandler emptySAXHandler = { |
604 | | NULL, /* internalSubset */ |
605 | | NULL, /* isStandalone */ |
606 | | NULL, /* hasInternalSubset */ |
607 | | NULL, /* hasExternalSubset */ |
608 | | NULL, /* resolveEntity */ |
609 | | NULL, /* getEntity */ |
610 | | NULL, /* entityDecl */ |
611 | | NULL, /* notationDecl */ |
612 | | NULL, /* attributeDecl */ |
613 | | NULL, /* elementDecl */ |
614 | | NULL, /* unparsedEntityDecl */ |
615 | | NULL, /* setDocumentLocator */ |
616 | | NULL, /* startDocument */ |
617 | | NULL, /* endDocument */ |
618 | | NULL, /* startElement */ |
619 | | NULL, /* endElement */ |
620 | | NULL, /* reference */ |
621 | | NULL, /* characters */ |
622 | | NULL, /* ignorableWhitespace */ |
623 | | NULL, /* processingInstruction */ |
624 | | NULL, /* comment */ |
625 | | NULL, /* xmlParserWarning */ |
626 | | NULL, /* xmlParserError */ |
627 | | NULL, /* xmlParserError */ |
628 | | NULL, /* getParameterEntity */ |
629 | | NULL, /* cdataBlock; */ |
630 | | NULL, /* externalSubset; */ |
631 | | XML_SAX2_MAGIC, |
632 | | NULL, |
633 | | NULL, /* startElementNs */ |
634 | | NULL, /* endElementNs */ |
635 | | NULL /* xmlStructuredErrorFunc */ |
636 | | }; |
637 | | |
638 | | static int |
639 | | isStandaloneDebug(void *ctx) |
640 | 0 | { |
641 | 0 | xmllintState *lint = ctx; |
642 | |
|
643 | 0 | lint->callbacks++; |
644 | 0 | if (lint->noout) |
645 | 0 | return(0); |
646 | 0 | fprintf(stdout, "SAX.isStandalone()\n"); |
647 | 0 | return(0); |
648 | 0 | } |
649 | | |
650 | | static int |
651 | | hasInternalSubsetDebug(void *ctx) |
652 | 0 | { |
653 | 0 | xmllintState *lint = ctx; |
654 | |
|
655 | 0 | lint->callbacks++; |
656 | 0 | if (lint->noout) |
657 | 0 | return(0); |
658 | 0 | fprintf(stdout, "SAX.hasInternalSubset()\n"); |
659 | 0 | return(0); |
660 | 0 | } |
661 | | |
662 | | static int |
663 | | hasExternalSubsetDebug(void *ctx) |
664 | 0 | { |
665 | 0 | xmllintState *lint = ctx; |
666 | |
|
667 | 0 | lint->callbacks++; |
668 | 0 | if (lint->noout) |
669 | 0 | return(0); |
670 | 0 | fprintf(stdout, "SAX.hasExternalSubset()\n"); |
671 | 0 | return(0); |
672 | 0 | } |
673 | | |
674 | | static void |
675 | | internalSubsetDebug(void *ctx, const xmlChar *name, |
676 | | const xmlChar *ExternalID, const xmlChar *SystemID) |
677 | 0 | { |
678 | 0 | xmllintState *lint = ctx; |
679 | |
|
680 | 0 | lint->callbacks++; |
681 | 0 | if (lint->noout) |
682 | 0 | return; |
683 | 0 | fprintf(stdout, "SAX.internalSubset(%s,", name); |
684 | 0 | if (ExternalID == NULL) |
685 | 0 | fprintf(stdout, " ,"); |
686 | 0 | else |
687 | 0 | fprintf(stdout, " %s,", ExternalID); |
688 | 0 | if (SystemID == NULL) |
689 | 0 | fprintf(stdout, " )\n"); |
690 | 0 | else |
691 | 0 | fprintf(stdout, " %s)\n", SystemID); |
692 | 0 | } |
693 | | |
694 | | static void |
695 | | externalSubsetDebug(void *ctx, const xmlChar *name, |
696 | | const xmlChar *ExternalID, const xmlChar *SystemID) |
697 | 0 | { |
698 | 0 | xmllintState *lint = ctx; |
699 | |
|
700 | 0 | lint->callbacks++; |
701 | 0 | if (lint->noout) |
702 | 0 | return; |
703 | 0 | fprintf(stdout, "SAX.externalSubset(%s,", name); |
704 | 0 | if (ExternalID == NULL) |
705 | 0 | fprintf(stdout, " ,"); |
706 | 0 | else |
707 | 0 | fprintf(stdout, " %s,", ExternalID); |
708 | 0 | if (SystemID == NULL) |
709 | 0 | fprintf(stdout, " )\n"); |
710 | 0 | else |
711 | 0 | fprintf(stdout, " %s)\n", SystemID); |
712 | 0 | } |
713 | | |
714 | | static xmlParserInputPtr |
715 | | resolveEntityDebug(void *ctx, const xmlChar *publicId, const xmlChar *systemId) |
716 | 0 | { |
717 | 0 | xmllintState *lint = ctx; |
718 | |
|
719 | 0 | lint->callbacks++; |
720 | 0 | if (lint->noout) |
721 | 0 | return(NULL); |
722 | | /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ |
723 | | |
724 | | |
725 | 0 | fprintf(stdout, "SAX.resolveEntity("); |
726 | 0 | if (publicId != NULL) |
727 | 0 | fprintf(stdout, "%s", (char *)publicId); |
728 | 0 | else |
729 | 0 | fprintf(stdout, " "); |
730 | 0 | if (systemId != NULL) |
731 | 0 | fprintf(stdout, ", %s)\n", (char *)systemId); |
732 | 0 | else |
733 | 0 | fprintf(stdout, ", )\n"); |
734 | 0 | return(NULL); |
735 | 0 | } |
736 | | |
737 | | static xmlEntityPtr |
738 | | getEntityDebug(void *ctx, const xmlChar *name) |
739 | 0 | { |
740 | 0 | xmllintState *lint = ctx; |
741 | |
|
742 | 0 | lint->callbacks++; |
743 | 0 | if (lint->noout) |
744 | 0 | return(NULL); |
745 | 0 | fprintf(stdout, "SAX.getEntity(%s)\n", name); |
746 | 0 | return(NULL); |
747 | 0 | } |
748 | | |
749 | | static xmlEntityPtr |
750 | | getParameterEntityDebug(void *ctx, const xmlChar *name) |
751 | 0 | { |
752 | 0 | xmllintState *lint = ctx; |
753 | |
|
754 | 0 | lint->callbacks++; |
755 | 0 | if (lint->noout) |
756 | 0 | return(NULL); |
757 | 0 | fprintf(stdout, "SAX.getParameterEntity(%s)\n", name); |
758 | 0 | return(NULL); |
759 | 0 | } |
760 | | |
761 | | static void |
762 | | entityDeclDebug(void *ctx, const xmlChar *name, int type, |
763 | | const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) |
764 | 0 | { |
765 | 0 | xmllintState *lint = ctx; |
766 | 0 | const xmlChar *nullstr = BAD_CAST "(null)"; |
767 | | |
768 | | /* not all libraries handle printing null pointers nicely */ |
769 | 0 | if (publicId == NULL) |
770 | 0 | publicId = nullstr; |
771 | 0 | if (systemId == NULL) |
772 | 0 | systemId = nullstr; |
773 | 0 | if (content == NULL) |
774 | 0 | content = (xmlChar *)nullstr; |
775 | 0 | lint->callbacks++; |
776 | 0 | if (lint->noout) |
777 | 0 | return; |
778 | 0 | fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n", |
779 | 0 | name, type, publicId, systemId, content); |
780 | 0 | } |
781 | | |
782 | | static void |
783 | | attributeDeclDebug(void *ctx, const xmlChar * elem, |
784 | | const xmlChar * name, int type, int def, |
785 | | const xmlChar * defaultValue, xmlEnumerationPtr tree) |
786 | 0 | { |
787 | 0 | xmllintState *lint = ctx; |
788 | |
|
789 | 0 | lint->callbacks++; |
790 | 0 | if (lint->noout) |
791 | 0 | return; |
792 | 0 | if (defaultValue == NULL) |
793 | 0 | fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n", |
794 | 0 | elem, name, type, def); |
795 | 0 | else |
796 | 0 | fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n", |
797 | 0 | elem, name, type, def, defaultValue); |
798 | 0 | xmlFreeEnumeration(tree); |
799 | 0 | } |
800 | | |
801 | | static void |
802 | | elementDeclDebug(void *ctx, const xmlChar *name, int type, |
803 | | xmlElementContentPtr content ATTRIBUTE_UNUSED) |
804 | 0 | { |
805 | 0 | xmllintState *lint = ctx; |
806 | |
|
807 | 0 | lint->callbacks++; |
808 | 0 | if (lint->noout) |
809 | 0 | return; |
810 | 0 | fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n", |
811 | 0 | name, type); |
812 | 0 | } |
813 | | |
814 | | static void |
815 | | notationDeclDebug(void *ctx, const xmlChar *name, |
816 | | const xmlChar *publicId, const xmlChar *systemId) |
817 | 0 | { |
818 | 0 | xmllintState *lint = ctx; |
819 | |
|
820 | 0 | lint->callbacks++; |
821 | 0 | if (lint->noout) |
822 | 0 | return; |
823 | 0 | fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n", |
824 | 0 | (char *) name, (char *) publicId, (char *) systemId); |
825 | 0 | } |
826 | | |
827 | | static void |
828 | | unparsedEntityDeclDebug(void *ctx, const xmlChar *name, |
829 | | const xmlChar *publicId, const xmlChar *systemId, |
830 | | const xmlChar *notationName) |
831 | 0 | { |
832 | 0 | xmllintState *lint = ctx; |
833 | 0 | const xmlChar *nullstr = BAD_CAST "(null)"; |
834 | |
|
835 | 0 | if (publicId == NULL) |
836 | 0 | publicId = nullstr; |
837 | 0 | if (systemId == NULL) |
838 | 0 | systemId = nullstr; |
839 | 0 | if (notationName == NULL) |
840 | 0 | notationName = nullstr; |
841 | 0 | lint->callbacks++; |
842 | 0 | if (lint->noout) |
843 | 0 | return; |
844 | 0 | fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n", |
845 | 0 | (char *) name, (char *) publicId, (char *) systemId, |
846 | 0 | (char *) notationName); |
847 | 0 | } |
848 | | |
849 | | static void |
850 | | setDocumentLocatorDebug(void *ctx, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) |
851 | 0 | { |
852 | 0 | xmllintState *lint = ctx; |
853 | |
|
854 | 0 | lint->callbacks++; |
855 | 0 | if (lint->noout) |
856 | 0 | return; |
857 | 0 | fprintf(stdout, "SAX.setDocumentLocator()\n"); |
858 | 0 | } |
859 | | |
860 | | static void |
861 | | startDocumentDebug(void *ctx) |
862 | 0 | { |
863 | 0 | xmllintState *lint = ctx; |
864 | |
|
865 | 0 | lint->callbacks++; |
866 | 0 | if (lint->noout) |
867 | 0 | return; |
868 | 0 | fprintf(stdout, "SAX.startDocument()\n"); |
869 | 0 | } |
870 | | |
871 | | static void |
872 | | endDocumentDebug(void *ctx) |
873 | 0 | { |
874 | 0 | xmllintState *lint = ctx; |
875 | |
|
876 | 0 | lint->callbacks++; |
877 | 0 | if (lint->noout) |
878 | 0 | return; |
879 | 0 | fprintf(stdout, "SAX.endDocument()\n"); |
880 | 0 | } |
881 | | |
882 | | static void |
883 | | startElementDebug(void *ctx, const xmlChar *name, const xmlChar **atts) |
884 | 0 | { |
885 | 0 | xmllintState *lint = ctx; |
886 | 0 | int i; |
887 | |
|
888 | 0 | lint->callbacks++; |
889 | 0 | if (lint->noout) |
890 | 0 | return; |
891 | 0 | fprintf(stdout, "SAX.startElement(%s", (char *) name); |
892 | 0 | if (atts != NULL) { |
893 | 0 | for (i = 0;(atts[i] != NULL);i++) { |
894 | 0 | fprintf(stdout, ", %s='", atts[i++]); |
895 | 0 | if (atts[i] != NULL) |
896 | 0 | fprintf(stdout, "%s'", atts[i]); |
897 | 0 | } |
898 | 0 | } |
899 | 0 | fprintf(stdout, ")\n"); |
900 | 0 | } |
901 | | |
902 | | static void |
903 | | endElementDebug(void *ctx, const xmlChar *name) |
904 | 0 | { |
905 | 0 | xmllintState *lint = ctx; |
906 | |
|
907 | 0 | lint->callbacks++; |
908 | 0 | if (lint->noout) |
909 | 0 | return; |
910 | 0 | fprintf(stdout, "SAX.endElement(%s)\n", (char *) name); |
911 | 0 | } |
912 | | |
913 | | static void |
914 | | charactersDebug(void *ctx, const xmlChar *ch, int len) |
915 | 0 | { |
916 | 0 | xmllintState *lint = ctx; |
917 | 0 | char out[40]; |
918 | 0 | int i; |
919 | |
|
920 | 0 | lint->callbacks++; |
921 | 0 | if (lint->noout) |
922 | 0 | return; |
923 | 0 | for (i = 0;(i<len) && (i < 30);i++) |
924 | 0 | out[i] = (char) ch[i]; |
925 | 0 | out[i] = 0; |
926 | |
|
927 | 0 | fprintf(stdout, "SAX.characters(%s, %d)\n", out, len); |
928 | 0 | } |
929 | | |
930 | | static void |
931 | | referenceDebug(void *ctx, const xmlChar *name) |
932 | 0 | { |
933 | 0 | xmllintState *lint = ctx; |
934 | |
|
935 | 0 | lint->callbacks++; |
936 | 0 | if (lint->noout) |
937 | 0 | return; |
938 | 0 | fprintf(stdout, "SAX.reference(%s)\n", name); |
939 | 0 | } |
940 | | |
941 | | static void |
942 | | ignorableWhitespaceDebug(void *ctx, const xmlChar *ch, int len) |
943 | 0 | { |
944 | 0 | xmllintState *lint = ctx; |
945 | 0 | char out[40]; |
946 | 0 | int i; |
947 | |
|
948 | 0 | lint->callbacks++; |
949 | 0 | if (lint->noout) |
950 | 0 | return; |
951 | 0 | for (i = 0;(i<len) && (i < 30);i++) |
952 | 0 | out[i] = ch[i]; |
953 | 0 | out[i] = 0; |
954 | 0 | fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len); |
955 | 0 | } |
956 | | |
957 | | static void |
958 | | processingInstructionDebug(void *ctx, const xmlChar *target, |
959 | | const xmlChar *data) |
960 | 0 | { |
961 | 0 | xmllintState *lint = ctx; |
962 | |
|
963 | 0 | lint->callbacks++; |
964 | 0 | if (lint->noout) |
965 | 0 | return; |
966 | 0 | if (data != NULL) |
967 | 0 | fprintf(stdout, "SAX.processingInstruction(%s, %s)\n", |
968 | 0 | (char *) target, (char *) data); |
969 | 0 | else |
970 | 0 | fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n", |
971 | 0 | (char *) target); |
972 | 0 | } |
973 | | |
974 | | static void |
975 | | cdataBlockDebug(void *ctx, const xmlChar *value, int len) |
976 | 0 | { |
977 | 0 | xmllintState *lint = ctx; |
978 | |
|
979 | 0 | lint->callbacks++; |
980 | 0 | if (lint->noout) |
981 | 0 | return; |
982 | 0 | fprintf(stdout, "SAX.pcdata(%.20s, %d)\n", |
983 | 0 | (char *) value, len); |
984 | 0 | } |
985 | | |
986 | | static void |
987 | | commentDebug(void *ctx, const xmlChar *value) |
988 | 0 | { |
989 | 0 | xmllintState *lint = ctx; |
990 | |
|
991 | 0 | lint->callbacks++; |
992 | 0 | if (lint->noout) |
993 | 0 | return; |
994 | 0 | fprintf(stdout, "SAX.comment(%s)\n", value); |
995 | 0 | } |
996 | | |
997 | | static void LIBXML_ATTR_FORMAT(2,3) |
998 | | warningDebug(void *ctx, const char *msg, ...) |
999 | 0 | { |
1000 | 0 | xmllintState *lint = ctx; |
1001 | 0 | va_list args; |
1002 | |
|
1003 | 0 | lint->callbacks++; |
1004 | 0 | if (lint->noout) |
1005 | 0 | return; |
1006 | 0 | va_start(args, msg); |
1007 | 0 | fprintf(stdout, "SAX.warning: "); |
1008 | 0 | vfprintf(stdout, msg, args); |
1009 | 0 | va_end(args); |
1010 | 0 | } |
1011 | | |
1012 | | static void LIBXML_ATTR_FORMAT(2,3) |
1013 | | errorDebug(void *ctx, const char *msg, ...) |
1014 | 65 | { |
1015 | 65 | xmllintState *lint = ctx; |
1016 | 65 | va_list args; |
1017 | | |
1018 | 65 | lint->callbacks++; |
1019 | 65 | if (lint->noout) |
1020 | 0 | return; |
1021 | 65 | va_start(args, msg); |
1022 | 65 | fprintf(stdout, "SAX.error: "); |
1023 | 65 | vfprintf(stdout, msg, args); |
1024 | 65 | va_end(args); |
1025 | 65 | } |
1026 | | |
1027 | | static void LIBXML_ATTR_FORMAT(2,3) |
1028 | | fatalErrorDebug(void *ctx, const char *msg, ...) |
1029 | 0 | { |
1030 | 0 | xmllintState *lint = ctx; |
1031 | 0 | va_list args; |
1032 | |
|
1033 | 0 | lint->callbacks++; |
1034 | 0 | if (lint->noout) |
1035 | 0 | return; |
1036 | 0 | va_start(args, msg); |
1037 | 0 | fprintf(stdout, "SAX.fatalError: "); |
1038 | 0 | vfprintf(stdout, msg, args); |
1039 | 0 | va_end(args); |
1040 | 0 | } |
1041 | | |
1042 | | #ifdef LIBXML_SAX1_ENABLED |
1043 | | static const xmlSAXHandler debugSAXHandler = { |
1044 | | internalSubsetDebug, |
1045 | | isStandaloneDebug, |
1046 | | hasInternalSubsetDebug, |
1047 | | hasExternalSubsetDebug, |
1048 | | resolveEntityDebug, |
1049 | | getEntityDebug, |
1050 | | entityDeclDebug, |
1051 | | notationDeclDebug, |
1052 | | attributeDeclDebug, |
1053 | | elementDeclDebug, |
1054 | | unparsedEntityDeclDebug, |
1055 | | setDocumentLocatorDebug, |
1056 | | startDocumentDebug, |
1057 | | endDocumentDebug, |
1058 | | startElementDebug, |
1059 | | endElementDebug, |
1060 | | referenceDebug, |
1061 | | charactersDebug, |
1062 | | ignorableWhitespaceDebug, |
1063 | | processingInstructionDebug, |
1064 | | commentDebug, |
1065 | | warningDebug, |
1066 | | errorDebug, |
1067 | | fatalErrorDebug, |
1068 | | getParameterEntityDebug, |
1069 | | cdataBlockDebug, |
1070 | | externalSubsetDebug, |
1071 | | 1, |
1072 | | NULL, |
1073 | | NULL, |
1074 | | NULL, |
1075 | | NULL |
1076 | | }; |
1077 | | #endif |
1078 | | |
1079 | | /* |
1080 | | * SAX2 specific callbacks |
1081 | | */ |
1082 | | |
1083 | | static void |
1084 | | startElementNsDebug(void *ctx, |
1085 | | const xmlChar *localname, |
1086 | | const xmlChar *prefix, |
1087 | | const xmlChar *URI, |
1088 | | int nb_namespaces, |
1089 | | const xmlChar **namespaces, |
1090 | | int nb_attributes, |
1091 | | int nb_defaulted, |
1092 | | const xmlChar **attributes) |
1093 | 0 | { |
1094 | 0 | xmllintState *lint = ctx; |
1095 | 0 | int i; |
1096 | |
|
1097 | 0 | lint->callbacks++; |
1098 | 0 | if (lint->noout) |
1099 | 0 | return; |
1100 | 0 | fprintf(stdout, "SAX.startElementNs(%s", (char *) localname); |
1101 | 0 | if (prefix == NULL) |
1102 | 0 | fprintf(stdout, ", NULL"); |
1103 | 0 | else |
1104 | 0 | fprintf(stdout, ", %s", (char *) prefix); |
1105 | 0 | if (URI == NULL) |
1106 | 0 | fprintf(stdout, ", NULL"); |
1107 | 0 | else |
1108 | 0 | fprintf(stdout, ", '%s'", (char *) URI); |
1109 | 0 | fprintf(stdout, ", %d", nb_namespaces); |
1110 | |
|
1111 | 0 | if (namespaces != NULL) { |
1112 | 0 | for (i = 0;i < nb_namespaces * 2;i++) { |
1113 | 0 | fprintf(stdout, ", xmlns"); |
1114 | 0 | if (namespaces[i] != NULL) |
1115 | 0 | fprintf(stdout, ":%s", namespaces[i]); |
1116 | 0 | i++; |
1117 | 0 | fprintf(stdout, "='%s'", namespaces[i]); |
1118 | 0 | } |
1119 | 0 | } |
1120 | 0 | fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted); |
1121 | 0 | if (attributes != NULL) { |
1122 | 0 | for (i = 0;i < nb_attributes * 5;i += 5) { |
1123 | 0 | if (attributes[i + 1] != NULL) |
1124 | 0 | fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]); |
1125 | 0 | else |
1126 | 0 | fprintf(stdout, ", %s='", attributes[i]); |
1127 | 0 | fprintf(stdout, "%.4s...', %d", attributes[i + 3], |
1128 | 0 | (int)(attributes[i + 4] - attributes[i + 3])); |
1129 | 0 | } |
1130 | 0 | } |
1131 | 0 | fprintf(stdout, ")\n"); |
1132 | 0 | } |
1133 | | |
1134 | | static void |
1135 | | endElementNsDebug(void *ctx, |
1136 | | const xmlChar *localname, |
1137 | | const xmlChar *prefix, |
1138 | | const xmlChar *URI) |
1139 | 0 | { |
1140 | 0 | xmllintState *lint = ctx; |
1141 | |
|
1142 | 0 | lint->callbacks++; |
1143 | 0 | if (lint->noout) |
1144 | 0 | return; |
1145 | 0 | fprintf(stdout, "SAX.endElementNs(%s", (char *) localname); |
1146 | 0 | if (prefix == NULL) |
1147 | 0 | fprintf(stdout, ", NULL"); |
1148 | 0 | else |
1149 | 0 | fprintf(stdout, ", %s", (char *) prefix); |
1150 | 0 | if (URI == NULL) |
1151 | 0 | fprintf(stdout, ", NULL)\n"); |
1152 | 0 | else |
1153 | 0 | fprintf(stdout, ", '%s')\n", (char *) URI); |
1154 | 0 | } |
1155 | | |
1156 | | static const xmlSAXHandler debugSAX2Handler = { |
1157 | | internalSubsetDebug, |
1158 | | isStandaloneDebug, |
1159 | | hasInternalSubsetDebug, |
1160 | | hasExternalSubsetDebug, |
1161 | | resolveEntityDebug, |
1162 | | getEntityDebug, |
1163 | | entityDeclDebug, |
1164 | | notationDeclDebug, |
1165 | | attributeDeclDebug, |
1166 | | elementDeclDebug, |
1167 | | unparsedEntityDeclDebug, |
1168 | | setDocumentLocatorDebug, |
1169 | | startDocumentDebug, |
1170 | | endDocumentDebug, |
1171 | | startElementDebug, /* for HTML */ |
1172 | | endElementDebug, |
1173 | | referenceDebug, |
1174 | | charactersDebug, |
1175 | | ignorableWhitespaceDebug, |
1176 | | processingInstructionDebug, |
1177 | | commentDebug, |
1178 | | warningDebug, |
1179 | | errorDebug, |
1180 | | fatalErrorDebug, |
1181 | | getParameterEntityDebug, |
1182 | | cdataBlockDebug, |
1183 | | externalSubsetDebug, |
1184 | | XML_SAX2_MAGIC, |
1185 | | NULL, |
1186 | | startElementNsDebug, |
1187 | | endElementNsDebug, |
1188 | | NULL |
1189 | | }; |
1190 | | |
1191 | | static void |
1192 | 670 | testSAX(xmllintState *lint, const char *filename) { |
1193 | 670 | lint->callbacks = 0; |
1194 | | |
1195 | 670 | #ifdef LIBXML_SCHEMAS_ENABLED |
1196 | 670 | if (lint->wxschemas != NULL) { |
1197 | 0 | int ret; |
1198 | 0 | xmlSchemaValidCtxtPtr vctxt; |
1199 | 0 | xmlParserInputBufferPtr buf; |
1200 | |
|
1201 | 0 | if (strcmp(filename, "-") == 0) |
1202 | 0 | buf = xmlParserInputBufferCreateFd(STDIN_FILENO, |
1203 | 0 | XML_CHAR_ENCODING_NONE); |
1204 | 0 | else |
1205 | 0 | buf = xmlParserInputBufferCreateFilename(filename, |
1206 | 0 | XML_CHAR_ENCODING_NONE); |
1207 | 0 | if (buf == NULL) |
1208 | 0 | return; |
1209 | | |
1210 | 0 | vctxt = xmlSchemaNewValidCtxt(lint->wxschemas); |
1211 | 0 | if (vctxt == NULL) { |
1212 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1213 | 0 | xmlFreeParserInputBuffer(buf); |
1214 | 0 | return; |
1215 | 0 | } |
1216 | 0 | xmlSchemaValidateSetFilename(vctxt, filename); |
1217 | |
|
1218 | 0 | ret = xmlSchemaValidateStream(vctxt, buf, 0, lint->ctxt->sax, lint); |
1219 | 0 | if (lint->repeat == 1) { |
1220 | 0 | if (ret == 0) { |
1221 | 0 | if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) { |
1222 | 0 | fprintf(lint->errStream, "%s validates\n", filename); |
1223 | 0 | } |
1224 | 0 | } else if (ret > 0) { |
1225 | 0 | fprintf(lint->errStream, "%s fails to validate\n", filename); |
1226 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
1227 | 0 | } else { |
1228 | 0 | fprintf(lint->errStream, "%s validation generated an internal error\n", |
1229 | 0 | filename); |
1230 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
1231 | 0 | } |
1232 | 0 | } |
1233 | 0 | xmlSchemaFreeValidCtxt(vctxt); |
1234 | 0 | } else |
1235 | 670 | #endif |
1236 | 670 | #ifdef LIBXML_HTML_ENABLED |
1237 | 670 | if (lint->appOptions & XML_LINT_HTML_ENABLED) { |
1238 | 0 | parseHtml(lint, filename); |
1239 | 0 | } else |
1240 | 670 | #endif |
1241 | 670 | { |
1242 | 670 | parseXml(lint, filename); |
1243 | 670 | } |
1244 | 670 | } |
1245 | | |
1246 | | /************************************************************************ |
1247 | | * * |
1248 | | * Stream Test processing * |
1249 | | * * |
1250 | | ************************************************************************/ |
1251 | | #ifdef LIBXML_READER_ENABLED |
1252 | 2.54k | static void processNode(xmllintState *lint, xmlTextReaderPtr reader) { |
1253 | 2.54k | const xmlChar *name, *value; |
1254 | 2.54k | int type, empty; |
1255 | | |
1256 | 2.54k | type = xmlTextReaderNodeType(reader); |
1257 | 2.54k | empty = xmlTextReaderIsEmptyElement(reader); |
1258 | | |
1259 | 2.54k | if (lint->appOptions & XML_LINT_DEBUG_ENABLED) { |
1260 | 1.72k | name = xmlTextReaderConstName(reader); |
1261 | 1.72k | if (name == NULL) |
1262 | 0 | name = BAD_CAST "--"; |
1263 | | |
1264 | 1.72k | value = xmlTextReaderConstValue(reader); |
1265 | | |
1266 | | |
1267 | 1.72k | printf("%d %d %s %d %d", |
1268 | 1.72k | xmlTextReaderDepth(reader), |
1269 | 1.72k | type, |
1270 | 1.72k | name, |
1271 | 1.72k | empty, |
1272 | 1.72k | xmlTextReaderHasValue(reader)); |
1273 | 1.72k | if (value == NULL) |
1274 | 1.15k | printf("\n"); |
1275 | 576 | else { |
1276 | 576 | printf(" %s\n", value); |
1277 | 576 | } |
1278 | 1.72k | } |
1279 | 2.54k | #ifdef LIBXML_PATTERN_ENABLED |
1280 | 2.54k | if (lint->patternc) { |
1281 | 1.27k | xmlChar *path = NULL; |
1282 | 1.27k | int match = -1; |
1283 | | |
1284 | 1.27k | if (type == XML_READER_TYPE_ELEMENT) { |
1285 | | /* do the check only on element start */ |
1286 | 425 | match = xmlPatternMatch(lint->patternc, |
1287 | 425 | xmlTextReaderCurrentNode(reader)); |
1288 | | |
1289 | 425 | if (match) { |
1290 | 113 | path = xmlGetNodePath(xmlTextReaderCurrentNode(reader)); |
1291 | 113 | printf("Node %s matches pattern %s\n", path, lint->pattern); |
1292 | 113 | } |
1293 | 425 | } |
1294 | 1.27k | if (lint->patstream != NULL) { |
1295 | 1.27k | int ret; |
1296 | | |
1297 | 1.27k | if (type == XML_READER_TYPE_ELEMENT) { |
1298 | 425 | ret = xmlStreamPush(lint->patstream, |
1299 | 425 | xmlTextReaderConstLocalName(reader), |
1300 | 425 | xmlTextReaderConstNamespaceUri(reader)); |
1301 | 425 | if (ret < 0) { |
1302 | 0 | fprintf(lint->errStream, "xmlStreamPush() failure\n"); |
1303 | 0 | xmlFreeStreamCtxt(lint->patstream); |
1304 | 0 | lint->patstream = NULL; |
1305 | 425 | } else if (ret != match) { |
1306 | 19 | if (path == NULL) { |
1307 | 10 | path = xmlGetNodePath( |
1308 | 10 | xmlTextReaderCurrentNode(reader)); |
1309 | 10 | } |
1310 | 19 | fprintf(lint->errStream, |
1311 | 19 | "xmlPatternMatch and xmlStreamPush disagree\n"); |
1312 | 19 | if (path != NULL) |
1313 | 19 | fprintf(lint->errStream, " pattern %s node %s\n", |
1314 | 19 | lint->pattern, path); |
1315 | 0 | else |
1316 | 0 | fprintf(lint->errStream, " pattern %s node %s\n", |
1317 | 0 | lint->pattern, xmlTextReaderConstName(reader)); |
1318 | 19 | } |
1319 | | |
1320 | 425 | } |
1321 | 1.27k | if ((type == XML_READER_TYPE_END_ELEMENT) || |
1322 | 1.27k | ((type == XML_READER_TYPE_ELEMENT) && (empty))) { |
1323 | 425 | ret = xmlStreamPop(lint->patstream); |
1324 | 425 | if (ret < 0) { |
1325 | 0 | fprintf(lint->errStream, "xmlStreamPop() failure\n"); |
1326 | 0 | xmlFreeStreamCtxt(lint->patstream); |
1327 | 0 | lint->patstream = NULL; |
1328 | 0 | } |
1329 | 425 | } |
1330 | 1.27k | } |
1331 | 1.27k | if (path != NULL) |
1332 | 123 | xmlFree(path); |
1333 | 1.27k | } |
1334 | 2.54k | #endif |
1335 | 2.54k | } |
1336 | | |
1337 | 3.07k | static void streamFile(xmllintState *lint, const char *filename) { |
1338 | 3.07k | xmlParserInputBufferPtr input = NULL; |
1339 | 3.07k | FILE *errStream = lint->errStream; |
1340 | 3.07k | xmlTextReaderPtr reader; |
1341 | 3.07k | int ret; |
1342 | | |
1343 | 3.07k | #if HAVE_DECL_MMAP |
1344 | 3.07k | if (lint->appOptions & XML_LINT_MEMORY) { |
1345 | 0 | reader = xmlReaderForMemory(lint->memoryData, lint->memorySize, |
1346 | 0 | filename, NULL, lint->parseOptions); |
1347 | 0 | if (reader == NULL) { |
1348 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1349 | 0 | return; |
1350 | 0 | } |
1351 | 0 | } else |
1352 | 3.07k | #endif |
1353 | 3.07k | { |
1354 | 3.07k | xmlResetLastError(); |
1355 | | |
1356 | 3.07k | if (strcmp(filename, "-") == 0) { |
1357 | 0 | reader = xmlReaderForFd(STDIN_FILENO, "-", NULL, |
1358 | 0 | lint->parseOptions | XML_PARSE_UNZIP); |
1359 | 0 | } |
1360 | 3.07k | else { |
1361 | 3.07k | reader = xmlReaderForFile(filename, NULL, |
1362 | 3.07k | lint->parseOptions | XML_PARSE_UNZIP); |
1363 | 3.07k | } |
1364 | 3.07k | if (reader == NULL) { |
1365 | 3.07k | const xmlError *error = xmlGetLastError(); |
1366 | | |
1367 | 3.07k | if ((error != NULL) && (error->code == XML_ERR_NO_MEMORY)) { |
1368 | 92 | lint->progresult = XMLLINT_ERR_MEM; |
1369 | 2.98k | } else { |
1370 | 2.98k | fprintf(errStream, "Unable to open %s\n", filename); |
1371 | 2.98k | lint->progresult = XMLLINT_ERR_RDFILE; |
1372 | 2.98k | } |
1373 | 3.07k | return; |
1374 | 3.07k | } |
1375 | 3.07k | } |
1376 | | |
1377 | 0 | #ifdef LIBXML_PATTERN_ENABLED |
1378 | 0 | if (lint->patternc != NULL) { |
1379 | 0 | lint->patstream = xmlPatternGetStreamCtxt(lint->patternc); |
1380 | 0 | if (lint->patstream != NULL) { |
1381 | 0 | ret = xmlStreamPush(lint->patstream, NULL, NULL); |
1382 | 0 | if (ret < 0) { |
1383 | 0 | fprintf(errStream, "xmlStreamPush() failure\n"); |
1384 | 0 | xmlFreeStreamCtxt(lint->patstream); |
1385 | 0 | lint->patstream = NULL; |
1386 | 0 | } |
1387 | 0 | } |
1388 | 0 | } |
1389 | 0 | #endif |
1390 | | |
1391 | |
|
1392 | 0 | xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, lint); |
1393 | 0 | if (lint->maxAmpl > 0) |
1394 | 0 | xmlTextReaderSetMaxAmplification(reader, lint->maxAmpl); |
1395 | |
|
1396 | 0 | #ifdef LIBXML_RELAXNG_ENABLED |
1397 | 0 | if (lint->relaxng != NULL) { |
1398 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1399 | 0 | startTimer(lint); |
1400 | 0 | } |
1401 | 0 | ret = xmlTextReaderRelaxNGValidate(reader, lint->relaxng); |
1402 | 0 | if (ret < 0) { |
1403 | 0 | fprintf(errStream, "Relax-NG schema %s failed to compile\n", |
1404 | 0 | lint->relaxng); |
1405 | 0 | lint->progresult = XMLLINT_ERR_SCHEMACOMP; |
1406 | 0 | lint->relaxng = NULL; |
1407 | 0 | } |
1408 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1409 | 0 | endTimer(lint, "Compiling the schemas"); |
1410 | 0 | } |
1411 | 0 | } |
1412 | 0 | #endif |
1413 | 0 | #ifdef LIBXML_SCHEMAS_ENABLED |
1414 | 0 | if (lint->schema != NULL) { |
1415 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1416 | 0 | startTimer(lint); |
1417 | 0 | } |
1418 | 0 | ret = xmlTextReaderSchemaValidate(reader, lint->schema); |
1419 | 0 | if (ret < 0) { |
1420 | 0 | fprintf(errStream, "XSD schema %s failed to compile\n", |
1421 | 0 | lint->schema); |
1422 | 0 | lint->progresult = XMLLINT_ERR_SCHEMACOMP; |
1423 | 0 | lint->schema = NULL; |
1424 | 0 | } |
1425 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1426 | 0 | endTimer(lint, "Compiling the schemas"); |
1427 | 0 | } |
1428 | 0 | } |
1429 | 0 | #endif |
1430 | | |
1431 | | /* |
1432 | | * Process all nodes in sequence |
1433 | | */ |
1434 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1435 | 0 | startTimer(lint); |
1436 | 0 | } |
1437 | 0 | ret = xmlTextReaderRead(reader); |
1438 | 0 | while (ret == 1) { |
1439 | 0 | if ((lint->appOptions & XML_LINT_DEBUG_ENABLED) |
1440 | 0 | #ifdef LIBXML_PATTERN_ENABLED |
1441 | 0 | || (lint->patternc) |
1442 | 0 | #endif |
1443 | 0 | ) |
1444 | 0 | processNode(lint, reader); |
1445 | 0 | ret = xmlTextReaderRead(reader); |
1446 | 0 | } |
1447 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1448 | 0 | #ifdef LIBXML_RELAXNG_ENABLED |
1449 | 0 | if (lint->relaxng != NULL) |
1450 | 0 | endTimer(lint, "Parsing and validating"); |
1451 | 0 | else |
1452 | 0 | #endif |
1453 | 0 | #ifdef LIBXML_VALID_ENABLED |
1454 | 0 | if (lint->parseOptions & XML_PARSE_DTDVALID) |
1455 | 0 | endTimer(lint, "Parsing and validating"); |
1456 | 0 | else |
1457 | 0 | #endif |
1458 | 0 | endTimer(lint, "Parsing"); |
1459 | 0 | } |
1460 | |
|
1461 | 0 | #ifdef LIBXML_VALID_ENABLED |
1462 | 0 | if (lint->parseOptions & XML_PARSE_DTDVALID) { |
1463 | 0 | if (xmlTextReaderIsValid(reader) != 1) { |
1464 | 0 | fprintf(errStream, |
1465 | 0 | "Document %s does not validate\n", filename); |
1466 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
1467 | 0 | } |
1468 | 0 | } |
1469 | 0 | #endif /* LIBXML_VALID_ENABLED */ |
1470 | 0 | #if defined(LIBXML_RELAXNG_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) |
1471 | 0 | { |
1472 | 0 | int hasSchema = 0; |
1473 | |
|
1474 | 0 | #ifdef LIBXML_RELAXNG_ENABLED |
1475 | 0 | if (lint->relaxng != NULL) |
1476 | 0 | hasSchema = 1; |
1477 | 0 | #endif |
1478 | 0 | #ifdef LIBXML_SCHEMAS_ENABLED |
1479 | 0 | if (lint->schema != NULL) |
1480 | 0 | hasSchema = 1; |
1481 | 0 | #endif |
1482 | 0 | if (hasSchema) { |
1483 | 0 | if (xmlTextReaderIsValid(reader) != 1) { |
1484 | 0 | fprintf(errStream, "%s fails to validate\n", filename); |
1485 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
1486 | 0 | } else { |
1487 | 0 | if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) { |
1488 | 0 | fprintf(errStream, "%s validates\n", filename); |
1489 | 0 | } |
1490 | 0 | } |
1491 | 0 | } |
1492 | 0 | } |
1493 | 0 | #endif |
1494 | | /* |
1495 | | * Done, cleanup and status |
1496 | | */ |
1497 | 0 | xmlFreeTextReader(reader); |
1498 | 0 | xmlFreeParserInputBuffer(input); |
1499 | 0 | if (ret != 0) { |
1500 | 0 | fprintf(errStream, "%s : failed to parse\n", filename); |
1501 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
1502 | 0 | } |
1503 | 0 | #ifdef LIBXML_PATTERN_ENABLED |
1504 | 0 | if (lint->patstream != NULL) { |
1505 | 0 | xmlFreeStreamCtxt(lint->patstream); |
1506 | 0 | lint->patstream = NULL; |
1507 | 0 | } |
1508 | 0 | #endif |
1509 | 0 | } |
1510 | | |
1511 | 1.90k | static void walkDoc(xmllintState *lint, xmlDocPtr doc) { |
1512 | 1.90k | FILE *errStream = lint->errStream; |
1513 | 1.90k | xmlTextReaderPtr reader; |
1514 | 1.90k | int ret; |
1515 | | |
1516 | 1.90k | #ifdef LIBXML_PATTERN_ENABLED |
1517 | 1.90k | if (lint->pattern != NULL) { |
1518 | 684 | xmlNodePtr root; |
1519 | 684 | const xmlChar *namespaces[22]; |
1520 | 684 | int i; |
1521 | 684 | xmlNsPtr ns; |
1522 | | |
1523 | 684 | root = xmlDocGetRootElement(doc); |
1524 | 684 | if (root == NULL ) { |
1525 | 0 | fprintf(errStream, |
1526 | 0 | "Document does not have a root element"); |
1527 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
1528 | 0 | return; |
1529 | 0 | } |
1530 | 684 | for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) { |
1531 | 0 | namespaces[i++] = ns->href; |
1532 | 0 | namespaces[i++] = ns->prefix; |
1533 | 0 | } |
1534 | 684 | namespaces[i++] = NULL; |
1535 | 684 | namespaces[i] = NULL; |
1536 | | |
1537 | 684 | ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict, |
1538 | 684 | 0, &namespaces[0], &lint->patternc); |
1539 | 684 | if (lint->patternc == NULL) { |
1540 | 222 | if (ret < 0) { |
1541 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1542 | 222 | } else { |
1543 | 222 | fprintf(errStream, "Pattern %s failed to compile\n", |
1544 | 222 | lint->pattern); |
1545 | 222 | lint->progresult = XMLLINT_ERR_SCHEMAPAT; |
1546 | 222 | } |
1547 | 222 | goto error; |
1548 | 222 | } |
1549 | | |
1550 | 462 | lint->patstream = xmlPatternGetStreamCtxt(lint->patternc); |
1551 | 462 | if (lint->patstream == NULL) { |
1552 | 37 | lint->progresult = XMLLINT_ERR_MEM; |
1553 | 37 | goto error; |
1554 | 37 | } |
1555 | | |
1556 | 425 | ret = xmlStreamPush(lint->patstream, NULL, NULL); |
1557 | 425 | if (ret < 0) { |
1558 | 0 | fprintf(errStream, "xmlStreamPush() failure\n"); |
1559 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1560 | 0 | goto error; |
1561 | 0 | } |
1562 | 425 | } |
1563 | 1.64k | #endif /* LIBXML_PATTERN_ENABLED */ |
1564 | 1.64k | reader = xmlReaderWalker(doc); |
1565 | 1.64k | if (reader != NULL) { |
1566 | 1.64k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1567 | 866 | startTimer(lint); |
1568 | 866 | } |
1569 | 1.64k | ret = xmlTextReaderRead(reader); |
1570 | 6.58k | while (ret == 1) { |
1571 | 4.94k | if ((lint->appOptions & XML_LINT_DEBUG_ENABLED) |
1572 | 4.94k | #ifdef LIBXML_PATTERN_ENABLED |
1573 | 4.94k | || (lint->patternc) |
1574 | 4.94k | #endif |
1575 | 4.94k | ) |
1576 | 2.54k | processNode(lint, reader); |
1577 | 4.94k | ret = xmlTextReaderRead(reader); |
1578 | 4.94k | } |
1579 | 1.64k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1580 | 866 | endTimer(lint, "walking through the doc"); |
1581 | 866 | } |
1582 | 1.64k | xmlFreeTextReader(reader); |
1583 | 1.64k | if (ret != 0) { |
1584 | 0 | fprintf(errStream, "failed to walk through the doc\n"); |
1585 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
1586 | 0 | } |
1587 | 1.64k | } else { |
1588 | 0 | fprintf(errStream, "Failed to create a reader from the document\n"); |
1589 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
1590 | 0 | } |
1591 | | |
1592 | 1.64k | #ifdef LIBXML_PATTERN_ENABLED |
1593 | 1.90k | error: |
1594 | 1.90k | if (lint->patternc != NULL) { |
1595 | 462 | xmlFreePattern(lint->patternc); |
1596 | 462 | lint->patternc = NULL; |
1597 | 462 | } |
1598 | 1.90k | if (lint->patstream != NULL) { |
1599 | 425 | xmlFreeStreamCtxt(lint->patstream); |
1600 | 425 | lint->patstream = NULL; |
1601 | 425 | } |
1602 | 1.90k | #endif |
1603 | 1.90k | } |
1604 | | #endif /* LIBXML_READER_ENABLED */ |
1605 | | |
1606 | | #ifdef LIBXML_XPATH_ENABLED |
1607 | | /************************************************************************ |
1608 | | * * |
1609 | | * XPath Query * |
1610 | | * * |
1611 | | ************************************************************************/ |
1612 | | |
1613 | | static void |
1614 | 4.71k | doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) { |
1615 | 4.71k | switch(cur->type) { |
1616 | 3.02k | case XPATH_NODESET: { |
1617 | 3.02k | #ifdef LIBXML_OUTPUT_ENABLED |
1618 | 3.02k | xmlOutputBufferPtr buf; |
1619 | 3.02k | xmlNodePtr node; |
1620 | 3.02k | int i; |
1621 | | |
1622 | 3.02k | if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) { |
1623 | 2.17k | lint->progresult = XMLLINT_ERR_XPATH_EMPTY; |
1624 | 2.17k | if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) { |
1625 | 1.85k | fprintf(lint->errStream, "XPath set is empty\n"); |
1626 | 1.85k | } |
1627 | 2.17k | break; |
1628 | 2.17k | } |
1629 | 851 | buf = xmlOutputBufferCreateFile(stdout, NULL); |
1630 | 851 | if (buf == NULL) { |
1631 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1632 | 0 | return; |
1633 | 0 | } |
1634 | 2.71k | for (i = 0;i < cur->nodesetval->nodeNr;i++) { |
1635 | 1.86k | node = cur->nodesetval->nodeTab[i]; |
1636 | 1.86k | xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL); |
1637 | 1.86k | xmlOutputBufferWrite(buf, 1, "\n"); |
1638 | 1.86k | } |
1639 | 851 | xmlOutputBufferClose(buf); |
1640 | | #else |
1641 | | printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr); |
1642 | | #endif |
1643 | 851 | break; |
1644 | 851 | } |
1645 | 717 | case XPATH_BOOLEAN: |
1646 | 717 | if (cur->boolval) printf("true\n"); |
1647 | 456 | else printf("false\n"); |
1648 | 717 | break; |
1649 | 493 | case XPATH_NUMBER: |
1650 | 493 | switch (xmlXPathIsInf(cur->floatval)) { |
1651 | 28 | case 1: |
1652 | 28 | printf("Infinity\n"); |
1653 | 28 | break; |
1654 | 6 | case -1: |
1655 | 6 | printf("-Infinity\n"); |
1656 | 6 | break; |
1657 | 459 | default: |
1658 | 459 | if (xmlXPathIsNaN(cur->floatval)) { |
1659 | 313 | printf("NaN\n"); |
1660 | 313 | } else { |
1661 | 146 | printf("%0g\n", cur->floatval); |
1662 | 146 | } |
1663 | 493 | } |
1664 | 493 | break; |
1665 | 493 | case XPATH_STRING: |
1666 | 481 | printf("%s\n", (const char *) cur->stringval); |
1667 | 481 | break; |
1668 | 0 | case XPATH_UNDEFINED: |
1669 | 0 | fprintf(lint->errStream, "XPath Object is uninitialized\n"); |
1670 | 0 | lint->progresult = XMLLINT_ERR_XPATH; |
1671 | 0 | break; |
1672 | 0 | default: |
1673 | 0 | fprintf(lint->errStream, "XPath object of unexpected type\n"); |
1674 | 0 | lint->progresult = XMLLINT_ERR_XPATH; |
1675 | 0 | break; |
1676 | 4.71k | } |
1677 | 4.71k | } |
1678 | | |
1679 | | static void |
1680 | 8.36k | doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) { |
1681 | 8.36k | xmlXPathContextPtr ctxt = NULL; |
1682 | 8.36k | xmlXPathCompExprPtr comp = NULL; |
1683 | 8.36k | xmlXPathObjectPtr res = NULL; |
1684 | | |
1685 | 8.36k | ctxt = xmlXPathNewContext(doc); |
1686 | 8.36k | if (ctxt == NULL) { |
1687 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1688 | 0 | goto error; |
1689 | 0 | } |
1690 | | |
1691 | 8.36k | comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query); |
1692 | 8.36k | if (comp == NULL) { |
1693 | 2.01k | fprintf(lint->errStream, "XPath compilation failure\n"); |
1694 | 2.01k | lint->progresult = XMLLINT_ERR_XPATH; |
1695 | 2.01k | goto error; |
1696 | 2.01k | } |
1697 | | |
1698 | | #ifdef LIBXML_DEBUG_ENABLED |
1699 | | if (lint->appOptions & XML_LINT_DEBUG_ENABLED) { |
1700 | | xmlXPathDebugDumpCompExpr(stdout, comp, 0); |
1701 | | printf("\n"); |
1702 | | } |
1703 | | #endif |
1704 | | |
1705 | 6.34k | ctxt->node = (xmlNodePtr) doc; |
1706 | 6.34k | res = xmlXPathCompiledEval(comp, ctxt); |
1707 | 6.34k | if (res == NULL) { |
1708 | 1.63k | fprintf(lint->errStream, "XPath evaluation failure\n"); |
1709 | 1.63k | lint->progresult = XMLLINT_ERR_XPATH; |
1710 | 1.63k | goto error; |
1711 | 1.63k | } |
1712 | | |
1713 | 4.71k | doXPathDump(lint, res); |
1714 | | |
1715 | 8.36k | error: |
1716 | 8.36k | xmlXPathFreeObject(res); |
1717 | 8.36k | xmlXPathFreeCompExpr(comp); |
1718 | 8.36k | xmlXPathFreeContext(ctxt); |
1719 | 8.36k | } |
1720 | | #endif /* LIBXML_XPATH_ENABLED */ |
1721 | | |
1722 | | /************************************************************************ |
1723 | | * * |
1724 | | * Tree Test processing * |
1725 | | * * |
1726 | | ************************************************************************/ |
1727 | | |
1728 | | static xmlDocPtr |
1729 | 16.0k | parseFile(xmllintState *lint, const char *filename) { |
1730 | 16.0k | xmlDocPtr doc = NULL; |
1731 | | |
1732 | 16.0k | if ((lint->appOptions & XML_LINT_GENERATE) && (filename == NULL)) { |
1733 | 9.24k | xmlNodePtr n; |
1734 | | |
1735 | 9.24k | doc = xmlNewDoc(BAD_CAST "1.0"); |
1736 | 9.24k | if (doc == NULL) { |
1737 | 39 | lint->progresult = XMLLINT_ERR_MEM; |
1738 | 39 | return(NULL); |
1739 | 39 | } |
1740 | 9.20k | n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL); |
1741 | 9.20k | if (n == NULL) { |
1742 | 0 | xmlFreeDoc(doc); |
1743 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1744 | 0 | return(NULL); |
1745 | 0 | } |
1746 | 9.20k | if (xmlNodeSetContent(n, BAD_CAST "abc") < 0) { |
1747 | 0 | xmlFreeNode(n); |
1748 | 0 | xmlFreeDoc(doc); |
1749 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1750 | 0 | return(NULL); |
1751 | 0 | } |
1752 | 9.20k | xmlDocSetRootElement(doc, n); |
1753 | | |
1754 | 9.20k | return(doc); |
1755 | 9.20k | } |
1756 | | |
1757 | 6.79k | #ifdef LIBXML_HTML_ENABLED |
1758 | 6.79k | if (lint->appOptions & XML_LINT_HTML_ENABLED) { |
1759 | 1.30k | doc = parseHtml(lint, filename); |
1760 | 1.30k | return(doc); |
1761 | 1.30k | } |
1762 | 5.49k | #endif /* LIBXML_HTML_ENABLED */ |
1763 | 5.49k | { |
1764 | 5.49k | doc = parseXml(lint, filename); |
1765 | 5.49k | } |
1766 | | |
1767 | 5.49k | if (doc == NULL) { |
1768 | 5.49k | if (lint->ctxt->errNo == XML_ERR_NO_MEMORY) |
1769 | 5.49k | lint->progresult = XMLLINT_ERR_MEM; |
1770 | 0 | else |
1771 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
1772 | 5.49k | } else { |
1773 | 0 | xmlParserStatus status = xmlCtxtGetStatus(lint->ctxt); |
1774 | 0 | if ((lint->parseOptions & XML_PARSE_DTDVALID) && |
1775 | 0 | (status & XML_STATUS_DTD_VALIDATION_FAILED)) |
1776 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
1777 | |
|
1778 | 0 | if ((lint->appOptions & XML_LINT_STRICT_NAMESPACE) && |
1779 | 0 | (status & XML_STATUS_NOT_NS_WELL_FORMED)) { |
1780 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
1781 | 0 | } |
1782 | 0 | } |
1783 | | |
1784 | 5.49k | return(doc); |
1785 | 6.79k | } |
1786 | | |
1787 | | static void |
1788 | 16.0k | parseAndPrintFile(xmllintState *lint, const char *filename) { |
1789 | 16.0k | FILE *errStream = lint->errStream; |
1790 | 16.0k | xmlDocPtr doc; |
1791 | | |
1792 | | /* Avoid unused variable warning */ |
1793 | 16.0k | (void) errStream; |
1794 | | |
1795 | 16.0k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) |
1796 | 3.50k | startTimer(lint); |
1797 | | |
1798 | 16.0k | doc = parseFile(lint, filename); |
1799 | 16.0k | if (doc == NULL) { |
1800 | 6.83k | if (lint->progresult == XMLLINT_RETURN_OK) |
1801 | 1.17k | lint->progresult = XMLLINT_ERR_UNCLASS; |
1802 | 6.83k | return; |
1803 | 6.83k | } |
1804 | | |
1805 | 9.20k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1806 | 2.21k | endTimer(lint, "Parsing"); |
1807 | 2.21k | } |
1808 | | |
1809 | 9.20k | if (lint->appOptions & XML_LINT_DROP_DTD) { |
1810 | 1.28k | xmlDtdPtr dtd; |
1811 | | |
1812 | 1.28k | dtd = xmlGetIntSubset(doc); |
1813 | 1.28k | if (dtd != NULL) { |
1814 | 0 | xmlUnlinkNode((xmlNodePtr)dtd); |
1815 | 0 | doc->intSubset = dtd; |
1816 | 0 | } |
1817 | 1.28k | } |
1818 | | |
1819 | 9.20k | #ifdef LIBXML_XINCLUDE_ENABLED |
1820 | 9.20k | if (lint->appOptions & XML_LINT_XINCLUDE) { |
1821 | 7.44k | xmlXIncludeCtxt *xinc; |
1822 | 7.44k | int res; |
1823 | | |
1824 | 7.44k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1825 | 2.00k | startTimer(lint); |
1826 | 2.00k | } |
1827 | | |
1828 | 7.44k | xinc = xmlXIncludeNewContext(doc); |
1829 | 7.44k | if (xinc == NULL) { |
1830 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1831 | 0 | goto done; |
1832 | 0 | } |
1833 | 7.44k | xmlXIncludeSetResourceLoader(xinc, xmllintResourceLoader, lint); |
1834 | 7.44k | xmlXIncludeSetFlags(xinc, lint->parseOptions); |
1835 | 7.44k | res = xmlXIncludeProcessNode(xinc, (xmlNode *) doc); |
1836 | 7.44k | xmlXIncludeFreeContext(xinc); |
1837 | 7.44k | if (res < 0) { |
1838 | | /* |
1839 | | * Return an error but continue to print the document |
1840 | | * to match long-standing behavior. |
1841 | | */ |
1842 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
1843 | 0 | } |
1844 | | |
1845 | 7.44k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1846 | 2.00k | endTimer(lint, "Xinclude processing"); |
1847 | 2.00k | } |
1848 | 7.44k | } |
1849 | 9.20k | #endif |
1850 | | |
1851 | | /* |
1852 | | * shell interaction |
1853 | | */ |
1854 | 9.20k | if (lint->appOptions & XML_LINT_NAVIGATING_SHELL) { |
1855 | 0 | #ifdef LIBXML_XPATH_ENABLED |
1856 | 0 | xmlXPathOrderDocElems(doc); |
1857 | 0 | #endif |
1858 | 0 | xmllintShell(doc, filename, stdout); |
1859 | 0 | goto done; |
1860 | 0 | } |
1861 | | |
1862 | 9.20k | #ifdef LIBXML_XPATH_ENABLED |
1863 | 9.20k | if (lint->xpathquery != NULL) { |
1864 | 8.36k | xmlXPathOrderDocElems(doc); |
1865 | 8.36k | doXPathQuery(lint, doc, lint->xpathquery); |
1866 | 8.36k | } |
1867 | 9.20k | #endif |
1868 | | |
1869 | | /* |
1870 | | * test intermediate copy if needed. |
1871 | | */ |
1872 | 9.20k | if (lint->appOptions & XML_LINT_COPY_ENABLED) { |
1873 | 2.59k | xmlDocPtr tmp; |
1874 | | |
1875 | 2.59k | tmp = doc; |
1876 | 2.59k | if (lint->appOptions & XML_LINT_TIMINGS) { |
1877 | 749 | startTimer(lint); |
1878 | 749 | } |
1879 | 2.59k | doc = xmlCopyDoc(doc, 1); |
1880 | 2.59k | if (doc == NULL) { |
1881 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
1882 | 0 | xmlFreeDoc(tmp); |
1883 | 0 | return; |
1884 | 0 | } |
1885 | 2.59k | if (lint->appOptions & XML_LINT_TIMINGS) { |
1886 | 749 | endTimer(lint, "Copying"); |
1887 | 749 | } |
1888 | 2.59k | if (lint->appOptions & XML_LINT_TIMINGS) { |
1889 | 749 | startTimer(lint); |
1890 | 749 | } |
1891 | 2.59k | xmlFreeDoc(tmp); |
1892 | 2.59k | if (lint->appOptions & XML_LINT_TIMINGS) { |
1893 | 749 | endTimer(lint, "Freeing original"); |
1894 | 749 | } |
1895 | 2.59k | } |
1896 | | |
1897 | 9.20k | #ifdef LIBXML_VALID_ENABLED |
1898 | 9.20k | if ((lint->appOptions & XML_LINT_VALID_INSERTIONS) |
1899 | 9.20k | #ifdef LIBXML_HTML_ENABLED |
1900 | 9.20k | && ((lint->appOptions & XML_LINT_HTML_ENABLED) != XML_LINT_HTML_ENABLED) |
1901 | 9.20k | #endif |
1902 | 9.20k | ) { |
1903 | 4.74k | const xmlChar* list[256]; |
1904 | 4.74k | int nb, i; |
1905 | 4.74k | xmlNodePtr node; |
1906 | | |
1907 | 4.74k | if (doc->children != NULL) { |
1908 | 4.74k | node = doc->children; |
1909 | 4.74k | while ((node != NULL) && |
1910 | 4.74k | ((node->type != XML_ELEMENT_NODE) || |
1911 | 4.74k | (node->last == NULL))) |
1912 | 0 | node = node->next; |
1913 | 4.74k | if (node != NULL) { |
1914 | 4.74k | nb = xmlValidGetValidElements(node->last, NULL, list, 256); |
1915 | 4.74k | if (nb < 0) { |
1916 | 4.74k | fprintf(errStream, "could not get valid list of elements\n"); |
1917 | 4.74k | } else if (nb == 0) { |
1918 | 0 | fprintf(errStream, "No element can be inserted under root\n"); |
1919 | 0 | } else { |
1920 | 0 | fprintf(errStream, "%d element types can be inserted under root:\n", |
1921 | 0 | nb); |
1922 | 0 | for (i = 0;i < nb;i++) { |
1923 | 0 | fprintf(errStream, "%s\n", (char *) list[i]); |
1924 | 0 | } |
1925 | 0 | } |
1926 | 4.74k | } |
1927 | 4.74k | } |
1928 | 4.74k | } else |
1929 | 4.46k | #endif /* LIBXML_VALID_ENABLED */ |
1930 | 4.46k | #ifdef LIBXML_READER_ENABLED |
1931 | 4.46k | if (lint->appOptions & XML_LINT_USE_WALKER) { |
1932 | 1.90k | walkDoc(lint, doc); |
1933 | 1.90k | } |
1934 | 9.20k | #endif /* LIBXML_READER_ENABLED */ |
1935 | 9.20k | #ifdef LIBXML_OUTPUT_ENABLED |
1936 | 9.20k | if (lint->noout == 0) { |
1937 | 237 | #ifdef LIBXML_ZLIB_ENABLED |
1938 | 237 | if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) |
1939 | 26 | xmlSetDocCompressMode(doc, 9); |
1940 | 237 | #endif |
1941 | | |
1942 | | /* |
1943 | | * print it. |
1944 | | */ |
1945 | | #ifdef LIBXML_DEBUG_ENABLED |
1946 | | if ((lint->appOptions & XML_LINT_DEBUG_ENABLED) != XML_LINT_DEBUG_ENABLED) { |
1947 | | #endif |
1948 | 237 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
1949 | 18 | startTimer(lint); |
1950 | 18 | } |
1951 | 237 | #ifdef LIBXML_C14N_ENABLED |
1952 | 237 | if (lint->appOptions & XML_LINT_CANONICAL_V1_0) { |
1953 | 35 | xmlChar *result = NULL; |
1954 | 35 | int size; |
1955 | | |
1956 | 35 | size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result); |
1957 | 35 | if (size >= 0) { |
1958 | 35 | if (write(1, result, size) == -1) { |
1959 | 0 | fprintf(errStream, "Can't write data\n"); |
1960 | 0 | } |
1961 | 35 | xmlFree(result); |
1962 | 35 | } else { |
1963 | 0 | fprintf(errStream, "Failed to canonicalize\n"); |
1964 | 0 | lint->progresult = XMLLINT_ERR_OUT; |
1965 | 0 | } |
1966 | 202 | } else if (lint->appOptions & XML_LINT_CANONICAL_V1_1) { |
1967 | 49 | xmlChar *result = NULL; |
1968 | 49 | int size; |
1969 | | |
1970 | 49 | size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result); |
1971 | 49 | if (size >= 0) { |
1972 | 49 | if (write(1, result, size) == -1) { |
1973 | 0 | fprintf(errStream, "Can't write data\n"); |
1974 | 0 | } |
1975 | 49 | xmlFree(result); |
1976 | 49 | } else { |
1977 | 0 | fprintf(errStream, "Failed to canonicalize\n"); |
1978 | 0 | lint->progresult = XMLLINT_ERR_OUT; |
1979 | 0 | } |
1980 | 153 | } else if (lint->appOptions & XML_LINT_CANONICAL_EXE) { |
1981 | 11 | xmlChar *result = NULL; |
1982 | 11 | int size; |
1983 | | |
1984 | 11 | size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result); |
1985 | 11 | if (size >= 0) { |
1986 | 11 | if (write(1, result, size) == -1) { |
1987 | 0 | fprintf(errStream, "Can't write data\n"); |
1988 | 0 | } |
1989 | 11 | xmlFree(result); |
1990 | 11 | } else { |
1991 | 0 | fprintf(errStream, "Failed to canonicalize\n"); |
1992 | 0 | lint->progresult = XMLLINT_ERR_OUT; |
1993 | 0 | } |
1994 | 11 | } else |
1995 | 142 | #endif |
1996 | 142 | #ifdef LIBXML_ZLIB_ENABLED |
1997 | 142 | if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) { |
1998 | 8 | xmlSaveFile(lint->output ? lint->output : "-", doc); |
1999 | 8 | } else |
2000 | 134 | #endif |
2001 | 134 | { |
2002 | 134 | xmlSaveCtxtPtr ctxt; |
2003 | 134 | int saveOpts = 0; |
2004 | | |
2005 | 134 | if (lint->format == 1) |
2006 | 54 | saveOpts |= XML_SAVE_FORMAT; |
2007 | 80 | else if (lint->format == 2) |
2008 | 19 | saveOpts |= XML_SAVE_WSNONSIG; |
2009 | | |
2010 | 134 | #if defined(LIBXML_HTML_ENABLED) |
2011 | 134 | if (lint->appOptions & XML_LINT_XML_OUT) |
2012 | 18 | saveOpts |= XML_SAVE_AS_XML; |
2013 | 134 | #endif |
2014 | | |
2015 | 134 | if (lint->output == NULL) |
2016 | 134 | ctxt = xmlSaveToFd(STDOUT_FILENO, lint->encoding, |
2017 | 134 | saveOpts); |
2018 | 0 | else |
2019 | 0 | ctxt = xmlSaveToFilename(lint->output, lint->encoding, |
2020 | 0 | saveOpts); |
2021 | | |
2022 | 134 | if (ctxt != NULL) { |
2023 | 46 | if (lint->indentString != NULL) |
2024 | 0 | xmlSaveSetIndentString(ctxt, lint->indentString); |
2025 | | |
2026 | 46 | if (xmlSaveDoc(ctxt, doc) < 0) { |
2027 | 0 | fprintf(errStream, "failed save to %s\n", |
2028 | 0 | lint->output ? lint->output : "-"); |
2029 | 0 | lint->progresult = XMLLINT_ERR_OUT; |
2030 | 0 | } |
2031 | 46 | xmlSaveClose(ctxt); |
2032 | 88 | } else { |
2033 | 88 | lint->progresult = XMLLINT_ERR_OUT; |
2034 | 88 | } |
2035 | 134 | } |
2036 | 237 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2037 | 18 | endTimer(lint, "Saving"); |
2038 | 18 | } |
2039 | | #ifdef LIBXML_DEBUG_ENABLED |
2040 | | } else { |
2041 | | FILE *out; |
2042 | | if (lint->output == NULL) |
2043 | | out = stdout; |
2044 | | else { |
2045 | | out = fopen(lint->output, "wb"); |
2046 | | } |
2047 | | if (out != NULL) { |
2048 | | xmlDebugDumpDocument(out, doc); |
2049 | | |
2050 | | if (lint->output != NULL) |
2051 | | fclose(out); |
2052 | | } else { |
2053 | | fprintf(errStream, "failed to open %s\n", lint->output); |
2054 | | lint->progresult = XMLLINT_ERR_OUT; |
2055 | | } |
2056 | | } |
2057 | | #endif |
2058 | 237 | } |
2059 | 9.20k | #endif /* LIBXML_OUTPUT_ENABLED */ |
2060 | | |
2061 | 9.20k | #ifdef LIBXML_VALID_ENABLED |
2062 | | /* |
2063 | | * A posteriori validation test |
2064 | | */ |
2065 | 9.20k | if ((lint->dtdvalid != NULL) || (lint->dtdvalidfpi != NULL)) { |
2066 | 0 | xmlDtdPtr dtd; |
2067 | |
|
2068 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2069 | 0 | startTimer(lint); |
2070 | 0 | } |
2071 | 0 | if (lint->dtdvalid != NULL) |
2072 | 0 | dtd = xmlParseDTD(NULL, BAD_CAST lint->dtdvalid); |
2073 | 0 | else |
2074 | 0 | dtd = xmlParseDTD(BAD_CAST lint->dtdvalidfpi, NULL); |
2075 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2076 | 0 | endTimer(lint, "Parsing DTD"); |
2077 | 0 | } |
2078 | 0 | if (dtd == NULL) { |
2079 | 0 | if (lint->dtdvalid != NULL) |
2080 | 0 | fprintf(errStream, "Could not parse DTD %s\n", |
2081 | 0 | lint->dtdvalid); |
2082 | 0 | else |
2083 | 0 | fprintf(errStream, "Could not parse DTD %s\n", |
2084 | 0 | lint->dtdvalidfpi); |
2085 | 0 | lint->progresult = XMLLINT_ERR_DTD; |
2086 | 0 | } else { |
2087 | 0 | xmlValidCtxtPtr cvp; |
2088 | |
|
2089 | 0 | cvp = xmlNewValidCtxt(); |
2090 | 0 | if (cvp == NULL) { |
2091 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
2092 | 0 | xmlFreeDtd(dtd); |
2093 | 0 | return; |
2094 | 0 | } |
2095 | | |
2096 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2097 | 0 | startTimer(lint); |
2098 | 0 | } |
2099 | 0 | if (!xmlValidateDtd(cvp, doc, dtd)) { |
2100 | 0 | if (lint->dtdvalid != NULL) |
2101 | 0 | fprintf(errStream, |
2102 | 0 | "Document %s does not validate against %s\n", |
2103 | 0 | filename, lint->dtdvalid); |
2104 | 0 | else |
2105 | 0 | fprintf(errStream, |
2106 | 0 | "Document %s does not validate against %s\n", |
2107 | 0 | filename, lint->dtdvalidfpi); |
2108 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
2109 | 0 | } |
2110 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2111 | 0 | endTimer(lint, "Validating against DTD"); |
2112 | 0 | } |
2113 | 0 | xmlFreeValidCtxt(cvp); |
2114 | 0 | xmlFreeDtd(dtd); |
2115 | 0 | } |
2116 | 9.20k | } else if (lint->appOptions & XML_LINT_POST_VALIDATION) { |
2117 | 1.56k | xmlValidCtxtPtr cvp; |
2118 | | |
2119 | 1.56k | cvp = xmlNewValidCtxt(); |
2120 | 1.56k | if (cvp == NULL) { |
2121 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
2122 | 0 | xmlFreeDoc(doc); |
2123 | 0 | return; |
2124 | 0 | } |
2125 | | |
2126 | 1.56k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2127 | 488 | startTimer(lint); |
2128 | 488 | } |
2129 | 1.56k | if (!xmlValidateDocument(cvp, doc)) { |
2130 | 1.56k | fprintf(errStream, |
2131 | 1.56k | "Document %s does not validate\n", filename); |
2132 | 1.56k | lint->progresult = XMLLINT_ERR_VALID; |
2133 | 1.56k | } |
2134 | 1.56k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2135 | 488 | endTimer(lint, "Validating"); |
2136 | 488 | } |
2137 | 1.56k | xmlFreeValidCtxt(cvp); |
2138 | 1.56k | } |
2139 | 9.20k | #endif /* LIBXML_VALID_ENABLED */ |
2140 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
2141 | | if (lint->wxschematron != NULL) { |
2142 | | xmlSchematronValidCtxtPtr ctxt; |
2143 | | int ret; |
2144 | | int flag; |
2145 | | |
2146 | | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2147 | | startTimer(lint); |
2148 | | } |
2149 | | |
2150 | | if (lint->appOptions & XML_LINT_DEBUG_ENABLED) |
2151 | | flag = XML_SCHEMATRON_OUT_XML; |
2152 | | else |
2153 | | flag = XML_SCHEMATRON_OUT_TEXT; |
2154 | | if (lint->noout) |
2155 | | flag |= XML_SCHEMATRON_OUT_QUIET; |
2156 | | ctxt = xmlSchematronNewValidCtxt(lint->wxschematron, flag); |
2157 | | if (ctxt == NULL) { |
2158 | | lint->progresult = XMLLINT_ERR_MEM; |
2159 | | xmlFreeDoc(doc); |
2160 | | return; |
2161 | | } |
2162 | | ret = xmlSchematronValidateDoc(ctxt, doc); |
2163 | | if (ret == 0) { |
2164 | | if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) { |
2165 | | fprintf(errStream, "%s validates\n", filename); |
2166 | | } |
2167 | | } else if (ret > 0) { |
2168 | | fprintf(errStream, "%s fails to validate\n", filename); |
2169 | | lint->progresult = XMLLINT_ERR_VALID; |
2170 | | } else { |
2171 | | fprintf(errStream, "%s validation generated an internal error\n", |
2172 | | filename); |
2173 | | lint->progresult = XMLLINT_ERR_VALID; |
2174 | | } |
2175 | | xmlSchematronFreeValidCtxt(ctxt); |
2176 | | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2177 | | endTimer(lint, "Validating"); |
2178 | | } |
2179 | | } |
2180 | | #endif |
2181 | | |
2182 | 9.20k | #ifdef LIBXML_RELAXNG_ENABLED |
2183 | 9.20k | if (lint->relaxngschemas != NULL) { |
2184 | 0 | xmlRelaxNGValidCtxtPtr ctxt; |
2185 | 0 | int ret; |
2186 | |
|
2187 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2188 | 0 | startTimer(lint); |
2189 | 0 | } |
2190 | |
|
2191 | 0 | ctxt = xmlRelaxNGNewValidCtxt(lint->relaxngschemas); |
2192 | 0 | if (ctxt == NULL) { |
2193 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
2194 | 0 | xmlFreeDoc(doc); |
2195 | 0 | return; |
2196 | 0 | } |
2197 | 0 | ret = xmlRelaxNGValidateDoc(ctxt, doc); |
2198 | 0 | if (ret == 0) { |
2199 | 0 | if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) { |
2200 | 0 | fprintf(errStream, "%s validates\n", filename); |
2201 | 0 | } |
2202 | 0 | } else if (ret > 0) { |
2203 | 0 | fprintf(errStream, "%s fails to validate\n", filename); |
2204 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
2205 | 0 | } else { |
2206 | 0 | fprintf(errStream, "%s validation generated an internal error\n", |
2207 | 0 | filename); |
2208 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
2209 | 0 | } |
2210 | 0 | xmlRelaxNGFreeValidCtxt(ctxt); |
2211 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2212 | 0 | endTimer(lint, "Validating"); |
2213 | 0 | } |
2214 | 0 | } |
2215 | 9.20k | #endif /* LIBXML_RELAXNG_ENABLED */ |
2216 | | |
2217 | 9.20k | #ifdef LIBXML_SCHEMAS_ENABLED |
2218 | 9.20k | if (lint->wxschemas != NULL) { |
2219 | 0 | xmlSchemaValidCtxtPtr ctxt; |
2220 | 0 | int ret; |
2221 | |
|
2222 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2223 | 0 | startTimer(lint); |
2224 | 0 | } |
2225 | |
|
2226 | 0 | ctxt = xmlSchemaNewValidCtxt(lint->wxschemas); |
2227 | 0 | if (ctxt == NULL) { |
2228 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
2229 | 0 | xmlFreeDoc(doc); |
2230 | 0 | return; |
2231 | 0 | } |
2232 | 0 | ret = xmlSchemaValidateDoc(ctxt, doc); |
2233 | 0 | if (ret == 0) { |
2234 | 0 | if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) { |
2235 | 0 | fprintf(errStream, "%s validates\n", filename); |
2236 | 0 | } |
2237 | 0 | } else if (ret > 0) { |
2238 | 0 | fprintf(errStream, "%s fails to validate\n", filename); |
2239 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
2240 | 0 | } else { |
2241 | 0 | fprintf(errStream, "%s validation generated an internal error\n", |
2242 | 0 | filename); |
2243 | 0 | lint->progresult = XMLLINT_ERR_VALID; |
2244 | 0 | } |
2245 | 0 | xmlSchemaFreeValidCtxt(ctxt); |
2246 | 0 | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2247 | 0 | endTimer(lint, "Validating"); |
2248 | 0 | } |
2249 | 0 | } |
2250 | 9.20k | #endif /* LIBXML_SCHEMAS_ENABLED */ |
2251 | | |
2252 | | /* Avoid unused label warning */ |
2253 | 9.20k | goto done; |
2254 | | |
2255 | 9.20k | done: |
2256 | | /* |
2257 | | * free it. |
2258 | | */ |
2259 | 9.20k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2260 | 2.21k | startTimer(lint); |
2261 | 2.21k | } |
2262 | 9.20k | xmlFreeDoc(doc); |
2263 | 9.20k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) { |
2264 | 2.21k | endTimer(lint, "Freeing"); |
2265 | 2.21k | } |
2266 | 9.20k | } |
2267 | | |
2268 | | /************************************************************************ |
2269 | | * * |
2270 | | * Usage and Main * |
2271 | | * * |
2272 | | ************************************************************************/ |
2273 | | |
2274 | 2.69k | static void showVersion(FILE *errStream, const char *name) { |
2275 | 2.69k | fprintf(errStream, "%s: using libxml version %s\n", name, xmlParserVersion); |
2276 | 2.69k | fprintf(errStream, " compiled with: "); |
2277 | 2.69k | if (xmlHasFeature(XML_WITH_THREAD)) fprintf(errStream, "Threads "); |
2278 | 2.69k | fprintf(errStream, "Tree "); |
2279 | 2.69k | if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(errStream, "Output "); |
2280 | 2.69k | if (xmlHasFeature(XML_WITH_PUSH)) fprintf(errStream, "Push "); |
2281 | 2.69k | if (xmlHasFeature(XML_WITH_READER)) fprintf(errStream, "Reader "); |
2282 | 2.69k | if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(errStream, "Patterns "); |
2283 | 2.69k | if (xmlHasFeature(XML_WITH_WRITER)) fprintf(errStream, "Writer "); |
2284 | 2.69k | if (xmlHasFeature(XML_WITH_SAX1)) fprintf(errStream, "SAXv1 "); |
2285 | 2.69k | if (xmlHasFeature(XML_WITH_VALID)) fprintf(errStream, "DTDValid "); |
2286 | 2.69k | if (xmlHasFeature(XML_WITH_HTML)) fprintf(errStream, "HTML "); |
2287 | 2.69k | if (xmlHasFeature(XML_WITH_C14N)) fprintf(errStream, "C14N "); |
2288 | 2.69k | if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(errStream, "Catalog "); |
2289 | 2.69k | if (xmlHasFeature(XML_WITH_XPATH)) fprintf(errStream, "XPath "); |
2290 | 2.69k | if (xmlHasFeature(XML_WITH_XPTR)) fprintf(errStream, "XPointer "); |
2291 | 2.69k | if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(errStream, "XInclude "); |
2292 | 2.69k | if (xmlHasFeature(XML_WITH_ICONV)) fprintf(errStream, "Iconv "); |
2293 | 2.69k | if (xmlHasFeature(XML_WITH_ICU)) fprintf(errStream, "ICU "); |
2294 | 2.69k | if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(errStream, "ISO8859X "); |
2295 | 2.69k | if (xmlHasFeature(XML_WITH_REGEXP)) |
2296 | 2.69k | fprintf(errStream, "Regexps Automata "); |
2297 | 2.69k | if (xmlHasFeature(XML_WITH_RELAXNG)) fprintf(errStream, "RelaxNG "); |
2298 | 2.69k | if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(errStream, "Schemas "); |
2299 | 2.69k | if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(errStream, "Schematron "); |
2300 | 2.69k | if (xmlHasFeature(XML_WITH_MODULES)) fprintf(errStream, "Modules "); |
2301 | 2.69k | if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(errStream, "Debug "); |
2302 | 2.69k | if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(errStream, "Zlib "); |
2303 | 2.69k | if (xmlHasFeature(XML_WITH_LZMA)) fprintf(errStream, "Lzma "); |
2304 | 2.69k | fprintf(errStream, "\n"); |
2305 | 2.69k | } |
2306 | | |
2307 | 130 | static void usage(FILE *f, const char *name) { |
2308 | 130 | fprintf(f, "Usage : %s [options] XMLfiles ...\n", name); |
2309 | 130 | #ifdef LIBXML_OUTPUT_ENABLED |
2310 | 130 | fprintf(f, "\tParse the XML files and output the result of the parsing\n"); |
2311 | | #else |
2312 | | fprintf(f, "\tParse the XML files\n"); |
2313 | | #endif /* LIBXML_OUTPUT_ENABLED */ |
2314 | 130 | fprintf(f, "\t--version : display the version of the XML library used\n"); |
2315 | 130 | fprintf(f, "\t--shell : run a navigating shell\n"); |
2316 | 130 | fprintf(f, "\t--debug : show additional debug information\n"); |
2317 | 130 | fprintf(f, "\t--copy : used to test the internal copy implementation\n"); |
2318 | 130 | fprintf(f, "\t--recover : output what was parsable on broken XML documents\n"); |
2319 | 130 | fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n"); |
2320 | 130 | fprintf(f, "\t--noent : substitute entity references by their value\n"); |
2321 | 130 | fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n"); |
2322 | 130 | fprintf(f, "\t--noout : don't output the result tree\n"); |
2323 | 130 | fprintf(f, "\t--path 'paths': provide a set of paths for resources\n"); |
2324 | 130 | fprintf(f, "\t--load-trace : print trace of all external entities loaded\n"); |
2325 | 130 | fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n"); |
2326 | 130 | fprintf(f, "\t--nocompact : do not generate compact text nodes\n"); |
2327 | 130 | #ifdef LIBXML_VALID_ENABLED |
2328 | 130 | fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n"); |
2329 | 130 | fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n"); |
2330 | 130 | fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n"); |
2331 | 130 | fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n"); |
2332 | 130 | fprintf(f, "\t--insert : ad-hoc test for valid insertions\n"); |
2333 | 130 | #endif /* LIBXML_VALID_ENABLED */ |
2334 | 130 | fprintf(f, "\t--strict-namespace : Return application failure if document has any namespace errors\n"); |
2335 | 130 | fprintf(f, "\t--quiet : be quiet when succeeded\n"); |
2336 | 130 | fprintf(f, "\t--timing : print some timings\n"); |
2337 | 130 | fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n"); |
2338 | 130 | fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n"); |
2339 | 130 | #ifdef LIBXML_HTML_ENABLED |
2340 | 130 | fprintf(f, "\t--html : use the HTML parser\n"); |
2341 | 130 | fprintf(f, "\t--nodefdtd : do not default HTML doctype\n"); |
2342 | 130 | #ifdef LIBXML_OUTPUT_ENABLED |
2343 | 130 | fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n"); |
2344 | 130 | #endif |
2345 | 130 | #endif |
2346 | 130 | #ifdef LIBXML_PUSH_ENABLED |
2347 | 130 | fprintf(f, "\t--push : use the push mode of the parser\n"); |
2348 | 130 | #endif /* LIBXML_PUSH_ENABLED */ |
2349 | 130 | #if HAVE_DECL_MMAP |
2350 | 130 | fprintf(f, "\t--memory : parse from memory\n"); |
2351 | 130 | #endif |
2352 | 130 | fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n"); |
2353 | 130 | fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n"); |
2354 | 130 | fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n"); |
2355 | 130 | fprintf(f, "\t--nocdata : replace cdata section with text nodes\n"); |
2356 | 130 | fprintf(f, "\t--nodict : create document without dictionary\n"); |
2357 | 130 | fprintf(f, "\t--pedantic : enable additional warnings\n"); |
2358 | 130 | #ifdef LIBXML_OUTPUT_ENABLED |
2359 | 130 | fprintf(f, "\t--output file or -o file: save to a given file\n"); |
2360 | 130 | fprintf(f, "\t--format : reformat/reindent the output\n"); |
2361 | 130 | fprintf(f, "\t--encode encoding : output in the given encoding\n"); |
2362 | 130 | fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n"); |
2363 | 130 | fprintf(f, "\t 0 Do not pretty print\n"); |
2364 | 130 | fprintf(f, "\t 1 Format the XML content, as --format\n"); |
2365 | 130 | fprintf(f, "\t 2 Add whitespace inside tags, preserving content\n"); |
2366 | 130 | #ifdef LIBXML_ZLIB_ENABLED |
2367 | 130 | fprintf(f, "\t--compress : turn on gzip compression of output\n"); |
2368 | 130 | #endif |
2369 | 130 | #ifdef LIBXML_C14N_ENABLED |
2370 | 130 | fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n"); |
2371 | 130 | fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n"); |
2372 | 130 | fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n"); |
2373 | 130 | #endif /* LIBXML_C14N_ENABLED */ |
2374 | 130 | #endif /* LIBXML_OUTPUT_ENABLED */ |
2375 | 130 | fprintf(f, "\t--nsclean : remove redundant namespace declarations\n"); |
2376 | 130 | #ifdef LIBXML_CATALOG_ENABLED |
2377 | 130 | fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n"); |
2378 | 130 | fprintf(f, "\t otherwise XML Catalogs starting from \n"); |
2379 | 130 | fprintf(f, "\t file://" XML_SYSCONFDIR "/xml/catalog " |
2380 | 130 | "are activated by default\n"); |
2381 | 130 | fprintf(f, "\t--nocatalogs: deactivate all catalogs\n"); |
2382 | 130 | #endif |
2383 | 130 | fprintf(f, "\t--auto : generate a small doc on the fly\n"); |
2384 | 130 | #ifdef LIBXML_XINCLUDE_ENABLED |
2385 | 130 | fprintf(f, "\t--xinclude : do XInclude processing\n"); |
2386 | 130 | fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n"); |
2387 | 130 | fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n"); |
2388 | 130 | #endif |
2389 | 130 | fprintf(f, "\t--loaddtd : fetch external DTD\n"); |
2390 | 130 | fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n"); |
2391 | 130 | #ifdef LIBXML_READER_ENABLED |
2392 | 130 | fprintf(f, "\t--stream : use the streaming interface to process very large files\n"); |
2393 | 130 | fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n"); |
2394 | 130 | #ifdef LIBXML_PATTERN_ENABLED |
2395 | 130 | fprintf(f, "\t--pattern pattern_value : test the pattern support\n"); |
2396 | 130 | #endif |
2397 | 130 | #endif /* LIBXML_READER_ENABLED */ |
2398 | 130 | #ifdef LIBXML_RELAXNG_ENABLED |
2399 | 130 | fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n"); |
2400 | 130 | #endif |
2401 | 130 | #ifdef LIBXML_SCHEMAS_ENABLED |
2402 | 130 | fprintf(f, "\t--schema schema : do validation against the WXS schema\n"); |
2403 | 130 | #endif |
2404 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
2405 | | fprintf(f, "\t--schematron schema : do validation against a schematron\n"); |
2406 | | #endif |
2407 | 130 | #ifdef LIBXML_SAX1_ENABLED |
2408 | 130 | fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n"); |
2409 | 130 | #endif |
2410 | 130 | fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n"); |
2411 | 130 | fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n"); |
2412 | 130 | #ifdef LIBXML_XPATH_ENABLED |
2413 | 130 | fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n"); |
2414 | 130 | #endif |
2415 | 130 | fprintf(f, "\t--max-ampl value: set maximum amplification factor\n"); |
2416 | | |
2417 | 130 | fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n"); |
2418 | 130 | } |
2419 | | |
2420 | | static int |
2421 | | parseInteger(unsigned long *result, FILE *errStream, const char *ctxt, |
2422 | 4.99k | const char *str, unsigned long min, unsigned long max) { |
2423 | 4.99k | char *strEnd; |
2424 | 4.99k | unsigned long val; |
2425 | | |
2426 | 4.99k | errno = 0; |
2427 | 4.99k | val = strtoul(str, &strEnd, 10); |
2428 | 4.99k | if (errno == EINVAL || *strEnd != 0) { |
2429 | 0 | fprintf(errStream, "%s: invalid integer: %s\n", ctxt, str); |
2430 | 0 | return(-1); |
2431 | 0 | } |
2432 | 4.99k | if (errno != 0 || val < min || val > max) { |
2433 | 16 | fprintf(errStream, "%s: integer out of range: %s\n", ctxt, str); |
2434 | 16 | return(-1); |
2435 | 16 | } |
2436 | | |
2437 | 4.98k | *result = val; |
2438 | 4.98k | return(0); |
2439 | 4.99k | } |
2440 | | |
2441 | | static int |
2442 | 155k | skipArgs(const char *arg) { |
2443 | 155k | if ((!strcmp(arg, "-path")) || |
2444 | 155k | (!strcmp(arg, "--path")) || |
2445 | 155k | (!strcmp(arg, "-maxmem")) || |
2446 | 155k | (!strcmp(arg, "--maxmem")) || |
2447 | 155k | #ifdef LIBXML_OUTPUT_ENABLED |
2448 | 155k | (!strcmp(arg, "-o")) || |
2449 | 155k | (!strcmp(arg, "-output")) || |
2450 | 155k | (!strcmp(arg, "--output")) || |
2451 | 155k | (!strcmp(arg, "-encode")) || |
2452 | 155k | (!strcmp(arg, "--encode")) || |
2453 | 155k | (!strcmp(arg, "-pretty")) || |
2454 | 155k | (!strcmp(arg, "--pretty")) || |
2455 | 155k | #endif |
2456 | 155k | #ifdef LIBXML_VALID_ENABLED |
2457 | 155k | (!strcmp(arg, "-dtdvalid")) || |
2458 | 155k | (!strcmp(arg, "--dtdvalid")) || |
2459 | 155k | (!strcmp(arg, "-dtdvalidfpi")) || |
2460 | 155k | (!strcmp(arg, "--dtdvalidfpi")) || |
2461 | 155k | #endif |
2462 | 155k | #ifdef LIBXML_RELAXNG_ENABLED |
2463 | 155k | (!strcmp(arg, "-relaxng")) || |
2464 | 155k | (!strcmp(arg, "--relaxng")) || |
2465 | 155k | #endif |
2466 | 155k | #ifdef LIBXML_SCHEMAS_ENABLED |
2467 | 155k | (!strcmp(arg, "-schema")) || |
2468 | 155k | (!strcmp(arg, "--schema")) || |
2469 | 155k | #endif |
2470 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
2471 | | (!strcmp(arg, "-schematron")) || |
2472 | | (!strcmp(arg, "--schematron")) || |
2473 | | #endif |
2474 | 155k | #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED) |
2475 | 155k | (!strcmp(arg, "-pattern")) || |
2476 | 155k | (!strcmp(arg, "--pattern")) || |
2477 | 155k | #endif |
2478 | 155k | #ifdef LIBXML_XPATH_ENABLED |
2479 | 155k | (!strcmp(arg, "-xpath")) || |
2480 | 155k | (!strcmp(arg, "--xpath")) || |
2481 | 155k | #endif |
2482 | 155k | (!strcmp(arg, "-max-ampl")) || |
2483 | 155k | (!strcmp(arg, "--max-ampl")) |
2484 | 155k | ) { |
2485 | 15.0k | return(1); |
2486 | 15.0k | } |
2487 | | |
2488 | 140k | return(0); |
2489 | 155k | } |
2490 | | |
2491 | | static void |
2492 | 10.4k | xmllintInit(xmllintState *lint) { |
2493 | 10.4k | memset(lint, 0, sizeof(*lint)); |
2494 | | |
2495 | 10.4k | lint->repeat = 1; |
2496 | 10.4k | lint->progresult = XMLLINT_RETURN_OK; |
2497 | 10.4k | lint->parseOptions = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES; |
2498 | 10.4k | #ifdef LIBXML_HTML_ENABLED |
2499 | 10.4k | lint->htmlOptions = HTML_PARSE_COMPACT | HTML_PARSE_BIG_LINES; |
2500 | 10.4k | #endif |
2501 | 10.4k | } |
2502 | | |
2503 | | static void |
2504 | 27.1k | xmllintOptWarnNoSupport(FILE *errStream, const char *opt, const char *nosupp) { |
2505 | 27.1k | fprintf(errStream, "Warning: Option %s doesn't support %s\n", opt, nosupp); |
2506 | 27.1k | } |
2507 | | |
2508 | | static int |
2509 | 10.4k | xmllintParseOptions(xmllintState *lint, int argc, const char **argv) { |
2510 | 10.4k | FILE *errStream = lint->errStream; |
2511 | 10.4k | const char *specialMode = NULL; |
2512 | 10.4k | int i; |
2513 | | |
2514 | 10.4k | if (argc <= 1) { |
2515 | 0 | usage(errStream, argv[0]); |
2516 | 0 | return(XMLLINT_ERR_UNCLASS); |
2517 | 0 | } |
2518 | | |
2519 | 186k | for (i = 1; i < argc ; i++) { |
2520 | 176k | unsigned long val; |
2521 | | |
2522 | 176k | if (argv[i][0] != '-' || argv[i][1] == 0) |
2523 | 10.3k | continue; |
2524 | | |
2525 | 165k | if ((!strcmp(argv[i], "-maxmem")) || |
2526 | 165k | (!strcmp(argv[i], "--maxmem"))) { |
2527 | 330 | i++; |
2528 | 330 | if (i >= argc) { |
2529 | 0 | fprintf(errStream, "maxmem: missing integer value\n"); |
2530 | 0 | return(XMLLINT_ERR_UNCLASS); |
2531 | 0 | } |
2532 | 330 | if (parseInteger(&val, errStream, "maxmem", argv[i], |
2533 | 330 | 0, INT_MAX) < 0) |
2534 | 0 | return(XMLLINT_ERR_UNCLASS); |
2535 | 330 | lint->maxmem = val; |
2536 | 165k | } else if ((!strcmp(argv[i], "-debug")) || |
2537 | 165k | (!strcmp(argv[i], "--debug"))) { |
2538 | 3.48k | lint->appOptions |= XML_LINT_DEBUG_ENABLED; |
2539 | 161k | } else if ((!strcmp(argv[i], "-shell")) || |
2540 | 161k | (!strcmp(argv[i], "--shell"))) { |
2541 | 0 | lint->appOptions |= XML_LINT_NAVIGATING_SHELL; |
2542 | 161k | } else if ((!strcmp(argv[i], "-copy")) || |
2543 | 161k | (!strcmp(argv[i], "--copy"))) { |
2544 | 2.92k | lint->appOptions |= XML_LINT_COPY_ENABLED; |
2545 | 159k | } else if ((!strcmp(argv[i], "-recover")) || |
2546 | 159k | (!strcmp(argv[i], "--recover"))) { |
2547 | 1.94k | lint->parseOptions |= XML_PARSE_RECOVER; |
2548 | 157k | } else if ((!strcmp(argv[i], "-huge")) || |
2549 | 157k | (!strcmp(argv[i], "--huge"))) { |
2550 | 3.68k | lint->parseOptions |= XML_PARSE_HUGE; |
2551 | 3.68k | #ifdef LIBXML_HTML_ENABLED |
2552 | 3.68k | lint->htmlOptions |= HTML_PARSE_HUGE; |
2553 | 3.68k | #endif |
2554 | 153k | } else if ((!strcmp(argv[i], "-noent")) || |
2555 | 153k | (!strcmp(argv[i], "--noent"))) { |
2556 | 1.76k | lint->parseOptions |= XML_PARSE_NOENT; |
2557 | 151k | } else if ((!strcmp(argv[i], "-noenc")) || |
2558 | 151k | (!strcmp(argv[i], "--noenc"))) { |
2559 | 2.56k | lint->parseOptions |= XML_PARSE_IGNORE_ENC; |
2560 | 2.56k | #ifdef LIBXML_HTML_ENABLED |
2561 | 2.56k | lint->htmlOptions |= HTML_PARSE_IGNORE_ENC; |
2562 | 2.56k | #endif |
2563 | 149k | } else if ((!strcmp(argv[i], "-nsclean")) || |
2564 | 149k | (!strcmp(argv[i], "--nsclean"))) { |
2565 | 4.02k | lint->parseOptions |= XML_PARSE_NSCLEAN; |
2566 | 145k | } else if ((!strcmp(argv[i], "-nocdata")) || |
2567 | 145k | (!strcmp(argv[i], "--nocdata"))) { |
2568 | 4.29k | lint->parseOptions |= XML_PARSE_NOCDATA; |
2569 | 140k | } else if ((!strcmp(argv[i], "-nodict")) || |
2570 | 140k | (!strcmp(argv[i], "--nodict"))) { |
2571 | 3.68k | lint->parseOptions |= XML_PARSE_NODICT; |
2572 | 137k | } else if ((!strcmp(argv[i], "-version")) || |
2573 | 137k | (!strcmp(argv[i], "--version"))) { |
2574 | 2.69k | showVersion(errStream, argv[0]); |
2575 | 2.69k | lint->version = 1; |
2576 | 134k | } else if ((!strcmp(argv[i], "-noout")) || |
2577 | 134k | (!strcmp(argv[i], "--noout"))) { |
2578 | 4.27k | lint->noout = 1; |
2579 | 4.27k | #ifdef LIBXML_HTML_ENABLED |
2580 | 130k | } else if ((!strcmp(argv[i], "-html")) || |
2581 | 130k | (!strcmp(argv[i], "--html"))) { |
2582 | 1.21k | lint->appOptions |= XML_LINT_HTML_ENABLED; |
2583 | 128k | } else if ((!strcmp(argv[i], "-nodefdtd")) || |
2584 | 128k | (!strcmp(argv[i], "--nodefdtd"))) { |
2585 | 2.50k | lint->htmlOptions |= HTML_PARSE_NODEFDTD; |
2586 | 2.50k | #ifdef LIBXML_OUTPUT_ENABLED |
2587 | 126k | } else if ((!strcmp(argv[i], "-xmlout")) || |
2588 | 126k | (!strcmp(argv[i], "--xmlout"))) { |
2589 | 2.46k | lint->appOptions |= XML_LINT_XML_OUT; |
2590 | 2.46k | #endif |
2591 | 2.46k | #endif /* LIBXML_HTML_ENABLED */ |
2592 | 123k | } else if ((!strcmp(argv[i], "-loaddtd")) || |
2593 | 123k | (!strcmp(argv[i], "--loaddtd"))) { |
2594 | 2.97k | lint->parseOptions |= XML_PARSE_DTDLOAD; |
2595 | 120k | } else if ((!strcmp(argv[i], "-dtdattr")) || |
2596 | 120k | (!strcmp(argv[i], "--dtdattr"))) { |
2597 | 4.77k | lint->parseOptions |= XML_PARSE_DTDATTR; |
2598 | 4.77k | #ifdef LIBXML_VALID_ENABLED |
2599 | 116k | } else if ((!strcmp(argv[i], "-valid")) || |
2600 | 116k | (!strcmp(argv[i], "--valid"))) { |
2601 | 2.61k | lint->parseOptions |= XML_PARSE_DTDVALID; |
2602 | 113k | } else if ((!strcmp(argv[i], "-postvalid")) || |
2603 | 113k | (!strcmp(argv[i], "--postvalid"))) { |
2604 | 1.80k | lint->appOptions |= XML_LINT_POST_VALIDATION; |
2605 | 1.80k | lint->parseOptions |= XML_PARSE_DTDLOAD; |
2606 | 111k | } else if ((!strcmp(argv[i], "-dtdvalid")) || |
2607 | 111k | (!strcmp(argv[i], "--dtdvalid"))) { |
2608 | 0 | i++; |
2609 | 0 | lint->dtdvalid = argv[i]; |
2610 | 0 | lint->parseOptions |= XML_PARSE_DTDLOAD; |
2611 | 111k | } else if ((!strcmp(argv[i], "-dtdvalidfpi")) || |
2612 | 111k | (!strcmp(argv[i], "--dtdvalidfpi"))) { |
2613 | 0 | i++; |
2614 | 0 | lint->dtdvalidfpi = argv[i]; |
2615 | 0 | lint->parseOptions |= XML_PARSE_DTDLOAD; |
2616 | 111k | } else if ((!strcmp(argv[i], "-insert")) || |
2617 | 111k | (!strcmp(argv[i], "--insert"))) { |
2618 | 5.89k | lint->appOptions |= XML_LINT_VALID_INSERTIONS; |
2619 | 5.89k | #endif /* LIBXML_VALID_ENABLED */ |
2620 | 105k | } else if ((!strcmp(argv[i], "-strict-namespace")) || |
2621 | 105k | (!strcmp(argv[i], "--strict-namespace"))) { |
2622 | 0 | lint->appOptions |= XML_LINT_STRICT_NAMESPACE; |
2623 | 105k | } else if ((!strcmp(argv[i], "-dropdtd")) || |
2624 | 105k | (!strcmp(argv[i], "--dropdtd"))) { |
2625 | 1.47k | lint->appOptions |= XML_LINT_DROP_DTD; |
2626 | 104k | } else if ((!strcmp(argv[i], "-quiet")) || |
2627 | 104k | (!strcmp(argv[i], "--quiet"))) { |
2628 | 1.65k | lint->appOptions |= XML_LINT_QUIET; |
2629 | 102k | } else if ((!strcmp(argv[i], "-timing")) || |
2630 | 102k | (!strcmp(argv[i], "--timing"))) { |
2631 | 2.65k | lint->appOptions |= XML_LINT_TIMINGS; |
2632 | 100k | } else if ((!strcmp(argv[i], "-auto")) || |
2633 | 100k | (!strcmp(argv[i], "--auto"))) { |
2634 | 9.69k | lint->appOptions |= XML_LINT_GENERATE; |
2635 | 90.3k | } else if ((!strcmp(argv[i], "-repeat")) || |
2636 | 90.3k | (!strcmp(argv[i], "--repeat"))) { |
2637 | 1.10k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
2638 | 1.10k | lint->repeat = 2; |
2639 | | #else |
2640 | | if (lint->repeat > 1) |
2641 | | lint->repeat *= 10; |
2642 | | else |
2643 | | lint->repeat = 100; |
2644 | | #endif |
2645 | 1.10k | #ifdef LIBXML_PUSH_ENABLED |
2646 | 89.2k | } else if ((!strcmp(argv[i], "-push")) || |
2647 | 89.2k | (!strcmp(argv[i], "--push"))) { |
2648 | 517 | lint->appOptions |= XML_LINT_PUSH_ENABLED; |
2649 | 517 | #endif /* LIBXML_PUSH_ENABLED */ |
2650 | 517 | #if HAVE_DECL_MMAP |
2651 | 88.7k | } else if ((!strcmp(argv[i], "-memory")) || |
2652 | 88.7k | (!strcmp(argv[i], "--memory"))) { |
2653 | 0 | lint->appOptions |= XML_LINT_MEMORY; |
2654 | 0 | #endif |
2655 | 0 | #ifdef LIBXML_XINCLUDE_ENABLED |
2656 | 88.7k | } else if ((!strcmp(argv[i], "-xinclude")) || |
2657 | 88.7k | (!strcmp(argv[i], "--xinclude"))) { |
2658 | 3.42k | lint->appOptions |= XML_LINT_XINCLUDE; |
2659 | 3.42k | lint->parseOptions |= XML_PARSE_XINCLUDE; |
2660 | 85.3k | } else if ((!strcmp(argv[i], "-noxincludenode")) || |
2661 | 85.3k | (!strcmp(argv[i], "--noxincludenode"))) { |
2662 | 5.35k | lint->appOptions |= XML_LINT_XINCLUDE; |
2663 | 5.35k | lint->parseOptions |= XML_PARSE_XINCLUDE; |
2664 | 5.35k | lint->parseOptions |= XML_PARSE_NOXINCNODE; |
2665 | 79.9k | } else if ((!strcmp(argv[i], "-nofixup-base-uris")) || |
2666 | 79.9k | (!strcmp(argv[i], "--nofixup-base-uris"))) { |
2667 | 3.50k | lint->appOptions |= XML_LINT_XINCLUDE; |
2668 | 3.50k | lint->parseOptions |= XML_PARSE_XINCLUDE; |
2669 | 3.50k | lint->parseOptions |= XML_PARSE_NOBASEFIX; |
2670 | 3.50k | #endif |
2671 | 76.4k | } else if ((!strcmp(argv[i], "-nowarning")) || |
2672 | 76.4k | (!strcmp(argv[i], "--nowarning"))) { |
2673 | 5.01k | lint->parseOptions |= XML_PARSE_NOWARNING; |
2674 | 5.01k | lint->parseOptions &= ~XML_PARSE_PEDANTIC; |
2675 | 5.01k | #ifdef LIBXML_HTML_ENABLED |
2676 | 5.01k | lint->htmlOptions |= HTML_PARSE_NOWARNING; |
2677 | 5.01k | #endif |
2678 | 71.4k | } else if ((!strcmp(argv[i], "-pedantic")) || |
2679 | 71.4k | (!strcmp(argv[i], "--pedantic"))) { |
2680 | 1.62k | lint->parseOptions |= XML_PARSE_PEDANTIC; |
2681 | 1.62k | lint->parseOptions &= ~XML_PARSE_NOWARNING; |
2682 | 1.62k | #ifdef LIBXML_CATALOG_ENABLED |
2683 | 69.8k | } else if ((!strcmp(argv[i], "-catalogs")) || |
2684 | 69.8k | (!strcmp(argv[i], "--catalogs"))) { |
2685 | 0 | lint->appOptions |= XML_LINT_USE_CATALOGS; |
2686 | 69.8k | } else if ((!strcmp(argv[i], "-nocatalogs")) || |
2687 | 69.8k | (!strcmp(argv[i], "--nocatalogs"))) { |
2688 | 10.4k | lint->appOptions |= XML_LINT_USE_NO_CATALOGS; |
2689 | 10.4k | lint->parseOptions |= XML_PARSE_NO_SYS_CATALOG; |
2690 | 10.4k | #endif |
2691 | 59.3k | } else if ((!strcmp(argv[i], "-noblanks")) || |
2692 | 59.3k | (!strcmp(argv[i], "--noblanks"))) { |
2693 | 3.08k | lint->parseOptions |= XML_PARSE_NOBLANKS; |
2694 | 3.08k | #ifdef LIBXML_HTML_ENABLED |
2695 | 3.08k | lint->htmlOptions |= HTML_PARSE_NOBLANKS; |
2696 | 3.08k | #endif |
2697 | 3.08k | #ifdef LIBXML_OUTPUT_ENABLED |
2698 | 56.2k | } else if ((!strcmp(argv[i], "-o")) || |
2699 | 56.2k | (!strcmp(argv[i], "-output")) || |
2700 | 56.2k | (!strcmp(argv[i], "--output"))) { |
2701 | 0 | i++; |
2702 | 0 | lint->output = argv[i]; |
2703 | 56.2k | } else if ((!strcmp(argv[i], "-format")) || |
2704 | 56.2k | (!strcmp(argv[i], "--format"))) { |
2705 | 5.63k | lint->format = 1; |
2706 | 5.63k | lint->parseOptions |= XML_PARSE_NOBLANKS; |
2707 | 5.63k | #ifdef LIBXML_HTML_ENABLED |
2708 | 5.63k | lint->htmlOptions |= HTML_PARSE_NOBLANKS; |
2709 | 5.63k | #endif |
2710 | 50.6k | } else if ((!strcmp(argv[i], "-encode")) || |
2711 | 50.6k | (!strcmp(argv[i], "--encode"))) { |
2712 | 1.08k | i++; |
2713 | 1.08k | lint->encoding = argv[i]; |
2714 | 49.5k | } else if ((!strcmp(argv[i], "-pretty")) || |
2715 | 49.5k | (!strcmp(argv[i], "--pretty"))) { |
2716 | 3.78k | i++; |
2717 | 3.78k | if (i >= argc) { |
2718 | 0 | fprintf(errStream, "pretty: missing integer value\n"); |
2719 | 0 | return(XMLLINT_ERR_UNCLASS); |
2720 | 0 | } |
2721 | 3.78k | if (parseInteger(&val, errStream, "pretty", argv[i], |
2722 | 3.78k | 0, 2) < 0) |
2723 | 16 | return(XMLLINT_ERR_UNCLASS); |
2724 | 3.77k | lint->format = val; |
2725 | 3.77k | #ifdef LIBXML_ZLIB_ENABLED |
2726 | 45.7k | } else if ((!strcmp(argv[i], "-compress")) || |
2727 | 45.7k | (!strcmp(argv[i], "--compress"))) { |
2728 | 2.21k | lint->appOptions |= XML_LINT_ZLIB_COMPRESSION; |
2729 | 2.21k | #endif |
2730 | 2.21k | #ifdef LIBXML_C14N_ENABLED |
2731 | 43.5k | } else if ((!strcmp(argv[i], "-c14n")) || |
2732 | 43.5k | (!strcmp(argv[i], "--c14n"))) { |
2733 | 2.85k | lint->appOptions |= XML_LINT_CANONICAL_V1_0; |
2734 | 2.85k | lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; |
2735 | 40.7k | } else if ((!strcmp(argv[i], "-c14n11")) || |
2736 | 40.7k | (!strcmp(argv[i], "--c14n11"))) { |
2737 | 5.68k | lint->appOptions |= XML_LINT_CANONICAL_V1_1; |
2738 | 5.68k | lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; |
2739 | 35.0k | } else if ((!strcmp(argv[i], "-exc-c14n")) || |
2740 | 35.0k | (!strcmp(argv[i], "--exc-c14n"))) { |
2741 | 3.20k | lint->appOptions |= XML_LINT_CANONICAL_EXE; |
2742 | 3.20k | lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; |
2743 | 3.20k | #endif /* LIBXML_C14N_ENABLED */ |
2744 | 3.20k | #endif /* LIBXML_OUTPUT_ENABLED */ |
2745 | 3.20k | #ifdef LIBXML_READER_ENABLED |
2746 | 31.8k | } else if ((!strcmp(argv[i], "-stream")) || |
2747 | 31.8k | (!strcmp(argv[i], "--stream"))) { |
2748 | 2.88k | lint->appOptions |= XML_LINT_USE_STREAMING; |
2749 | 28.9k | } else if ((!strcmp(argv[i], "-walker")) || |
2750 | 28.9k | (!strcmp(argv[i], "--walker"))) { |
2751 | 3.04k | lint->appOptions |= XML_LINT_USE_WALKER; |
2752 | 3.04k | lint->noout = 1; |
2753 | 3.04k | #ifdef LIBXML_PATTERN_ENABLED |
2754 | 25.8k | } else if ((!strcmp(argv[i], "-pattern")) || |
2755 | 25.8k | (!strcmp(argv[i], "--pattern"))) { |
2756 | 1.76k | i++; |
2757 | 1.76k | lint->pattern = argv[i]; |
2758 | 1.76k | #endif |
2759 | 1.76k | #endif /* LIBXML_READER_ENABLED */ |
2760 | 1.76k | #ifdef LIBXML_SAX1_ENABLED |
2761 | 24.1k | } else if ((!strcmp(argv[i], "-sax1")) || |
2762 | 24.1k | (!strcmp(argv[i], "--sax1"))) { |
2763 | 553 | lint->parseOptions |= XML_PARSE_SAX1; |
2764 | 553 | #endif /* LIBXML_SAX1_ENABLED */ |
2765 | 23.5k | } else if ((!strcmp(argv[i], "-sax")) || |
2766 | 23.5k | (!strcmp(argv[i], "--sax"))) { |
2767 | 576 | lint->appOptions |= XML_LINT_SAX_ENABLED; |
2768 | 576 | #ifdef LIBXML_RELAXNG_ENABLED |
2769 | 23.0k | } else if ((!strcmp(argv[i], "-relaxng")) || |
2770 | 23.0k | (!strcmp(argv[i], "--relaxng"))) { |
2771 | 0 | i++; |
2772 | 0 | lint->relaxng = argv[i]; |
2773 | 0 | lint->parseOptions |= XML_PARSE_NOENT; |
2774 | 0 | #endif |
2775 | 0 | #ifdef LIBXML_SCHEMAS_ENABLED |
2776 | 23.0k | } else if ((!strcmp(argv[i], "-schema")) || |
2777 | 23.0k | (!strcmp(argv[i], "--schema"))) { |
2778 | 0 | i++; |
2779 | 0 | lint->schema = argv[i]; |
2780 | 0 | lint->parseOptions |= XML_PARSE_NOENT; |
2781 | 0 | #endif |
2782 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
2783 | | } else if ((!strcmp(argv[i], "-schematron")) || |
2784 | | (!strcmp(argv[i], "--schematron"))) { |
2785 | | i++; |
2786 | | lint->schematron = argv[i]; |
2787 | | lint->parseOptions |= XML_PARSE_NOENT; |
2788 | | #endif |
2789 | 23.0k | } else if ((!strcmp(argv[i], "-nonet")) || |
2790 | 23.0k | (!strcmp(argv[i], "--nonet"))) { |
2791 | 2.70k | lint->parseOptions |= XML_PARSE_NONET; |
2792 | 20.2k | } else if ((!strcmp(argv[i], "-nocompact")) || |
2793 | 20.2k | (!strcmp(argv[i], "--nocompact"))) { |
2794 | 3.47k | lint->parseOptions &= ~XML_PARSE_COMPACT; |
2795 | 3.47k | #ifdef LIBXML_HTML_ENABLED |
2796 | 3.47k | lint->htmlOptions &= ~HTML_PARSE_COMPACT; |
2797 | 3.47k | #endif |
2798 | 16.8k | } else if ((!strcmp(argv[i], "-load-trace")) || |
2799 | 16.8k | (!strcmp(argv[i], "--load-trace"))) { |
2800 | 3.57k | lint->appOptions |= XML_LINT_USE_LOAD_TRACE; |
2801 | 13.2k | } else if ((!strcmp(argv[i], "-path")) || |
2802 | 13.2k | (!strcmp(argv[i], "--path"))) { |
2803 | 0 | i++; |
2804 | 0 | parsePath(lint, BAD_CAST argv[i]); |
2805 | 0 | #ifdef LIBXML_XPATH_ENABLED |
2806 | 13.2k | } else if ((!strcmp(argv[i], "-xpath")) || |
2807 | 13.2k | (!strcmp(argv[i], "--xpath"))) { |
2808 | 8.51k | i++; |
2809 | 8.51k | lint->noout++; |
2810 | 8.51k | lint->xpathquery = argv[i]; |
2811 | 8.51k | #endif |
2812 | 8.51k | } else if ((!strcmp(argv[i], "-oldxml10")) || |
2813 | 4.74k | (!strcmp(argv[i], "--oldxml10"))) { |
2814 | 3.73k | lint->parseOptions |= XML_PARSE_OLD10; |
2815 | 3.73k | } else if ((!strcmp(argv[i], "-max-ampl")) || |
2816 | 1.00k | (!strcmp(argv[i], "--max-ampl"))) { |
2817 | 879 | i++; |
2818 | 879 | if (i >= argc) { |
2819 | 0 | fprintf(errStream, "max-ampl: missing integer value\n"); |
2820 | 0 | return(XMLLINT_ERR_UNCLASS); |
2821 | 0 | } |
2822 | 879 | if (parseInteger(&val, errStream, "max-ampl", argv[i], |
2823 | 879 | 1, UINT_MAX) < 0) |
2824 | 0 | return(XMLLINT_ERR_UNCLASS); |
2825 | 879 | lint->maxAmpl = val; |
2826 | 879 | } else { |
2827 | 130 | fprintf(errStream, "Unknown option %s\n", argv[i]); |
2828 | 130 | usage(errStream, argv[0]); |
2829 | 130 | return(XMLLINT_ERR_UNCLASS); |
2830 | 130 | } |
2831 | 165k | } |
2832 | | |
2833 | 10.3k | if (lint->appOptions & XML_LINT_NAVIGATING_SHELL) |
2834 | 0 | lint->repeat = 1; |
2835 | | |
2836 | 10.3k | #ifdef LIBXML_READER_ENABLED |
2837 | 10.3k | if (lint->appOptions & XML_LINT_USE_STREAMING) { |
2838 | 2.87k | specialMode = "--stream"; |
2839 | | |
2840 | 2.87k | if (lint->appOptions & XML_LINT_SAX_ENABLED) |
2841 | 0 | xmllintOptWarnNoSupport(errStream, "--stream", "--sax"); |
2842 | 2.87k | #ifdef LIBXML_PUSH_ENABLED |
2843 | 2.87k | if (lint->appOptions & XML_LINT_PUSH_ENABLED) |
2844 | 378 | xmllintOptWarnNoSupport(errStream, "--stream", "--push"); |
2845 | 2.87k | #endif |
2846 | 2.87k | #ifdef LIBXML_HTML_ENABLED |
2847 | 2.87k | if (lint->appOptions & XML_LINT_HTML_ENABLED) |
2848 | 0 | xmllintOptWarnNoSupport(errStream, "--stream", "--html"); |
2849 | 2.87k | #endif |
2850 | 2.87k | } |
2851 | 10.3k | #endif /* LIBXML_READER_ENABLED */ |
2852 | | |
2853 | 10.3k | if (lint->appOptions & XML_LINT_SAX_ENABLED) { |
2854 | 575 | specialMode = "--sax"; |
2855 | | |
2856 | 575 | #ifdef LIBXML_XINCLUDE_ENABLED |
2857 | 575 | if (lint->appOptions & XML_LINT_XINCLUDE) |
2858 | 504 | xmllintOptWarnNoSupport(errStream, "--sax", "--xinclude"); |
2859 | 575 | #endif |
2860 | 575 | #ifdef LIBXML_RELAXNG_ENABLED |
2861 | 575 | if (lint->relaxng != NULL) |
2862 | 0 | xmllintOptWarnNoSupport(errStream, "--sax", "--relaxng"); |
2863 | 575 | #endif |
2864 | 575 | } |
2865 | | |
2866 | 10.3k | if (specialMode != NULL) { |
2867 | 3.45k | if (lint->appOptions & XML_LINT_GENERATE) |
2868 | 3.29k | xmllintOptWarnNoSupport(errStream, specialMode, "--auto"); |
2869 | 3.45k | if (lint->appOptions & XML_LINT_DROP_DTD) |
2870 | 516 | xmllintOptWarnNoSupport(errStream, specialMode, "--dropdtd"); |
2871 | 3.45k | if (lint->appOptions & XML_LINT_NAVIGATING_SHELL) |
2872 | 0 | xmllintOptWarnNoSupport(errStream, specialMode, "--shell"); |
2873 | 3.45k | if (lint->appOptions & XML_LINT_COPY_ENABLED) |
2874 | 1.12k | xmllintOptWarnNoSupport(errStream, specialMode, "--copy"); |
2875 | 3.45k | #ifdef LIBXML_XPATH_ENABLED |
2876 | 3.45k | if (lint->xpathquery != NULL) |
2877 | 2.85k | xmllintOptWarnNoSupport(errStream, specialMode, "--xpath"); |
2878 | 3.45k | #endif |
2879 | 3.45k | #ifdef LIBXML_READER_ENABLED |
2880 | 3.45k | if (lint->appOptions & XML_LINT_USE_WALKER) |
2881 | 1.41k | xmllintOptWarnNoSupport(errStream, specialMode, "--walker"); |
2882 | 3.45k | #endif |
2883 | 3.45k | #ifdef LIBXML_VALID_ENABLED |
2884 | 3.45k | if (lint->appOptions & XML_LINT_VALID_INSERTIONS) |
2885 | 1.84k | xmllintOptWarnNoSupport(errStream, specialMode, "--insert"); |
2886 | 3.45k | if (lint->dtdvalid != NULL) |
2887 | 0 | xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalid"); |
2888 | 3.45k | if (lint->dtdvalidfpi != NULL) |
2889 | 0 | xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalidfpi"); |
2890 | 3.45k | if (lint->appOptions & XML_LINT_POST_VALIDATION) |
2891 | 700 | xmllintOptWarnNoSupport(errStream, specialMode, "--postvalid"); |
2892 | 3.45k | #endif |
2893 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
2894 | | if (lint->schematron != NULL) |
2895 | | xmllintOptWarnNoSupport(errStream, specialMode, "--schematron"); |
2896 | | #endif |
2897 | 3.45k | #ifdef LIBXML_OUTPUT_ENABLED |
2898 | 3.45k | if (lint->output != NULL) |
2899 | 0 | xmllintOptWarnNoSupport(errStream, specialMode, "--output"); |
2900 | 3.45k | if (lint->encoding != NULL) |
2901 | 338 | xmllintOptWarnNoSupport(errStream, specialMode, "--encode"); |
2902 | 3.45k | if (lint->format > 0) |
2903 | 1.89k | xmllintOptWarnNoSupport(errStream, specialMode, |
2904 | 1.89k | "--format or -pretty"); |
2905 | 3.45k | #ifdef LIBXML_ZLIB_ENABLED |
2906 | 3.45k | if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) |
2907 | 708 | xmllintOptWarnNoSupport(errStream, specialMode, "--compress"); |
2908 | 3.45k | #endif |
2909 | 3.45k | #ifdef LIBXML_HTML_ENABLED |
2910 | 3.45k | if (lint->appOptions & XML_LINT_XML_OUT) |
2911 | 1.06k | xmllintOptWarnNoSupport(errStream, specialMode, "--xmlout"); |
2912 | 3.45k | #endif |
2913 | 3.45k | #ifdef LIBXML_C14N_ENABLED |
2914 | 3.45k | if (lint->appOptions & XML_LINT_CANONICAL_V1_0) |
2915 | 1.00k | xmllintOptWarnNoSupport(errStream, specialMode, "--c14n"); |
2916 | 3.45k | if (lint->appOptions & XML_LINT_CANONICAL_V1_1) |
2917 | 1.76k | xmllintOptWarnNoSupport(errStream, specialMode, "--c14n11"); |
2918 | 3.45k | if (lint->appOptions & XML_LINT_CANONICAL_EXE) |
2919 | 1.07k | xmllintOptWarnNoSupport(errStream, specialMode, "--exc-c14n"); |
2920 | 3.45k | #endif |
2921 | 3.45k | #endif /* LIBXML_OUTPUT_ENABLED */ |
2922 | 3.45k | } |
2923 | | |
2924 | 10.3k | #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED) |
2925 | 10.3k | if (lint->pattern && !((lint->appOptions & XML_LINT_USE_STREAMING) || (lint->appOptions & XML_LINT_USE_WALKER))) |
2926 | 741 | fprintf(errStream, "Warning: Option %s requires %s\n", |
2927 | 741 | "--pattern", "--stream or --walker"); |
2928 | 10.3k | #endif |
2929 | | |
2930 | 10.3k | #ifdef LIBXML_HTML_ENABLED |
2931 | 10.3k | if (lint->appOptions & XML_LINT_HTML_ENABLED) { |
2932 | 1.21k | if (lint->parseOptions & XML_PARSE_DTDATTR) |
2933 | 1.12k | xmllintOptWarnNoSupport(errStream, "--html", "--dtdattr"); |
2934 | 1.21k | if (lint->parseOptions & XML_PARSE_DTDLOAD) |
2935 | 1.09k | xmllintOptWarnNoSupport(errStream, "--html", "--loaddtd"); |
2936 | 1.21k | if (lint->maxAmpl) |
2937 | 176 | xmllintOptWarnNoSupport(errStream, "--html", "--max-ampl"); |
2938 | 1.21k | if (lint->parseOptions & XML_PARSE_NOCDATA) |
2939 | 696 | xmllintOptWarnNoSupport(errStream, "--html", "--nocdata"); |
2940 | 1.21k | if (lint->parseOptions & XML_PARSE_NODICT) |
2941 | 382 | xmllintOptWarnNoSupport(errStream, "--html", "--nodict"); |
2942 | 1.21k | if (lint->parseOptions & XML_PARSE_NOENT) |
2943 | 1.07k | xmllintOptWarnNoSupport(errStream, "--html", "--noent"); |
2944 | 1.21k | if (lint->parseOptions & XML_PARSE_NONET) |
2945 | 412 | xmllintOptWarnNoSupport(errStream, "--html", "--nonet"); |
2946 | 1.21k | if (lint->parseOptions & XML_PARSE_NSCLEAN) |
2947 | 380 | xmllintOptWarnNoSupport(errStream, "--html", "--nsclean"); |
2948 | 1.21k | if (lint->parseOptions & XML_PARSE_OLD10) |
2949 | 378 | xmllintOptWarnNoSupport(errStream, "--html", "--oldxml10"); |
2950 | 1.21k | if (lint->parseOptions & XML_PARSE_PEDANTIC) |
2951 | 152 | xmllintOptWarnNoSupport(errStream, "--html", "--pedantic"); |
2952 | 1.21k | if (lint->parseOptions & XML_PARSE_DTDVALID) |
2953 | 708 | xmllintOptWarnNoSupport(errStream, "--html", "--valid"); |
2954 | 1.21k | if (lint->parseOptions & XML_PARSE_SAX1) |
2955 | 76 | xmllintOptWarnNoSupport(errStream, "--html", "--sax1"); |
2956 | 9.09k | } else { |
2957 | 9.09k | if (lint->htmlOptions & HTML_PARSE_NODEFDTD) |
2958 | 2.15k | fprintf(errStream, "Warning: Option %s requires %s\n", |
2959 | 2.15k | "--nodefdtd", "--html"); |
2960 | 9.09k | #ifdef LIBXML_OUTPUT_ENABLED |
2961 | 9.09k | if (lint->appOptions & XML_LINT_XML_OUT) |
2962 | 1.72k | fprintf(errStream, "Warning: Option %s requires %s\n", |
2963 | 1.72k | "--xmlout", "--html"); |
2964 | 9.09k | #endif |
2965 | 9.09k | } |
2966 | 10.3k | #endif |
2967 | | |
2968 | 10.3k | return(XMLLINT_RETURN_OK); |
2969 | 10.4k | } |
2970 | | |
2971 | | int |
2972 | | xmllintMain(int argc, const char **argv, FILE *errStream, |
2973 | 10.4k | xmlResourceLoader loader) { |
2974 | 10.4k | xmllintState state, *lint; |
2975 | 10.4k | int i, j, res; |
2976 | 10.4k | int files = 0; |
2977 | | |
2978 | | #ifdef _WIN32 |
2979 | | _setmode(_fileno(stdin), _O_BINARY); |
2980 | | _setmode(_fileno(stdout), _O_BINARY); |
2981 | | _setmode(_fileno(stderr), _O_BINARY); |
2982 | | #endif |
2983 | | |
2984 | 10.4k | lint = &state; |
2985 | 10.4k | xmllintInit(lint); |
2986 | 10.4k | lint->errStream = errStream; |
2987 | 10.4k | lint->defaultResourceLoader = loader; |
2988 | | |
2989 | 10.4k | res = xmllintParseOptions(lint, argc, argv); |
2990 | 10.4k | if (res != XMLLINT_RETURN_OK) { |
2991 | 146 | return(res); |
2992 | 146 | } |
2993 | | |
2994 | | /* |
2995 | | * Note that we must not make any memory allocations through xmlMalloc |
2996 | | * before calling xmlMemSetup. |
2997 | | */ |
2998 | 10.3k | if (lint->maxmem != 0) { |
2999 | 298 | xmllintMaxmem = 0; |
3000 | 298 | xmllintMaxmemReached = 0; |
3001 | 298 | xmllintOom = 0; |
3002 | 298 | xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc); |
3003 | 298 | } |
3004 | | |
3005 | 10.3k | LIBXML_TEST_VERSION |
3006 | | |
3007 | 10.3k | #ifdef LIBXML_CATALOG_ENABLED |
3008 | 10.3k | if ((lint->appOptions & XML_LINT_USE_NO_CATALOGS) != XML_LINT_USE_NO_CATALOGS) { |
3009 | 0 | if (lint->appOptions & XML_LINT_USE_CATALOGS) { |
3010 | 0 | const char *catal; |
3011 | |
|
3012 | 0 | catal = getenv("SGML_CATALOG_FILES"); |
3013 | 0 | if (catal != NULL) { |
3014 | 0 | xmlLoadCatalogs(catal); |
3015 | 0 | } else { |
3016 | 0 | fprintf(errStream, "Variable $SGML_CATALOG_FILES not set\n"); |
3017 | 0 | } |
3018 | 0 | } |
3019 | 0 | } |
3020 | 10.3k | #endif |
3021 | | |
3022 | 10.3k | #ifdef LIBXML_OUTPUT_ENABLED |
3023 | 10.3k | { |
3024 | 10.3k | const char *indent = getenv("XMLLINT_INDENT"); |
3025 | 10.3k | if (indent != NULL) { |
3026 | 0 | lint->indentString = indent; |
3027 | 0 | } |
3028 | 10.3k | } |
3029 | 10.3k | #endif |
3030 | | |
3031 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
3032 | | if ((lint->schematron != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED) |
3033 | | #ifdef LIBXML_READER_ENABLED |
3034 | | && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING) |
3035 | | #endif /* LIBXML_READER_ENABLED */ |
3036 | | ) { |
3037 | | xmlSchematronParserCtxtPtr ctxt; |
3038 | | |
3039 | | /* forces loading the DTDs */ |
3040 | | lint->parseOptions |= XML_PARSE_DTDLOAD; |
3041 | | if (lint->appOptions & XML_LINT_TIMINGS) { |
3042 | | startTimer(lint); |
3043 | | } |
3044 | | ctxt = xmlSchematronNewParserCtxt(lint->schematron); |
3045 | | if (ctxt == NULL) { |
3046 | | lint->progresult = XMLLINT_ERR_MEM; |
3047 | | goto error; |
3048 | | } |
3049 | | lint->wxschematron = xmlSchematronParse(ctxt); |
3050 | | xmlSchematronFreeParserCtxt(ctxt); |
3051 | | if (lint->wxschematron == NULL) { |
3052 | | fprintf(errStream, "Schematron schema %s failed to compile\n", |
3053 | | lint->schematron); |
3054 | | lint->progresult = XMLLINT_ERR_SCHEMACOMP; |
3055 | | goto error; |
3056 | | } |
3057 | | if (lint->appOptions & XML_LINT_TIMINGS) { |
3058 | | endTimer(lint, "Compiling the schemas"); |
3059 | | } |
3060 | | } |
3061 | | #endif |
3062 | | |
3063 | 10.3k | #ifdef LIBXML_RELAXNG_ENABLED |
3064 | 10.3k | if ((lint->relaxng != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED) |
3065 | 10.3k | #ifdef LIBXML_READER_ENABLED |
3066 | 10.3k | && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING) |
3067 | 10.3k | #endif /* LIBXML_READER_ENABLED */ |
3068 | 10.3k | ) { |
3069 | 0 | xmlRelaxNGParserCtxtPtr ctxt; |
3070 | | |
3071 | | /* forces loading the DTDs */ |
3072 | 0 | lint->parseOptions |= XML_PARSE_DTDLOAD; |
3073 | 0 | if (lint->appOptions & XML_LINT_TIMINGS) { |
3074 | 0 | startTimer(lint); |
3075 | 0 | } |
3076 | 0 | ctxt = xmlRelaxNGNewParserCtxt(lint->relaxng); |
3077 | 0 | if (ctxt == NULL) { |
3078 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
3079 | 0 | goto error; |
3080 | 0 | } |
3081 | 0 | xmlRelaxNGSetResourceLoader(ctxt, xmllintResourceLoader, lint); |
3082 | 0 | lint->relaxngschemas = xmlRelaxNGParse(ctxt); |
3083 | 0 | xmlRelaxNGFreeParserCtxt(ctxt); |
3084 | 0 | if (lint->relaxngschemas == NULL) { |
3085 | 0 | fprintf(errStream, "Relax-NG schema %s failed to compile\n", |
3086 | 0 | lint->relaxng); |
3087 | 0 | lint->progresult = XMLLINT_ERR_SCHEMACOMP; |
3088 | 0 | goto error; |
3089 | 0 | } |
3090 | 0 | if (lint->appOptions & XML_LINT_TIMINGS) { |
3091 | 0 | endTimer(lint, "Compiling the schemas"); |
3092 | 0 | } |
3093 | 0 | } |
3094 | 10.3k | #endif /* LIBXML_RELAXNG_ENABLED */ |
3095 | | |
3096 | 10.3k | #ifdef LIBXML_SCHEMAS_ENABLED |
3097 | 10.3k | if ((lint->schema != NULL) |
3098 | 10.3k | #ifdef LIBXML_READER_ENABLED |
3099 | 10.3k | && ((lint->appOptions& XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING) |
3100 | 10.3k | #endif |
3101 | 10.3k | ) { |
3102 | 0 | xmlSchemaParserCtxtPtr ctxt; |
3103 | |
|
3104 | 0 | if (lint->appOptions & XML_LINT_TIMINGS) { |
3105 | 0 | startTimer(lint); |
3106 | 0 | } |
3107 | 0 | ctxt = xmlSchemaNewParserCtxt(lint->schema); |
3108 | 0 | if (ctxt == NULL) { |
3109 | 0 | lint->progresult = XMLLINT_ERR_MEM; |
3110 | 0 | goto error; |
3111 | 0 | } |
3112 | 0 | xmlSchemaSetResourceLoader(ctxt, xmllintResourceLoader, lint); |
3113 | 0 | lint->wxschemas = xmlSchemaParse(ctxt); |
3114 | 0 | xmlSchemaFreeParserCtxt(ctxt); |
3115 | 0 | if (lint->wxschemas == NULL) { |
3116 | 0 | fprintf(errStream, "WXS schema %s failed to compile\n", |
3117 | 0 | lint->schema); |
3118 | 0 | lint->progresult = XMLLINT_ERR_SCHEMACOMP; |
3119 | 0 | goto error; |
3120 | 0 | } |
3121 | 0 | if (lint->appOptions & XML_LINT_TIMINGS) { |
3122 | 0 | endTimer(lint, "Compiling the schemas"); |
3123 | 0 | } |
3124 | 0 | } |
3125 | 10.3k | #endif /* LIBXML_SCHEMAS_ENABLED */ |
3126 | | |
3127 | 10.3k | #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED) |
3128 | 10.3k | if ((lint->pattern != NULL) && ((lint->appOptions & XML_LINT_USE_WALKER) != XML_LINT_USE_WALKER)) { |
3129 | 1.02k | res = xmlPatternCompileSafe(BAD_CAST lint->pattern, NULL, 0, NULL, |
3130 | 1.02k | &lint->patternc); |
3131 | 1.02k | if (lint->patternc == NULL) { |
3132 | 599 | if (res < 0) { |
3133 | 55 | lint->progresult = XMLLINT_ERR_MEM; |
3134 | 544 | } else { |
3135 | 544 | fprintf(errStream, "Pattern %s failed to compile\n", |
3136 | 544 | lint->pattern); |
3137 | 544 | lint->progresult = XMLLINT_ERR_SCHEMAPAT; |
3138 | 544 | } |
3139 | 599 | goto error; |
3140 | 599 | } |
3141 | 1.02k | } |
3142 | 9.70k | #endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */ |
3143 | | |
3144 | | /* |
3145 | | * The main loop over input documents |
3146 | | */ |
3147 | 175k | for (i = 1; i < argc ; i++) { |
3148 | 165k | const char *filename = argv[i]; |
3149 | 165k | #if HAVE_DECL_MMAP |
3150 | 165k | int memoryFd = -1; |
3151 | 165k | #endif |
3152 | | |
3153 | 165k | if ((filename[0] == '-') && (strcmp(filename, "-") != 0)) { |
3154 | 155k | i += skipArgs(filename); |
3155 | 155k | continue; |
3156 | 155k | } |
3157 | | |
3158 | 9.70k | #if HAVE_DECL_MMAP |
3159 | 9.70k | if (lint->appOptions & XML_LINT_MEMORY) { |
3160 | 0 | struct stat info; |
3161 | 0 | if (stat(filename, &info) < 0) { |
3162 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
3163 | 0 | break; |
3164 | 0 | } |
3165 | 0 | memoryFd = open(filename, O_RDONLY); |
3166 | 0 | if (memoryFd < 0) { |
3167 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
3168 | 0 | break; |
3169 | 0 | } |
3170 | 0 | lint->memoryData = mmap(NULL, info.st_size, PROT_READ, |
3171 | 0 | MAP_SHARED, memoryFd, 0); |
3172 | 0 | if (lint->memoryData == (void *) MAP_FAILED) { |
3173 | 0 | close(memoryFd); |
3174 | 0 | fprintf(errStream, "mmap failure for file %s\n", filename); |
3175 | 0 | lint->progresult = XMLLINT_ERR_RDFILE; |
3176 | 0 | break; |
3177 | 0 | } |
3178 | 0 | lint->memorySize = info.st_size; |
3179 | 0 | } |
3180 | 9.70k | #endif /* HAVE_DECL_MMAP */ |
3181 | | |
3182 | 9.70k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) |
3183 | 309 | startTimer(lint); |
3184 | | |
3185 | 9.70k | #ifdef LIBXML_READER_ENABLED |
3186 | 9.70k | if (lint->appOptions & XML_LINT_USE_STREAMING) { |
3187 | 5.78k | for (j = 0; j < lint->repeat; j++) |
3188 | 3.07k | streamFile(lint, filename); |
3189 | 2.71k | } else |
3190 | 6.99k | #endif /* LIBXML_READER_ENABLED */ |
3191 | 6.99k | { |
3192 | 6.99k | xmlParserCtxtPtr ctxt; |
3193 | | |
3194 | 6.99k | #ifdef LIBXML_HTML_ENABLED |
3195 | 6.99k | if (lint->appOptions & XML_LINT_HTML_ENABLED) { |
3196 | 1.20k | #ifdef LIBXML_PUSH_ENABLED |
3197 | 1.20k | if (lint->appOptions & XML_LINT_PUSH_ENABLED) { |
3198 | 15 | ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, |
3199 | 15 | filename, |
3200 | 15 | XML_CHAR_ENCODING_NONE); |
3201 | 15 | } else |
3202 | 1.18k | #endif /* LIBXML_PUSH_ENABLED */ |
3203 | 1.18k | { |
3204 | 1.18k | ctxt = htmlNewParserCtxt(); |
3205 | 1.18k | } |
3206 | 1.20k | htmlCtxtUseOptions(ctxt, lint->htmlOptions); |
3207 | 1.20k | } else |
3208 | 5.79k | #endif /* LIBXML_HTML_ENABLED */ |
3209 | 5.79k | { |
3210 | 5.79k | #ifdef LIBXML_PUSH_ENABLED |
3211 | 5.79k | if (lint->appOptions & XML_LINT_PUSH_ENABLED) { |
3212 | 21 | ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, |
3213 | 21 | filename); |
3214 | 21 | } else |
3215 | 5.77k | #endif /* LIBXML_PUSH_ENABLED */ |
3216 | 5.77k | { |
3217 | 5.77k | ctxt = xmlNewParserCtxt(); |
3218 | 5.77k | } |
3219 | 5.79k | xmlCtxtUseOptions(ctxt, lint->parseOptions); |
3220 | 5.79k | } |
3221 | 6.99k | if (ctxt == NULL) { |
3222 | 194 | lint->progresult = XMLLINT_ERR_MEM; |
3223 | 194 | goto error; |
3224 | 194 | } |
3225 | | |
3226 | 6.80k | if (lint->appOptions & XML_LINT_SAX_ENABLED) { |
3227 | 551 | const xmlSAXHandler *handler; |
3228 | | |
3229 | 551 | if (lint->noout) { |
3230 | 515 | handler = &emptySAXHandler; |
3231 | 515 | #ifdef LIBXML_SAX1_ENABLED |
3232 | 515 | } else if (lint->parseOptions & XML_PARSE_SAX1) { |
3233 | 7 | handler = &debugSAXHandler; |
3234 | 7 | #endif |
3235 | 29 | } else { |
3236 | 29 | handler = &debugSAX2Handler; |
3237 | 29 | } |
3238 | | |
3239 | 551 | *ctxt->sax = *handler; |
3240 | 551 | ctxt->userData = lint; |
3241 | 551 | } |
3242 | | |
3243 | 6.80k | xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint); |
3244 | 6.80k | if (lint->maxAmpl > 0) |
3245 | 542 | xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl); |
3246 | | |
3247 | 6.80k | lint->ctxt = ctxt; |
3248 | | |
3249 | 14.2k | for (j = 0; j < lint->repeat; j++) { |
3250 | 7.46k | if (j > 0) { |
3251 | 663 | #ifdef LIBXML_PUSH_ENABLED |
3252 | 663 | if (lint->appOptions & XML_LINT_PUSH_ENABLED) { |
3253 | 0 | xmlCtxtResetPush(ctxt, NULL, 0, NULL, NULL); |
3254 | 0 | } else |
3255 | 663 | #endif |
3256 | 663 | { |
3257 | 663 | xmlCtxtReset(ctxt); |
3258 | 663 | } |
3259 | 663 | } |
3260 | | |
3261 | 7.46k | if (lint->appOptions & XML_LINT_SAX_ENABLED) { |
3262 | 670 | testSAX(lint, filename); |
3263 | 6.79k | } else { |
3264 | 6.79k | parseAndPrintFile(lint, filename); |
3265 | 6.79k | } |
3266 | 7.46k | } |
3267 | | |
3268 | 6.80k | xmlFreeParserCtxt(ctxt); |
3269 | 6.80k | } |
3270 | | |
3271 | 9.51k | if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) { |
3272 | 299 | endTimer(lint, "%d iterations", lint->repeat); |
3273 | 299 | } |
3274 | | |
3275 | 9.51k | files += 1; |
3276 | | |
3277 | 9.51k | #if HAVE_DECL_MMAP |
3278 | 9.51k | if (lint->appOptions & XML_LINT_MEMORY) { |
3279 | 0 | munmap(lint->memoryData, lint->memorySize); |
3280 | 0 | close(memoryFd); |
3281 | 0 | } |
3282 | 9.51k | #endif |
3283 | 9.51k | } |
3284 | | |
3285 | 9.51k | if (lint->appOptions & XML_LINT_GENERATE) |
3286 | 9.24k | parseAndPrintFile(lint, NULL); |
3287 | | |
3288 | 9.51k | if ((files == 0) && ((lint->appOptions & XML_LINT_GENERATE) != XML_LINT_GENERATE) && (lint->version == 0)) { |
3289 | 0 | usage(errStream, argv[0]); |
3290 | 0 | lint->progresult = XMLLINT_ERR_UNCLASS; |
3291 | 0 | } |
3292 | | |
3293 | 10.3k | error: |
3294 | | |
3295 | | #ifdef LIBXML_SCHEMATRON_ENABLED |
3296 | | if (lint->wxschematron != NULL) |
3297 | | xmlSchematronFree(lint->wxschematron); |
3298 | | #endif |
3299 | 10.3k | #ifdef LIBXML_RELAXNG_ENABLED |
3300 | 10.3k | if (lint->relaxngschemas != NULL) |
3301 | 0 | xmlRelaxNGFree(lint->relaxngschemas); |
3302 | 10.3k | #endif |
3303 | 10.3k | #ifdef LIBXML_SCHEMAS_ENABLED |
3304 | 10.3k | if (lint->wxschemas != NULL) |
3305 | 0 | xmlSchemaFree(lint->wxschemas); |
3306 | 10.3k | #endif |
3307 | 10.3k | #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED) |
3308 | 10.3k | if (lint->patternc != NULL) |
3309 | 427 | xmlFreePattern(lint->patternc); |
3310 | 10.3k | #endif |
3311 | | |
3312 | 10.3k | xmlCleanupParser(); |
3313 | | |
3314 | 10.3k | if ((lint->maxmem) && (xmllintMaxmemReached)) { |
3315 | 295 | fprintf(errStream, "Maximum memory exceeded (%d bytes)\n", |
3316 | 295 | xmllintMaxmem); |
3317 | 10.0k | } else if (lint->progresult == XMLLINT_ERR_MEM) { |
3318 | 1.61k | fprintf(errStream, "Out-of-memory error reported\n"); |
3319 | 1.61k | } |
3320 | | |
3321 | 10.3k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
3322 | 10.3k | if ((lint->maxmem) && |
3323 | 10.3k | (xmllintOom != (lint->progresult == XMLLINT_ERR_MEM))) { |
3324 | 0 | fprintf(stderr, "xmllint: malloc failure %s reported\n", |
3325 | 0 | xmllintOom ? "not" : "erroneously"); |
3326 | 0 | abort(); |
3327 | 0 | } |
3328 | 10.3k | #endif |
3329 | | |
3330 | 10.3k | return(lint->progresult); |
3331 | 10.3k | } |
3332 | | |