Coverage Report

Created: 2026-07-16 06:17

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
2.64k
                      xmlParserInputFlags flags, xmlParserInputPtr *out) {
278
2.64k
    xmllintState *lint = ctxt;
279
2.64k
    xmlParserErrors code;
280
2.64k
    int i;
281
2.64k
    const char *lastsegment = URL;
282
2.64k
    const char *iter = URL;
283
284
2.64k
    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
2.64k
    if (lint->defaultResourceLoader != NULL)
293
2.64k
        code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out);
294
0
    else
295
0
        code = xmlNewInputFromUrl(URL, flags, out);
296
2.64k
    if (code != XML_IO_ENOENT) {
297
2.64k
        if ((lint->appOptions & XML_LINT_USE_LOAD_TRACE) && (code == XML_ERR_OK)) {
298
744
            fprintf(lint->errStream, "Loaded URL=\"%s\" ID=\"%s\"\n",
299
744
                    URL, ID ? ID : "(null)");
300
744
        }
301
2.64k
        return(code);
302
2.64k
    }
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
14
xmllintGzRead(void *ctxt, char *buf, int len) {
344
14
    return gzread(ctxt, buf, len);
345
14
}
346
347
#ifdef LIBXML_OUTPUT_ENABLED
348
static int
349
9
xmllintGzWrite(void *ctxt, const char *buf, int len) {
350
9
    return gzwrite(ctxt, buf, len);
351
9
}
352
#endif
353
354
static int
355
21
xmllintGzClose(void *ctxt) {
356
21
    if (gzclose(ctxt) != Z_OK)
357
3
        return -1;
358
359
18
    return 0;
360
21
}
361
#endif
362
363
static xmlDocPtr
364
3.22k
parseXml(xmllintState *lint, const char *filename) {
365
3.22k
    xmlParserCtxtPtr ctxt = lint->ctxt;
366
3.22k
    xmlDocPtr doc;
367
3.22k
#ifdef LIBXML_ZLIB_ENABLED
368
3.22k
    gzFile gz;
369
3.22k
#endif
370
371
3.22k
#ifdef LIBXML_PUSH_ENABLED
372
3.22k
    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
373
16
        FILE *f;
374
16
        int res;
375
16
        char chars[4096];
376
377
16
        if ((filename[0] == '-') && (filename[1] == 0)) {
378
0
            f = stdin;
379
16
        } else {
380
16
            f = fopen(filename, "rb");
381
16
            if (f == NULL) {
382
2
                fprintf(lint->errStream, "Can't open %s\n", filename);
383
2
                lint->progresult = XMLLINT_ERR_RDFILE;
384
2
                return(NULL);
385
2
            }
386
16
        }
387
388
14
        while ((res = fread(chars, 1, 4096, f)) > 0) {
389
0
            xmlParseChunk(ctxt, chars, res, 0);
390
0
        }
391
14
        xmlParseChunk(ctxt, chars, 0, 1);
392
14
        doc = xmlCtxtGetDocument(ctxt);
393
394
14
        if (f != stdin)
395
14
            fclose(f);
396
397
14
        return(doc);
398
16
    }
399
3.20k
#endif /* LIBXML_PUSH_ENABLED */
400
401
3.20k
#if HAVE_DECL_MMAP
402
3.20k
    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
3.20k
#endif
416
417
3.20k
#ifdef LIBXML_ZLIB_ENABLED
418
3.20k
    if (strcmp(filename, "-") == 0)
419
0
        gz = gzdopen(STDIN_FILENO, "rb");
420
3.20k
    else
421
3.20k
        gz = gzopen(filename, "rb");
422
423
3.20k
    if (gz == NULL) {
424
3.19k
        fprintf(lint->errStream, "Can't open %s\n", filename);
425
3.19k
        lint->progresult = XMLLINT_ERR_RDFILE;
426
3.19k
        return(NULL);
427
3.19k
    }
428
429
10
    doc = xmlCtxtReadIO(ctxt, xmllintGzRead, xmllintGzClose, gz,
430
10
                        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
10
    return(doc);
439
3.20k
}
440
441
#ifdef LIBXML_HTML_ENABLED
442
static xmlDocPtr
443
2.65k
parseHtml(xmllintState *lint, const char *filename) {
444
2.65k
    xmlParserCtxtPtr ctxt = lint->ctxt;
445
2.65k
    xmlDocPtr doc;
446
447
2.65k
#ifdef LIBXML_PUSH_ENABLED
448
2.65k
    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
449
7
        FILE *f;
450
7
        int res;
451
7
        char chars[4096];
452
453
7
        if ((filename[0] == '-') && (filename[1] == 0)) {
454
0
            f = stdin;
455
7
        } else {
456
7
      f = fopen(filename, "rb");
457
7
            if (f == NULL) {
458
4
                fprintf(lint->errStream, "Can't open %s\n", filename);
459
4
                lint->progresult = XMLLINT_ERR_RDFILE;
460
4
                return(NULL);
461
4
            }
462
7
        }
463
464
3
        while ((res = fread(chars, 1, 4096, f)) > 0) {
465
0
            htmlParseChunk(ctxt, chars, res, 0);
466
0
        }
467
3
        htmlParseChunk(ctxt, chars, 0, 1);
468
3
        doc = xmlCtxtGetDocument(ctxt);
469
470
3
        if (f != stdin)
471
3
            fclose(f);
472
473
3
        return(doc);
474
7
    }
475
2.64k
#endif /* LIBXML_PUSH_ENABLED */
476
477
2.64k
#if HAVE_DECL_MMAP
478
2.64k
    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
2.64k
#endif
492
493
2.64k
    if (strcmp(filename, "-") == 0)
494
0
        doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
495
0
                             lint->htmlOptions);
496
2.64k
    else
497
2.64k
        doc = htmlCtxtReadFile(ctxt, filename, NULL, lint->htmlOptions);
498
499
2.64k
    return(doc);
500
2.64k
}
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
913k
myFreeFunc(void *mem) {
513
913k
    xmlMemFree(mem);
514
913k
}
515
516
static void *
517
876k
myMallocFunc(size_t size) {
518
876k
    void *ret;
519
520
876k
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
521
#if XMLLINT_ABORT_ON_FAILURE
522
        abort();
523
#endif
524
452
        xmllintMaxmemReached = 1;
525
452
        xmllintOom = 1;
526
452
        return(NULL);
527
452
    }
528
529
875k
    ret = xmlMemMalloc(size);
530
875k
    if (ret == NULL)
531
0
        xmllintOom = 1;
532
533
875k
    return(ret);
534
876k
}
535
536
static void *
537
100k
myReallocFunc(void *mem, size_t size) {
538
100k
    void *ret;
539
100k
    size_t oldsize = xmlMemSize(mem);
540
541
100k
    if (xmlMemUsed() + size - oldsize > (size_t) xmllintMaxmem) {
542
#if XMLLINT_ABORT_ON_FAILURE
543
        abort();
544
#endif
545
518
        xmllintMaxmemReached = 1;
546
518
        xmllintOom = 1;
547
518
        return(NULL);
548
518
    }
549
550
100k
    ret = xmlMemRealloc(mem, size);
551
100k
    if (ret == NULL)
552
0
        xmllintOom = 1;
553
554
100k
    return(ret);
555
100k
}
556
557
static char *
558
5.11k
myStrdupFunc(const char *str) {
559
5.11k
    size_t size;
560
5.11k
    char *ret;
561
562
5.11k
    if (str == NULL)
563
0
        return(NULL);
564
565
5.11k
    size = strlen(str) + 1;
566
5.11k
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
567
#if XMLLINT_ABORT_ON_FAILURE
568
        abort();
569
#endif
570
638
        xmllintMaxmemReached = 1;
571
638
        xmllintOom = 1;
572
638
        return(NULL);
573
638
    }
574
575
4.47k
    ret = xmlMemMalloc(size);
576
4.47k
    if (ret == NULL) {
577
0
        xmllintOom = 1;
578
0
        return(NULL);
579
0
    }
580
581
4.47k
    memcpy(ret, str, size);
582
583
4.47k
    return(ret);
584
4.47k
}
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
14.1k
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
14.1k
    struct timeval tv;
603
604
14.1k
    gettimeofday(&tv, NULL);
605
14.1k
    time->sec = tv.tv_sec;
606
14.1k
    time->usec = tv.tv_usec;
607
14.1k
#endif /* _WIN32 */
608
14.1k
}
609
610
/*
611
 * startTimer: call where you want to start timing
612
 */
613
static void
614
startTimer(xmllintState *lint)
615
7.45k
{
616
7.45k
    getTime(&lint->begin);
617
7.45k
}
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
6.71k
{
627
6.71k
    xmlSeconds msec;
628
6.71k
    va_list ap;
629
630
6.71k
    getTime(&lint->end);
631
6.71k
    msec = lint->end.sec - lint->begin.sec;
632
6.71k
    msec *= 1000;
633
6.71k
    msec += (lint->end.usec - lint->begin.usec) / 1000;
634
635
6.71k
    va_start(ap, fmt);
636
6.71k
    vfprintf(lint->errStream, fmt, ap);
637
6.71k
    va_end(ap);
638
639
6.71k
    fprintf(lint->errStream, " took %ld ms\n", (long) msec);
640
6.71k
}
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
3
{
922
3
    xmllintState *lint = ctx;
923
924
3
    lint->callbacks++;
925
3
    if (lint->noout)
926
0
  return;
927
3
    fprintf(stdout, "SAX.endDocument()\n");
928
3
}
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
3
{
1063
3
    xmllintState *lint = ctx;
1064
3
    va_list args;
1065
1066
3
    lint->callbacks++;
1067
3
    if (lint->noout)
1068
0
  return;
1069
3
    va_start(args, msg);
1070
3
    fprintf(stdout, "SAX.error: ");
1071
3
    vfprintf(stdout, msg, args);
1072
3
    va_end(args);
1073
3
}
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
314
testSAX(xmllintState *lint, const char *filename) {
1241
314
    lint->callbacks = 0;
1242
1243
314
#ifdef LIBXML_SCHEMAS_ENABLED
1244
314
    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
314
#endif
1284
314
#ifdef LIBXML_HTML_ENABLED
1285
314
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1286
0
        parseHtml(lint, filename);
1287
0
    } else
1288
314
#endif
1289
314
    {
1290
314
        parseXml(lint, filename);
1291
314
    }
1292
314
}
1293
1294
/************************************************************************
1295
 *                  *
1296
 *      Stream Test processing        *
1297
 *                  *
1298
 ************************************************************************/
1299
#ifdef LIBXML_READER_ENABLED
1300
4.58k
static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
1301
4.58k
    const xmlChar *name, *value;
1302
4.58k
    int type, empty;
1303
1304
4.58k
    type = xmlTextReaderNodeType(reader);
1305
4.58k
    empty = xmlTextReaderIsEmptyElement(reader);
1306
1307
4.58k
    if (lint->appOptions & XML_LINT_DEBUG_ENABLED) {
1308
4.02k
  name = xmlTextReaderConstName(reader);
1309
4.02k
  if (name == NULL)
1310
0
      name = BAD_CAST "--";
1311
1312
4.02k
  value = xmlTextReaderConstValue(reader);
1313
1314
1315
4.02k
  printf("%d %d %s %d %d",
1316
4.02k
    xmlTextReaderDepth(reader),
1317
4.02k
    type,
1318
4.02k
    name,
1319
4.02k
    empty,
1320
4.02k
    xmlTextReaderHasValue(reader));
1321
4.02k
  if (value == NULL)
1322
1.12k
      printf("\n");
1323
2.90k
  else {
1324
2.90k
      printf(" %s\n", value);
1325
2.90k
  }
1326
4.02k
    }
1327
4.58k
#ifdef LIBXML_PATTERN_ENABLED
1328
4.58k
    if (lint->patternc) {
1329
844
        xmlChar *path = NULL;
1330
844
        int match = -1;
1331
1332
844
  if (type == XML_READER_TYPE_ELEMENT) {
1333
      /* do the check only on element start */
1334
283
      match = xmlPatternMatch(lint->patternc,
1335
283
                                    xmlTextReaderCurrentNode(reader));
1336
1337
283
      if (match) {
1338
61
    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1339
61
    printf("Node %s matches pattern %s\n", path, lint->pattern);
1340
61
      }
1341
283
  }
1342
844
  if (lint->patstream != NULL) {
1343
844
      int ret;
1344
1345
844
      if (type == XML_READER_TYPE_ELEMENT) {
1346
283
    ret = xmlStreamPush(lint->patstream,
1347
283
                        xmlTextReaderConstLocalName(reader),
1348
283
            xmlTextReaderConstNamespaceUri(reader));
1349
283
    if (ret < 0) {
1350
0
        fprintf(lint->errStream, "xmlStreamPush() failure\n");
1351
0
                    xmlFreeStreamCtxt(lint->patstream);
1352
0
        lint->patstream = NULL;
1353
283
    } else if (ret != match) {
1354
4
        if (path == NULL) {
1355
3
            path = xmlGetNodePath(
1356
3
                           xmlTextReaderCurrentNode(reader));
1357
3
        }
1358
4
        fprintf(lint->errStream,
1359
4
                "xmlPatternMatch and xmlStreamPush disagree\n");
1360
4
                    if (path != NULL)
1361
4
                        fprintf(lint->errStream, "  pattern %s node %s\n",
1362
4
                                lint->pattern, path);
1363
0
                    else
1364
0
            fprintf(lint->errStream, "  pattern %s node %s\n",
1365
0
          lint->pattern, xmlTextReaderConstName(reader));
1366
4
    }
1367
1368
283
      }
1369
844
      if ((type == XML_READER_TYPE_END_ELEMENT) ||
1370
573
          ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1371
283
          ret = xmlStreamPop(lint->patstream);
1372
283
    if (ret < 0) {
1373
0
        fprintf(lint->errStream, "xmlStreamPop() failure\n");
1374
0
                    xmlFreeStreamCtxt(lint->patstream);
1375
0
        lint->patstream = NULL;
1376
0
    }
1377
283
      }
1378
844
  }
1379
844
  if (path != NULL)
1380
64
      xmlFree(path);
1381
844
    }
1382
4.58k
#endif
1383
4.58k
}
1384
1385
1.39k
static void streamFile(xmllintState *lint, const char *filename) {
1386
1.39k
    xmlParserInputBufferPtr input = NULL;
1387
1.39k
    FILE *errStream = lint->errStream;
1388
1.39k
    xmlTextReaderPtr reader;
1389
1.39k
    int ret;
1390
1391
1.39k
#if HAVE_DECL_MMAP
1392
1.39k
    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
1.39k
#endif
1401
1.39k
    {
1402
1.39k
#ifdef LIBXML_ZLIB_ENABLED
1403
1.39k
        gzFile gz;
1404
1.39k
#endif
1405
1406
1.39k
        xmlResetLastError();
1407
1408
1.39k
#ifdef LIBXML_ZLIB_ENABLED
1409
1.39k
        if (strcmp(filename, "-") == 0)
1410
0
            gz = gzdopen(STDIN_FILENO, "rb");
1411
1.39k
        else
1412
1.39k
            gz = gzopen(filename, "rb");
1413
1414
1.39k
        if (gz == NULL) {
1415
1.39k
            fprintf(lint->errStream, "Can't open %s\n", filename);
1416
1.39k
            lint->progresult = XMLLINT_ERR_RDFILE;
1417
1.39k
            return;
1418
1.39k
        }
1419
1420
7
        reader = xmlReaderForIO(xmllintGzRead, xmllintGzClose, gz,
1421
7
                                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
7
        if (reader == NULL) {
1432
2
            const xmlError *error = xmlGetLastError();
1433
1434
2
            if ((error != NULL) && (error->code == XML_ERR_NO_MEMORY)) {
1435
0
                lint->progresult = XMLLINT_ERR_MEM;
1436
2
            } else {
1437
2
                fprintf(errStream, "Unable to open %s\n", filename);
1438
2
                lint->progresult = XMLLINT_ERR_RDFILE;
1439
2
            }
1440
2
            return;
1441
2
        }
1442
7
    }
1443
1444
5
#ifdef LIBXML_PATTERN_ENABLED
1445
5
    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
5
#endif
1457
1458
1459
5
    xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, lint);
1460
5
    if (lint->maxAmpl > 0)
1461
1
        xmlTextReaderSetMaxAmplification(reader, lint->maxAmpl);
1462
1463
5
#ifdef LIBXML_RELAXNG_ENABLED
1464
5
    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
5
#endif
1480
5
#ifdef LIBXML_SCHEMAS_ENABLED
1481
5
    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
5
#endif
1497
1498
    /*
1499
     * Process all nodes in sequence
1500
     */
1501
5
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1502
1
        startTimer(lint);
1503
1
    }
1504
5
    ret = xmlTextReaderRead(reader);
1505
5
    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
5
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1515
1
#ifdef LIBXML_RELAXNG_ENABLED
1516
1
        if (lint->relaxng != NULL)
1517
0
            endTimer(lint, "Parsing and validating");
1518
1
        else
1519
1
#endif
1520
1
#ifdef LIBXML_VALID_ENABLED
1521
1
        if (lint->parseOptions & XML_PARSE_DTDVALID)
1522
1
            endTimer(lint, "Parsing and validating");
1523
0
        else
1524
0
#endif
1525
0
        endTimer(lint, "Parsing");
1526
1
    }
1527
1528
5
#ifdef LIBXML_VALID_ENABLED
1529
5
    if (lint->parseOptions & XML_PARSE_DTDVALID) {
1530
1
        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
1
    }
1536
5
#endif /* LIBXML_VALID_ENABLED */
1537
5
#if defined(LIBXML_RELAXNG_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
1538
5
    {
1539
5
        int hasSchema = 0;
1540
1541
5
#ifdef LIBXML_RELAXNG_ENABLED
1542
5
        if (lint->relaxng != NULL)
1543
0
            hasSchema = 1;
1544
5
#endif
1545
5
#ifdef LIBXML_SCHEMAS_ENABLED
1546
5
        if (lint->schema != NULL)
1547
0
            hasSchema = 1;
1548
5
#endif
1549
5
        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
5
    }
1560
5
#endif
1561
    /*
1562
     * Done, cleanup and status
1563
     */
1564
5
    xmlFreeTextReader(reader);
1565
5
    xmlFreeParserInputBuffer(input);
1566
5
    if (ret != 0) {
1567
5
        fprintf(errStream, "%s : failed to parse\n", filename);
1568
5
        lint->progresult = XMLLINT_ERR_UNCLASS;
1569
5
    }
1570
5
#ifdef LIBXML_PATTERN_ENABLED
1571
5
    if (lint->patstream != NULL) {
1572
0
  xmlFreeStreamCtxt(lint->patstream);
1573
0
  lint->patstream = NULL;
1574
0
    }
1575
5
#endif
1576
5
}
1577
1578
1.73k
static void walkDoc(xmllintState *lint, xmlDocPtr doc) {
1579
1.73k
    FILE *errStream = lint->errStream;
1580
1.73k
    xmlTextReaderPtr reader;
1581
1.73k
    int ret;
1582
1583
1.73k
#ifdef LIBXML_PATTERN_ENABLED
1584
1.73k
    if (lint->pattern != NULL) {
1585
412
        xmlNodePtr root;
1586
412
        const xmlChar *namespaces[22];
1587
412
        int i;
1588
412
        xmlNsPtr ns;
1589
1590
412
        root = xmlDocGetRootElement(doc);
1591
412
        if (root == NULL ) {
1592
8
            fprintf(errStream,
1593
8
                    "Document does not have a root element");
1594
8
            lint->progresult = XMLLINT_ERR_UNCLASS;
1595
8
            return;
1596
8
        }
1597
404
        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
404
        namespaces[i++] = NULL;
1602
404
        namespaces[i] = NULL;
1603
1604
404
        ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict,
1605
404
                                    0, &namespaces[0], &lint->patternc);
1606
404
  if (lint->patternc == NULL) {
1607
165
            if (ret < 0) {
1608
44
                lint->progresult = XMLLINT_ERR_MEM;
1609
121
            } else {
1610
121
                fprintf(errStream, "Pattern %s failed to compile\n",
1611
121
                        lint->pattern);
1612
121
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
1613
121
            }
1614
165
            goto error;
1615
165
  }
1616
1617
239
        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
1618
239
        if (lint->patstream == NULL) {
1619
14
            lint->progresult = XMLLINT_ERR_MEM;
1620
14
            goto error;
1621
14
        }
1622
1623
225
        ret = xmlStreamPush(lint->patstream, NULL, NULL);
1624
225
        if (ret < 0) {
1625
1
            fprintf(errStream, "xmlStreamPush() failure\n");
1626
1
            lint->progresult = XMLLINT_ERR_MEM;
1627
1
            goto error;
1628
1
        }
1629
225
    }
1630
1.54k
#endif /* LIBXML_PATTERN_ENABLED */
1631
1.54k
    reader = xmlReaderWalker(doc);
1632
1.54k
    if (reader != NULL) {
1633
1.54k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1634
539
      startTimer(lint);
1635
539
  }
1636
1.54k
  ret = xmlTextReaderRead(reader);
1637
44.0k
  while (ret == 1) {
1638
42.4k
      if ((lint->appOptions & XML_LINT_DEBUG_ENABLED)
1639
38.4k
#ifdef LIBXML_PATTERN_ENABLED
1640
38.4k
          || (lint->patternc)
1641
42.4k
#endif
1642
42.4k
         )
1643
4.58k
    processNode(lint, reader);
1644
42.4k
      ret = xmlTextReaderRead(reader);
1645
42.4k
  }
1646
1.54k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1647
539
      endTimer(lint, "walking through the doc");
1648
539
  }
1649
1.54k
  xmlFreeTextReader(reader);
1650
1.54k
  if (ret != 0) {
1651
0
      fprintf(errStream, "failed to walk through the doc\n");
1652
0
      lint->progresult = XMLLINT_ERR_UNCLASS;
1653
0
  }
1654
1.54k
    } else {
1655
2
  fprintf(errStream, "Failed to create a reader from the document\n");
1656
2
  lint->progresult = XMLLINT_ERR_UNCLASS;
1657
2
    }
1658
1659
1.54k
#ifdef LIBXML_PATTERN_ENABLED
1660
1.72k
error:
1661
1.72k
    if (lint->patternc != NULL) {
1662
239
        xmlFreePattern(lint->patternc);
1663
239
        lint->patternc = NULL;
1664
239
    }
1665
1.72k
    if (lint->patstream != NULL) {
1666
225
  xmlFreeStreamCtxt(lint->patstream);
1667
225
  lint->patstream = NULL;
1668
225
    }
1669
1.72k
#endif
1670
1.72k
}
1671
#endif /* LIBXML_READER_ENABLED */
1672
1673
#ifdef LIBXML_XPATH_ENABLED
1674
/************************************************************************
1675
 *                  *
1676
 *      XPath Query                                     *
1677
 *                  *
1678
 ************************************************************************/
1679
1680
static void
1681
3.54k
doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) {
1682
3.54k
    switch(cur->type) {
1683
2.91k
        case XPATH_NODESET: {
1684
2.91k
#ifdef LIBXML_OUTPUT_ENABLED
1685
2.91k
            xmlOutputBufferPtr buf;
1686
2.91k
            xmlNodePtr node;
1687
2.91k
            int i;
1688
1689
2.91k
            if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
1690
1.64k
                lint->progresult = XMLLINT_ERR_XPATH_EMPTY;
1691
1.64k
                if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
1692
1.38k
                    fprintf(lint->errStream, "XPath set is empty\n");
1693
1.38k
                }
1694
1.64k
                break;
1695
1.64k
            }
1696
1.27k
            buf = xmlOutputBufferCreateFile(stdout, NULL);
1697
1.27k
            if (buf == NULL) {
1698
117
                lint->progresult = XMLLINT_ERR_MEM;
1699
117
                return;
1700
117
            }
1701
34.9k
            for (i = 0;i < cur->nodesetval->nodeNr;i++) {
1702
33.7k
                node = cur->nodesetval->nodeTab[i];
1703
33.7k
                xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
1704
33.7k
                xmlOutputBufferWrite(buf, 1, lint->xpathsep);
1705
33.7k
            }
1706
1.16k
            xmlOutputBufferClose(buf);
1707
#else
1708
            printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
1709
#endif
1710
1.16k
      break;
1711
1.27k
        }
1712
209
        case XPATH_BOOLEAN:
1713
209
      if (cur->boolval) printf("true%s", lint->xpathsep);
1714
150
      else printf("false%s", lint->xpathsep);
1715
209
      break;
1716
130
        case XPATH_NUMBER:
1717
130
      switch (xmlXPathIsInf(cur->floatval)) {
1718
8
      case 1:
1719
8
    printf("Infinity%s", lint->xpathsep);
1720
8
    break;
1721
1
      case -1:
1722
1
    printf("-Infinity%s", lint->xpathsep);
1723
1
    break;
1724
121
      default:
1725
121
    if (xmlXPathIsNaN(cur->floatval)) {
1726
93
        printf("NaN%s", lint->xpathsep);
1727
93
    } else {
1728
28
        printf("%0g%s", cur->floatval, lint->xpathsep);
1729
28
    }
1730
130
      }
1731
130
      break;
1732
289
        case XPATH_STRING:
1733
289
      printf("%s%s", (const char *) cur->stringval, lint->xpathsep);
1734
289
      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
3.54k
    }
1744
3.54k
}
1745
1746
static void
1747
5.99k
doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) {
1748
5.99k
    xmlXPathContextPtr ctxt = NULL;
1749
5.99k
    xmlXPathCompExprPtr comp = NULL;
1750
5.99k
    xmlXPathObjectPtr res = NULL;
1751
1752
5.99k
    ctxt = xmlXPathNewContext(doc);
1753
5.99k
    if (ctxt == NULL) {
1754
11
        lint->progresult = XMLLINT_ERR_MEM;
1755
11
        goto error;
1756
11
    }
1757
1758
5.98k
    comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query);
1759
5.98k
    if (comp == NULL) {
1760
1.77k
        fprintf(lint->errStream, "XPath compilation failure\n");
1761
1.77k
        lint->progresult = XMLLINT_ERR_XPATH;
1762
1.77k
        goto error;
1763
1.77k
    }
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
4.20k
    ctxt->node = (xmlNodePtr) doc;
1773
4.20k
    res = xmlXPathCompiledEval(comp, ctxt);
1774
4.20k
    if (res == NULL) {
1775
660
        fprintf(lint->errStream, "XPath evaluation failure\n");
1776
660
        lint->progresult = XMLLINT_ERR_XPATH;
1777
660
        goto error;
1778
660
    }
1779
1780
3.54k
    doXPathDump(lint, res);
1781
1782
5.99k
error:
1783
5.99k
    xmlXPathFreeObject(res);
1784
5.99k
    xmlXPathFreeCompExpr(comp);
1785
5.99k
    xmlXPathFreeContext(ctxt);
1786
5.99k
}
1787
#endif /* LIBXML_XPATH_ENABLED */
1788
1789
/************************************************************************
1790
 *                  *
1791
 *      Tree Test processing        *
1792
 *                  *
1793
 ************************************************************************/
1794
1795
static xmlDocPtr
1796
11.3k
parseFile(xmllintState *lint, const char *filename) {
1797
11.3k
    xmlDocPtr doc = NULL;
1798
1799
11.3k
    if ((lint->appOptions & XML_LINT_GENERATE) && (filename == NULL)) {
1800
5.83k
        xmlNodePtr n;
1801
1802
5.83k
        doc = xmlNewDoc(BAD_CAST "1.0");
1803
5.83k
        if (doc == NULL) {
1804
0
            lint->progresult = XMLLINT_ERR_MEM;
1805
0
            return(NULL);
1806
0
        }
1807
5.83k
        n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
1808
5.83k
        if (n == NULL) {
1809
0
            xmlFreeDoc(doc);
1810
0
            lint->progresult = XMLLINT_ERR_MEM;
1811
0
            return(NULL);
1812
0
        }
1813
5.83k
        if (xmlNodeSetContent(n, BAD_CAST "abc") < 0) {
1814
1
            xmlFreeNode(n);
1815
1
            xmlFreeDoc(doc);
1816
1
            lint->progresult = XMLLINT_ERR_MEM;
1817
1
            return(NULL);
1818
1
        }
1819
5.82k
        xmlDocSetRootElement(doc, n);
1820
1821
5.82k
        return(doc);
1822
5.83k
    }
1823
1824
5.55k
#ifdef LIBXML_HTML_ENABLED
1825
5.55k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1826
2.65k
        doc = parseHtml(lint, filename);
1827
2.65k
        return(doc);
1828
2.65k
    }
1829
2.90k
#endif /* LIBXML_HTML_ENABLED */
1830
2.90k
    {
1831
2.90k
        doc = parseXml(lint, filename);
1832
2.90k
    }
1833
1834
2.90k
    if (doc == NULL) {
1835
2.90k
        if (lint->ctxt->errNo == XML_ERR_NO_MEMORY)
1836
9
            lint->progresult = XMLLINT_ERR_MEM;
1837
2.89k
        else
1838
2.89k
      lint->progresult = XMLLINT_ERR_RDFILE;
1839
2.90k
    } 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
2.90k
    return(doc);
1852
5.55k
}
1853
1854
static void
1855
11.3k
parseAndPrintFile(xmllintState *lint, const char *filename) {
1856
11.3k
    FILE *errStream = lint->errStream;
1857
11.3k
    xmlDocPtr doc;
1858
1859
    /* Avoid unused variable warning */
1860
11.3k
    (void) errStream;
1861
1862
11.3k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1))
1863
2.24k
  startTimer(lint);
1864
1865
11.3k
    doc = parseFile(lint, filename);
1866
11.3k
    if (doc == NULL) {
1867
3.61k
        if (lint->progresult == XMLLINT_RETURN_OK)
1868
604
            lint->progresult = XMLLINT_ERR_UNCLASS;
1869
3.61k
  return;
1870
3.61k
    }
1871
1872
7.77k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1873
1.51k
  endTimer(lint, "Parsing");
1874
1.51k
    }
1875
1876
7.77k
    if (lint->appOptions & XML_LINT_DROP_DTD) {
1877
2.02k
  xmlDtdPtr dtd;
1878
1879
2.02k
  dtd = xmlGetIntSubset(doc);
1880
2.02k
  if (dtd != NULL) {
1881
646
      xmlUnlinkNode((xmlNodePtr)dtd);
1882
646
            doc->intSubset = dtd;
1883
646
  }
1884
2.02k
    }
1885
1886
7.77k
#ifdef LIBXML_XINCLUDE_ENABLED
1887
7.77k
    if (lint->appOptions & XML_LINT_XINCLUDE) {
1888
5.77k
        xmlXIncludeCtxt *xinc;
1889
5.77k
        int res;
1890
1891
5.77k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1892
1.31k
      startTimer(lint);
1893
1.31k
  }
1894
1895
5.77k
        xinc = xmlXIncludeNewContext(doc);
1896
5.77k
        if (xinc == NULL) {
1897
3
            lint->progresult = XMLLINT_ERR_MEM;
1898
3
            goto done;
1899
3
        }
1900
5.77k
        xmlXIncludeSetResourceLoader(xinc, xmllintResourceLoader, lint);
1901
5.77k
        xmlXIncludeSetFlags(xinc, lint->parseOptions);
1902
5.77k
        res = xmlXIncludeProcessNode(xinc, (xmlNode *) doc);
1903
5.77k
        xmlXIncludeFreeContext(xinc);
1904
5.77k
        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
5.77k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1913
1.31k
      endTimer(lint, "Xinclude processing");
1914
1.31k
  }
1915
5.77k
    }
1916
7.76k
#endif
1917
1918
    /*
1919
     * shell interaction
1920
     */
1921
7.76k
    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
7.76k
#ifdef LIBXML_XPATH_ENABLED
1930
7.76k
    if (lint->xpathquery != NULL) {
1931
5.99k
  xmlXPathOrderDocElems(doc);
1932
5.99k
        doXPathQuery(lint, doc, lint->xpathquery);
1933
5.99k
    }
1934
7.76k
#endif
1935
1936
    /*
1937
     * test intermediate copy if needed.
1938
     */
1939
7.76k
    if (lint->appOptions & XML_LINT_COPY_ENABLED) {
1940
2.46k
        xmlDocPtr tmp;
1941
1942
2.46k
        tmp = doc;
1943
2.46k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1944
570
      startTimer(lint);
1945
570
  }
1946
2.46k
  doc = xmlCopyDoc(doc, 1);
1947
2.46k
        if (doc == NULL) {
1948
29
            lint->progresult = XMLLINT_ERR_MEM;
1949
29
            xmlFreeDoc(tmp);
1950
29
            return;
1951
29
        }
1952
2.43k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1953
550
      endTimer(lint, "Copying");
1954
550
  }
1955
2.43k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1956
550
      startTimer(lint);
1957
550
  }
1958
2.43k
  xmlFreeDoc(tmp);
1959
2.43k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1960
550
      endTimer(lint, "Freeing original");
1961
550
  }
1962
2.43k
    }
1963
1964
7.73k
#ifdef LIBXML_VALID_ENABLED
1965
7.73k
    if ((lint->appOptions & XML_LINT_VALID_INSERTIONS)
1966
3.41k
#ifdef LIBXML_HTML_ENABLED
1967
3.41k
        && ((lint->appOptions & XML_LINT_HTML_ENABLED) != XML_LINT_HTML_ENABLED)
1968
7.73k
#endif
1969
7.73k
    ) {
1970
1.90k
        const xmlChar* list[256];
1971
1.90k
  int nb, i;
1972
1.90k
  xmlNodePtr node;
1973
1974
1.90k
  if (doc->children != NULL) {
1975
1.90k
      node = doc->children;
1976
1.90k
      while ((node != NULL) &&
1977
1.90k
                   ((node->type != XML_ELEMENT_NODE) ||
1978
1.90k
                    (node->last == NULL)))
1979
0
                node = node->next;
1980
1.90k
      if (node != NULL) {
1981
1.90k
    nb = xmlValidGetValidElements(node->last, NULL, list, 256);
1982
1.90k
    if (nb < 0) {
1983
1.90k
        fprintf(errStream, "could not get valid list of elements\n");
1984
1.90k
    } 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
1.90k
      }
1994
1.90k
  }
1995
1.90k
    } else
1996
5.83k
#endif /* LIBXML_VALID_ENABLED */
1997
5.83k
#ifdef LIBXML_READER_ENABLED
1998
5.83k
    if (lint->appOptions & XML_LINT_USE_WALKER) {
1999
1.73k
        walkDoc(lint, doc);
2000
1.73k
    }
2001
7.73k
#endif /* LIBXML_READER_ENABLED */
2002
7.73k
#ifdef LIBXML_OUTPUT_ENABLED
2003
7.73k
    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
1.42k
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2011
72
    startTimer(lint);
2012
72
      }
2013
1.42k
#ifdef LIBXML_C14N_ENABLED
2014
1.42k
            if (lint->appOptions & XML_LINT_CANONICAL_V1_0) {
2015
204
          xmlChar *result = NULL;
2016
204
    int size;
2017
2018
204
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2019
204
    if (size >= 0) {
2020
204
        if (write(1, result, size) == -1) {
2021
191
            fprintf(errStream, "Can't write data\n");
2022
191
        }
2023
204
        xmlFree(result);
2024
204
    } else {
2025
0
        fprintf(errStream, "Failed to canonicalize\n");
2026
0
        lint->progresult = XMLLINT_ERR_OUT;
2027
0
    }
2028
1.22k
      } else if (lint->appOptions & XML_LINT_CANONICAL_V1_1) {
2029
81
          xmlChar *result = NULL;
2030
81
    int size;
2031
2032
81
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
2033
81
    if (size >= 0) {
2034
81
        if (write(1, result, size) == -1) {
2035
61
            fprintf(errStream, "Can't write data\n");
2036
61
        }
2037
81
        xmlFree(result);
2038
81
    } else {
2039
0
        fprintf(errStream, "Failed to canonicalize\n");
2040
0
        lint->progresult = XMLLINT_ERR_OUT;
2041
0
    }
2042
1.14k
      } else if (lint->appOptions & XML_LINT_CANONICAL_EXE) {
2043
112
          xmlChar *result = NULL;
2044
112
    int size;
2045
2046
112
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
2047
112
    if (size >= 0) {
2048
112
        if (write(1, result, size) == -1) {
2049
112
            fprintf(errStream, "Can't write data\n");
2050
112
        }
2051
112
        xmlFree(result);
2052
112
    } else {
2053
0
        fprintf(errStream, "Failed to canonicalize\n");
2054
0
        lint->progresult = XMLLINT_ERR_OUT;
2055
0
    }
2056
112
      } else
2057
1.02k
#endif
2058
1.02k
            {
2059
1.02k
          xmlSaveCtxtPtr ctxt = NULL;
2060
1.02k
    int saveOpts = 0;
2061
2062
1.02k
                if (lint->format == 1)
2063
92
        saveOpts |= XML_SAVE_FORMAT;
2064
936
                else if (lint->format == 2)
2065
901
                    saveOpts |= XML_SAVE_WSNONSIG;
2066
2067
1.02k
#if defined(LIBXML_HTML_ENABLED)
2068
1.02k
                if (lint->appOptions & XML_LINT_XML_OUT)
2069
64
                    saveOpts |= XML_SAVE_AS_XML;
2070
1.02k
#endif
2071
2072
1.02k
#ifdef LIBXML_ZLIB_ENABLED
2073
1.02k
          if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) {
2074
6
                    gzFile gz;
2075
2076
6
                    if (lint->output == NULL)
2077
6
                        gz = gzdopen(STDOUT_FILENO, "wb9");
2078
0
                    else
2079
0
                        gz = gzopen(lint->output, "wb9");
2080
2081
6
                    if (gz != NULL)
2082
6
                        ctxt = xmlSaveToIO(xmllintGzWrite, xmllintGzClose, gz,
2083
6
                                           lint->encoding, saveOpts);
2084
6
                } else
2085
1.02k
#endif
2086
1.02k
                {
2087
1.02k
                    if (lint->output == NULL)
2088
1.02k
                        ctxt = xmlSaveToFd(STDOUT_FILENO, lint->encoding,
2089
1.02k
                                           saveOpts);
2090
0
                    else
2091
0
                        ctxt = xmlSaveToFilename(lint->output, lint->encoding,
2092
0
                                                 saveOpts);
2093
1.02k
                }
2094
2095
1.02k
    if (ctxt != NULL) {
2096
376
                    if (lint->indentString != NULL)
2097
0
                        xmlSaveSetIndentString(ctxt, lint->indentString);
2098
2099
376
        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
376
        xmlSaveClose(ctxt);
2105
652
    } else {
2106
652
                    fprintf(errStream, "failed save to %s\n",
2107
652
                            lint->output ? lint->output : "-");
2108
652
        lint->progresult = XMLLINT_ERR_OUT;
2109
652
    }
2110
1.02k
      }
2111
1.42k
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2112
72
    endTimer(lint, "Saving");
2113
72
      }
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
1.42k
    }
2134
7.73k
#endif /* LIBXML_OUTPUT_ENABLED */
2135
2136
7.73k
#ifdef LIBXML_VALID_ENABLED
2137
    /*
2138
     * A posteriori validation test
2139
     */
2140
7.73k
    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
7.73k
    } else if (lint->appOptions & XML_LINT_POST_VALIDATION) {
2192
2.72k
  xmlValidCtxtPtr cvp;
2193
2194
2.72k
  cvp = xmlNewValidCtxt();
2195
2.72k
  if (cvp == NULL) {
2196
0
            lint->progresult = XMLLINT_ERR_MEM;
2197
0
            xmlFreeDoc(doc);
2198
0
            return;
2199
0
  }
2200
2201
2.72k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2202
232
      startTimer(lint);
2203
232
  }
2204
2.72k
  if (!xmlValidateDocument(cvp, doc)) {
2205
2.72k
      fprintf(errStream,
2206
2.72k
        "Document %s does not validate\n", filename);
2207
2.72k
      lint->progresult = XMLLINT_ERR_VALID;
2208
2.72k
  }
2209
2.72k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2210
232
      endTimer(lint, "Validating");
2211
232
  }
2212
2.72k
  xmlFreeValidCtxt(cvp);
2213
2.72k
    }
2214
7.73k
#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
7.73k
#ifdef LIBXML_RELAXNG_ENABLED
2258
7.73k
    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
7.73k
#endif /* LIBXML_RELAXNG_ENABLED */
2291
2292
7.73k
#ifdef LIBXML_SCHEMAS_ENABLED
2293
7.73k
    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
7.73k
#endif /* LIBXML_SCHEMAS_ENABLED */
2326
2327
    /* Avoid unused label warning */
2328
7.73k
    goto done;
2329
2330
7.74k
done:
2331
    /*
2332
     * free it.
2333
     */
2334
7.74k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2335
1.51k
  startTimer(lint);
2336
1.51k
    }
2337
7.74k
    xmlFreeDoc(doc);
2338
7.74k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2339
1.51k
  endTimer(lint, "Freeing");
2340
1.51k
    }
2341
7.74k
}
2342
2343
/************************************************************************
2344
 *                  *
2345
 *      Usage and Main          *
2346
 *                  *
2347
 ************************************************************************/
2348
2349
1.46k
static void showVersion(FILE *errStream, const char *name) {
2350
1.46k
    fprintf(errStream, "%s: using libxml version %s\n", name, xmlParserVersion);
2351
1.46k
    fprintf(errStream, "   compiled with: ");
2352
1.46k
    if (xmlHasFeature(XML_WITH_THREAD)) fprintf(errStream, "Threads ");
2353
1.46k
    fprintf(errStream, "Tree ");
2354
1.46k
    if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(errStream, "Output ");
2355
1.46k
    if (xmlHasFeature(XML_WITH_PUSH)) fprintf(errStream, "Push ");
2356
1.46k
    if (xmlHasFeature(XML_WITH_READER)) fprintf(errStream, "Reader ");
2357
1.46k
    if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(errStream, "Patterns ");
2358
1.46k
    if (xmlHasFeature(XML_WITH_WRITER)) fprintf(errStream, "Writer ");
2359
1.46k
    if (xmlHasFeature(XML_WITH_SAX1)) fprintf(errStream, "SAXv1 ");
2360
1.46k
    if (xmlHasFeature(XML_WITH_VALID)) fprintf(errStream, "DTDValid ");
2361
1.46k
    if (xmlHasFeature(XML_WITH_HTML)) fprintf(errStream, "HTML ");
2362
1.46k
    if (xmlHasFeature(XML_WITH_C14N)) fprintf(errStream, "C14N ");
2363
1.46k
    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(errStream, "Catalog ");
2364
1.46k
    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(errStream, "XPath ");
2365
1.46k
    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(errStream, "XPointer ");
2366
1.46k
    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(errStream, "XInclude ");
2367
1.46k
    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(errStream, "Iconv ");
2368
1.46k
    if (xmlHasFeature(XML_WITH_ICU)) fprintf(errStream, "ICU ");
2369
1.46k
    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(errStream, "ISO8859X ");
2370
1.46k
    if (xmlHasFeature(XML_WITH_REGEXP))
2371
1.46k
        fprintf(errStream, "Regexps Automata ");
2372
1.46k
    if (xmlHasFeature(XML_WITH_RELAXNG)) fprintf(errStream, "RelaxNG ");
2373
1.46k
    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(errStream, "Schemas ");
2374
1.46k
    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(errStream, "Schematron ");
2375
1.46k
    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(errStream, "Modules ");
2376
1.46k
    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(errStream, "Debug ");
2377
1.46k
    if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(errStream, "Zlib ");
2378
1.46k
    fprintf(errStream, "\n");
2379
1.46k
}
2380
2381
70
static void usage(FILE *f, const char *name) {
2382
70
    fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
2383
70
#ifdef LIBXML_OUTPUT_ENABLED
2384
70
    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
70
    fprintf(f, "\t--version : display the version of the XML library used\n");
2389
70
    fprintf(f, "\t--shell : run a navigating shell\n");
2390
70
    fprintf(f, "\t--debug : show additional debug information\n");
2391
70
    fprintf(f, "\t--copy : used to test the internal copy implementation\n");
2392
70
    fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
2393
70
    fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
2394
70
    fprintf(f, "\t--noent : substitute entity references by their value\n");
2395
70
    fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
2396
70
    fprintf(f, "\t--noout : don't output the result tree\n");
2397
70
    fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
2398
70
    fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
2399
70
    fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
2400
70
    fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
2401
70
#ifdef LIBXML_VALID_ENABLED
2402
70
    fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
2403
70
    fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
2404
70
    fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
2405
70
    fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
2406
70
    fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
2407
70
#endif /* LIBXML_VALID_ENABLED */
2408
70
    fprintf(f, "\t--strict-namespace : Return application failure if document has any namespace errors\n");
2409
70
    fprintf(f, "\t--quiet : be quiet when succeeded\n");
2410
70
    fprintf(f, "\t--timing : print some timings\n");
2411
70
    fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
2412
70
    fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
2413
70
#ifdef LIBXML_HTML_ENABLED
2414
70
    fprintf(f, "\t--html : use the HTML parser\n");
2415
70
    fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
2416
70
#ifdef LIBXML_OUTPUT_ENABLED
2417
70
    fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
2418
70
#endif
2419
70
#endif
2420
70
#ifdef LIBXML_PUSH_ENABLED
2421
70
    fprintf(f, "\t--push : use the push mode of the parser\n");
2422
70
#endif /* LIBXML_PUSH_ENABLED */
2423
70
#if HAVE_DECL_MMAP
2424
70
    fprintf(f, "\t--memory : parse from memory\n");
2425
70
#endif
2426
70
    fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
2427
70
    fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
2428
70
    fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
2429
70
    fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
2430
70
    fprintf(f, "\t--nodict : create document without dictionary\n");
2431
70
    fprintf(f, "\t--pedantic : enable additional warnings\n");
2432
70
#ifdef LIBXML_OUTPUT_ENABLED
2433
70
    fprintf(f, "\t--output file or -o file: save to a given file\n");
2434
70
    fprintf(f, "\t--format : reformat/reindent the output\n");
2435
70
    fprintf(f, "\t--encode encoding : output in the given encoding\n");
2436
70
    fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
2437
70
    fprintf(f, "\t                 0 Do not pretty print\n");
2438
70
    fprintf(f, "\t                 1 Format the XML content, as --format\n");
2439
70
    fprintf(f, "\t                 2 Add whitespace inside tags, preserving content\n");
2440
70
#ifdef LIBXML_ZLIB_ENABLED
2441
70
    fprintf(f, "\t--compress : turn on gzip compression of output\n");
2442
70
#endif
2443
70
#ifdef LIBXML_C14N_ENABLED
2444
70
    fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
2445
70
    fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
2446
70
    fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
2447
70
#endif /* LIBXML_C14N_ENABLED */
2448
70
#endif /* LIBXML_OUTPUT_ENABLED */
2449
70
    fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
2450
70
#ifdef LIBXML_CATALOG_ENABLED
2451
70
    fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2452
70
    fprintf(f, "\t             otherwise XML Catalogs starting from \n");
2453
70
    fprintf(f, "\t         file://" XML_SYSCONFDIR "/xml/catalog "
2454
70
            "are activated by default\n");
2455
70
    fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
2456
70
#endif
2457
70
    fprintf(f, "\t--auto : generate a small doc on the fly\n");
2458
70
#ifdef LIBXML_XINCLUDE_ENABLED
2459
70
    fprintf(f, "\t--xinclude : do XInclude processing\n");
2460
70
    fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
2461
70
    fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
2462
70
#endif
2463
70
    fprintf(f, "\t--loaddtd : fetch external DTD\n");
2464
70
    fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
2465
70
#ifdef LIBXML_READER_ENABLED
2466
70
    fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
2467
70
    fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
2468
70
#ifdef LIBXML_PATTERN_ENABLED
2469
70
    fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
2470
70
#endif
2471
70
#endif /* LIBXML_READER_ENABLED */
2472
70
#ifdef LIBXML_RELAXNG_ENABLED
2473
70
    fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
2474
70
#endif
2475
70
#ifdef LIBXML_SCHEMAS_ENABLED
2476
70
    fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
2477
70
#endif
2478
#ifdef LIBXML_SCHEMATRON_ENABLED
2479
    fprintf(f, "\t--schematron schema : do validation against a schematron\n");
2480
#endif
2481
70
#ifdef LIBXML_SAX1_ENABLED
2482
70
    fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
2483
70
#endif
2484
70
    fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
2485
70
    fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
2486
70
#ifdef LIBXML_XPATH_ENABLED
2487
70
    fprintf(f, "\t--xpath expr: evaluate the XPath expression, results are separated by \\n, imply --noout\n");
2488
70
    fprintf(f, "\t--xpath0 expr: evaluate the XPath expression, results are separated by \\0, imply --noout\n");
2489
70
#endif
2490
70
    fprintf(f, "\t--max-ampl value: set maximum amplification factor\n");
2491
2492
70
    fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
2493
70
}
2494
2495
static int
2496
parseInteger(unsigned long *result, FILE *errStream, const char *ctxt,
2497
5.19k
             const char *str, unsigned long min, unsigned long max) {
2498
5.19k
    char *strEnd;
2499
5.19k
    unsigned long val;
2500
2501
5.19k
    if (str != NULL && *str == '-') {
2502
0
        fprintf(errStream, "%s: value not allowed: %s\n", ctxt, str);
2503
0
        return(-1);
2504
0
    }
2505
2506
5.19k
    errno = 0;
2507
5.19k
    val = strtoul(str, &strEnd, 10);
2508
5.19k
    if (errno == EINVAL || *strEnd != 0) {
2509
0
        fprintf(errStream, "%s: invalid integer: %s\n", ctxt, str);
2510
0
        return(-1);
2511
0
    }
2512
5.19k
    if (errno != 0 || val < min || val > max) {
2513
13
        fprintf(errStream, "%s: integer out of range: %s\n", ctxt, str);
2514
13
        return(-1);
2515
13
    }
2516
2517
5.17k
    *result = val;
2518
5.17k
    return(0);
2519
5.19k
}
2520
2521
static int
2522
103k
skipArgs(const char *arg) {
2523
103k
    if ((!strcmp(arg, "-path")) ||
2524
103k
        (!strcmp(arg, "--path")) ||
2525
103k
        (!strcmp(arg, "-maxmem")) ||
2526
103k
        (!strcmp(arg, "--maxmem")) ||
2527
101k
#ifdef LIBXML_OUTPUT_ENABLED
2528
101k
        (!strcmp(arg, "-o")) ||
2529
101k
        (!strcmp(arg, "-output")) ||
2530
101k
        (!strcmp(arg, "--output")) ||
2531
101k
        (!strcmp(arg, "-encode")) ||
2532
101k
        (!strcmp(arg, "--encode")) ||
2533
99.7k
        (!strcmp(arg, "-pretty")) ||
2534
99.7k
        (!strcmp(arg, "--pretty")) ||
2535
97.0k
#endif
2536
97.0k
#ifdef LIBXML_VALID_ENABLED
2537
97.0k
        (!strcmp(arg, "-dtdvalid")) ||
2538
97.0k
        (!strcmp(arg, "--dtdvalid")) ||
2539
97.0k
        (!strcmp(arg, "-dtdvalidfpi")) ||
2540
97.0k
        (!strcmp(arg, "--dtdvalidfpi")) ||
2541
97.0k
#endif
2542
97.0k
#ifdef LIBXML_RELAXNG_ENABLED
2543
97.0k
        (!strcmp(arg, "-relaxng")) ||
2544
97.0k
        (!strcmp(arg, "--relaxng")) ||
2545
97.0k
#endif
2546
97.0k
#ifdef LIBXML_SCHEMAS_ENABLED
2547
97.0k
        (!strcmp(arg, "-schema")) ||
2548
97.0k
        (!strcmp(arg, "--schema")) ||
2549
97.0k
#endif
2550
#ifdef LIBXML_SCHEMATRON_ENABLED
2551
        (!strcmp(arg, "-schematron")) ||
2552
        (!strcmp(arg, "--schematron")) ||
2553
#endif
2554
97.0k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2555
97.0k
        (!strcmp(arg, "-pattern")) ||
2556
97.0k
        (!strcmp(arg, "--pattern")) ||
2557
95.7k
#endif
2558
95.7k
#ifdef LIBXML_XPATH_ENABLED
2559
95.7k
        (!strcmp(arg, "-xpath")) ||
2560
95.7k
        (!strcmp(arg, "--xpath")) ||
2561
90.7k
        (!strcmp(arg, "-xpath0")) ||
2562
90.7k
        (!strcmp(arg, "--xpath0")) ||
2563
90.7k
#endif
2564
90.7k
        (!strcmp(arg, "-max-ampl")) ||
2565
90.7k
        (!strcmp(arg, "--max-ampl"))
2566
103k
    ) {
2567
13.3k
        return(1);
2568
13.3k
    }
2569
2570
90.3k
    return(0);
2571
103k
}
2572
2573
static void
2574
6.58k
xmllintInit(xmllintState *lint) {
2575
6.58k
    memset(lint, 0, sizeof(*lint));
2576
2577
6.58k
    lint->repeat = 1;
2578
6.58k
    lint->progresult = XMLLINT_RETURN_OK;
2579
6.58k
    lint->parseOptions = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
2580
6.58k
#ifdef LIBXML_HTML_ENABLED
2581
6.58k
    lint->htmlOptions = HTML_PARSE_COMPACT | HTML_PARSE_BIG_LINES;
2582
6.58k
#endif
2583
6.58k
}
2584
2585
static void
2586
22.0k
xmllintOptWarnNoSupport(FILE *errStream, const char *opt, const char *nosupp) {
2587
22.0k
    fprintf(errStream, "Warning: Option %s doesn't support %s\n", opt, nosupp);
2588
22.0k
}
2589
2590
static int
2591
6.58k
xmllintParseOptions(xmllintState *lint, int argc, const char **argv) {
2592
6.58k
    FILE *errStream = lint->errStream;
2593
6.58k
    const char *specialMode = NULL;
2594
6.58k
    int i;
2595
2596
6.58k
    if (argc <= 1) {
2597
0
        usage(errStream, argv[0]);
2598
0
        return(XMLLINT_ERR_UNCLASS);
2599
0
    }
2600
2601
120k
    for (i = 1; i < argc ; i++) {
2602
113k
        unsigned long val;
2603
2604
113k
        if (argv[i][0] != '-' || argv[i][1] == 0)
2605
6.50k
            continue;
2606
2607
107k
        if ((!strcmp(argv[i], "-maxmem")) ||
2608
107k
            (!strcmp(argv[i], "--maxmem"))) {
2609
1.92k
            i++;
2610
1.92k
            if (i >= argc) {
2611
0
                fprintf(errStream, "maxmem: missing integer value\n");
2612
0
                return(XMLLINT_ERR_UNCLASS);
2613
0
            }
2614
1.92k
            if (parseInteger(&val, errStream, "maxmem", argv[i],
2615
1.92k
                             0, INT_MAX) < 0)
2616
0
                return(XMLLINT_ERR_UNCLASS);
2617
1.92k
            lint->maxmem = val;
2618
105k
        } else if ((!strcmp(argv[i], "-debug")) ||
2619
105k
                   (!strcmp(argv[i], "--debug"))) {
2620
1.91k
            lint->appOptions |= XML_LINT_DEBUG_ENABLED;
2621
103k
        } else if ((!strcmp(argv[i], "-shell")) ||
2622
103k
                   (!strcmp(argv[i], "--shell"))) {
2623
0
            lint->appOptions |= XML_LINT_NAVIGATING_SHELL;
2624
103k
        } else if ((!strcmp(argv[i], "-copy")) ||
2625
103k
                   (!strcmp(argv[i], "--copy"))) {
2626
1.91k
            lint->appOptions |= XML_LINT_COPY_ENABLED;
2627
101k
        } else if ((!strcmp(argv[i], "-recover")) ||
2628
101k
                   (!strcmp(argv[i], "--recover"))) {
2629
977
            lint->parseOptions |= XML_PARSE_RECOVER;
2630
100k
        } else if ((!strcmp(argv[i], "-huge")) ||
2631
100k
                   (!strcmp(argv[i], "--huge"))) {
2632
2.21k
            lint->parseOptions |= XML_PARSE_HUGE;
2633
2.21k
#ifdef LIBXML_HTML_ENABLED
2634
2.21k
            lint->htmlOptions |= HTML_PARSE_HUGE;
2635
2.21k
#endif
2636
98.1k
        } else if ((!strcmp(argv[i], "-noent")) ||
2637
98.1k
                   (!strcmp(argv[i], "--noent"))) {
2638
1.53k
            lint->parseOptions |= XML_PARSE_NOENT;
2639
96.6k
        } else if ((!strcmp(argv[i], "-noenc")) ||
2640
96.6k
                   (!strcmp(argv[i], "--noenc"))) {
2641
1.40k
            lint->parseOptions |= XML_PARSE_IGNORE_ENC;
2642
1.40k
#ifdef LIBXML_HTML_ENABLED
2643
1.40k
            lint->htmlOptions |= HTML_PARSE_IGNORE_ENC;
2644
1.40k
#endif
2645
95.2k
        } else if ((!strcmp(argv[i], "-nsclean")) ||
2646
95.2k
                   (!strcmp(argv[i], "--nsclean"))) {
2647
2.51k
            lint->parseOptions |= XML_PARSE_NSCLEAN;
2648
92.6k
        } else if ((!strcmp(argv[i], "-nocdata")) ||
2649
92.6k
                   (!strcmp(argv[i], "--nocdata"))) {
2650
2.48k
            lint->parseOptions |= XML_PARSE_NOCDATA;
2651
90.2k
        } else if ((!strcmp(argv[i], "-nodict")) ||
2652
90.2k
                   (!strcmp(argv[i], "--nodict"))) {
2653
2.92k
            lint->parseOptions |= XML_PARSE_NODICT;
2654
87.2k
        } else if ((!strcmp(argv[i], "-version")) ||
2655
87.2k
                   (!strcmp(argv[i], "--version"))) {
2656
1.46k
            showVersion(errStream, argv[0]);
2657
1.46k
            lint->version = 1;
2658
85.8k
        } else if ((!strcmp(argv[i], "-noout")) ||
2659
85.8k
                   (!strcmp(argv[i], "--noout"))) {
2660
1.94k
            lint->noout = 1;
2661
1.94k
#ifdef LIBXML_HTML_ENABLED
2662
83.8k
        } else if ((!strcmp(argv[i], "-html")) ||
2663
83.8k
                   (!strcmp(argv[i], "--html"))) {
2664
2.17k
            lint->appOptions |= XML_LINT_HTML_ENABLED;
2665
81.6k
        } else if ((!strcmp(argv[i], "-nodefdtd")) ||
2666
81.6k
                   (!strcmp(argv[i], "--nodefdtd"))) {
2667
1.84k
            lint->htmlOptions |= HTML_PARSE_NODEFDTD;
2668
1.84k
#ifdef LIBXML_OUTPUT_ENABLED
2669
79.8k
        } else if ((!strcmp(argv[i], "-xmlout")) ||
2670
79.8k
                   (!strcmp(argv[i], "--xmlout"))) {
2671
1.85k
            lint->appOptions |= XML_LINT_XML_OUT;
2672
1.85k
#endif
2673
1.85k
#endif /* LIBXML_HTML_ENABLED */
2674
78.0k
        } else if ((!strcmp(argv[i], "-loaddtd")) ||
2675
78.0k
                   (!strcmp(argv[i], "--loaddtd"))) {
2676
2.07k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2677
75.9k
        } else if ((!strcmp(argv[i], "-dtdattr")) ||
2678
75.9k
                   (!strcmp(argv[i], "--dtdattr"))) {
2679
2.76k
            lint->parseOptions |= XML_PARSE_DTDATTR;
2680
2.76k
#ifdef LIBXML_VALID_ENABLED
2681
73.1k
        } else if ((!strcmp(argv[i], "-valid")) ||
2682
73.1k
                   (!strcmp(argv[i], "--valid"))) {
2683
1.61k
            lint->parseOptions |= XML_PARSE_DTDVALID;
2684
71.5k
        } else if ((!strcmp(argv[i], "-postvalid")) ||
2685
71.5k
                   (!strcmp(argv[i], "--postvalid"))) {
2686
1.77k
            lint->appOptions |= XML_LINT_POST_VALIDATION;
2687
1.77k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2688
69.7k
        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
2689
69.7k
                   (!strcmp(argv[i], "--dtdvalid"))) {
2690
0
            i++;
2691
0
            lint->dtdvalid = argv[i];
2692
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2693
69.7k
        } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2694
69.7k
                   (!strcmp(argv[i], "--dtdvalidfpi"))) {
2695
0
            i++;
2696
0
            lint->dtdvalidfpi = argv[i];
2697
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2698
69.7k
        } else if ((!strcmp(argv[i], "-insert")) ||
2699
69.7k
                   (!strcmp(argv[i], "--insert"))) {
2700
3.03k
            lint->appOptions |= XML_LINT_VALID_INSERTIONS;
2701
3.03k
#endif /* LIBXML_VALID_ENABLED */
2702
66.7k
        } else if ((!strcmp(argv[i], "-strict-namespace")) ||
2703
66.7k
            (!strcmp(argv[i], "--strict-namespace"))) {
2704
0
            lint->appOptions |= XML_LINT_STRICT_NAMESPACE;
2705
66.7k
        } else if ((!strcmp(argv[i], "-dropdtd")) ||
2706
66.7k
                   (!strcmp(argv[i], "--dropdtd"))) {
2707
1.42k
            lint->appOptions |= XML_LINT_DROP_DTD;
2708
65.3k
        } else if ((!strcmp(argv[i], "-quiet")) ||
2709
65.3k
                   (!strcmp(argv[i], "--quiet"))) {
2710
755
            lint->appOptions |= XML_LINT_QUIET;
2711
64.5k
        } else if ((!strcmp(argv[i], "-timing")) ||
2712
64.5k
                   (!strcmp(argv[i], "--timing"))) {
2713
1.81k
            lint->appOptions |= XML_LINT_TIMINGS;
2714
62.7k
        } else if ((!strcmp(argv[i], "-auto")) ||
2715
62.7k
                   (!strcmp(argv[i], "--auto"))) {
2716
5.93k
            lint->appOptions |= XML_LINT_GENERATE;
2717
56.8k
        } else if ((!strcmp(argv[i], "-repeat")) ||
2718
56.8k
                   (!strcmp(argv[i], "--repeat"))) {
2719
1.00k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2720
1.00k
            lint->repeat = 2;
2721
#else
2722
            if (lint->repeat > 1)
2723
                lint->repeat *= 10;
2724
            else
2725
                lint->repeat = 100;
2726
#endif
2727
1.00k
#ifdef LIBXML_PUSH_ENABLED
2728
55.8k
        } else if ((!strcmp(argv[i], "-push")) ||
2729
55.8k
                   (!strcmp(argv[i], "--push"))) {
2730
242
            lint->appOptions |= XML_LINT_PUSH_ENABLED;
2731
242
#endif /* LIBXML_PUSH_ENABLED */
2732
242
#if HAVE_DECL_MMAP
2733
55.5k
        } else if ((!strcmp(argv[i], "-memory")) ||
2734
55.5k
                   (!strcmp(argv[i], "--memory"))) {
2735
0
            lint->appOptions |= XML_LINT_MEMORY;
2736
0
#endif
2737
0
#ifdef LIBXML_XINCLUDE_ENABLED
2738
55.5k
        } else if ((!strcmp(argv[i], "-xinclude")) ||
2739
55.5k
                   (!strcmp(argv[i], "--xinclude"))) {
2740
2.22k
            lint->appOptions |= XML_LINT_XINCLUDE;
2741
2.22k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2742
53.3k
        } else if ((!strcmp(argv[i], "-noxincludenode")) ||
2743
53.3k
                   (!strcmp(argv[i], "--noxincludenode"))) {
2744
3.14k
            lint->appOptions |= XML_LINT_XINCLUDE;
2745
3.14k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2746
3.14k
            lint->parseOptions |= XML_PARSE_NOXINCNODE;
2747
50.2k
        } else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
2748
50.2k
                   (!strcmp(argv[i], "--nofixup-base-uris"))) {
2749
2.60k
            lint->appOptions |= XML_LINT_XINCLUDE;
2750
2.60k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2751
2.60k
            lint->parseOptions |= XML_PARSE_NOBASEFIX;
2752
2.60k
#endif
2753
47.6k
        } else if ((!strcmp(argv[i], "-nowarning")) ||
2754
47.6k
                   (!strcmp(argv[i], "--nowarning"))) {
2755
2.42k
            lint->parseOptions |= XML_PARSE_NOWARNING;
2756
2.42k
            lint->parseOptions &= ~XML_PARSE_PEDANTIC;
2757
2.42k
#ifdef LIBXML_HTML_ENABLED
2758
2.42k
            lint->htmlOptions |= HTML_PARSE_NOWARNING;
2759
2.42k
#endif
2760
45.1k
        } else if ((!strcmp(argv[i], "-pedantic")) ||
2761
45.1k
                   (!strcmp(argv[i], "--pedantic"))) {
2762
800
            lint->parseOptions |= XML_PARSE_PEDANTIC;
2763
800
            lint->parseOptions &= ~XML_PARSE_NOWARNING;
2764
800
#ifdef LIBXML_CATALOG_ENABLED
2765
44.3k
        } else if ((!strcmp(argv[i], "-catalogs")) ||
2766
44.3k
                   (!strcmp(argv[i], "--catalogs"))) {
2767
0
            lint->appOptions |= XML_LINT_USE_CATALOGS;
2768
44.3k
        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
2769
44.3k
                   (!strcmp(argv[i], "--nocatalogs"))) {
2770
6.58k
            lint->appOptions |= XML_LINT_USE_NO_CATALOGS;
2771
6.58k
            lint->parseOptions |= XML_PARSE_NO_SYS_CATALOG;
2772
6.58k
#endif
2773
37.7k
        } else if ((!strcmp(argv[i], "-noblanks")) ||
2774
37.7k
                   (!strcmp(argv[i], "--noblanks"))) {
2775
1.79k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2776
1.79k
#ifdef LIBXML_HTML_ENABLED
2777
1.79k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2778
1.79k
#endif
2779
1.79k
#ifdef LIBXML_OUTPUT_ENABLED
2780
36.0k
        } else if ((!strcmp(argv[i], "-o")) ||
2781
36.0k
                   (!strcmp(argv[i], "-output")) ||
2782
36.0k
                   (!strcmp(argv[i], "--output"))) {
2783
0
            i++;
2784
0
            lint->output = argv[i];
2785
36.0k
        } else if ((!strcmp(argv[i], "-format")) ||
2786
36.0k
                   (!strcmp(argv[i], "--format"))) {
2787
2.95k
            lint->format = 1;
2788
2.95k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2789
2.95k
#ifdef LIBXML_HTML_ENABLED
2790
2.95k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2791
2.95k
#endif
2792
33.0k
        } else if ((!strcmp(argv[i], "-encode")) ||
2793
33.0k
                   (!strcmp(argv[i], "--encode"))) {
2794
2.05k
            i++;
2795
2.05k
            lint->encoding = argv[i];
2796
31.0k
        } else if ((!strcmp(argv[i], "-pretty")) ||
2797
31.0k
                   (!strcmp(argv[i], "--pretty"))) {
2798
2.86k
            i++;
2799
2.86k
            if (i >= argc) {
2800
0
                fprintf(errStream, "pretty: missing integer value\n");
2801
0
                return(XMLLINT_ERR_UNCLASS);
2802
0
            }
2803
2.86k
            if (parseInteger(&val, errStream, "pretty", argv[i],
2804
2.86k
                             0, 2) < 0)
2805
13
                return(XMLLINT_ERR_UNCLASS);
2806
2.85k
            lint->format = val;
2807
2.85k
#ifdef LIBXML_ZLIB_ENABLED
2808
28.1k
        } else if ((!strcmp(argv[i], "-compress")) ||
2809
28.1k
                   (!strcmp(argv[i], "--compress"))) {
2810
713
            lint->appOptions |= XML_LINT_ZLIB_COMPRESSION;
2811
713
#endif
2812
713
#ifdef LIBXML_C14N_ENABLED
2813
27.4k
        } else if ((!strcmp(argv[i], "-c14n")) ||
2814
27.4k
                   (!strcmp(argv[i], "--c14n"))) {
2815
1.72k
            lint->appOptions |= XML_LINT_CANONICAL_V1_0;
2816
1.72k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2817
25.7k
        } else if ((!strcmp(argv[i], "-c14n11")) ||
2818
25.7k
                   (!strcmp(argv[i], "--c14n11"))) {
2819
2.60k
            lint->appOptions |= XML_LINT_CANONICAL_V1_1;
2820
2.60k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2821
23.0k
        } else if ((!strcmp(argv[i], "-exc-c14n")) ||
2822
23.0k
                   (!strcmp(argv[i], "--exc-c14n"))) {
2823
1.87k
            lint->appOptions |= XML_LINT_CANONICAL_EXE;
2824
1.87k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2825
1.87k
#endif /* LIBXML_C14N_ENABLED */
2826
1.87k
#endif /* LIBXML_OUTPUT_ENABLED */
2827
1.87k
#ifdef LIBXML_READER_ENABLED
2828
21.2k
        } else if ((!strcmp(argv[i], "-stream")) ||
2829
21.2k
                   (!strcmp(argv[i], "--stream"))) {
2830
1.27k
             lint->appOptions |= XML_LINT_USE_STREAMING;
2831
19.9k
        } else if ((!strcmp(argv[i], "-walker")) ||
2832
19.9k
                   (!strcmp(argv[i], "--walker"))) {
2833
1.76k
             lint->appOptions |= XML_LINT_USE_WALKER;
2834
1.76k
             lint->noout = 1;
2835
1.76k
#ifdef LIBXML_PATTERN_ENABLED
2836
18.1k
        } else if ((!strcmp(argv[i], "-pattern")) ||
2837
18.1k
                   (!strcmp(argv[i], "--pattern"))) {
2838
1.43k
            i++;
2839
1.43k
            lint->pattern = argv[i];
2840
1.43k
#endif
2841
1.43k
#endif /* LIBXML_READER_ENABLED */
2842
1.43k
#ifdef LIBXML_SAX1_ENABLED
2843
16.7k
        } else if ((!strcmp(argv[i], "-sax1")) ||
2844
16.7k
                   (!strcmp(argv[i], "--sax1"))) {
2845
1.73k
            lint->parseOptions |= XML_PARSE_SAX1;
2846
1.73k
#endif /* LIBXML_SAX1_ENABLED */
2847
15.0k
        } else if ((!strcmp(argv[i], "-sax")) ||
2848
15.0k
                   (!strcmp(argv[i], "--sax"))) {
2849
260
            lint->appOptions |= XML_LINT_SAX_ENABLED;
2850
260
#ifdef LIBXML_RELAXNG_ENABLED
2851
14.7k
        } else if ((!strcmp(argv[i], "-relaxng")) ||
2852
14.7k
                   (!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
14.7k
        } else if ((!strcmp(argv[i], "-schema")) ||
2859
14.7k
                 (!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
14.7k
        } else if ((!strcmp(argv[i], "-nonet")) ||
2872
14.7k
                   (!strcmp(argv[i], "--nonet"))) {
2873
2.23k
            lint->parseOptions |= XML_PARSE_NONET;
2874
12.5k
        } else if ((!strcmp(argv[i], "-nocompact")) ||
2875
12.5k
                   (!strcmp(argv[i], "--nocompact"))) {
2876
2.30k
            lint->parseOptions &= ~XML_PARSE_COMPACT;
2877
2.30k
#ifdef LIBXML_HTML_ENABLED
2878
2.30k
            lint->htmlOptions &= ~HTML_PARSE_COMPACT;
2879
2.30k
#endif
2880
10.2k
        } else if ((!strcmp(argv[i], "-load-trace")) ||
2881
10.2k
                   (!strcmp(argv[i], "--load-trace"))) {
2882
2.47k
            lint->appOptions |= XML_LINT_USE_LOAD_TRACE;
2883
7.73k
        } else if ((!strcmp(argv[i], "-path")) ||
2884
7.73k
                   (!strcmp(argv[i], "--path"))) {
2885
0
            i++;
2886
0
            parsePath(lint, BAD_CAST argv[i]);
2887
0
#ifdef LIBXML_XPATH_ENABLED
2888
7.73k
        } else if ((!strcmp(argv[i], "-xpath")) ||
2889
7.73k
                   (!strcmp(argv[i], "--xpath"))) {
2890
5.05k
            i++;
2891
5.05k
            lint->noout++;
2892
5.05k
            lint->xpathquery = argv[i];
2893
5.05k
            lint->xpathsep = "\n";
2894
5.05k
        } else if ((!strcmp(argv[i], "-xpath0")) ||
2895
2.68k
                   (!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
2.68k
        } else if ((!strcmp(argv[i], "-oldxml10")) ||
2902
2.68k
                   (!strcmp(argv[i], "--oldxml10"))) {
2903
2.21k
            lint->parseOptions |= XML_PARSE_OLD10;
2904
2.21k
        } else if ((!strcmp(argv[i], "-max-ampl")) ||
2905
469
                   (!strcmp(argv[i], "--max-ampl"))) {
2906
399
            i++;
2907
399
            if (i >= argc) {
2908
0
                fprintf(errStream, "max-ampl: missing integer value\n");
2909
0
                return(XMLLINT_ERR_UNCLASS);
2910
0
            }
2911
399
            if (parseInteger(&val, errStream, "max-ampl", argv[i],
2912
399
                             1, UINT_MAX) < 0)
2913
0
                return(XMLLINT_ERR_UNCLASS);
2914
399
            lint->maxAmpl = val;
2915
399
        } else {
2916
70
            fprintf(errStream, "Unknown option %s\n", argv[i]);
2917
70
            usage(errStream, argv[0]);
2918
70
            return(XMLLINT_ERR_UNCLASS);
2919
70
        }
2920
107k
    }
2921
2922
6.50k
    if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2923
0
        lint->repeat = 1;
2924
2925
6.50k
#ifdef LIBXML_READER_ENABLED
2926
6.50k
    if (lint->appOptions & XML_LINT_USE_STREAMING) {
2927
1.27k
        specialMode = "--stream";
2928
2929
1.27k
        if (lint->appOptions & XML_LINT_SAX_ENABLED)
2930
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--sax");
2931
1.27k
#ifdef LIBXML_PUSH_ENABLED
2932
1.27k
        if (lint->appOptions & XML_LINT_PUSH_ENABLED)
2933
150
            xmllintOptWarnNoSupport(errStream, "--stream", "--push");
2934
1.27k
#endif
2935
1.27k
#ifdef LIBXML_HTML_ENABLED
2936
1.27k
        if (lint->appOptions & XML_LINT_HTML_ENABLED)
2937
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--html");
2938
1.27k
#endif
2939
1.27k
    }
2940
6.50k
#endif /* LIBXML_READER_ENABLED */
2941
2942
6.50k
    if (lint->appOptions & XML_LINT_SAX_ENABLED) {
2943
260
        specialMode = "--sax";
2944
2945
260
#ifdef LIBXML_XINCLUDE_ENABLED
2946
260
        if (lint->appOptions & XML_LINT_XINCLUDE)
2947
244
            xmllintOptWarnNoSupport(errStream, "--sax", "--xinclude");
2948
260
#endif
2949
260
#ifdef LIBXML_RELAXNG_ENABLED
2950
260
        if (lint->relaxng != NULL)
2951
0
            xmllintOptWarnNoSupport(errStream, "--sax", "--relaxng");
2952
260
#endif
2953
260
    }
2954
2955
6.50k
    if (specialMode != NULL) {
2956
1.53k
        if (lint->appOptions & XML_LINT_GENERATE)
2957
1.44k
            xmllintOptWarnNoSupport(errStream, specialMode, "--auto");
2958
1.53k
        if (lint->appOptions & XML_LINT_DROP_DTD)
2959
168
            xmllintOptWarnNoSupport(errStream, specialMode, "--dropdtd");
2960
1.53k
        if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2961
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--shell");
2962
1.53k
        if (lint->appOptions & XML_LINT_COPY_ENABLED)
2963
423
            xmllintOptWarnNoSupport(errStream, specialMode, "--copy");
2964
1.53k
#ifdef LIBXML_XPATH_ENABLED
2965
1.53k
        if (lint->xpathquery != NULL)
2966
1.29k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xpath");
2967
1.53k
#endif
2968
1.53k
#ifdef LIBXML_READER_ENABLED
2969
1.53k
        if (lint->appOptions & XML_LINT_USE_WALKER)
2970
622
            xmllintOptWarnNoSupport(errStream, specialMode, "--walker");
2971
1.53k
#endif
2972
1.53k
#ifdef LIBXML_VALID_ENABLED
2973
1.53k
        if (lint->appOptions & XML_LINT_VALID_INSERTIONS)
2974
839
            xmllintOptWarnNoSupport(errStream, specialMode, "--insert");
2975
1.53k
        if (lint->dtdvalid != NULL)
2976
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalid");
2977
1.53k
        if (lint->dtdvalidfpi != NULL)
2978
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalidfpi");
2979
1.53k
        if (lint->appOptions & XML_LINT_POST_VALIDATION)
2980
273
            xmllintOptWarnNoSupport(errStream, specialMode, "--postvalid");
2981
1.53k
#endif
2982
#ifdef LIBXML_SCHEMATRON_ENABLED
2983
        if (lint->schematron != NULL)
2984
            xmllintOptWarnNoSupport(errStream, specialMode, "--schematron");
2985
#endif
2986
1.53k
#ifdef LIBXML_OUTPUT_ENABLED
2987
1.53k
        if (lint->output != NULL)
2988
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--output");
2989
1.53k
        if (lint->encoding != NULL)
2990
206
            xmllintOptWarnNoSupport(errStream, specialMode, "--encode");
2991
1.53k
        if (lint->format > 0)
2992
923
            xmllintOptWarnNoSupport(errStream, specialMode,
2993
923
                                    "--format or -pretty");
2994
1.53k
#ifdef LIBXML_ZLIB_ENABLED
2995
1.53k
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
2996
209
            xmllintOptWarnNoSupport(errStream, specialMode, "--compress");
2997
1.53k
#endif
2998
1.53k
#ifdef LIBXML_HTML_ENABLED
2999
1.53k
        if (lint->appOptions & XML_LINT_XML_OUT)
3000
500
            xmllintOptWarnNoSupport(errStream, specialMode, "--xmlout");
3001
1.53k
#endif
3002
1.53k
#ifdef LIBXML_C14N_ENABLED
3003
1.53k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_0)
3004
406
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n");
3005
1.53k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_1)
3006
797
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n11");
3007
1.53k
        if (lint->appOptions & XML_LINT_CANONICAL_EXE)
3008
458
            xmllintOptWarnNoSupport(errStream, specialMode, "--exc-c14n");
3009
1.53k
#endif
3010
1.53k
#endif /* LIBXML_OUTPUT_ENABLED */
3011
1.53k
    }
3012
3013
6.50k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3014
6.50k
    if (lint->pattern && !((lint->appOptions & XML_LINT_USE_STREAMING) || (lint->appOptions & XML_LINT_USE_WALKER)))
3015
1.00k
        fprintf(errStream, "Warning: Option %s requires %s\n",
3016
1.00k
                "--pattern", "--stream or --walker");
3017
6.50k
#endif
3018
3019
6.50k
#ifdef LIBXML_HTML_ENABLED
3020
6.50k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3021
2.17k
        if (lint->parseOptions & XML_PARSE_DTDATTR)
3022
1.89k
            xmllintOptWarnNoSupport(errStream, "--html", "--dtdattr");
3023
2.17k
        if (lint->parseOptions & XML_PARSE_DTDLOAD)
3024
1.90k
            xmllintOptWarnNoSupport(errStream, "--html", "--loaddtd");
3025
2.17k
        if (lint->maxAmpl)
3026
134
            xmllintOptWarnNoSupport(errStream, "--html", "--max-ampl");
3027
2.17k
        if (lint->parseOptions & XML_PARSE_NOCDATA)
3028
591
            xmllintOptWarnNoSupport(errStream, "--html", "--nocdata");
3029
2.17k
        if (lint->parseOptions & XML_PARSE_NODICT)
3030
1.29k
            xmllintOptWarnNoSupport(errStream, "--html", "--nodict");
3031
2.17k
        if (lint->parseOptions & XML_PARSE_NOENT)
3032
1.89k
            xmllintOptWarnNoSupport(errStream, "--html", "--noent");
3033
2.17k
        if (lint->parseOptions & XML_PARSE_NONET)
3034
1.12k
            xmllintOptWarnNoSupport(errStream, "--html", "--nonet");
3035
2.17k
        if (lint->parseOptions & XML_PARSE_NSCLEAN)
3036
978
            xmllintOptWarnNoSupport(errStream, "--html", "--nsclean");
3037
2.17k
        if (lint->parseOptions & XML_PARSE_OLD10)
3038
947
            xmllintOptWarnNoSupport(errStream, "--html", "--oldxml10");
3039
2.17k
        if (lint->parseOptions & XML_PARSE_PEDANTIC)
3040
192
            xmllintOptWarnNoSupport(errStream, "--html", "--pedantic");
3041
2.17k
        if (lint->parseOptions & XML_PARSE_DTDVALID)
3042
707
            xmllintOptWarnNoSupport(errStream, "--html", "--valid");
3043
2.17k
        if (lint->parseOptions & XML_PARSE_SAX1)
3044
1.42k
            xmllintOptWarnNoSupport(errStream, "--html", "--sax1");
3045
4.32k
    } else {
3046
4.32k
        if (lint->htmlOptions & HTML_PARSE_NODEFDTD)
3047
1.17k
            fprintf(errStream, "Warning: Option %s requires %s\n",
3048
1.17k
                    "--nodefdtd", "--html");
3049
4.32k
#ifdef LIBXML_OUTPUT_ENABLED
3050
4.32k
        if (lint->appOptions & XML_LINT_XML_OUT)
3051
982
            fprintf(errStream, "Warning: Option %s requires %s\n",
3052
982
                    "--xmlout", "--html");
3053
4.32k
#endif
3054
4.32k
    }
3055
6.50k
#endif
3056
3057
6.50k
    return(XMLLINT_RETURN_OK);
3058
6.58k
}
3059
3060
int
3061
xmllintMain(int argc, const char **argv, FILE *errStream,
3062
6.58k
            xmlResourceLoader loader) {
3063
6.58k
    xmllintState state, *lint;
3064
6.58k
    int i, j, res;
3065
6.58k
    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
6.58k
    lint = &state;
3074
6.58k
    xmllintInit(lint);
3075
6.58k
    lint->errStream = errStream;
3076
6.58k
    lint->defaultResourceLoader = loader;
3077
3078
6.58k
    res = xmllintParseOptions(lint, argc, argv);
3079
6.58k
    if (res != XMLLINT_RETURN_OK) {
3080
83
        return(res);
3081
83
    }
3082
3083
    /*
3084
     * Note that we must not make any memory allocations through xmlMalloc
3085
     * before calling xmlMemSetup.
3086
     */
3087
6.50k
    xmllintMaxmem = 0;
3088
6.50k
    if (lint->maxmem != 0) {
3089
1.90k
        xmllintMaxmem = lint->maxmem;
3090
1.90k
        xmllintMaxmemReached = 0;
3091
1.90k
        xmllintOom = 0;
3092
1.90k
        xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
3093
1.90k
    }
3094
3095
6.50k
    LIBXML_TEST_VERSION
3096
3097
6.50k
#ifdef LIBXML_CATALOG_ENABLED
3098
6.50k
    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
6.50k
#endif
3111
3112
6.50k
#ifdef LIBXML_OUTPUT_ENABLED
3113
6.50k
    {
3114
6.50k
        const char *indent = getenv("XMLLINT_INDENT");
3115
6.50k
        if (indent != NULL) {
3116
0
            lint->indentString = indent;
3117
0
        }
3118
6.50k
    }
3119
6.50k
#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
6.50k
#ifdef LIBXML_RELAXNG_ENABLED
3154
6.50k
    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
6.50k
#endif /* LIBXML_READER_ENABLED */
3158
6.50k
  ) {
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
6.50k
#endif /* LIBXML_RELAXNG_ENABLED */
3185
3186
6.50k
#ifdef LIBXML_SCHEMAS_ENABLED
3187
6.50k
    if ((lint->schema != NULL)
3188
0
#ifdef LIBXML_READER_ENABLED
3189
0
        && ((lint->appOptions& XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3190
6.50k
#endif
3191
6.50k
  ) {
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
6.50k
#endif /* LIBXML_SCHEMAS_ENABLED */
3216
3217
6.50k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3218
6.50k
    if ((lint->pattern != NULL) && ((lint->appOptions & XML_LINT_USE_WALKER) != XML_LINT_USE_WALKER)) {
3219
1.08k
        res = xmlPatternCompileSafe(BAD_CAST lint->pattern, NULL, 0, NULL,
3220
1.08k
                                    &lint->patternc);
3221
1.08k
  if (lint->patternc == NULL) {
3222
156
            if (res < 0) {
3223
26
                lint->progresult = XMLLINT_ERR_MEM;
3224
130
            } else {
3225
130
                fprintf(errStream, "Pattern %s failed to compile\n",
3226
130
                        lint->pattern);
3227
130
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
3228
130
            }
3229
156
            goto error;
3230
156
  }
3231
1.08k
    }
3232
6.34k
#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
3233
3234
    /*
3235
     * The main loop over input documents
3236
     */
3237
116k
    for (i = 1; i < argc ; i++) {
3238
109k
        const char *filename = argv[i];
3239
109k
#if HAVE_DECL_MMAP
3240
109k
        int memoryFd = -1;
3241
109k
#endif
3242
3243
109k
  if ((filename[0] == '-') && (strcmp(filename, "-") != 0)) {
3244
103k
            i += skipArgs(filename);
3245
103k
            continue;
3246
103k
        }
3247
3248
6.34k
#if HAVE_DECL_MMAP
3249
6.34k
        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
6.34k
#endif /* HAVE_DECL_MMAP */
3271
3272
6.34k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1))
3273
426
      startTimer(lint);
3274
3275
6.34k
#ifdef LIBXML_READER_ENABLED
3276
6.34k
        if (lint->appOptions & XML_LINT_USE_STREAMING) {
3277
2.63k
            for (j = 0; j < lint->repeat; j++)
3278
1.39k
                streamFile(lint, filename);
3279
1.23k
        } else
3280
5.11k
#endif /* LIBXML_READER_ENABLED */
3281
5.11k
        {
3282
5.11k
            xmlParserCtxtPtr ctxt;
3283
3284
5.11k
#ifdef LIBXML_HTML_ENABLED
3285
5.11k
            if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3286
2.17k
#ifdef LIBXML_PUSH_ENABLED
3287
2.17k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3288
9
                    ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3289
9
                                                    filename,
3290
9
                                                    XML_CHAR_ENCODING_NONE);
3291
9
                } else
3292
2.16k
#endif /* LIBXML_PUSH_ENABLED */
3293
2.16k
                {
3294
2.16k
                    ctxt = htmlNewParserCtxt();
3295
2.16k
                }
3296
2.17k
                htmlCtxtUseOptions(ctxt, lint->htmlOptions);
3297
2.17k
            } else
3298
2.94k
#endif /* LIBXML_HTML_ENABLED */
3299
2.94k
            {
3300
2.94k
#ifdef LIBXML_PUSH_ENABLED
3301
2.94k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3302
30
                    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3303
30
                                                   filename);
3304
30
                } else
3305
2.91k
#endif /* LIBXML_PUSH_ENABLED */
3306
2.91k
                {
3307
2.91k
                    ctxt = xmlNewParserCtxt();
3308
2.91k
                }
3309
2.94k
                xmlCtxtUseOptions(ctxt, lint->parseOptions);
3310
2.94k
            }
3311
5.11k
            if (ctxt == NULL) {
3312
56
                lint->progresult = XMLLINT_ERR_MEM;
3313
56
                goto error;
3314
56
            }
3315
3316
5.05k
            if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3317
255
                const xmlSAXHandler *handler;
3318
3319
255
                if (lint->noout) {
3320
210
                    handler = &emptySAXHandler;
3321
210
#ifdef LIBXML_SAX1_ENABLED
3322
210
                } else if (lint->parseOptions & XML_PARSE_SAX1) {
3323
11
                    handler = &debugSAXHandler;
3324
11
#endif
3325
34
                } else {
3326
34
                    handler = &debugSAX2Handler;
3327
34
                }
3328
3329
255
                *ctxt->sax = *handler;
3330
255
                ctxt->userData = lint;
3331
255
            }
3332
3333
5.05k
            xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3334
5.05k
            if (lint->maxAmpl > 0)
3335
273
                xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl);
3336
3337
5.05k
            lint->ctxt = ctxt;
3338
3339
10.9k
            for (j = 0; j < lint->repeat; j++) {
3340
5.87k
                if (j > 0) {
3341
812
#ifdef LIBXML_PUSH_ENABLED
3342
812
                    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3343
8
                        xmlCtxtResetPush(ctxt, NULL, 0, NULL, NULL);
3344
8
                    } else
3345
804
#endif
3346
804
                    {
3347
804
                        xmlCtxtReset(ctxt);
3348
804
                    }
3349
812
                }
3350
3351
5.87k
                if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3352
314
                    testSAX(lint, filename);
3353
5.55k
                } else {
3354
5.55k
                    parseAndPrintFile(lint, filename);
3355
5.55k
                }
3356
5.87k
            }
3357
3358
5.05k
            xmlFreeParserCtxt(ctxt);
3359
5.05k
        }
3360
3361
6.29k
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) {
3362
425
            endTimer(lint, "%d iterations", lint->repeat);
3363
425
        }
3364
3365
6.29k
        files += 1;
3366
3367
6.29k
#if HAVE_DECL_MMAP
3368
6.29k
        if (lint->appOptions & XML_LINT_MEMORY) {
3369
0
            munmap(lint->memoryData, lint->memorySize);
3370
0
            close(memoryFd);
3371
0
        }
3372
6.29k
#endif
3373
6.29k
    }
3374
3375
6.29k
    if (lint->appOptions & XML_LINT_GENERATE)
3376
5.83k
  parseAndPrintFile(lint, NULL);
3377
3378
6.29k
    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
6.50k
error:
3384
3385
#ifdef LIBXML_SCHEMATRON_ENABLED
3386
    if (lint->wxschematron != NULL)
3387
  xmlSchematronFree(lint->wxschematron);
3388
#endif
3389
6.50k
#ifdef LIBXML_RELAXNG_ENABLED
3390
6.50k
    if (lint->relaxngschemas != NULL)
3391
0
  xmlRelaxNGFree(lint->relaxngschemas);
3392
6.50k
#endif
3393
6.50k
#ifdef LIBXML_SCHEMAS_ENABLED
3394
6.50k
    if (lint->wxschemas != NULL)
3395
0
  xmlSchemaFree(lint->wxschemas);
3396
6.50k
#endif
3397
6.50k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3398
6.50k
    if (lint->patternc != NULL)
3399
930
        xmlFreePattern(lint->patternc);
3400
6.50k
#endif
3401
3402
6.50k
    xmlCleanupParser();
3403
3404
6.50k
    if ((lint->maxmem) && (xmllintMaxmemReached)) {
3405
223
        fprintf(errStream, "Maximum memory exceeded (%d bytes)\n",
3406
223
                xmllintMaxmem);
3407
6.28k
    } else if (lint->progresult == XMLLINT_ERR_MEM) {
3408
21
        fprintf(errStream, "Out-of-memory error reported\n");
3409
21
    }
3410
3411
6.50k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
3412
6.50k
    if ((lint->maxmem) &&
3413
1.90k
        (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
6.50k
#endif
3419
3420
6.50k
    return(lint->progresult);
3421
6.50k
}
3422