Coverage Report

Created: 2026-09-03 06:05

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