Coverage Report

Created: 2026-10-28 06:30

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
4.40k
                      xmlParserInputFlags flags, xmlParserInputPtr *out) {
278
4.40k
    xmllintState *lint = ctxt;
279
4.40k
    xmlParserErrors code;
280
4.40k
    int i;
281
4.40k
    const char *lastsegment = URL;
282
4.40k
    const char *iter = URL;
283
284
4.40k
    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
4.40k
    if (lint->defaultResourceLoader != NULL)
293
4.40k
        code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out);
294
0
    else
295
0
        code = xmlNewInputFromUrl(URL, flags, out);
296
4.40k
    if (code != XML_IO_ENOENT) {
297
4.40k
        if ((lint->appOptions & XML_LINT_USE_LOAD_TRACE) && (code == XML_ERR_OK)) {
298
1.51k
            fprintf(lint->errStream, "Loaded URL=\"%s\" ID=\"%s\"\n",
299
1.51k
                    URL, ID ? ID : "(null)");
300
1.51k
        }
301
4.40k
        return(code);
302
4.40k
    }
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
20
xmllintGzRead(void *ctxt, char *buf, int len) {
344
20
    return gzread(ctxt, buf, len);
345
20
}
346
347
#ifdef LIBXML_OUTPUT_ENABLED
348
static int
349
202
xmllintGzWrite(void *ctxt, const char *buf, int len) {
350
202
    return gzwrite(ctxt, buf, len);
351
202
}
352
#endif
353
354
static int
355
39
xmllintGzClose(void *ctxt) {
356
39
    if (gzclose(ctxt) != Z_OK)
357
17
        return -1;
358
359
22
    return 0;
360
39
}
361
#endif
362
363
static xmlDocPtr
364
3.02k
parseXml(xmllintState *lint, const char *filename) {
365
3.02k
    xmlParserCtxtPtr ctxt = lint->ctxt;
366
3.02k
    xmlDocPtr doc;
367
3.02k
#ifdef LIBXML_ZLIB_ENABLED
368
3.02k
    gzFile gz;
369
3.02k
#endif
370
371
3.02k
#ifdef LIBXML_PUSH_ENABLED
372
3.02k
    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.01k
#endif /* LIBXML_PUSH_ENABLED */
400
401
3.01k
#if HAVE_DECL_MMAP
402
3.01k
    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.01k
#endif
416
417
3.01k
#ifdef LIBXML_ZLIB_ENABLED
418
3.01k
    if (strcmp(filename, "-") == 0)
419
0
        gz = gzdopen(STDIN_FILENO, "rb");
420
3.01k
    else
421
3.01k
        gz = gzopen(filename, "rb");
422
423
3.01k
    if (gz == NULL) {
424
2.99k
        fprintf(lint->errStream, "Can't open %s\n", filename);
425
2.99k
        lint->progresult = XMLLINT_ERR_RDFILE;
426
2.99k
        return(NULL);
427
2.99k
    }
428
429
12
    doc = xmlCtxtReadIO(ctxt, xmllintGzRead, xmllintGzClose, gz,
430
12
                        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
12
    return(doc);
439
3.01k
}
440
441
#ifdef LIBXML_HTML_ENABLED
442
static xmlDocPtr
443
4.41k
parseHtml(xmllintState *lint, const char *filename) {
444
4.41k
    xmlParserCtxtPtr ctxt = lint->ctxt;
445
4.41k
    xmlDocPtr doc;
446
447
4.41k
#ifdef LIBXML_PUSH_ENABLED
448
4.41k
    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
449
9
        FILE *f;
450
9
        int res;
451
9
        char chars[4096];
452
453
9
        if ((filename[0] == '-') && (filename[1] == 0)) {
454
0
            f = stdin;
455
9
        } else {
456
9
      f = fopen(filename, "rb");
457
9
            if (f == NULL) {
458
6
                fprintf(lint->errStream, "Can't open %s\n", filename);
459
6
                lint->progresult = XMLLINT_ERR_RDFILE;
460
6
                return(NULL);
461
6
            }
462
9
        }
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
9
    }
475
4.40k
#endif /* LIBXML_PUSH_ENABLED */
476
477
4.40k
#if HAVE_DECL_MMAP
478
4.40k
    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
4.40k
#endif
492
493
4.40k
    if (strcmp(filename, "-") == 0)
494
0
        doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
495
0
                             lint->htmlOptions);
496
4.40k
    else
497
4.40k
        doc = htmlCtxtReadFile(ctxt, filename, NULL, lint->htmlOptions);
498
499
4.40k
    return(doc);
500
4.40k
}
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.36M
myFreeFunc(void *mem) {
513
1.36M
    xmlMemFree(mem);
514
1.36M
}
515
516
static void *
517
1.29M
myMallocFunc(size_t size) {
518
1.29M
    void *ret;
519
520
1.29M
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
521
#if XMLLINT_ABORT_ON_FAILURE
522
        abort();
523
#endif
524
1.15k
        xmllintMaxmemReached = 1;
525
1.15k
        xmllintOom = 1;
526
1.15k
        return(NULL);
527
1.15k
    }
528
529
1.29M
    ret = xmlMemMalloc(size);
530
1.29M
    if (ret == NULL)
531
0
        xmllintOom = 1;
532
533
1.29M
    return(ret);
534
1.29M
}
535
536
static void *
537
125k
myReallocFunc(void *mem, size_t size) {
538
125k
    void *ret;
539
125k
    size_t oldsize = xmlMemSize(mem);
540
541
125k
    if (xmlMemUsed() + size - oldsize > (size_t) xmllintMaxmem) {
542
#if XMLLINT_ABORT_ON_FAILURE
543
        abort();
544
#endif
545
1.45k
        xmllintMaxmemReached = 1;
546
1.45k
        xmllintOom = 1;
547
1.45k
        return(NULL);
548
1.45k
    }
549
550
123k
    ret = xmlMemRealloc(mem, size);
551
123k
    if (ret == NULL)
552
0
        xmllintOom = 1;
553
554
123k
    return(ret);
555
125k
}
556
557
static char *
558
9.22k
myStrdupFunc(const char *str) {
559
9.22k
    size_t size;
560
9.22k
    char *ret;
561
562
9.22k
    if (str == NULL)
563
0
        return(NULL);
564
565
9.22k
    size = strlen(str) + 1;
566
9.22k
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
567
#if XMLLINT_ABORT_ON_FAILURE
568
        abort();
569
#endif
570
584
        xmllintMaxmemReached = 1;
571
584
        xmllintOom = 1;
572
584
        return(NULL);
573
584
    }
574
575
8.63k
    ret = xmlMemMalloc(size);
576
8.63k
    if (ret == NULL) {
577
0
        xmllintOom = 1;
578
0
        return(NULL);
579
0
    }
580
581
8.63k
    memcpy(ret, str, size);
582
583
8.63k
    return(ret);
584
8.63k
}
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
19.6k
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
19.6k
    struct timeval tv;
603
604
19.6k
    gettimeofday(&tv, NULL);
605
19.6k
    time->sec = tv.tv_sec;
606
19.6k
    time->usec = tv.tv_usec;
607
19.6k
#endif /* _WIN32 */
608
19.6k
}
609
610
/*
611
 * startTimer: call where you want to start timing
612
 */
613
static void
614
startTimer(xmllintState *lint)
615
10.2k
{
616
10.2k
    getTime(&lint->begin);
617
10.2k
}
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
9.39k
{
627
9.39k
    xmlSeconds msec;
628
9.39k
    va_list ap;
629
630
9.39k
    getTime(&lint->end);
631
9.39k
    msec = lint->end.sec - lint->begin.sec;
632
9.39k
    msec *= 1000;
633
9.39k
    msec += (lint->end.usec - lint->begin.usec) / 1000;
634
635
9.39k
    va_start(ap, fmt);
636
9.39k
    vfprintf(lint->errStream, fmt, ap);
637
9.39k
    va_end(ap);
638
639
9.39k
    fprintf(lint->errStream, " took %ld ms\n", (long) msec);
640
9.39k
}
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
327
testSAX(xmllintState *lint, const char *filename) {
1241
327
    lint->callbacks = 0;
1242
1243
327
#ifdef LIBXML_SCHEMAS_ENABLED
1244
327
    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
327
#endif
1284
327
#ifdef LIBXML_HTML_ENABLED
1285
327
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1286
0
        parseHtml(lint, filename);
1287
0
    } else
1288
327
#endif
1289
327
    {
1290
327
        parseXml(lint, filename);
1291
327
    }
1292
327
}
1293
1294
/************************************************************************
1295
 *                  *
1296
 *      Stream Test processing        *
1297
 *                  *
1298
 ************************************************************************/
1299
#ifdef LIBXML_READER_ENABLED
1300
10.4k
static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
1301
10.4k
    const xmlChar *name, *value;
1302
10.4k
    int type, empty;
1303
1304
10.4k
    type = xmlTextReaderNodeType(reader);
1305
10.4k
    empty = xmlTextReaderIsEmptyElement(reader);
1306
1307
10.4k
    if (lint->appOptions & XML_LINT_DEBUG_ENABLED) {
1308
9.77k
  name = xmlTextReaderConstName(reader);
1309
9.77k
  if (name == NULL)
1310
6
      name = BAD_CAST "--";
1311
1312
9.77k
  value = xmlTextReaderConstValue(reader);
1313
1314
1315
9.77k
  printf("%d %d %s %d %d",
1316
9.77k
    xmlTextReaderDepth(reader),
1317
9.77k
    type,
1318
9.77k
    name,
1319
9.77k
    empty,
1320
9.77k
    xmlTextReaderHasValue(reader));
1321
9.77k
  if (value == NULL)
1322
2.66k
      printf("\n");
1323
7.11k
  else {
1324
7.11k
      printf(" %s\n", value);
1325
7.11k
  }
1326
9.77k
    }
1327
10.4k
#ifdef LIBXML_PATTERN_ENABLED
1328
10.4k
    if (lint->patternc) {
1329
1.42k
        xmlChar *path = NULL;
1330
1.42k
        int match = -1;
1331
1332
1.42k
  if (type == XML_READER_TYPE_ELEMENT) {
1333
      /* do the check only on element start */
1334
479
      match = xmlPatternMatch(lint->patternc,
1335
479
                                    xmlTextReaderCurrentNode(reader));
1336
1337
479
      if (match) {
1338
69
    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1339
69
    printf("Node %s matches pattern %s\n", path, lint->pattern);
1340
69
      }
1341
479
  }
1342
1.42k
  if (lint->patstream != NULL) {
1343
1.42k
      int ret;
1344
1345
1.42k
      if (type == XML_READER_TYPE_ELEMENT) {
1346
479
    ret = xmlStreamPush(lint->patstream,
1347
479
                        xmlTextReaderConstLocalName(reader),
1348
479
            xmlTextReaderConstNamespaceUri(reader));
1349
479
    if (ret < 0) {
1350
0
        fprintf(lint->errStream, "xmlStreamPush() failure\n");
1351
0
                    xmlFreeStreamCtxt(lint->patstream);
1352
0
        lint->patstream = NULL;
1353
479
    } 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
479
      }
1369
1.42k
      if ((type == XML_READER_TYPE_END_ELEMENT) ||
1370
967
          ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1371
479
          ret = xmlStreamPop(lint->patstream);
1372
479
    if (ret < 0) {
1373
0
        fprintf(lint->errStream, "xmlStreamPop() failure\n");
1374
0
                    xmlFreeStreamCtxt(lint->patstream);
1375
0
        lint->patstream = NULL;
1376
0
    }
1377
479
      }
1378
1.42k
  }
1379
1.42k
  if (path != NULL)
1380
72
      xmlFree(path);
1381
1.42k
    }
1382
10.4k
#endif
1383
10.4k
}
1384
1385
1.34k
static void streamFile(xmllintState *lint, const char *filename) {
1386
1.34k
    xmlParserInputBufferPtr input = NULL;
1387
1.34k
    FILE *errStream = lint->errStream;
1388
1.34k
    xmlTextReaderPtr reader;
1389
1.34k
    int ret;
1390
1391
1.34k
#if HAVE_DECL_MMAP
1392
1.34k
    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.34k
#endif
1401
1.34k
    {
1402
1.34k
#ifdef LIBXML_ZLIB_ENABLED
1403
1.34k
        gzFile gz;
1404
1.34k
#endif
1405
1406
1.34k
        xmlResetLastError();
1407
1408
1.34k
#ifdef LIBXML_ZLIB_ENABLED
1409
1.34k
        if (strcmp(filename, "-") == 0)
1410
0
            gz = gzdopen(STDIN_FILENO, "rb");
1411
1.34k
        else
1412
1.34k
            gz = gzopen(filename, "rb");
1413
1414
1.34k
        if (gz == NULL) {
1415
1.33k
            fprintf(lint->errStream, "Can't open %s\n", filename);
1416
1.33k
            lint->progresult = XMLLINT_ERR_RDFILE;
1417
1.33k
            return;
1418
1.33k
        }
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
3.06k
static void walkDoc(xmllintState *lint, xmlDocPtr doc) {
1579
3.06k
    FILE *errStream = lint->errStream;
1580
3.06k
    xmlTextReaderPtr reader;
1581
3.06k
    int ret;
1582
1583
3.06k
#ifdef LIBXML_PATTERN_ENABLED
1584
3.06k
    if (lint->pattern != NULL) {
1585
646
        xmlNodePtr root;
1586
646
        const xmlChar *namespaces[22];
1587
646
        int i;
1588
646
        xmlNsPtr ns;
1589
1590
646
        root = xmlDocGetRootElement(doc);
1591
646
        if (root == NULL ) {
1592
28
            fprintf(errStream,
1593
28
                    "Document does not have a root element");
1594
28
            lint->progresult = XMLLINT_ERR_UNCLASS;
1595
28
            return;
1596
28
        }
1597
618
        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
618
        namespaces[i++] = NULL;
1602
618
        namespaces[i] = NULL;
1603
1604
618
        ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict,
1605
618
                                    0, &namespaces[0], &lint->patternc);
1606
618
  if (lint->patternc == NULL) {
1607
302
            if (ret < 0) {
1608
80
                lint->progresult = XMLLINT_ERR_MEM;
1609
222
            } else {
1610
222
                fprintf(errStream, "Pattern %s failed to compile\n",
1611
222
                        lint->pattern);
1612
222
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
1613
222
            }
1614
302
            goto error;
1615
302
  }
1616
1617
316
        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
1618
316
        if (lint->patstream == NULL) {
1619
33
            lint->progresult = XMLLINT_ERR_MEM;
1620
33
            goto error;
1621
33
        }
1622
1623
283
        ret = xmlStreamPush(lint->patstream, NULL, NULL);
1624
283
        if (ret < 0) {
1625
1
            fprintf(errStream, "xmlStreamPush() failure\n");
1626
1
            lint->progresult = XMLLINT_ERR_MEM;
1627
1
            goto error;
1628
1
        }
1629
283
    }
1630
2.69k
#endif /* LIBXML_PATTERN_ENABLED */
1631
2.69k
    reader = xmlReaderWalker(doc);
1632
2.69k
    if (reader != NULL) {
1633
2.69k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1634
921
      startTimer(lint);
1635
921
  }
1636
2.69k
  ret = xmlTextReaderRead(reader);
1637
138k
  while (ret == 1) {
1638
135k
      if ((lint->appOptions & XML_LINT_DEBUG_ENABLED)
1639
125k
#ifdef LIBXML_PATTERN_ENABLED
1640
125k
          || (lint->patternc)
1641
135k
#endif
1642
135k
         )
1643
10.4k
    processNode(lint, reader);
1644
135k
      ret = xmlTextReaderRead(reader);
1645
135k
  }
1646
2.69k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1647
921
      endTimer(lint, "walking through the doc");
1648
921
  }
1649
2.69k
  xmlFreeTextReader(reader);
1650
2.69k
  if (ret != 0) {
1651
6
      fprintf(errStream, "failed to walk through the doc\n");
1652
6
      lint->progresult = XMLLINT_ERR_UNCLASS;
1653
6
  }
1654
2.69k
    } else {
1655
9
  fprintf(errStream, "Failed to create a reader from the document\n");
1656
9
  lint->progresult = XMLLINT_ERR_UNCLASS;
1657
9
    }
1658
1659
2.69k
#ifdef LIBXML_PATTERN_ENABLED
1660
3.03k
error:
1661
3.03k
    if (lint->patternc != NULL) {
1662
316
        xmlFreePattern(lint->patternc);
1663
316
        lint->patternc = NULL;
1664
316
    }
1665
3.03k
    if (lint->patstream != NULL) {
1666
283
  xmlFreeStreamCtxt(lint->patstream);
1667
283
  lint->patstream = NULL;
1668
283
    }
1669
3.03k
#endif
1670
3.03k
}
1671
#endif /* LIBXML_READER_ENABLED */
1672
1673
#ifdef LIBXML_XPATH_ENABLED
1674
/************************************************************************
1675
 *                  *
1676
 *      XPath Query                                     *
1677
 *                  *
1678
 ************************************************************************/
1679
1680
static void
1681
4.38k
doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) {
1682
4.38k
    switch(cur->type) {
1683
3.84k
        case XPATH_NODESET: {
1684
3.84k
#ifdef LIBXML_OUTPUT_ENABLED
1685
3.84k
            xmlOutputBufferPtr buf;
1686
3.84k
            xmlNodePtr node;
1687
3.84k
            int i;
1688
1689
3.84k
            if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
1690
1.56k
                lint->progresult = XMLLINT_ERR_XPATH_EMPTY;
1691
1.56k
                if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
1692
1.34k
                    fprintf(lint->errStream, "XPath set is empty\n");
1693
1.34k
                }
1694
1.56k
                break;
1695
1.56k
            }
1696
2.27k
            buf = xmlOutputBufferCreateFile(stdout, NULL);
1697
2.27k
            if (buf == NULL) {
1698
441
                lint->progresult = XMLLINT_ERR_MEM;
1699
441
                return;
1700
441
            }
1701
122k
            for (i = 0;i < cur->nodesetval->nodeNr;i++) {
1702
120k
                node = cur->nodesetval->nodeTab[i];
1703
120k
                xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
1704
120k
                xmlOutputBufferWrite(buf, 1, lint->xpathsep);
1705
120k
            }
1706
1.83k
            xmlOutputBufferClose(buf);
1707
#else
1708
            printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
1709
#endif
1710
1.83k
      break;
1711
2.27k
        }
1712
175
        case XPATH_BOOLEAN:
1713
175
      if (cur->boolval) printf("true%s", lint->xpathsep);
1714
125
      else printf("false%s", lint->xpathsep);
1715
175
      break;
1716
121
        case XPATH_NUMBER:
1717
121
      switch (xmlXPathIsInf(cur->floatval)) {
1718
5
      case 1:
1719
5
    printf("Infinity%s", lint->xpathsep);
1720
5
    break;
1721
3
      case -1:
1722
3
    printf("-Infinity%s", lint->xpathsep);
1723
3
    break;
1724
113
      default:
1725
113
    if (xmlXPathIsNaN(cur->floatval)) {
1726
85
        printf("NaN%s", lint->xpathsep);
1727
85
    } else {
1728
28
        printf("%0g%s", cur->floatval, lint->xpathsep);
1729
28
    }
1730
121
      }
1731
121
      break;
1732
245
        case XPATH_STRING:
1733
245
      printf("%s%s", (const char *) cur->stringval, lint->xpathsep);
1734
245
      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.38k
    }
1744
4.38k
}
1745
1746
static void
1747
7.62k
doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) {
1748
7.62k
    xmlXPathContextPtr ctxt = NULL;
1749
7.62k
    xmlXPathCompExprPtr comp = NULL;
1750
7.62k
    xmlXPathObjectPtr res = NULL;
1751
1752
7.62k
    ctxt = xmlXPathNewContext(doc);
1753
7.62k
    if (ctxt == NULL) {
1754
23
        lint->progresult = XMLLINT_ERR_MEM;
1755
23
        goto error;
1756
23
    }
1757
1758
7.59k
    comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query);
1759
7.59k
    if (comp == NULL) {
1760
2.47k
        fprintf(lint->errStream, "XPath compilation failure\n");
1761
2.47k
        lint->progresult = XMLLINT_ERR_XPATH;
1762
2.47k
        goto error;
1763
2.47k
    }
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
5.12k
    ctxt->node = (xmlNodePtr) doc;
1773
5.12k
    res = xmlXPathCompiledEval(comp, ctxt);
1774
5.12k
    if (res == NULL) {
1775
740
        fprintf(lint->errStream, "XPath evaluation failure\n");
1776
740
        lint->progresult = XMLLINT_ERR_XPATH;
1777
740
        goto error;
1778
740
    }
1779
1780
4.38k
    doXPathDump(lint, res);
1781
1782
7.62k
error:
1783
7.62k
    xmlXPathFreeObject(res);
1784
7.62k
    xmlXPathFreeCompExpr(comp);
1785
7.62k
    xmlXPathFreeContext(ctxt);
1786
7.62k
}
1787
#endif /* LIBXML_XPATH_ENABLED */
1788
1789
/************************************************************************
1790
 *                  *
1791
 *      Tree Test processing        *
1792
 *                  *
1793
 ************************************************************************/
1794
1795
static xmlDocPtr
1796
13.7k
parseFile(xmllintState *lint, const char *filename) {
1797
13.7k
    xmlDocPtr doc = NULL;
1798
1799
13.7k
    if ((lint->appOptions & XML_LINT_GENERATE) && (filename == NULL)) {
1800
6.62k
        xmlNodePtr n;
1801
1802
6.62k
        doc = xmlNewDoc(BAD_CAST "1.0");
1803
6.62k
        if (doc == NULL) {
1804
0
            lint->progresult = XMLLINT_ERR_MEM;
1805
0
            return(NULL);
1806
0
        }
1807
6.62k
        n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
1808
6.62k
        if (n == NULL) {
1809
0
            xmlFreeDoc(doc);
1810
0
            lint->progresult = XMLLINT_ERR_MEM;
1811
0
            return(NULL);
1812
0
        }
1813
6.62k
        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.62k
        xmlDocSetRootElement(doc, n);
1820
1821
6.62k
        return(doc);
1822
6.62k
    }
1823
1824
7.10k
#ifdef LIBXML_HTML_ENABLED
1825
7.10k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1826
4.41k
        doc = parseHtml(lint, filename);
1827
4.41k
        return(doc);
1828
4.41k
    }
1829
2.69k
#endif /* LIBXML_HTML_ENABLED */
1830
2.69k
    {
1831
2.69k
        doc = parseXml(lint, filename);
1832
2.69k
    }
1833
1834
2.69k
    if (doc == NULL) {
1835
2.69k
        if (lint->ctxt->errNo == XML_ERR_NO_MEMORY)
1836
10
            lint->progresult = XMLLINT_ERR_MEM;
1837
2.68k
        else
1838
2.68k
      lint->progresult = XMLLINT_ERR_RDFILE;
1839
2.69k
    } 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.69k
    return(doc);
1852
7.10k
}
1853
1854
static void
1855
13.7k
parseAndPrintFile(xmllintState *lint, const char *filename) {
1856
13.7k
    FILE *errStream = lint->errStream;
1857
13.7k
    xmlDocPtr doc;
1858
1859
    /* Avoid unused variable warning */
1860
13.7k
    (void) errStream;
1861
1862
13.7k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1))
1863
2.79k
  startTimer(lint);
1864
1865
13.7k
    doc = parseFile(lint, filename);
1866
13.7k
    if (doc == NULL) {
1867
3.53k
        if (lint->progresult == XMLLINT_RETURN_OK)
1868
712
            lint->progresult = XMLLINT_ERR_UNCLASS;
1869
3.53k
  return;
1870
3.53k
    }
1871
1872
10.2k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1873
1.97k
  endTimer(lint, "Parsing");
1874
1.97k
    }
1875
1876
10.2k
    if (lint->appOptions & XML_LINT_DROP_DTD) {
1877
3.13k
  xmlDtdPtr dtd;
1878
1879
3.13k
  dtd = xmlGetIntSubset(doc);
1880
3.13k
  if (dtd != NULL) {
1881
958
      xmlUnlinkNode((xmlNodePtr)dtd);
1882
958
            doc->intSubset = dtd;
1883
958
  }
1884
3.13k
    }
1885
1886
10.2k
#ifdef LIBXML_XINCLUDE_ENABLED
1887
10.2k
    if (lint->appOptions & XML_LINT_XINCLUDE) {
1888
7.23k
        xmlXIncludeCtxt *xinc;
1889
7.23k
        int res;
1890
1891
7.23k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1892
1.44k
      startTimer(lint);
1893
1.44k
  }
1894
1895
7.23k
        xinc = xmlXIncludeNewContext(doc);
1896
7.23k
        if (xinc == NULL) {
1897
3
            lint->progresult = XMLLINT_ERR_MEM;
1898
3
            goto done;
1899
3
        }
1900
7.23k
        xmlXIncludeSetResourceLoader(xinc, xmllintResourceLoader, lint);
1901
7.23k
        xmlXIncludeSetFlags(xinc, lint->parseOptions);
1902
7.23k
        res = xmlXIncludeProcessNode(xinc, (xmlNode *) doc);
1903
7.23k
        xmlXIncludeFreeContext(xinc);
1904
7.23k
        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.23k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1913
1.44k
      endTimer(lint, "Xinclude processing");
1914
1.44k
  }
1915
7.23k
    }
1916
10.2k
#endif
1917
1918
    /*
1919
     * shell interaction
1920
     */
1921
10.2k
    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
10.2k
#ifdef LIBXML_XPATH_ENABLED
1930
10.2k
    if (lint->xpathquery != NULL) {
1931
7.62k
  xmlXPathOrderDocElems(doc);
1932
7.62k
        doXPathQuery(lint, doc, lint->xpathquery);
1933
7.62k
    }
1934
10.2k
#endif
1935
1936
    /*
1937
     * test intermediate copy if needed.
1938
     */
1939
10.2k
    if (lint->appOptions & XML_LINT_COPY_ENABLED) {
1940
3.16k
        xmlDocPtr tmp;
1941
1942
3.16k
        tmp = doc;
1943
3.16k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1944
952
      startTimer(lint);
1945
952
  }
1946
3.16k
  doc = xmlCopyDoc(doc, 1);
1947
3.16k
        if (doc == NULL) {
1948
56
            lint->progresult = XMLLINT_ERR_MEM;
1949
56
            xmlFreeDoc(tmp);
1950
56
            return;
1951
56
        }
1952
3.11k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1953
916
      endTimer(lint, "Copying");
1954
916
  }
1955
3.11k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1956
916
      startTimer(lint);
1957
916
  }
1958
3.11k
  xmlFreeDoc(tmp);
1959
3.11k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1960
916
      endTimer(lint, "Freeing original");
1961
916
  }
1962
3.11k
    }
1963
1964
10.1k
#ifdef LIBXML_VALID_ENABLED
1965
10.1k
    if ((lint->appOptions & XML_LINT_VALID_INSERTIONS)
1966
4.74k
#ifdef LIBXML_HTML_ENABLED
1967
4.74k
        && ((lint->appOptions & XML_LINT_HTML_ENABLED) != XML_LINT_HTML_ENABLED)
1968
10.1k
#endif
1969
10.1k
    ) {
1970
1.79k
        const xmlChar* list[256];
1971
1.79k
  int nb, i;
1972
1.79k
  xmlNodePtr node;
1973
1974
1.79k
  if (doc->children != NULL) {
1975
1.79k
      node = doc->children;
1976
1.79k
      while ((node != NULL) &&
1977
1.79k
                   ((node->type != XML_ELEMENT_NODE) ||
1978
1.79k
                    (node->last == NULL)))
1979
0
                node = node->next;
1980
1.79k
      if (node != NULL) {
1981
1.79k
    nb = xmlValidGetValidElements(node->last, NULL, list, 256);
1982
1.79k
    if (nb < 0) {
1983
1.79k
        fprintf(errStream, "could not get valid list of elements\n");
1984
1.79k
    } 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.79k
      }
1994
1.79k
  }
1995
1.79k
    } else
1996
8.34k
#endif /* LIBXML_VALID_ENABLED */
1997
8.34k
#ifdef LIBXML_READER_ENABLED
1998
8.34k
    if (lint->appOptions & XML_LINT_USE_WALKER) {
1999
3.06k
        walkDoc(lint, doc);
2000
3.06k
    }
2001
10.1k
#endif /* LIBXML_READER_ENABLED */
2002
10.1k
#ifdef LIBXML_OUTPUT_ENABLED
2003
10.1k
    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.14k
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2011
146
    startTimer(lint);
2012
146
      }
2013
2.14k
#ifdef LIBXML_C14N_ENABLED
2014
2.14k
            if (lint->appOptions & XML_LINT_CANONICAL_V1_0) {
2015
355
          xmlChar *result = NULL;
2016
355
    int size;
2017
2018
355
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2019
355
    if (size >= 0) {
2020
355
        if (write(1, result, size) == -1) {
2021
353
            fprintf(errStream, "Can't write data\n");
2022
353
        }
2023
355
        xmlFree(result);
2024
355
    } else {
2025
0
        fprintf(errStream, "Failed to canonicalize\n");
2026
0
        lint->progresult = XMLLINT_ERR_OUT;
2027
0
    }
2028
1.78k
      } else if (lint->appOptions & XML_LINT_CANONICAL_V1_1) {
2029
134
          xmlChar *result = NULL;
2030
134
    int size;
2031
2032
134
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
2033
134
    if (size >= 0) {
2034
134
        if (write(1, result, size) == -1) {
2035
128
            fprintf(errStream, "Can't write data\n");
2036
128
        }
2037
134
        xmlFree(result);
2038
134
    } else {
2039
0
        fprintf(errStream, "Failed to canonicalize\n");
2040
0
        lint->progresult = XMLLINT_ERR_OUT;
2041
0
    }
2042
1.65k
      } else if (lint->appOptions & XML_LINT_CANONICAL_EXE) {
2043
284
          xmlChar *result = NULL;
2044
284
    int size;
2045
2046
284
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
2047
284
    if (size >= 0) {
2048
283
        if (write(1, result, size) == -1) {
2049
283
            fprintf(errStream, "Can't write data\n");
2050
283
        }
2051
283
        xmlFree(result);
2052
283
    } else {
2053
1
        fprintf(errStream, "Failed to canonicalize\n");
2054
1
        lint->progresult = XMLLINT_ERR_OUT;
2055
1
    }
2056
284
      } else
2057
1.36k
#endif
2058
1.36k
            {
2059
1.36k
          xmlSaveCtxtPtr ctxt = NULL;
2060
1.36k
    int saveOpts = 0;
2061
2062
1.36k
                if (lint->format == 1)
2063
104
        saveOpts |= XML_SAVE_FORMAT;
2064
1.26k
                else if (lint->format == 2)
2065
1.16k
                    saveOpts |= XML_SAVE_WSNONSIG;
2066
2067
1.36k
#if defined(LIBXML_HTML_ENABLED)
2068
1.36k
                if (lint->appOptions & XML_LINT_XML_OUT)
2069
185
                    saveOpts |= XML_SAVE_AS_XML;
2070
1.36k
#endif
2071
2072
1.36k
#ifdef LIBXML_ZLIB_ENABLED
2073
1.36k
          if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) {
2074
20
                    gzFile gz;
2075
2076
20
                    if (lint->output == NULL)
2077
20
                        gz = gzdopen(STDOUT_FILENO, "wb9");
2078
0
                    else
2079
0
                        gz = gzopen(lint->output, "wb9");
2080
2081
20
                    if (gz != NULL)
2082
20
                        ctxt = xmlSaveToIO(xmllintGzWrite, xmllintGzClose, gz,
2083
20
                                           lint->encoding, saveOpts);
2084
20
                } 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.36k
    if (ctxt != NULL) {
2096
948
                    if (lint->indentString != NULL)
2097
0
                        xmlSaveSetIndentString(ctxt, lint->indentString);
2098
2099
948
        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
948
        xmlSaveClose(ctxt);
2105
948
    } else {
2106
420
                    fprintf(errStream, "failed save to %s\n",
2107
420
                            lint->output ? lint->output : "-");
2108
420
        lint->progresult = XMLLINT_ERR_OUT;
2109
420
    }
2110
1.36k
      }
2111
2.14k
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2112
146
    endTimer(lint, "Saving");
2113
146
      }
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.14k
    }
2134
10.1k
#endif /* LIBXML_OUTPUT_ENABLED */
2135
2136
10.1k
#ifdef LIBXML_VALID_ENABLED
2137
    /*
2138
     * A posteriori validation test
2139
     */
2140
10.1k
    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
10.1k
    } else if (lint->appOptions & XML_LINT_POST_VALIDATION) {
2192
3.84k
  xmlValidCtxtPtr cvp;
2193
2194
3.84k
  cvp = xmlNewValidCtxt();
2195
3.84k
  if (cvp == NULL) {
2196
0
            lint->progresult = XMLLINT_ERR_MEM;
2197
0
            xmlFreeDoc(doc);
2198
0
            return;
2199
0
  }
2200
2201
3.84k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2202
304
      startTimer(lint);
2203
304
  }
2204
3.84k
  if (!xmlValidateDocument(cvp, doc)) {
2205
3.84k
      fprintf(errStream,
2206
3.84k
        "Document %s does not validate\n", filename);
2207
3.84k
      lint->progresult = XMLLINT_ERR_VALID;
2208
3.84k
  }
2209
3.84k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2210
304
      endTimer(lint, "Validating");
2211
304
  }
2212
3.84k
  xmlFreeValidCtxt(cvp);
2213
3.84k
    }
2214
10.1k
#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
10.1k
#ifdef LIBXML_RELAXNG_ENABLED
2258
10.1k
    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
10.1k
#endif /* LIBXML_RELAXNG_ENABLED */
2291
2292
10.1k
#ifdef LIBXML_SCHEMAS_ENABLED
2293
10.1k
    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
10.1k
#endif /* LIBXML_SCHEMAS_ENABLED */
2326
2327
    /* Avoid unused label warning */
2328
10.1k
    goto done;
2329
2330
10.1k
done:
2331
    /*
2332
     * free it.
2333
     */
2334
10.1k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2335
1.96k
  startTimer(lint);
2336
1.96k
    }
2337
10.1k
    xmlFreeDoc(doc);
2338
10.1k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2339
1.96k
  endTimer(lint, "Freeing");
2340
1.96k
    }
2341
10.1k
}
2342
2343
/************************************************************************
2344
 *                  *
2345
 *      Usage and Main          *
2346
 *                  *
2347
 ************************************************************************/
2348
2349
2.13k
static void showVersion(FILE *errStream, const char *name) {
2350
2.13k
    fprintf(errStream, "%s: using libxml version %s\n", name, xmlParserVersion);
2351
2.13k
    fprintf(errStream, "   compiled with: ");
2352
2.13k
    if (xmlHasFeature(XML_WITH_THREAD)) fprintf(errStream, "Threads ");
2353
2.13k
    fprintf(errStream, "Tree ");
2354
2.13k
    if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(errStream, "Output ");
2355
2.13k
    if (xmlHasFeature(XML_WITH_PUSH)) fprintf(errStream, "Push ");
2356
2.13k
    if (xmlHasFeature(XML_WITH_READER)) fprintf(errStream, "Reader ");
2357
2.13k
    if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(errStream, "Patterns ");
2358
2.13k
    if (xmlHasFeature(XML_WITH_WRITER)) fprintf(errStream, "Writer ");
2359
2.13k
    if (xmlHasFeature(XML_WITH_SAX1)) fprintf(errStream, "SAXv1 ");
2360
2.13k
    if (xmlHasFeature(XML_WITH_VALID)) fprintf(errStream, "DTDValid ");
2361
2.13k
    if (xmlHasFeature(XML_WITH_HTML)) fprintf(errStream, "HTML ");
2362
2.13k
    if (xmlHasFeature(XML_WITH_C14N)) fprintf(errStream, "C14N ");
2363
2.13k
    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(errStream, "Catalog ");
2364
2.13k
    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(errStream, "XPath ");
2365
2.13k
    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(errStream, "XPointer ");
2366
2.13k
    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(errStream, "XInclude ");
2367
2.13k
    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(errStream, "Iconv ");
2368
2.13k
    if (xmlHasFeature(XML_WITH_ICU)) fprintf(errStream, "ICU ");
2369
2.13k
    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(errStream, "ISO8859X ");
2370
2.13k
    if (xmlHasFeature(XML_WITH_REGEXP))
2371
2.13k
        fprintf(errStream, "Regexps Automata ");
2372
2.13k
    if (xmlHasFeature(XML_WITH_RELAXNG)) fprintf(errStream, "RelaxNG ");
2373
2.13k
    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(errStream, "Schemas ");
2374
2.13k
    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(errStream, "Schematron ");
2375
2.13k
    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(errStream, "Modules ");
2376
2.13k
    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(errStream, "Debug ");
2377
2.13k
    if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(errStream, "Zlib ");
2378
2.13k
    fprintf(errStream, "\n");
2379
2.13k
}
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
7.10k
             const char *str, unsigned long min, unsigned long max) {
2498
7.10k
    char *strEnd;
2499
7.10k
    unsigned long val;
2500
2501
7.10k
    if (str != NULL && *str == '-') {
2502
0
        fprintf(errStream, "%s: value not allowed: %s\n", ctxt, str);
2503
0
        return(-1);
2504
0
    }
2505
2506
7.10k
    errno = 0;
2507
7.10k
    val = strtoul(str, &strEnd, 10);
2508
7.10k
    if (errno == EINVAL || *strEnd != 0) {
2509
0
        fprintf(errStream, "%s: invalid integer: %s\n", ctxt, str);
2510
0
        return(-1);
2511
0
    }
2512
7.10k
    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
7.09k
    *result = val;
2518
7.09k
    return(0);
2519
7.10k
}
2520
2521
static int
2522
125k
skipArgs(const char *arg) {
2523
125k
    if ((!strcmp(arg, "-path")) ||
2524
125k
        (!strcmp(arg, "--path")) ||
2525
125k
        (!strcmp(arg, "-maxmem")) ||
2526
125k
        (!strcmp(arg, "--maxmem")) ||
2527
122k
#ifdef LIBXML_OUTPUT_ENABLED
2528
122k
        (!strcmp(arg, "-o")) ||
2529
122k
        (!strcmp(arg, "-output")) ||
2530
122k
        (!strcmp(arg, "--output")) ||
2531
122k
        (!strcmp(arg, "-encode")) ||
2532
122k
        (!strcmp(arg, "--encode")) ||
2533
119k
        (!strcmp(arg, "-pretty")) ||
2534
119k
        (!strcmp(arg, "--pretty")) ||
2535
116k
#endif
2536
116k
#ifdef LIBXML_VALID_ENABLED
2537
116k
        (!strcmp(arg, "-dtdvalid")) ||
2538
116k
        (!strcmp(arg, "--dtdvalid")) ||
2539
116k
        (!strcmp(arg, "-dtdvalidfpi")) ||
2540
116k
        (!strcmp(arg, "--dtdvalidfpi")) ||
2541
116k
#endif
2542
116k
#ifdef LIBXML_RELAXNG_ENABLED
2543
116k
        (!strcmp(arg, "-relaxng")) ||
2544
116k
        (!strcmp(arg, "--relaxng")) ||
2545
116k
#endif
2546
116k
#ifdef LIBXML_SCHEMAS_ENABLED
2547
116k
        (!strcmp(arg, "-schema")) ||
2548
116k
        (!strcmp(arg, "--schema")) ||
2549
116k
#endif
2550
#ifdef LIBXML_SCHEMATRON_ENABLED
2551
        (!strcmp(arg, "-schematron")) ||
2552
        (!strcmp(arg, "--schematron")) ||
2553
#endif
2554
116k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2555
116k
        (!strcmp(arg, "-pattern")) ||
2556
116k
        (!strcmp(arg, "--pattern")) ||
2557
114k
#endif
2558
114k
#ifdef LIBXML_XPATH_ENABLED
2559
114k
        (!strcmp(arg, "-xpath")) ||
2560
114k
        (!strcmp(arg, "--xpath")) ||
2561
109k
        (!strcmp(arg, "-xpath0")) ||
2562
109k
        (!strcmp(arg, "--xpath0")) ||
2563
109k
#endif
2564
109k
        (!strcmp(arg, "-max-ampl")) ||
2565
109k
        (!strcmp(arg, "--max-ampl"))
2566
125k
    ) {
2567
17.4k
        return(1);
2568
17.4k
    }
2569
2570
108k
    return(0);
2571
125k
}
2572
2573
static void
2574
7.61k
xmllintInit(xmllintState *lint) {
2575
7.61k
    memset(lint, 0, sizeof(*lint));
2576
2577
7.61k
    lint->repeat = 1;
2578
7.61k
    lint->progresult = XMLLINT_RETURN_OK;
2579
7.61k
    lint->parseOptions = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
2580
7.61k
#ifdef LIBXML_HTML_ENABLED
2581
7.61k
    lint->htmlOptions = HTML_PARSE_COMPACT | HTML_PARSE_BIG_LINES;
2582
7.61k
#endif
2583
7.61k
}
2584
2585
static void
2586
29.5k
xmllintOptWarnNoSupport(FILE *errStream, const char *opt, const char *nosupp) {
2587
29.5k
    fprintf(errStream, "Warning: Option %s doesn't support %s\n", opt, nosupp);
2588
29.5k
}
2589
2590
static int
2591
7.61k
xmllintParseOptions(xmllintState *lint, int argc, const char **argv) {
2592
7.61k
    FILE *errStream = lint->errStream;
2593
7.61k
    const char *specialMode = NULL;
2594
7.61k
    int i;
2595
2596
7.61k
    if (argc <= 1) {
2597
0
        usage(errStream, argv[0]);
2598
0
        return(XMLLINT_ERR_UNCLASS);
2599
0
    }
2600
2601
144k
    for (i = 1; i < argc ; i++) {
2602
137k
        unsigned long val;
2603
2604
137k
        if (argv[i][0] != '-' || argv[i][1] == 0)
2605
7.52k
            continue;
2606
2607
129k
        if ((!strcmp(argv[i], "-maxmem")) ||
2608
129k
            (!strcmp(argv[i], "--maxmem"))) {
2609
3.23k
            i++;
2610
3.23k
            if (i >= argc) {
2611
0
                fprintf(errStream, "maxmem: missing integer value\n");
2612
0
                return(XMLLINT_ERR_UNCLASS);
2613
0
            }
2614
3.23k
            if (parseInteger(&val, errStream, "maxmem", argv[i],
2615
3.23k
                             0, INT_MAX) < 0)
2616
0
                return(XMLLINT_ERR_UNCLASS);
2617
3.23k
            lint->maxmem = val;
2618
126k
        } else if ((!strcmp(argv[i], "-debug")) ||
2619
126k
                   (!strcmp(argv[i], "--debug"))) {
2620
2.04k
            lint->appOptions |= XML_LINT_DEBUG_ENABLED;
2621
124k
        } else if ((!strcmp(argv[i], "-shell")) ||
2622
124k
                   (!strcmp(argv[i], "--shell"))) {
2623
0
            lint->appOptions |= XML_LINT_NAVIGATING_SHELL;
2624
124k
        } else if ((!strcmp(argv[i], "-copy")) ||
2625
124k
                   (!strcmp(argv[i], "--copy"))) {
2626
2.22k
            lint->appOptions |= XML_LINT_COPY_ENABLED;
2627
122k
        } else if ((!strcmp(argv[i], "-recover")) ||
2628
122k
                   (!strcmp(argv[i], "--recover"))) {
2629
1.14k
            lint->parseOptions |= XML_PARSE_RECOVER;
2630
120k
        } else if ((!strcmp(argv[i], "-huge")) ||
2631
120k
                   (!strcmp(argv[i], "--huge"))) {
2632
2.38k
            lint->parseOptions |= XML_PARSE_HUGE;
2633
2.38k
#ifdef LIBXML_HTML_ENABLED
2634
2.38k
            lint->htmlOptions |= HTML_PARSE_HUGE;
2635
2.38k
#endif
2636
118k
        } else if ((!strcmp(argv[i], "-noent")) ||
2637
118k
                   (!strcmp(argv[i], "--noent"))) {
2638
2.15k
            lint->parseOptions |= XML_PARSE_NOENT;
2639
116k
        } else if ((!strcmp(argv[i], "-noenc")) ||
2640
116k
                   (!strcmp(argv[i], "--noenc"))) {
2641
1.72k
            lint->parseOptions |= XML_PARSE_IGNORE_ENC;
2642
1.72k
#ifdef LIBXML_HTML_ENABLED
2643
1.72k
            lint->htmlOptions |= HTML_PARSE_IGNORE_ENC;
2644
1.72k
#endif
2645
114k
        } else if ((!strcmp(argv[i], "-nsclean")) ||
2646
114k
                   (!strcmp(argv[i], "--nsclean"))) {
2647
2.75k
            lint->parseOptions |= XML_PARSE_NSCLEAN;
2648
111k
        } else if ((!strcmp(argv[i], "-nocdata")) ||
2649
111k
                   (!strcmp(argv[i], "--nocdata"))) {
2650
2.75k
            lint->parseOptions |= XML_PARSE_NOCDATA;
2651
109k
        } else if ((!strcmp(argv[i], "-nodict")) ||
2652
109k
                   (!strcmp(argv[i], "--nodict"))) {
2653
3.64k
            lint->parseOptions |= XML_PARSE_NODICT;
2654
105k
        } else if ((!strcmp(argv[i], "-version")) ||
2655
105k
                   (!strcmp(argv[i], "--version"))) {
2656
2.13k
            showVersion(errStream, argv[0]);
2657
2.13k
            lint->version = 1;
2658
103k
        } else if ((!strcmp(argv[i], "-noout")) ||
2659
103k
                   (!strcmp(argv[i], "--noout"))) {
2660
1.88k
            lint->noout = 1;
2661
1.88k
#ifdef LIBXML_HTML_ENABLED
2662
101k
        } else if ((!strcmp(argv[i], "-html")) ||
2663
101k
                   (!strcmp(argv[i], "--html"))) {
2664
3.42k
            lint->appOptions |= XML_LINT_HTML_ENABLED;
2665
98.0k
        } else if ((!strcmp(argv[i], "-nodefdtd")) ||
2666
98.0k
                   (!strcmp(argv[i], "--nodefdtd"))) {
2667
2.39k
            lint->htmlOptions |= HTML_PARSE_NODEFDTD;
2668
2.39k
#ifdef LIBXML_OUTPUT_ENABLED
2669
95.6k
        } else if ((!strcmp(argv[i], "-xmlout")) ||
2670
95.6k
                   (!strcmp(argv[i], "--xmlout"))) {
2671
2.49k
            lint->appOptions |= XML_LINT_XML_OUT;
2672
2.49k
#endif
2673
2.49k
#endif /* LIBXML_HTML_ENABLED */
2674
93.2k
        } else if ((!strcmp(argv[i], "-loaddtd")) ||
2675
93.2k
                   (!strcmp(argv[i], "--loaddtd"))) {
2676
2.39k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2677
90.8k
        } else if ((!strcmp(argv[i], "-dtdattr")) ||
2678
90.8k
                   (!strcmp(argv[i], "--dtdattr"))) {
2679
3.28k
            lint->parseOptions |= XML_PARSE_DTDATTR;
2680
3.28k
#ifdef LIBXML_VALID_ENABLED
2681
87.5k
        } else if ((!strcmp(argv[i], "-valid")) ||
2682
87.5k
                   (!strcmp(argv[i], "--valid"))) {
2683
2.24k
            lint->parseOptions |= XML_PARSE_DTDVALID;
2684
85.2k
        } else if ((!strcmp(argv[i], "-postvalid")) ||
2685
85.2k
                   (!strcmp(argv[i], "--postvalid"))) {
2686
2.33k
            lint->appOptions |= XML_LINT_POST_VALIDATION;
2687
2.33k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2688
82.9k
        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
2689
82.9k
                   (!strcmp(argv[i], "--dtdvalid"))) {
2690
0
            i++;
2691
0
            lint->dtdvalid = argv[i];
2692
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2693
82.9k
        } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2694
82.9k
                   (!strcmp(argv[i], "--dtdvalidfpi"))) {
2695
0
            i++;
2696
0
            lint->dtdvalidfpi = argv[i];
2697
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2698
82.9k
        } else if ((!strcmp(argv[i], "-insert")) ||
2699
82.9k
                   (!strcmp(argv[i], "--insert"))) {
2700
3.65k
            lint->appOptions |= XML_LINT_VALID_INSERTIONS;
2701
3.65k
#endif /* LIBXML_VALID_ENABLED */
2702
79.2k
        } else if ((!strcmp(argv[i], "-strict-namespace")) ||
2703
79.2k
            (!strcmp(argv[i], "--strict-namespace"))) {
2704
0
            lint->appOptions |= XML_LINT_STRICT_NAMESPACE;
2705
79.2k
        } else if ((!strcmp(argv[i], "-dropdtd")) ||
2706
79.2k
                   (!strcmp(argv[i], "--dropdtd"))) {
2707
2.02k
            lint->appOptions |= XML_LINT_DROP_DTD;
2708
77.2k
        } else if ((!strcmp(argv[i], "-quiet")) ||
2709
77.2k
                   (!strcmp(argv[i], "--quiet"))) {
2710
746
            lint->appOptions |= XML_LINT_QUIET;
2711
76.5k
        } else if ((!strcmp(argv[i], "-timing")) ||
2712
76.5k
                   (!strcmp(argv[i], "--timing"))) {
2713
2.46k
            lint->appOptions |= XML_LINT_TIMINGS;
2714
74.0k
        } else if ((!strcmp(argv[i], "-auto")) ||
2715
74.0k
                   (!strcmp(argv[i], "--auto"))) {
2716
6.74k
            lint->appOptions |= XML_LINT_GENERATE;
2717
67.3k
        } else if ((!strcmp(argv[i], "-repeat")) ||
2718
67.3k
                   (!strcmp(argv[i], "--repeat"))) {
2719
1.50k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2720
1.50k
            lint->repeat = 2;
2721
#else
2722
            if (lint->repeat > 1)
2723
                lint->repeat *= 10;
2724
            else
2725
                lint->repeat = 100;
2726
#endif
2727
1.50k
#ifdef LIBXML_PUSH_ENABLED
2728
65.8k
        } else if ((!strcmp(argv[i], "-push")) ||
2729
65.8k
                   (!strcmp(argv[i], "--push"))) {
2730
245
            lint->appOptions |= XML_LINT_PUSH_ENABLED;
2731
245
#endif /* LIBXML_PUSH_ENABLED */
2732
245
#if HAVE_DECL_MMAP
2733
65.5k
        } else if ((!strcmp(argv[i], "-memory")) ||
2734
65.5k
                   (!strcmp(argv[i], "--memory"))) {
2735
0
            lint->appOptions |= XML_LINT_MEMORY;
2736
0
#endif
2737
0
#ifdef LIBXML_XINCLUDE_ENABLED
2738
65.5k
        } else if ((!strcmp(argv[i], "-xinclude")) ||
2739
65.5k
                   (!strcmp(argv[i], "--xinclude"))) {
2740
2.55k
            lint->appOptions |= XML_LINT_XINCLUDE;
2741
2.55k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2742
63.0k
        } else if ((!strcmp(argv[i], "-noxincludenode")) ||
2743
63.0k
                   (!strcmp(argv[i], "--noxincludenode"))) {
2744
3.37k
            lint->appOptions |= XML_LINT_XINCLUDE;
2745
3.37k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2746
3.37k
            lint->parseOptions |= XML_PARSE_NOXINCNODE;
2747
59.6k
        } else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
2748
59.6k
                   (!strcmp(argv[i], "--nofixup-base-uris"))) {
2749
3.11k
            lint->appOptions |= XML_LINT_XINCLUDE;
2750
3.11k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2751
3.11k
            lint->parseOptions |= XML_PARSE_NOBASEFIX;
2752
3.11k
#endif
2753
56.5k
        } else if ((!strcmp(argv[i], "-nowarning")) ||
2754
56.5k
                   (!strcmp(argv[i], "--nowarning"))) {
2755
2.57k
            lint->parseOptions |= XML_PARSE_NOWARNING;
2756
2.57k
            lint->parseOptions &= ~XML_PARSE_PEDANTIC;
2757
2.57k
#ifdef LIBXML_HTML_ENABLED
2758
2.57k
            lint->htmlOptions |= HTML_PARSE_NOWARNING;
2759
2.57k
#endif
2760
53.9k
        } else if ((!strcmp(argv[i], "-pedantic")) ||
2761
53.9k
                   (!strcmp(argv[i], "--pedantic"))) {
2762
1.16k
            lint->parseOptions |= XML_PARSE_PEDANTIC;
2763
1.16k
            lint->parseOptions &= ~XML_PARSE_NOWARNING;
2764
1.16k
#ifdef LIBXML_CATALOG_ENABLED
2765
52.7k
        } else if ((!strcmp(argv[i], "-catalogs")) ||
2766
52.7k
                   (!strcmp(argv[i], "--catalogs"))) {
2767
0
            lint->appOptions |= XML_LINT_USE_CATALOGS;
2768
52.7k
        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
2769
52.7k
                   (!strcmp(argv[i], "--nocatalogs"))) {
2770
7.61k
            lint->appOptions |= XML_LINT_USE_NO_CATALOGS;
2771
7.61k
            lint->parseOptions |= XML_PARSE_NO_SYS_CATALOG;
2772
7.61k
#endif
2773
45.1k
        } else if ((!strcmp(argv[i], "-noblanks")) ||
2774
45.1k
                   (!strcmp(argv[i], "--noblanks"))) {
2775
2.22k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2776
2.22k
#ifdef LIBXML_HTML_ENABLED
2777
2.22k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2778
2.22k
#endif
2779
2.22k
#ifdef LIBXML_OUTPUT_ENABLED
2780
42.9k
        } else if ((!strcmp(argv[i], "-o")) ||
2781
42.9k
                   (!strcmp(argv[i], "-output")) ||
2782
42.9k
                   (!strcmp(argv[i], "--output"))) {
2783
0
            i++;
2784
0
            lint->output = argv[i];
2785
42.9k
        } else if ((!strcmp(argv[i], "-format")) ||
2786
42.9k
                   (!strcmp(argv[i], "--format"))) {
2787
3.03k
            lint->format = 1;
2788
3.03k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2789
3.03k
#ifdef LIBXML_HTML_ENABLED
2790
3.03k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2791
3.03k
#endif
2792
39.9k
        } else if ((!strcmp(argv[i], "-encode")) ||
2793
39.9k
                   (!strcmp(argv[i], "--encode"))) {
2794
3.22k
            i++;
2795
3.22k
            lint->encoding = argv[i];
2796
36.6k
        } else if ((!strcmp(argv[i], "-pretty")) ||
2797
36.6k
                   (!strcmp(argv[i], "--pretty"))) {
2798
3.26k
            i++;
2799
3.26k
            if (i >= argc) {
2800
0
                fprintf(errStream, "pretty: missing integer value\n");
2801
0
                return(XMLLINT_ERR_UNCLASS);
2802
0
            }
2803
3.26k
            if (parseInteger(&val, errStream, "pretty", argv[i],
2804
3.26k
                             0, 2) < 0)
2805
12
                return(XMLLINT_ERR_UNCLASS);
2806
3.25k
            lint->format = val;
2807
3.25k
#ifdef LIBXML_ZLIB_ENABLED
2808
33.4k
        } else if ((!strcmp(argv[i], "-compress")) ||
2809
33.4k
                   (!strcmp(argv[i], "--compress"))) {
2810
817
            lint->appOptions |= XML_LINT_ZLIB_COMPRESSION;
2811
817
#endif
2812
817
#ifdef LIBXML_C14N_ENABLED
2813
32.6k
        } else if ((!strcmp(argv[i], "-c14n")) ||
2814
32.6k
                   (!strcmp(argv[i], "--c14n"))) {
2815
2.04k
            lint->appOptions |= XML_LINT_CANONICAL_V1_0;
2816
2.04k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2817
30.5k
        } else if ((!strcmp(argv[i], "-c14n11")) ||
2818
30.5k
                   (!strcmp(argv[i], "--c14n11"))) {
2819
2.87k
            lint->appOptions |= XML_LINT_CANONICAL_V1_1;
2820
2.87k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2821
27.6k
        } else if ((!strcmp(argv[i], "-exc-c14n")) ||
2822
27.6k
                   (!strcmp(argv[i], "--exc-c14n"))) {
2823
2.14k
            lint->appOptions |= XML_LINT_CANONICAL_EXE;
2824
2.14k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2825
2.14k
#endif /* LIBXML_C14N_ENABLED */
2826
2.14k
#endif /* LIBXML_OUTPUT_ENABLED */
2827
2.14k
#ifdef LIBXML_READER_ENABLED
2828
25.5k
        } else if ((!strcmp(argv[i], "-stream")) ||
2829
25.5k
                   (!strcmp(argv[i], "--stream"))) {
2830
1.23k
             lint->appOptions |= XML_LINT_USE_STREAMING;
2831
24.3k
        } else if ((!strcmp(argv[i], "-walker")) ||
2832
24.3k
                   (!strcmp(argv[i], "--walker"))) {
2833
2.31k
             lint->appOptions |= XML_LINT_USE_WALKER;
2834
2.31k
             lint->noout = 1;
2835
2.31k
#ifdef LIBXML_PATTERN_ENABLED
2836
21.9k
        } else if ((!strcmp(argv[i], "-pattern")) ||
2837
21.9k
                   (!strcmp(argv[i], "--pattern"))) {
2838
1.87k
            i++;
2839
1.87k
            lint->pattern = argv[i];
2840
1.87k
#endif
2841
1.87k
#endif /* LIBXML_READER_ENABLED */
2842
1.87k
#ifdef LIBXML_SAX1_ENABLED
2843
20.1k
        } else if ((!strcmp(argv[i], "-sax1")) ||
2844
20.1k
                   (!strcmp(argv[i], "--sax1"))) {
2845
2.58k
            lint->parseOptions |= XML_PARSE_SAX1;
2846
2.58k
#endif /* LIBXML_SAX1_ENABLED */
2847
17.5k
        } else if ((!strcmp(argv[i], "-sax")) ||
2848
17.5k
                   (!strcmp(argv[i], "--sax"))) {
2849
271
            lint->appOptions |= XML_LINT_SAX_ENABLED;
2850
271
#ifdef LIBXML_RELAXNG_ENABLED
2851
17.2k
        } else if ((!strcmp(argv[i], "-relaxng")) ||
2852
17.2k
                   (!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
17.2k
        } else if ((!strcmp(argv[i], "-schema")) ||
2859
17.2k
                 (!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
17.2k
        } else if ((!strcmp(argv[i], "-nonet")) ||
2872
17.2k
                   (!strcmp(argv[i], "--nonet"))) {
2873
2.75k
            lint->parseOptions |= XML_PARSE_NONET;
2874
14.5k
        } else if ((!strcmp(argv[i], "-nocompact")) ||
2875
14.5k
                   (!strcmp(argv[i], "--nocompact"))) {
2876
2.59k
            lint->parseOptions &= ~XML_PARSE_COMPACT;
2877
2.59k
#ifdef LIBXML_HTML_ENABLED
2878
2.59k
            lint->htmlOptions &= ~HTML_PARSE_COMPACT;
2879
2.59k
#endif
2880
11.9k
        } else if ((!strcmp(argv[i], "-load-trace")) ||
2881
11.9k
                   (!strcmp(argv[i], "--load-trace"))) {
2882
2.99k
            lint->appOptions |= XML_LINT_USE_LOAD_TRACE;
2883
8.90k
        } else if ((!strcmp(argv[i], "-path")) ||
2884
8.90k
                   (!strcmp(argv[i], "--path"))) {
2885
0
            i++;
2886
0
            parsePath(lint, BAD_CAST argv[i]);
2887
0
#ifdef LIBXML_XPATH_ENABLED
2888
8.90k
        } else if ((!strcmp(argv[i], "-xpath")) ||
2889
8.90k
                   (!strcmp(argv[i], "--xpath"))) {
2890
5.64k
            i++;
2891
5.64k
            lint->noout++;
2892
5.64k
            lint->xpathquery = argv[i];
2893
5.64k
            lint->xpathsep = "\n";
2894
5.64k
        } else if ((!strcmp(argv[i], "-xpath0")) ||
2895
3.26k
                   (!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.26k
        } else if ((!strcmp(argv[i], "-oldxml10")) ||
2902
3.26k
                   (!strcmp(argv[i], "--oldxml10"))) {
2903
2.57k
            lint->parseOptions |= XML_PARSE_OLD10;
2904
2.57k
        } else if ((!strcmp(argv[i], "-max-ampl")) ||
2905
690
                   (!strcmp(argv[i], "--max-ampl"))) {
2906
614
            i++;
2907
614
            if (i >= argc) {
2908
0
                fprintf(errStream, "max-ampl: missing integer value\n");
2909
0
                return(XMLLINT_ERR_UNCLASS);
2910
0
            }
2911
614
            if (parseInteger(&val, errStream, "max-ampl", argv[i],
2912
614
                             1, UINT_MAX) < 0)
2913
0
                return(XMLLINT_ERR_UNCLASS);
2914
614
            lint->maxAmpl = val;
2915
614
        } 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
129k
    }
2921
2922
7.52k
    if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2923
0
        lint->repeat = 1;
2924
2925
7.52k
#ifdef LIBXML_READER_ENABLED
2926
7.52k
    if (lint->appOptions & XML_LINT_USE_STREAMING) {
2927
1.22k
        specialMode = "--stream";
2928
2929
1.22k
        if (lint->appOptions & XML_LINT_SAX_ENABLED)
2930
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--sax");
2931
1.22k
#ifdef LIBXML_PUSH_ENABLED
2932
1.22k
        if (lint->appOptions & XML_LINT_PUSH_ENABLED)
2933
154
            xmllintOptWarnNoSupport(errStream, "--stream", "--push");
2934
1.22k
#endif
2935
1.22k
#ifdef LIBXML_HTML_ENABLED
2936
1.22k
        if (lint->appOptions & XML_LINT_HTML_ENABLED)
2937
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--html");
2938
1.22k
#endif
2939
1.22k
    }
2940
7.52k
#endif /* LIBXML_READER_ENABLED */
2941
2942
7.52k
    if (lint->appOptions & XML_LINT_SAX_ENABLED) {
2943
271
        specialMode = "--sax";
2944
2945
271
#ifdef LIBXML_XINCLUDE_ENABLED
2946
271
        if (lint->appOptions & XML_LINT_XINCLUDE)
2947
252
            xmllintOptWarnNoSupport(errStream, "--sax", "--xinclude");
2948
271
#endif
2949
271
#ifdef LIBXML_RELAXNG_ENABLED
2950
271
        if (lint->relaxng != NULL)
2951
0
            xmllintOptWarnNoSupport(errStream, "--sax", "--relaxng");
2952
271
#endif
2953
271
    }
2954
2955
7.52k
    if (specialMode != NULL) {
2956
1.49k
        if (lint->appOptions & XML_LINT_GENERATE)
2957
1.40k
            xmllintOptWarnNoSupport(errStream, specialMode, "--auto");
2958
1.49k
        if (lint->appOptions & XML_LINT_DROP_DTD)
2959
171
            xmllintOptWarnNoSupport(errStream, specialMode, "--dropdtd");
2960
1.49k
        if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2961
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--shell");
2962
1.49k
        if (lint->appOptions & XML_LINT_COPY_ENABLED)
2963
418
            xmllintOptWarnNoSupport(errStream, specialMode, "--copy");
2964
1.49k
#ifdef LIBXML_XPATH_ENABLED
2965
1.49k
        if (lint->xpathquery != NULL)
2966
1.24k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xpath");
2967
1.49k
#endif
2968
1.49k
#ifdef LIBXML_READER_ENABLED
2969
1.49k
        if (lint->appOptions & XML_LINT_USE_WALKER)
2970
587
            xmllintOptWarnNoSupport(errStream, specialMode, "--walker");
2971
1.49k
#endif
2972
1.49k
#ifdef LIBXML_VALID_ENABLED
2973
1.49k
        if (lint->appOptions & XML_LINT_VALID_INSERTIONS)
2974
823
            xmllintOptWarnNoSupport(errStream, specialMode, "--insert");
2975
1.49k
        if (lint->dtdvalid != NULL)
2976
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalid");
2977
1.49k
        if (lint->dtdvalidfpi != NULL)
2978
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalidfpi");
2979
1.49k
        if (lint->appOptions & XML_LINT_POST_VALIDATION)
2980
274
            xmllintOptWarnNoSupport(errStream, specialMode, "--postvalid");
2981
1.49k
#endif
2982
#ifdef LIBXML_SCHEMATRON_ENABLED
2983
        if (lint->schematron != NULL)
2984
            xmllintOptWarnNoSupport(errStream, specialMode, "--schematron");
2985
#endif
2986
1.49k
#ifdef LIBXML_OUTPUT_ENABLED
2987
1.49k
        if (lint->output != NULL)
2988
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--output");
2989
1.49k
        if (lint->encoding != NULL)
2990
190
            xmllintOptWarnNoSupport(errStream, specialMode, "--encode");
2991
1.49k
        if (lint->format > 0)
2992
876
            xmllintOptWarnNoSupport(errStream, specialMode,
2993
876
                                    "--format or -pretty");
2994
1.49k
#ifdef LIBXML_ZLIB_ENABLED
2995
1.49k
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
2996
209
            xmllintOptWarnNoSupport(errStream, specialMode, "--compress");
2997
1.49k
#endif
2998
1.49k
#ifdef LIBXML_HTML_ENABLED
2999
1.49k
        if (lint->appOptions & XML_LINT_XML_OUT)
3000
465
            xmllintOptWarnNoSupport(errStream, specialMode, "--xmlout");
3001
1.49k
#endif
3002
1.49k
#ifdef LIBXML_C14N_ENABLED
3003
1.49k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_0)
3004
374
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n");
3005
1.49k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_1)
3006
803
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n11");
3007
1.49k
        if (lint->appOptions & XML_LINT_CANONICAL_EXE)
3008
463
            xmllintOptWarnNoSupport(errStream, specialMode, "--exc-c14n");
3009
1.49k
#endif
3010
1.49k
#endif /* LIBXML_OUTPUT_ENABLED */
3011
1.49k
    }
3012
3013
7.52k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3014
7.52k
    if (lint->pattern && !((lint->appOptions & XML_LINT_USE_STREAMING) || (lint->appOptions & XML_LINT_USE_WALKER)))
3015
1.32k
        fprintf(errStream, "Warning: Option %s requires %s\n",
3016
1.32k
                "--pattern", "--stream or --walker");
3017
7.52k
#endif
3018
3019
7.52k
#ifdef LIBXML_HTML_ENABLED
3020
7.52k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3021
3.42k
        if (lint->parseOptions & XML_PARSE_DTDATTR)
3022
2.86k
            xmllintOptWarnNoSupport(errStream, "--html", "--dtdattr");
3023
3.42k
        if (lint->parseOptions & XML_PARSE_DTDLOAD)
3024
2.83k
            xmllintOptWarnNoSupport(errStream, "--html", "--loaddtd");
3025
3.42k
        if (lint->maxAmpl)
3026
376
            xmllintOptWarnNoSupport(errStream, "--html", "--max-ampl");
3027
3.42k
        if (lint->parseOptions & XML_PARSE_NOCDATA)
3028
965
            xmllintOptWarnNoSupport(errStream, "--html", "--nocdata");
3029
3.42k
        if (lint->parseOptions & XML_PARSE_NODICT)
3030
2.11k
            xmllintOptWarnNoSupport(errStream, "--html", "--nodict");
3031
3.42k
        if (lint->parseOptions & XML_PARSE_NOENT)
3032
3.07k
            xmllintOptWarnNoSupport(errStream, "--html", "--noent");
3033
3.42k
        if (lint->parseOptions & XML_PARSE_NONET)
3034
1.75k
            xmllintOptWarnNoSupport(errStream, "--html", "--nonet");
3035
3.42k
        if (lint->parseOptions & XML_PARSE_NSCLEAN)
3036
1.33k
            xmllintOptWarnNoSupport(errStream, "--html", "--nsclean");
3037
3.42k
        if (lint->parseOptions & XML_PARSE_OLD10)
3038
1.37k
            xmllintOptWarnNoSupport(errStream, "--html", "--oldxml10");
3039
3.42k
        if (lint->parseOptions & XML_PARSE_PEDANTIC)
3040
546
            xmllintOptWarnNoSupport(errStream, "--html", "--pedantic");
3041
3.42k
        if (lint->parseOptions & XML_PARSE_DTDVALID)
3042
1.37k
            xmllintOptWarnNoSupport(errStream, "--html", "--valid");
3043
3.42k
        if (lint->parseOptions & XML_PARSE_SAX1)
3044
2.25k
            xmllintOptWarnNoSupport(errStream, "--html", "--sax1");
3045
4.09k
    } else {
3046
4.09k
        if (lint->htmlOptions & HTML_PARSE_NODEFDTD)
3047
1.10k
            fprintf(errStream, "Warning: Option %s requires %s\n",
3048
1.10k
                    "--nodefdtd", "--html");
3049
4.09k
#ifdef LIBXML_OUTPUT_ENABLED
3050
4.09k
        if (lint->appOptions & XML_LINT_XML_OUT)
3051
917
            fprintf(errStream, "Warning: Option %s requires %s\n",
3052
917
                    "--xmlout", "--html");
3053
4.09k
#endif
3054
4.09k
    }
3055
7.52k
#endif
3056
3057
7.52k
    return(XMLLINT_RETURN_OK);
3058
7.61k
}
3059
3060
int
3061
xmllintMain(int argc, const char **argv, FILE *errStream,
3062
7.61k
            xmlResourceLoader loader) {
3063
7.61k
    xmllintState state, *lint;
3064
7.61k
    int i, j, res;
3065
7.61k
    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.61k
    lint = &state;
3074
7.61k
    xmllintInit(lint);
3075
7.61k
    lint->errStream = errStream;
3076
7.61k
    lint->defaultResourceLoader = loader;
3077
3078
7.61k
    res = xmllintParseOptions(lint, argc, argv);
3079
7.61k
    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.52k
    xmllintMaxmem = 0;
3088
7.52k
    if (lint->maxmem != 0) {
3089
3.21k
        xmllintMaxmem = lint->maxmem;
3090
3.21k
        xmllintMaxmemReached = 0;
3091
3.21k
        xmllintOom = 0;
3092
3.21k
        xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
3093
3.21k
    }
3094
3095
7.52k
    LIBXML_TEST_VERSION
3096
3097
7.52k
#ifdef LIBXML_CATALOG_ENABLED
3098
7.52k
    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.52k
#endif
3111
3112
7.52k
#ifdef LIBXML_OUTPUT_ENABLED
3113
7.52k
    {
3114
7.52k
        const char *indent = getenv("XMLLINT_INDENT");
3115
7.52k
        if (indent != NULL) {
3116
0
            lint->indentString = indent;
3117
0
        }
3118
7.52k
    }
3119
7.52k
#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.52k
#ifdef LIBXML_RELAXNG_ENABLED
3154
7.52k
    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.52k
#endif /* LIBXML_READER_ENABLED */
3158
7.52k
  ) {
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.52k
#endif /* LIBXML_RELAXNG_ENABLED */
3185
3186
7.52k
#ifdef LIBXML_SCHEMAS_ENABLED
3187
7.52k
    if ((lint->schema != NULL)
3188
0
#ifdef LIBXML_READER_ENABLED
3189
0
        && ((lint->appOptions& XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3190
7.52k
#endif
3191
7.52k
  ) {
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.52k
#endif /* LIBXML_SCHEMAS_ENABLED */
3216
3217
7.52k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3218
7.52k
    if ((lint->pattern != NULL) && ((lint->appOptions & XML_LINT_USE_WALKER) != XML_LINT_USE_WALKER)) {
3219
1.42k
        res = xmlPatternCompileSafe(BAD_CAST lint->pattern, NULL, 0, NULL,
3220
1.42k
                                    &lint->patternc);
3221
1.42k
  if (lint->patternc == NULL) {
3222
164
            if (res < 0) {
3223
26
                lint->progresult = XMLLINT_ERR_MEM;
3224
138
            } else {
3225
138
                fprintf(errStream, "Pattern %s failed to compile\n",
3226
138
                        lint->pattern);
3227
138
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
3228
138
            }
3229
164
            goto error;
3230
164
  }
3231
1.42k
    }
3232
7.36k
#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
3233
3234
    /*
3235
     * The main loop over input documents
3236
     */
3237
140k
    for (i = 1; i < argc ; i++) {
3238
133k
        const char *filename = argv[i];
3239
133k
#if HAVE_DECL_MMAP
3240
133k
        int memoryFd = -1;
3241
133k
#endif
3242
3243
133k
  if ((filename[0] == '-') && (strcmp(filename, "-") != 0)) {
3244
125k
            i += skipArgs(filename);
3245
125k
            continue;
3246
125k
        }
3247
3248
7.36k
#if HAVE_DECL_MMAP
3249
7.36k
        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.36k
#endif /* HAVE_DECL_MMAP */
3271
3272
7.36k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1))
3273
809
      startTimer(lint);
3274
3275
7.36k
#ifdef LIBXML_READER_ENABLED
3276
7.36k
        if (lint->appOptions & XML_LINT_USE_STREAMING) {
3277
2.52k
            for (j = 0; j < lint->repeat; j++)
3278
1.34k
                streamFile(lint, filename);
3279
1.18k
        } else
3280
6.17k
#endif /* LIBXML_READER_ENABLED */
3281
6.17k
        {
3282
6.17k
            xmlParserCtxtPtr ctxt;
3283
3284
6.17k
#ifdef LIBXML_HTML_ENABLED
3285
6.17k
            if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3286
3.41k
#ifdef LIBXML_PUSH_ENABLED
3287
3.41k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3288
10
                    ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3289
10
                                                    filename,
3290
10
                                                    XML_CHAR_ENCODING_NONE);
3291
10
                } else
3292
3.40k
#endif /* LIBXML_PUSH_ENABLED */
3293
3.40k
                {
3294
3.40k
                    ctxt = htmlNewParserCtxt();
3295
3.40k
                }
3296
3.41k
                htmlCtxtUseOptions(ctxt, lint->htmlOptions);
3297
3.41k
            } else
3298
2.76k
#endif /* LIBXML_HTML_ENABLED */
3299
2.76k
            {
3300
2.76k
#ifdef LIBXML_PUSH_ENABLED
3301
2.76k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3302
28
                    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3303
28
                                                   filename);
3304
28
                } else
3305
2.73k
#endif /* LIBXML_PUSH_ENABLED */
3306
2.73k
                {
3307
2.73k
                    ctxt = xmlNewParserCtxt();
3308
2.73k
                }
3309
2.76k
                xmlCtxtUseOptions(ctxt, lint->parseOptions);
3310
2.76k
            }
3311
6.17k
            if (ctxt == NULL) {
3312
55
                lint->progresult = XMLLINT_ERR_MEM;
3313
55
                goto error;
3314
55
            }
3315
3316
6.12k
            if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3317
262
                const xmlSAXHandler *handler;
3318
3319
262
                if (lint->noout) {
3320
214
                    handler = &emptySAXHandler;
3321
214
#ifdef LIBXML_SAX1_ENABLED
3322
214
                } else if (lint->parseOptions & XML_PARSE_SAX1) {
3323
18
                    handler = &debugSAXHandler;
3324
18
#endif
3325
30
                } else {
3326
30
                    handler = &debugSAX2Handler;
3327
30
                }
3328
3329
262
                *ctxt->sax = *handler;
3330
262
                ctxt->userData = lint;
3331
262
            }
3332
3333
6.12k
            xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3334
6.12k
            if (lint->maxAmpl > 0)
3335
498
                xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl);
3336
3337
6.12k
            lint->ctxt = ctxt;
3338
3339
13.5k
            for (j = 0; j < lint->repeat; j++) {
3340
7.43k
                if (j > 0) {
3341
1.31k
#ifdef LIBXML_PUSH_ENABLED
3342
1.31k
                    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3343
6
                        xmlCtxtResetPush(ctxt, NULL, 0, NULL, NULL);
3344
6
                    } else
3345
1.30k
#endif
3346
1.30k
                    {
3347
1.30k
                        xmlCtxtReset(ctxt);
3348
1.30k
                    }
3349
1.31k
                }
3350
3351
7.43k
                if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3352
327
                    testSAX(lint, filename);
3353
7.10k
                } else {
3354
7.10k
                    parseAndPrintFile(lint, filename);
3355
7.10k
                }
3356
7.43k
            }
3357
3358
6.12k
            xmlFreeParserCtxt(ctxt);
3359
6.12k
        }
3360
3361
7.30k
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) {
3362
807
            endTimer(lint, "%d iterations", lint->repeat);
3363
807
        }
3364
3365
7.30k
        files += 1;
3366
3367
7.30k
#if HAVE_DECL_MMAP
3368
7.30k
        if (lint->appOptions & XML_LINT_MEMORY) {
3369
0
            munmap(lint->memoryData, lint->memorySize);
3370
0
            close(memoryFd);
3371
0
        }
3372
7.30k
#endif
3373
7.30k
    }
3374
3375
7.30k
    if (lint->appOptions & XML_LINT_GENERATE)
3376
6.62k
  parseAndPrintFile(lint, NULL);
3377
3378
7.30k
    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.52k
error:
3384
3385
#ifdef LIBXML_SCHEMATRON_ENABLED
3386
    if (lint->wxschematron != NULL)
3387
  xmlSchematronFree(lint->wxschematron);
3388
#endif
3389
7.52k
#ifdef LIBXML_RELAXNG_ENABLED
3390
7.52k
    if (lint->relaxngschemas != NULL)
3391
0
  xmlRelaxNGFree(lint->relaxngschemas);
3392
7.52k
#endif
3393
7.52k
#ifdef LIBXML_SCHEMAS_ENABLED
3394
7.52k
    if (lint->wxschemas != NULL)
3395
0
  xmlSchemaFree(lint->wxschemas);
3396
7.52k
#endif
3397
7.52k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3398
7.52k
    if (lint->patternc != NULL)
3399
1.26k
        xmlFreePattern(lint->patternc);
3400
7.52k
#endif
3401
3402
7.52k
    xmlCleanupParser();
3403
3404
7.52k
    if ((lint->maxmem) && (xmllintMaxmemReached)) {
3405
513
        fprintf(errStream, "Maximum memory exceeded (%d bytes)\n",
3406
513
                xmllintMaxmem);
3407
7.01k
    } else if (lint->progresult == XMLLINT_ERR_MEM) {
3408
20
        fprintf(errStream, "Out-of-memory error reported\n");
3409
20
    }
3410
3411
7.52k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
3412
7.52k
    if ((lint->maxmem) &&
3413
3.21k
        (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.52k
#endif
3419
3420
7.52k
    return(lint->progresult);
3421
7.52k
}
3422