Coverage Report

Created: 2025-07-18 06:55

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