Coverage Report

Created: 2026-05-30 06:16

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