Coverage Report

Created: 2025-07-11 06:36

/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.46k
                      xmlParserInputFlags flags, xmlParserInputPtr *out) {
273
7.46k
    xmllintState *lint = ctxt;
274
7.46k
    xmlParserErrors code;
275
7.46k
    int i;
276
7.46k
    const char *lastsegment = URL;
277
7.46k
    const char *iter = URL;
278
279
7.46k
    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.46k
    if (lint->defaultResourceLoader != NULL)
288
7.46k
        code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out);
289
0
    else
290
0
        code = xmlNewInputFromUrl(URL, flags, out);
291
7.46k
    if (code != XML_IO_ENOENT) {
292
7.46k
        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.46k
        return(code);
297
7.46k
    }
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.16k
parseXml(xmllintState *lint, const char *filename) {
334
6.16k
    xmlParserCtxtPtr ctxt = lint->ctxt;
335
6.16k
    xmlDocPtr doc;
336
337
6.16k
#ifdef LIBXML_PUSH_ENABLED
338
6.16k
    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.16k
#endif /* LIBXML_PUSH_ENABLED */
366
367
6.16k
#if HAVE_DECL_MMAP
368
6.16k
    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.16k
#endif
382
383
6.16k
    if (strcmp(filename, "-") == 0)
384
0
        doc = xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
385
0
                            lint->parseOptions | XML_PARSE_UNZIP);
386
6.16k
    else
387
6.16k
        doc = xmlCtxtReadFile(ctxt, filename, NULL,
388
6.16k
                              lint->parseOptions | XML_PARSE_UNZIP);
389
390
6.16k
    return(doc);
391
6.16k
}
392
393
#ifdef LIBXML_HTML_ENABLED
394
static xmlDocPtr
395
1.30k
parseHtml(xmllintState *lint, const char *filename) {
396
1.30k
    xmlParserCtxtPtr ctxt = lint->ctxt;
397
1.30k
    xmlDocPtr doc;
398
399
1.30k
#ifdef LIBXML_PUSH_ENABLED
400
1.30k
    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.30k
#endif /* LIBXML_PUSH_ENABLED */
428
429
1.30k
#if HAVE_DECL_MMAP
430
1.30k
    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.30k
#endif
444
445
1.30k
    if (strcmp(filename, "-") == 0)
446
0
        doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
447
0
                             lint->htmlOptions);
448
1.30k
    else
449
1.30k
        doc = htmlCtxtReadFile(ctxt, filename, NULL, lint->htmlOptions);
450
451
1.30k
    return(doc);
452
1.30k
}
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
390
myFreeFunc(void *mem) {
465
390
    xmlMemFree(mem);
466
390
}
467
468
static void *
469
430
myMallocFunc(size_t size) {
470
430
    void *ret;
471
472
430
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
473
#if XMLLINT_ABORT_ON_FAILURE
474
        abort();
475
#endif
476
430
        xmllintMaxmemReached = 1;
477
430
        xmllintOom = 1;
478
430
        return(NULL);
479
430
    }
480
481
0
    ret = xmlMemMalloc(size);
482
0
    if (ret == NULL)
483
0
        xmllintOom = 1;
484
485
0
    return(ret);
486
430
}
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.53k
myStrdupFunc(const char *str) {
511
7.53k
    size_t size;
512
7.53k
    char *ret;
513
514
7.53k
    if (str == NULL)
515
0
        return(NULL);
516
517
7.53k
    size = strlen(str) + 1;
518
7.53k
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
519
#if XMLLINT_ABORT_ON_FAILURE
520
        abort();
521
#endif
522
7.53k
        xmllintMaxmemReached = 1;
523
7.53k
        xmllintOom = 1;
524
7.53k
        return(NULL);
525
7.53k
    }
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
20.5k
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
20.5k
    struct timeval tv;
555
556
20.5k
    gettimeofday(&tv, NULL);
557
20.5k
    time->sec = tv.tv_sec;
558
20.5k
    time->usec = tv.tv_usec;
559
20.5k
#endif /* _WIN32 */
560
20.5k
}
561
562
/*
563
 * startTimer: call where you want to start timing
564
 */
565
static void
566
startTimer(xmllintState *lint)
567
10.9k
{
568
10.9k
    getTime(&lint->begin);
569
10.9k
}
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
9.60k
{
579
9.60k
    xmlSeconds msec;
580
9.60k
    va_list ap;
581
582
9.60k
    getTime(&lint->end);
583
9.60k
    msec = lint->end.sec - lint->begin.sec;
584
9.60k
    msec *= 1000;
585
9.60k
    msec += (lint->end.usec - lint->begin.usec) / 1000;
586
587
9.60k
    va_start(ap, fmt);
588
9.60k
    vfprintf(lint->errStream, fmt, ap);
589
9.60k
    va_end(ap);
590
591
9.60k
    fprintf(lint->errStream, " took %ld ms\n", (long) msec);
592
9.60k
}
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
65
{
1015
65
    xmllintState *lint = ctx;
1016
65
    va_list args;
1017
1018
65
    lint->callbacks++;
1019
65
    if (lint->noout)
1020
0
  return;
1021
65
    va_start(args, msg);
1022
65
    fprintf(stdout, "SAX.error: ");
1023
65
    vfprintf(stdout, msg, args);
1024
65
    va_end(args);
1025
65
}
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
670
testSAX(xmllintState *lint, const char *filename) {
1193
670
    lint->callbacks = 0;
1194
1195
670
#ifdef LIBXML_SCHEMAS_ENABLED
1196
670
    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
670
#endif
1236
670
#ifdef LIBXML_HTML_ENABLED
1237
670
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1238
0
        parseHtml(lint, filename);
1239
0
    } else
1240
670
#endif
1241
670
    {
1242
670
        parseXml(lint, filename);
1243
670
    }
1244
670
}
1245
1246
/************************************************************************
1247
 *                  *
1248
 *      Stream Test processing        *
1249
 *                  *
1250
 ************************************************************************/
1251
#ifdef LIBXML_READER_ENABLED
1252
2.54k
static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
1253
2.54k
    const xmlChar *name, *value;
1254
2.54k
    int type, empty;
1255
1256
2.54k
    type = xmlTextReaderNodeType(reader);
1257
2.54k
    empty = xmlTextReaderIsEmptyElement(reader);
1258
1259
2.54k
    if (lint->appOptions & XML_LINT_DEBUG_ENABLED) {
1260
1.72k
  name = xmlTextReaderConstName(reader);
1261
1.72k
  if (name == NULL)
1262
0
      name = BAD_CAST "--";
1263
1264
1.72k
  value = xmlTextReaderConstValue(reader);
1265
1266
1267
1.72k
  printf("%d %d %s %d %d",
1268
1.72k
    xmlTextReaderDepth(reader),
1269
1.72k
    type,
1270
1.72k
    name,
1271
1.72k
    empty,
1272
1.72k
    xmlTextReaderHasValue(reader));
1273
1.72k
  if (value == NULL)
1274
1.15k
      printf("\n");
1275
576
  else {
1276
576
      printf(" %s\n", value);
1277
576
  }
1278
1.72k
    }
1279
2.54k
#ifdef LIBXML_PATTERN_ENABLED
1280
2.54k
    if (lint->patternc) {
1281
1.27k
        xmlChar *path = NULL;
1282
1.27k
        int match = -1;
1283
1284
1.27k
  if (type == XML_READER_TYPE_ELEMENT) {
1285
      /* do the check only on element start */
1286
425
      match = xmlPatternMatch(lint->patternc,
1287
425
                                    xmlTextReaderCurrentNode(reader));
1288
1289
425
      if (match) {
1290
113
    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1291
113
    printf("Node %s matches pattern %s\n", path, lint->pattern);
1292
113
      }
1293
425
  }
1294
1.27k
  if (lint->patstream != NULL) {
1295
1.27k
      int ret;
1296
1297
1.27k
      if (type == XML_READER_TYPE_ELEMENT) {
1298
425
    ret = xmlStreamPush(lint->patstream,
1299
425
                        xmlTextReaderConstLocalName(reader),
1300
425
            xmlTextReaderConstNamespaceUri(reader));
1301
425
    if (ret < 0) {
1302
0
        fprintf(lint->errStream, "xmlStreamPush() failure\n");
1303
0
                    xmlFreeStreamCtxt(lint->patstream);
1304
0
        lint->patstream = NULL;
1305
425
    } else if (ret != match) {
1306
19
        if (path == NULL) {
1307
10
            path = xmlGetNodePath(
1308
10
                           xmlTextReaderCurrentNode(reader));
1309
10
        }
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
425
      }
1321
1.27k
      if ((type == XML_READER_TYPE_END_ELEMENT) ||
1322
1.27k
          ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1323
425
          ret = xmlStreamPop(lint->patstream);
1324
425
    if (ret < 0) {
1325
0
        fprintf(lint->errStream, "xmlStreamPop() failure\n");
1326
0
                    xmlFreeStreamCtxt(lint->patstream);
1327
0
        lint->patstream = NULL;
1328
0
    }
1329
425
      }
1330
1.27k
  }
1331
1.27k
  if (path != NULL)
1332
123
      xmlFree(path);
1333
1.27k
    }
1334
2.54k
#endif
1335
2.54k
}
1336
1337
3.07k
static void streamFile(xmllintState *lint, const char *filename) {
1338
3.07k
    xmlParserInputBufferPtr input = NULL;
1339
3.07k
    FILE *errStream = lint->errStream;
1340
3.07k
    xmlTextReaderPtr reader;
1341
3.07k
    int ret;
1342
1343
3.07k
#if HAVE_DECL_MMAP
1344
3.07k
    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.07k
#endif
1353
3.07k
    {
1354
3.07k
        xmlResetLastError();
1355
1356
3.07k
        if (strcmp(filename, "-") == 0) {
1357
0
            reader = xmlReaderForFd(STDIN_FILENO, "-", NULL,
1358
0
                                    lint->parseOptions | XML_PARSE_UNZIP);
1359
0
        }
1360
3.07k
        else {
1361
3.07k
            reader = xmlReaderForFile(filename, NULL,
1362
3.07k
                                      lint->parseOptions | XML_PARSE_UNZIP);
1363
3.07k
        }
1364
3.07k
        if (reader == NULL) {
1365
3.07k
            const xmlError *error = xmlGetLastError();
1366
1367
3.07k
            if ((error != NULL) && (error->code == XML_ERR_NO_MEMORY)) {
1368
92
                lint->progresult = XMLLINT_ERR_MEM;
1369
2.98k
            } else {
1370
2.98k
                fprintf(errStream, "Unable to open %s\n", filename);
1371
2.98k
                lint->progresult = XMLLINT_ERR_RDFILE;
1372
2.98k
            }
1373
3.07k
            return;
1374
3.07k
        }
1375
3.07k
    }
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.90k
static void walkDoc(xmllintState *lint, xmlDocPtr doc) {
1512
1.90k
    FILE *errStream = lint->errStream;
1513
1.90k
    xmlTextReaderPtr reader;
1514
1.90k
    int ret;
1515
1516
1.90k
#ifdef LIBXML_PATTERN_ENABLED
1517
1.90k
    if (lint->pattern != NULL) {
1518
684
        xmlNodePtr root;
1519
684
        const xmlChar *namespaces[22];
1520
684
        int i;
1521
684
        xmlNsPtr ns;
1522
1523
684
        root = xmlDocGetRootElement(doc);
1524
684
        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
684
        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
684
        namespaces[i++] = NULL;
1535
684
        namespaces[i] = NULL;
1536
1537
684
        ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict,
1538
684
                                    0, &namespaces[0], &lint->patternc);
1539
684
  if (lint->patternc == NULL) {
1540
222
            if (ret < 0) {
1541
0
                lint->progresult = XMLLINT_ERR_MEM;
1542
222
            } else {
1543
222
                fprintf(errStream, "Pattern %s failed to compile\n",
1544
222
                        lint->pattern);
1545
222
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
1546
222
            }
1547
222
            goto error;
1548
222
  }
1549
1550
462
        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
1551
462
        if (lint->patstream == NULL) {
1552
37
            lint->progresult = XMLLINT_ERR_MEM;
1553
37
            goto error;
1554
37
        }
1555
1556
425
        ret = xmlStreamPush(lint->patstream, NULL, NULL);
1557
425
        if (ret < 0) {
1558
0
            fprintf(errStream, "xmlStreamPush() failure\n");
1559
0
            lint->progresult = XMLLINT_ERR_MEM;
1560
0
            goto error;
1561
0
        }
1562
425
    }
1563
1.64k
#endif /* LIBXML_PATTERN_ENABLED */
1564
1.64k
    reader = xmlReaderWalker(doc);
1565
1.64k
    if (reader != NULL) {
1566
1.64k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1567
866
      startTimer(lint);
1568
866
  }
1569
1.64k
  ret = xmlTextReaderRead(reader);
1570
6.58k
  while (ret == 1) {
1571
4.94k
      if ((lint->appOptions & XML_LINT_DEBUG_ENABLED)
1572
4.94k
#ifdef LIBXML_PATTERN_ENABLED
1573
4.94k
          || (lint->patternc)
1574
4.94k
#endif
1575
4.94k
         )
1576
2.54k
    processNode(lint, reader);
1577
4.94k
      ret = xmlTextReaderRead(reader);
1578
4.94k
  }
1579
1.64k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1580
866
      endTimer(lint, "walking through the doc");
1581
866
  }
1582
1.64k
  xmlFreeTextReader(reader);
1583
1.64k
  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.64k
    } 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.64k
#ifdef LIBXML_PATTERN_ENABLED
1593
1.90k
error:
1594
1.90k
    if (lint->patternc != NULL) {
1595
462
        xmlFreePattern(lint->patternc);
1596
462
        lint->patternc = NULL;
1597
462
    }
1598
1.90k
    if (lint->patstream != NULL) {
1599
425
  xmlFreeStreamCtxt(lint->patstream);
1600
425
  lint->patstream = NULL;
1601
425
    }
1602
1.90k
#endif
1603
1.90k
}
1604
#endif /* LIBXML_READER_ENABLED */
1605
1606
#ifdef LIBXML_XPATH_ENABLED
1607
/************************************************************************
1608
 *                  *
1609
 *      XPath Query                                     *
1610
 *                  *
1611
 ************************************************************************/
1612
1613
static void
1614
4.71k
doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) {
1615
4.71k
    switch(cur->type) {
1616
3.02k
        case XPATH_NODESET: {
1617
3.02k
#ifdef LIBXML_OUTPUT_ENABLED
1618
3.02k
            xmlOutputBufferPtr buf;
1619
3.02k
            xmlNodePtr node;
1620
3.02k
            int i;
1621
1622
3.02k
            if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
1623
2.17k
                lint->progresult = XMLLINT_ERR_XPATH_EMPTY;
1624
2.17k
                if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
1625
1.85k
                    fprintf(lint->errStream, "XPath set is empty\n");
1626
1.85k
                }
1627
2.17k
                break;
1628
2.17k
            }
1629
851
            buf = xmlOutputBufferCreateFile(stdout, NULL);
1630
851
            if (buf == NULL) {
1631
0
                lint->progresult = XMLLINT_ERR_MEM;
1632
0
                return;
1633
0
            }
1634
2.71k
            for (i = 0;i < cur->nodesetval->nodeNr;i++) {
1635
1.86k
                node = cur->nodesetval->nodeTab[i];
1636
1.86k
                xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
1637
1.86k
                xmlOutputBufferWrite(buf, 1, "\n");
1638
1.86k
            }
1639
851
            xmlOutputBufferClose(buf);
1640
#else
1641
            printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
1642
#endif
1643
851
      break;
1644
851
        }
1645
717
        case XPATH_BOOLEAN:
1646
717
      if (cur->boolval) printf("true\n");
1647
456
      else printf("false\n");
1648
717
      break;
1649
493
        case XPATH_NUMBER:
1650
493
      switch (xmlXPathIsInf(cur->floatval)) {
1651
28
      case 1:
1652
28
    printf("Infinity\n");
1653
28
    break;
1654
6
      case -1:
1655
6
    printf("-Infinity\n");
1656
6
    break;
1657
459
      default:
1658
459
    if (xmlXPathIsNaN(cur->floatval)) {
1659
313
        printf("NaN\n");
1660
313
    } else {
1661
146
        printf("%0g\n", cur->floatval);
1662
146
    }
1663
493
      }
1664
493
      break;
1665
493
        case XPATH_STRING:
1666
481
      printf("%s\n", (const char *) cur->stringval);
1667
481
      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
4.71k
    }
1677
4.71k
}
1678
1679
static void
1680
8.36k
doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) {
1681
8.36k
    xmlXPathContextPtr ctxt = NULL;
1682
8.36k
    xmlXPathCompExprPtr comp = NULL;
1683
8.36k
    xmlXPathObjectPtr res = NULL;
1684
1685
8.36k
    ctxt = xmlXPathNewContext(doc);
1686
8.36k
    if (ctxt == NULL) {
1687
0
        lint->progresult = XMLLINT_ERR_MEM;
1688
0
        goto error;
1689
0
    }
1690
1691
8.36k
    comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query);
1692
8.36k
    if (comp == NULL) {
1693
2.01k
        fprintf(lint->errStream, "XPath compilation failure\n");
1694
2.01k
        lint->progresult = XMLLINT_ERR_XPATH;
1695
2.01k
        goto error;
1696
2.01k
    }
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.34k
    ctxt->node = (xmlNodePtr) doc;
1706
6.34k
    res = xmlXPathCompiledEval(comp, ctxt);
1707
6.34k
    if (res == NULL) {
1708
1.63k
        fprintf(lint->errStream, "XPath evaluation failure\n");
1709
1.63k
        lint->progresult = XMLLINT_ERR_XPATH;
1710
1.63k
        goto error;
1711
1.63k
    }
1712
1713
4.71k
    doXPathDump(lint, res);
1714
1715
8.36k
error:
1716
8.36k
    xmlXPathFreeObject(res);
1717
8.36k
    xmlXPathFreeCompExpr(comp);
1718
8.36k
    xmlXPathFreeContext(ctxt);
1719
8.36k
}
1720
#endif /* LIBXML_XPATH_ENABLED */
1721
1722
/************************************************************************
1723
 *                  *
1724
 *      Tree Test processing        *
1725
 *                  *
1726
 ************************************************************************/
1727
1728
static xmlDocPtr
1729
16.0k
parseFile(xmllintState *lint, const char *filename) {
1730
16.0k
    xmlDocPtr doc = NULL;
1731
1732
16.0k
    if ((lint->appOptions & XML_LINT_GENERATE) && (filename == NULL)) {
1733
9.24k
        xmlNodePtr n;
1734
1735
9.24k
        doc = xmlNewDoc(BAD_CAST "1.0");
1736
9.24k
        if (doc == NULL) {
1737
39
            lint->progresult = XMLLINT_ERR_MEM;
1738
39
            return(NULL);
1739
39
        }
1740
9.20k
        n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
1741
9.20k
        if (n == NULL) {
1742
0
            xmlFreeDoc(doc);
1743
0
            lint->progresult = XMLLINT_ERR_MEM;
1744
0
            return(NULL);
1745
0
        }
1746
9.20k
        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.20k
        xmlDocSetRootElement(doc, n);
1753
1754
9.20k
        return(doc);
1755
9.20k
    }
1756
1757
6.79k
#ifdef LIBXML_HTML_ENABLED
1758
6.79k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1759
1.30k
        doc = parseHtml(lint, filename);
1760
1.30k
        return(doc);
1761
1.30k
    }
1762
5.49k
#endif /* LIBXML_HTML_ENABLED */
1763
5.49k
    {
1764
5.49k
        doc = parseXml(lint, filename);
1765
5.49k
    }
1766
1767
5.49k
    if (doc == NULL) {
1768
5.49k
        if (lint->ctxt->errNo == XML_ERR_NO_MEMORY)
1769
5.49k
            lint->progresult = XMLLINT_ERR_MEM;
1770
0
        else
1771
0
      lint->progresult = XMLLINT_ERR_RDFILE;
1772
5.49k
    } 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.49k
    return(doc);
1785
6.79k
}
1786
1787
static void
1788
16.0k
parseAndPrintFile(xmllintState *lint, const char *filename) {
1789
16.0k
    FILE *errStream = lint->errStream;
1790
16.0k
    xmlDocPtr doc;
1791
1792
    /* Avoid unused variable warning */
1793
16.0k
    (void) errStream;
1794
1795
16.0k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1))
1796
3.50k
  startTimer(lint);
1797
1798
16.0k
    doc = parseFile(lint, filename);
1799
16.0k
    if (doc == NULL) {
1800
6.83k
        if (lint->progresult == XMLLINT_RETURN_OK)
1801
1.17k
            lint->progresult = XMLLINT_ERR_UNCLASS;
1802
6.83k
  return;
1803
6.83k
    }
1804
1805
9.20k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1806
2.21k
  endTimer(lint, "Parsing");
1807
2.21k
    }
1808
1809
9.20k
    if (lint->appOptions & XML_LINT_DROP_DTD) {
1810
1.28k
  xmlDtdPtr dtd;
1811
1812
1.28k
  dtd = xmlGetIntSubset(doc);
1813
1.28k
  if (dtd != NULL) {
1814
0
      xmlUnlinkNode((xmlNodePtr)dtd);
1815
0
            doc->intSubset = dtd;
1816
0
  }
1817
1.28k
    }
1818
1819
9.20k
#ifdef LIBXML_XINCLUDE_ENABLED
1820
9.20k
    if (lint->appOptions & XML_LINT_XINCLUDE) {
1821
7.44k
        xmlXIncludeCtxt *xinc;
1822
7.44k
        int res;
1823
1824
7.44k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1825
2.00k
      startTimer(lint);
1826
2.00k
  }
1827
1828
7.44k
        xinc = xmlXIncludeNewContext(doc);
1829
7.44k
        if (xinc == NULL) {
1830
0
            lint->progresult = XMLLINT_ERR_MEM;
1831
0
            goto done;
1832
0
        }
1833
7.44k
        xmlXIncludeSetResourceLoader(xinc, xmllintResourceLoader, lint);
1834
7.44k
        xmlXIncludeSetFlags(xinc, lint->parseOptions);
1835
7.44k
        res = xmlXIncludeProcessNode(xinc, (xmlNode *) doc);
1836
7.44k
        xmlXIncludeFreeContext(xinc);
1837
7.44k
        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.44k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1846
2.00k
      endTimer(lint, "Xinclude processing");
1847
2.00k
  }
1848
7.44k
    }
1849
9.20k
#endif
1850
1851
    /*
1852
     * shell interaction
1853
     */
1854
9.20k
    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.20k
#ifdef LIBXML_XPATH_ENABLED
1863
9.20k
    if (lint->xpathquery != NULL) {
1864
8.36k
  xmlXPathOrderDocElems(doc);
1865
8.36k
        doXPathQuery(lint, doc, lint->xpathquery);
1866
8.36k
    }
1867
9.20k
#endif
1868
1869
    /*
1870
     * test intermediate copy if needed.
1871
     */
1872
9.20k
    if (lint->appOptions & XML_LINT_COPY_ENABLED) {
1873
2.59k
        xmlDocPtr tmp;
1874
1875
2.59k
        tmp = doc;
1876
2.59k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1877
749
      startTimer(lint);
1878
749
  }
1879
2.59k
  doc = xmlCopyDoc(doc, 1);
1880
2.59k
        if (doc == NULL) {
1881
0
            lint->progresult = XMLLINT_ERR_MEM;
1882
0
            xmlFreeDoc(tmp);
1883
0
            return;
1884
0
        }
1885
2.59k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1886
749
      endTimer(lint, "Copying");
1887
749
  }
1888
2.59k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1889
749
      startTimer(lint);
1890
749
  }
1891
2.59k
  xmlFreeDoc(tmp);
1892
2.59k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1893
749
      endTimer(lint, "Freeing original");
1894
749
  }
1895
2.59k
    }
1896
1897
9.20k
#ifdef LIBXML_VALID_ENABLED
1898
9.20k
    if ((lint->appOptions & XML_LINT_VALID_INSERTIONS)
1899
9.20k
#ifdef LIBXML_HTML_ENABLED
1900
9.20k
        && ((lint->appOptions & XML_LINT_HTML_ENABLED) != XML_LINT_HTML_ENABLED)
1901
9.20k
#endif
1902
9.20k
    ) {
1903
4.74k
        const xmlChar* list[256];
1904
4.74k
  int nb, i;
1905
4.74k
  xmlNodePtr node;
1906
1907
4.74k
  if (doc->children != NULL) {
1908
4.74k
      node = doc->children;
1909
4.74k
      while ((node != NULL) &&
1910
4.74k
                   ((node->type != XML_ELEMENT_NODE) ||
1911
4.74k
                    (node->last == NULL)))
1912
0
                node = node->next;
1913
4.74k
      if (node != NULL) {
1914
4.74k
    nb = xmlValidGetValidElements(node->last, NULL, list, 256);
1915
4.74k
    if (nb < 0) {
1916
4.74k
        fprintf(errStream, "could not get valid list of elements\n");
1917
4.74k
    } 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
4.74k
      }
1927
4.74k
  }
1928
4.74k
    } else
1929
4.46k
#endif /* LIBXML_VALID_ENABLED */
1930
4.46k
#ifdef LIBXML_READER_ENABLED
1931
4.46k
    if (lint->appOptions & XML_LINT_USE_WALKER) {
1932
1.90k
        walkDoc(lint, doc);
1933
1.90k
    }
1934
9.20k
#endif /* LIBXML_READER_ENABLED */
1935
9.20k
#ifdef LIBXML_OUTPUT_ENABLED
1936
9.20k
    if (lint->noout == 0) {
1937
237
#ifdef LIBXML_ZLIB_ENABLED
1938
237
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
1939
26
            xmlSetDocCompressMode(doc, 9);
1940
237
#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
237
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1949
18
    startTimer(lint);
1950
18
      }
1951
237
#ifdef LIBXML_C14N_ENABLED
1952
237
            if (lint->appOptions & XML_LINT_CANONICAL_V1_0) {
1953
35
          xmlChar *result = NULL;
1954
35
    int size;
1955
1956
35
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
1957
35
    if (size >= 0) {
1958
35
        if (write(1, result, size) == -1) {
1959
0
            fprintf(errStream, "Can't write data\n");
1960
0
        }
1961
35
        xmlFree(result);
1962
35
    } else {
1963
0
        fprintf(errStream, "Failed to canonicalize\n");
1964
0
        lint->progresult = XMLLINT_ERR_OUT;
1965
0
    }
1966
202
      } else if (lint->appOptions & XML_LINT_CANONICAL_V1_1) {
1967
49
          xmlChar *result = NULL;
1968
49
    int size;
1969
1970
49
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
1971
49
    if (size >= 0) {
1972
49
        if (write(1, result, size) == -1) {
1973
0
            fprintf(errStream, "Can't write data\n");
1974
0
        }
1975
49
        xmlFree(result);
1976
49
    } else {
1977
0
        fprintf(errStream, "Failed to canonicalize\n");
1978
0
        lint->progresult = XMLLINT_ERR_OUT;
1979
0
    }
1980
153
      } else if (lint->appOptions & XML_LINT_CANONICAL_EXE) {
1981
11
          xmlChar *result = NULL;
1982
11
    int size;
1983
1984
11
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
1985
11
    if (size >= 0) {
1986
11
        if (write(1, result, size) == -1) {
1987
0
            fprintf(errStream, "Can't write data\n");
1988
0
        }
1989
11
        xmlFree(result);
1990
11
    } else {
1991
0
        fprintf(errStream, "Failed to canonicalize\n");
1992
0
        lint->progresult = XMLLINT_ERR_OUT;
1993
0
    }
1994
11
      } else
1995
142
#endif
1996
142
#ifdef LIBXML_ZLIB_ENABLED
1997
142
      if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) {
1998
8
    xmlSaveFile(lint->output ? lint->output : "-", doc);
1999
8
      } else
2000
134
#endif
2001
134
            {
2002
134
          xmlSaveCtxtPtr ctxt;
2003
134
    int saveOpts = 0;
2004
2005
134
                if (lint->format == 1)
2006
54
        saveOpts |= XML_SAVE_FORMAT;
2007
80
                else if (lint->format == 2)
2008
19
                    saveOpts |= XML_SAVE_WSNONSIG;
2009
2010
134
#if defined(LIBXML_HTML_ENABLED)
2011
134
                if (lint->appOptions & XML_LINT_XML_OUT)
2012
18
                    saveOpts |= XML_SAVE_AS_XML;
2013
134
#endif
2014
2015
134
    if (lint->output == NULL)
2016
134
        ctxt = xmlSaveToFd(STDOUT_FILENO, lint->encoding,
2017
134
                                       saveOpts);
2018
0
    else
2019
0
        ctxt = xmlSaveToFilename(lint->output, lint->encoding,
2020
0
                                             saveOpts);
2021
2022
134
    if (ctxt != NULL) {
2023
46
                    if (lint->indentString != NULL)
2024
0
                        xmlSaveSetIndentString(ctxt, lint->indentString);
2025
2026
46
        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
46
        xmlSaveClose(ctxt);
2032
88
    } else {
2033
88
        lint->progresult = XMLLINT_ERR_OUT;
2034
88
    }
2035
134
      }
2036
237
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2037
18
    endTimer(lint, "Saving");
2038
18
      }
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
237
    }
2059
9.20k
#endif /* LIBXML_OUTPUT_ENABLED */
2060
2061
9.20k
#ifdef LIBXML_VALID_ENABLED
2062
    /*
2063
     * A posteriori validation test
2064
     */
2065
9.20k
    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.20k
    } else if (lint->appOptions & XML_LINT_POST_VALIDATION) {
2117
1.56k
  xmlValidCtxtPtr cvp;
2118
2119
1.56k
  cvp = xmlNewValidCtxt();
2120
1.56k
  if (cvp == NULL) {
2121
0
            lint->progresult = XMLLINT_ERR_MEM;
2122
0
            xmlFreeDoc(doc);
2123
0
            return;
2124
0
  }
2125
2126
1.56k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2127
488
      startTimer(lint);
2128
488
  }
2129
1.56k
  if (!xmlValidateDocument(cvp, doc)) {
2130
1.56k
      fprintf(errStream,
2131
1.56k
        "Document %s does not validate\n", filename);
2132
1.56k
      lint->progresult = XMLLINT_ERR_VALID;
2133
1.56k
  }
2134
1.56k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2135
488
      endTimer(lint, "Validating");
2136
488
  }
2137
1.56k
  xmlFreeValidCtxt(cvp);
2138
1.56k
    }
2139
9.20k
#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.20k
#ifdef LIBXML_RELAXNG_ENABLED
2183
9.20k
    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.20k
#endif /* LIBXML_RELAXNG_ENABLED */
2216
2217
9.20k
#ifdef LIBXML_SCHEMAS_ENABLED
2218
9.20k
    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.20k
#endif /* LIBXML_SCHEMAS_ENABLED */
2251
2252
    /* Avoid unused label warning */
2253
9.20k
    goto done;
2254
2255
9.20k
done:
2256
    /*
2257
     * free it.
2258
     */
2259
9.20k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2260
2.21k
  startTimer(lint);
2261
2.21k
    }
2262
9.20k
    xmlFreeDoc(doc);
2263
9.20k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2264
2.21k
  endTimer(lint, "Freeing");
2265
2.21k
    }
2266
9.20k
}
2267
2268
/************************************************************************
2269
 *                  *
2270
 *      Usage and Main          *
2271
 *                  *
2272
 ************************************************************************/
2273
2274
2.69k
static void showVersion(FILE *errStream, const char *name) {
2275
2.69k
    fprintf(errStream, "%s: using libxml version %s\n", name, xmlParserVersion);
2276
2.69k
    fprintf(errStream, "   compiled with: ");
2277
2.69k
    if (xmlHasFeature(XML_WITH_THREAD)) fprintf(errStream, "Threads ");
2278
2.69k
    fprintf(errStream, "Tree ");
2279
2.69k
    if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(errStream, "Output ");
2280
2.69k
    if (xmlHasFeature(XML_WITH_PUSH)) fprintf(errStream, "Push ");
2281
2.69k
    if (xmlHasFeature(XML_WITH_READER)) fprintf(errStream, "Reader ");
2282
2.69k
    if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(errStream, "Patterns ");
2283
2.69k
    if (xmlHasFeature(XML_WITH_WRITER)) fprintf(errStream, "Writer ");
2284
2.69k
    if (xmlHasFeature(XML_WITH_SAX1)) fprintf(errStream, "SAXv1 ");
2285
2.69k
    if (xmlHasFeature(XML_WITH_VALID)) fprintf(errStream, "DTDValid ");
2286
2.69k
    if (xmlHasFeature(XML_WITH_HTML)) fprintf(errStream, "HTML ");
2287
2.69k
    if (xmlHasFeature(XML_WITH_C14N)) fprintf(errStream, "C14N ");
2288
2.69k
    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(errStream, "Catalog ");
2289
2.69k
    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(errStream, "XPath ");
2290
2.69k
    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(errStream, "XPointer ");
2291
2.69k
    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(errStream, "XInclude ");
2292
2.69k
    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(errStream, "Iconv ");
2293
2.69k
    if (xmlHasFeature(XML_WITH_ICU)) fprintf(errStream, "ICU ");
2294
2.69k
    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(errStream, "ISO8859X ");
2295
2.69k
    if (xmlHasFeature(XML_WITH_REGEXP))
2296
2.69k
        fprintf(errStream, "Regexps Automata ");
2297
2.69k
    if (xmlHasFeature(XML_WITH_RELAXNG)) fprintf(errStream, "RelaxNG ");
2298
2.69k
    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(errStream, "Schemas ");
2299
2.69k
    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(errStream, "Schematron ");
2300
2.69k
    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(errStream, "Modules ");
2301
2.69k
    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(errStream, "Debug ");
2302
2.69k
    if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(errStream, "Zlib ");
2303
2.69k
    if (xmlHasFeature(XML_WITH_LZMA)) fprintf(errStream, "Lzma ");
2304
2.69k
    fprintf(errStream, "\n");
2305
2.69k
}
2306
2307
130
static void usage(FILE *f, const char *name) {
2308
130
    fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
2309
130
#ifdef LIBXML_OUTPUT_ENABLED
2310
130
    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
130
    fprintf(f, "\t--version : display the version of the XML library used\n");
2315
130
    fprintf(f, "\t--shell : run a navigating shell\n");
2316
130
    fprintf(f, "\t--debug : show additional debug information\n");
2317
130
    fprintf(f, "\t--copy : used to test the internal copy implementation\n");
2318
130
    fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
2319
130
    fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
2320
130
    fprintf(f, "\t--noent : substitute entity references by their value\n");
2321
130
    fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
2322
130
    fprintf(f, "\t--noout : don't output the result tree\n");
2323
130
    fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
2324
130
    fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
2325
130
    fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
2326
130
    fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
2327
130
#ifdef LIBXML_VALID_ENABLED
2328
130
    fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
2329
130
    fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
2330
130
    fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
2331
130
    fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
2332
130
    fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
2333
130
#endif /* LIBXML_VALID_ENABLED */
2334
130
    fprintf(f, "\t--strict-namespace : Return application failure if document has any namespace errors\n");
2335
130
    fprintf(f, "\t--quiet : be quiet when succeeded\n");
2336
130
    fprintf(f, "\t--timing : print some timings\n");
2337
130
    fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
2338
130
    fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
2339
130
#ifdef LIBXML_HTML_ENABLED
2340
130
    fprintf(f, "\t--html : use the HTML parser\n");
2341
130
    fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
2342
130
#ifdef LIBXML_OUTPUT_ENABLED
2343
130
    fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
2344
130
#endif
2345
130
#endif
2346
130
#ifdef LIBXML_PUSH_ENABLED
2347
130
    fprintf(f, "\t--push : use the push mode of the parser\n");
2348
130
#endif /* LIBXML_PUSH_ENABLED */
2349
130
#if HAVE_DECL_MMAP
2350
130
    fprintf(f, "\t--memory : parse from memory\n");
2351
130
#endif
2352
130
    fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
2353
130
    fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
2354
130
    fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
2355
130
    fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
2356
130
    fprintf(f, "\t--nodict : create document without dictionary\n");
2357
130
    fprintf(f, "\t--pedantic : enable additional warnings\n");
2358
130
#ifdef LIBXML_OUTPUT_ENABLED
2359
130
    fprintf(f, "\t--output file or -o file: save to a given file\n");
2360
130
    fprintf(f, "\t--format : reformat/reindent the output\n");
2361
130
    fprintf(f, "\t--encode encoding : output in the given encoding\n");
2362
130
    fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
2363
130
    fprintf(f, "\t                 0 Do not pretty print\n");
2364
130
    fprintf(f, "\t                 1 Format the XML content, as --format\n");
2365
130
    fprintf(f, "\t                 2 Add whitespace inside tags, preserving content\n");
2366
130
#ifdef LIBXML_ZLIB_ENABLED
2367
130
    fprintf(f, "\t--compress : turn on gzip compression of output\n");
2368
130
#endif
2369
130
#ifdef LIBXML_C14N_ENABLED
2370
130
    fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
2371
130
    fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
2372
130
    fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
2373
130
#endif /* LIBXML_C14N_ENABLED */
2374
130
#endif /* LIBXML_OUTPUT_ENABLED */
2375
130
    fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
2376
130
#ifdef LIBXML_CATALOG_ENABLED
2377
130
    fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2378
130
    fprintf(f, "\t             otherwise XML Catalogs starting from \n");
2379
130
    fprintf(f, "\t         file://" XML_SYSCONFDIR "/xml/catalog "
2380
130
            "are activated by default\n");
2381
130
    fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
2382
130
#endif
2383
130
    fprintf(f, "\t--auto : generate a small doc on the fly\n");
2384
130
#ifdef LIBXML_XINCLUDE_ENABLED
2385
130
    fprintf(f, "\t--xinclude : do XInclude processing\n");
2386
130
    fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
2387
130
    fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
2388
130
#endif
2389
130
    fprintf(f, "\t--loaddtd : fetch external DTD\n");
2390
130
    fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
2391
130
#ifdef LIBXML_READER_ENABLED
2392
130
    fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
2393
130
    fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
2394
130
#ifdef LIBXML_PATTERN_ENABLED
2395
130
    fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
2396
130
#endif
2397
130
#endif /* LIBXML_READER_ENABLED */
2398
130
#ifdef LIBXML_RELAXNG_ENABLED
2399
130
    fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
2400
130
#endif
2401
130
#ifdef LIBXML_SCHEMAS_ENABLED
2402
130
    fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
2403
130
#endif
2404
#ifdef LIBXML_SCHEMATRON_ENABLED
2405
    fprintf(f, "\t--schematron schema : do validation against a schematron\n");
2406
#endif
2407
130
#ifdef LIBXML_SAX1_ENABLED
2408
130
    fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
2409
130
#endif
2410
130
    fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
2411
130
    fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
2412
130
#ifdef LIBXML_XPATH_ENABLED
2413
130
    fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
2414
130
#endif
2415
130
    fprintf(f, "\t--max-ampl value: set maximum amplification factor\n");
2416
2417
130
    fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
2418
130
}
2419
2420
static int
2421
parseInteger(unsigned long *result, FILE *errStream, const char *ctxt,
2422
4.99k
             const char *str, unsigned long min, unsigned long max) {
2423
4.99k
    char *strEnd;
2424
4.99k
    unsigned long val;
2425
2426
4.99k
    errno = 0;
2427
4.99k
    val = strtoul(str, &strEnd, 10);
2428
4.99k
    if (errno == EINVAL || *strEnd != 0) {
2429
0
        fprintf(errStream, "%s: invalid integer: %s\n", ctxt, str);
2430
0
        return(-1);
2431
0
    }
2432
4.99k
    if (errno != 0 || val < min || val > max) {
2433
16
        fprintf(errStream, "%s: integer out of range: %s\n", ctxt, str);
2434
16
        return(-1);
2435
16
    }
2436
2437
4.98k
    *result = val;
2438
4.98k
    return(0);
2439
4.99k
}
2440
2441
static int
2442
155k
skipArgs(const char *arg) {
2443
155k
    if ((!strcmp(arg, "-path")) ||
2444
155k
        (!strcmp(arg, "--path")) ||
2445
155k
        (!strcmp(arg, "-maxmem")) ||
2446
155k
        (!strcmp(arg, "--maxmem")) ||
2447
155k
#ifdef LIBXML_OUTPUT_ENABLED
2448
155k
        (!strcmp(arg, "-o")) ||
2449
155k
        (!strcmp(arg, "-output")) ||
2450
155k
        (!strcmp(arg, "--output")) ||
2451
155k
        (!strcmp(arg, "-encode")) ||
2452
155k
        (!strcmp(arg, "--encode")) ||
2453
155k
        (!strcmp(arg, "-pretty")) ||
2454
155k
        (!strcmp(arg, "--pretty")) ||
2455
155k
#endif
2456
155k
#ifdef LIBXML_VALID_ENABLED
2457
155k
        (!strcmp(arg, "-dtdvalid")) ||
2458
155k
        (!strcmp(arg, "--dtdvalid")) ||
2459
155k
        (!strcmp(arg, "-dtdvalidfpi")) ||
2460
155k
        (!strcmp(arg, "--dtdvalidfpi")) ||
2461
155k
#endif
2462
155k
#ifdef LIBXML_RELAXNG_ENABLED
2463
155k
        (!strcmp(arg, "-relaxng")) ||
2464
155k
        (!strcmp(arg, "--relaxng")) ||
2465
155k
#endif
2466
155k
#ifdef LIBXML_SCHEMAS_ENABLED
2467
155k
        (!strcmp(arg, "-schema")) ||
2468
155k
        (!strcmp(arg, "--schema")) ||
2469
155k
#endif
2470
#ifdef LIBXML_SCHEMATRON_ENABLED
2471
        (!strcmp(arg, "-schematron")) ||
2472
        (!strcmp(arg, "--schematron")) ||
2473
#endif
2474
155k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2475
155k
        (!strcmp(arg, "-pattern")) ||
2476
155k
        (!strcmp(arg, "--pattern")) ||
2477
155k
#endif
2478
155k
#ifdef LIBXML_XPATH_ENABLED
2479
155k
        (!strcmp(arg, "-xpath")) ||
2480
155k
        (!strcmp(arg, "--xpath")) ||
2481
155k
#endif
2482
155k
        (!strcmp(arg, "-max-ampl")) ||
2483
155k
        (!strcmp(arg, "--max-ampl"))
2484
155k
    ) {
2485
15.0k
        return(1);
2486
15.0k
    }
2487
2488
140k
    return(0);
2489
155k
}
2490
2491
static void
2492
10.4k
xmllintInit(xmllintState *lint) {
2493
10.4k
    memset(lint, 0, sizeof(*lint));
2494
2495
10.4k
    lint->repeat = 1;
2496
10.4k
    lint->progresult = XMLLINT_RETURN_OK;
2497
10.4k
    lint->parseOptions = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
2498
10.4k
#ifdef LIBXML_HTML_ENABLED
2499
10.4k
    lint->htmlOptions = HTML_PARSE_COMPACT | HTML_PARSE_BIG_LINES;
2500
10.4k
#endif
2501
10.4k
}
2502
2503
static void
2504
27.1k
xmllintOptWarnNoSupport(FILE *errStream, const char *opt, const char *nosupp) {
2505
27.1k
    fprintf(errStream, "Warning: Option %s doesn't support %s\n", opt, nosupp);
2506
27.1k
}
2507
2508
static int
2509
10.4k
xmllintParseOptions(xmllintState *lint, int argc, const char **argv) {
2510
10.4k
    FILE *errStream = lint->errStream;
2511
10.4k
    const char *specialMode = NULL;
2512
10.4k
    int i;
2513
2514
10.4k
    if (argc <= 1) {
2515
0
        usage(errStream, argv[0]);
2516
0
        return(XMLLINT_ERR_UNCLASS);
2517
0
    }
2518
2519
186k
    for (i = 1; i < argc ; i++) {
2520
176k
        unsigned long val;
2521
2522
176k
        if (argv[i][0] != '-' || argv[i][1] == 0)
2523
10.3k
            continue;
2524
2525
165k
        if ((!strcmp(argv[i], "-maxmem")) ||
2526
165k
            (!strcmp(argv[i], "--maxmem"))) {
2527
330
            i++;
2528
330
            if (i >= argc) {
2529
0
                fprintf(errStream, "maxmem: missing integer value\n");
2530
0
                return(XMLLINT_ERR_UNCLASS);
2531
0
            }
2532
330
            if (parseInteger(&val, errStream, "maxmem", argv[i],
2533
330
                             0, INT_MAX) < 0)
2534
0
                return(XMLLINT_ERR_UNCLASS);
2535
330
            lint->maxmem = val;
2536
165k
        } else if ((!strcmp(argv[i], "-debug")) ||
2537
165k
                   (!strcmp(argv[i], "--debug"))) {
2538
3.48k
            lint->appOptions |= XML_LINT_DEBUG_ENABLED;
2539
161k
        } else if ((!strcmp(argv[i], "-shell")) ||
2540
161k
                   (!strcmp(argv[i], "--shell"))) {
2541
0
            lint->appOptions |= XML_LINT_NAVIGATING_SHELL;
2542
161k
        } else if ((!strcmp(argv[i], "-copy")) ||
2543
161k
                   (!strcmp(argv[i], "--copy"))) {
2544
2.92k
            lint->appOptions |= XML_LINT_COPY_ENABLED;
2545
159k
        } else if ((!strcmp(argv[i], "-recover")) ||
2546
159k
                   (!strcmp(argv[i], "--recover"))) {
2547
1.94k
            lint->parseOptions |= XML_PARSE_RECOVER;
2548
157k
        } else if ((!strcmp(argv[i], "-huge")) ||
2549
157k
                   (!strcmp(argv[i], "--huge"))) {
2550
3.68k
            lint->parseOptions |= XML_PARSE_HUGE;
2551
3.68k
#ifdef LIBXML_HTML_ENABLED
2552
3.68k
            lint->htmlOptions |= HTML_PARSE_HUGE;
2553
3.68k
#endif
2554
153k
        } else if ((!strcmp(argv[i], "-noent")) ||
2555
153k
                   (!strcmp(argv[i], "--noent"))) {
2556
1.76k
            lint->parseOptions |= XML_PARSE_NOENT;
2557
151k
        } else if ((!strcmp(argv[i], "-noenc")) ||
2558
151k
                   (!strcmp(argv[i], "--noenc"))) {
2559
2.56k
            lint->parseOptions |= XML_PARSE_IGNORE_ENC;
2560
2.56k
#ifdef LIBXML_HTML_ENABLED
2561
2.56k
            lint->htmlOptions |= HTML_PARSE_IGNORE_ENC;
2562
2.56k
#endif
2563
149k
        } else if ((!strcmp(argv[i], "-nsclean")) ||
2564
149k
                   (!strcmp(argv[i], "--nsclean"))) {
2565
4.02k
            lint->parseOptions |= XML_PARSE_NSCLEAN;
2566
145k
        } else if ((!strcmp(argv[i], "-nocdata")) ||
2567
145k
                   (!strcmp(argv[i], "--nocdata"))) {
2568
4.29k
            lint->parseOptions |= XML_PARSE_NOCDATA;
2569
140k
        } else if ((!strcmp(argv[i], "-nodict")) ||
2570
140k
                   (!strcmp(argv[i], "--nodict"))) {
2571
3.68k
            lint->parseOptions |= XML_PARSE_NODICT;
2572
137k
        } else if ((!strcmp(argv[i], "-version")) ||
2573
137k
                   (!strcmp(argv[i], "--version"))) {
2574
2.69k
            showVersion(errStream, argv[0]);
2575
2.69k
            lint->version = 1;
2576
134k
        } else if ((!strcmp(argv[i], "-noout")) ||
2577
134k
                   (!strcmp(argv[i], "--noout"))) {
2578
4.27k
            lint->noout = 1;
2579
4.27k
#ifdef LIBXML_HTML_ENABLED
2580
130k
        } else if ((!strcmp(argv[i], "-html")) ||
2581
130k
                   (!strcmp(argv[i], "--html"))) {
2582
1.21k
            lint->appOptions |= XML_LINT_HTML_ENABLED;
2583
128k
        } else if ((!strcmp(argv[i], "-nodefdtd")) ||
2584
128k
                   (!strcmp(argv[i], "--nodefdtd"))) {
2585
2.50k
            lint->htmlOptions |= HTML_PARSE_NODEFDTD;
2586
2.50k
#ifdef LIBXML_OUTPUT_ENABLED
2587
126k
        } else if ((!strcmp(argv[i], "-xmlout")) ||
2588
126k
                   (!strcmp(argv[i], "--xmlout"))) {
2589
2.46k
            lint->appOptions |= XML_LINT_XML_OUT;
2590
2.46k
#endif
2591
2.46k
#endif /* LIBXML_HTML_ENABLED */
2592
123k
        } else if ((!strcmp(argv[i], "-loaddtd")) ||
2593
123k
                   (!strcmp(argv[i], "--loaddtd"))) {
2594
2.97k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2595
120k
        } else if ((!strcmp(argv[i], "-dtdattr")) ||
2596
120k
                   (!strcmp(argv[i], "--dtdattr"))) {
2597
4.77k
            lint->parseOptions |= XML_PARSE_DTDATTR;
2598
4.77k
#ifdef LIBXML_VALID_ENABLED
2599
116k
        } else if ((!strcmp(argv[i], "-valid")) ||
2600
116k
                   (!strcmp(argv[i], "--valid"))) {
2601
2.61k
            lint->parseOptions |= XML_PARSE_DTDVALID;
2602
113k
        } else if ((!strcmp(argv[i], "-postvalid")) ||
2603
113k
                   (!strcmp(argv[i], "--postvalid"))) {
2604
1.80k
            lint->appOptions |= XML_LINT_POST_VALIDATION;
2605
1.80k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2606
111k
        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
2607
111k
                   (!strcmp(argv[i], "--dtdvalid"))) {
2608
0
            i++;
2609
0
            lint->dtdvalid = argv[i];
2610
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2611
111k
        } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2612
111k
                   (!strcmp(argv[i], "--dtdvalidfpi"))) {
2613
0
            i++;
2614
0
            lint->dtdvalidfpi = argv[i];
2615
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2616
111k
        } else if ((!strcmp(argv[i], "-insert")) ||
2617
111k
                   (!strcmp(argv[i], "--insert"))) {
2618
5.89k
            lint->appOptions |= XML_LINT_VALID_INSERTIONS;
2619
5.89k
#endif /* LIBXML_VALID_ENABLED */
2620
105k
        } else if ((!strcmp(argv[i], "-strict-namespace")) ||
2621
105k
            (!strcmp(argv[i], "--strict-namespace"))) {
2622
0
            lint->appOptions |= XML_LINT_STRICT_NAMESPACE;
2623
105k
        } else if ((!strcmp(argv[i], "-dropdtd")) ||
2624
105k
                   (!strcmp(argv[i], "--dropdtd"))) {
2625
1.47k
            lint->appOptions |= XML_LINT_DROP_DTD;
2626
104k
        } else if ((!strcmp(argv[i], "-quiet")) ||
2627
104k
                   (!strcmp(argv[i], "--quiet"))) {
2628
1.65k
            lint->appOptions |= XML_LINT_QUIET;
2629
102k
        } else if ((!strcmp(argv[i], "-timing")) ||
2630
102k
                   (!strcmp(argv[i], "--timing"))) {
2631
2.65k
            lint->appOptions |= XML_LINT_TIMINGS;
2632
100k
        } else if ((!strcmp(argv[i], "-auto")) ||
2633
100k
                   (!strcmp(argv[i], "--auto"))) {
2634
9.69k
            lint->appOptions |= XML_LINT_GENERATE;
2635
90.3k
        } else if ((!strcmp(argv[i], "-repeat")) ||
2636
90.3k
                   (!strcmp(argv[i], "--repeat"))) {
2637
1.10k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2638
1.10k
            lint->repeat = 2;
2639
#else
2640
            if (lint->repeat > 1)
2641
                lint->repeat *= 10;
2642
            else
2643
                lint->repeat = 100;
2644
#endif
2645
1.10k
#ifdef LIBXML_PUSH_ENABLED
2646
89.2k
        } else if ((!strcmp(argv[i], "-push")) ||
2647
89.2k
                   (!strcmp(argv[i], "--push"))) {
2648
517
            lint->appOptions |= XML_LINT_PUSH_ENABLED;
2649
517
#endif /* LIBXML_PUSH_ENABLED */
2650
517
#if HAVE_DECL_MMAP
2651
88.7k
        } else if ((!strcmp(argv[i], "-memory")) ||
2652
88.7k
                   (!strcmp(argv[i], "--memory"))) {
2653
0
            lint->appOptions |= XML_LINT_MEMORY;
2654
0
#endif
2655
0
#ifdef LIBXML_XINCLUDE_ENABLED
2656
88.7k
        } else if ((!strcmp(argv[i], "-xinclude")) ||
2657
88.7k
                   (!strcmp(argv[i], "--xinclude"))) {
2658
3.42k
            lint->appOptions |= XML_LINT_XINCLUDE;
2659
3.42k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2660
85.3k
        } else if ((!strcmp(argv[i], "-noxincludenode")) ||
2661
85.3k
                   (!strcmp(argv[i], "--noxincludenode"))) {
2662
5.35k
            lint->appOptions |= XML_LINT_XINCLUDE;
2663
5.35k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2664
5.35k
            lint->parseOptions |= XML_PARSE_NOXINCNODE;
2665
79.9k
        } else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
2666
79.9k
                   (!strcmp(argv[i], "--nofixup-base-uris"))) {
2667
3.50k
            lint->appOptions |= XML_LINT_XINCLUDE;
2668
3.50k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2669
3.50k
            lint->parseOptions |= XML_PARSE_NOBASEFIX;
2670
3.50k
#endif
2671
76.4k
        } else if ((!strcmp(argv[i], "-nowarning")) ||
2672
76.4k
                   (!strcmp(argv[i], "--nowarning"))) {
2673
5.01k
            lint->parseOptions |= XML_PARSE_NOWARNING;
2674
5.01k
            lint->parseOptions &= ~XML_PARSE_PEDANTIC;
2675
5.01k
#ifdef LIBXML_HTML_ENABLED
2676
5.01k
            lint->htmlOptions |= HTML_PARSE_NOWARNING;
2677
5.01k
#endif
2678
71.4k
        } else if ((!strcmp(argv[i], "-pedantic")) ||
2679
71.4k
                   (!strcmp(argv[i], "--pedantic"))) {
2680
1.62k
            lint->parseOptions |= XML_PARSE_PEDANTIC;
2681
1.62k
            lint->parseOptions &= ~XML_PARSE_NOWARNING;
2682
1.62k
#ifdef LIBXML_CATALOG_ENABLED
2683
69.8k
        } else if ((!strcmp(argv[i], "-catalogs")) ||
2684
69.8k
                   (!strcmp(argv[i], "--catalogs"))) {
2685
0
            lint->appOptions |= XML_LINT_USE_CATALOGS;
2686
69.8k
        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
2687
69.8k
                   (!strcmp(argv[i], "--nocatalogs"))) {
2688
10.4k
            lint->appOptions |= XML_LINT_USE_NO_CATALOGS;
2689
10.4k
            lint->parseOptions |= XML_PARSE_NO_SYS_CATALOG;
2690
10.4k
#endif
2691
59.3k
        } else if ((!strcmp(argv[i], "-noblanks")) ||
2692
59.3k
                   (!strcmp(argv[i], "--noblanks"))) {
2693
3.08k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2694
3.08k
#ifdef LIBXML_HTML_ENABLED
2695
3.08k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2696
3.08k
#endif
2697
3.08k
#ifdef LIBXML_OUTPUT_ENABLED
2698
56.2k
        } else if ((!strcmp(argv[i], "-o")) ||
2699
56.2k
                   (!strcmp(argv[i], "-output")) ||
2700
56.2k
                   (!strcmp(argv[i], "--output"))) {
2701
0
            i++;
2702
0
            lint->output = argv[i];
2703
56.2k
        } else if ((!strcmp(argv[i], "-format")) ||
2704
56.2k
                   (!strcmp(argv[i], "--format"))) {
2705
5.63k
            lint->format = 1;
2706
5.63k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2707
5.63k
#ifdef LIBXML_HTML_ENABLED
2708
5.63k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2709
5.63k
#endif
2710
50.6k
        } else if ((!strcmp(argv[i], "-encode")) ||
2711
50.6k
                   (!strcmp(argv[i], "--encode"))) {
2712
1.08k
            i++;
2713
1.08k
            lint->encoding = argv[i];
2714
49.5k
        } else if ((!strcmp(argv[i], "-pretty")) ||
2715
49.5k
                   (!strcmp(argv[i], "--pretty"))) {
2716
3.78k
            i++;
2717
3.78k
            if (i >= argc) {
2718
0
                fprintf(errStream, "pretty: missing integer value\n");
2719
0
                return(XMLLINT_ERR_UNCLASS);
2720
0
            }
2721
3.78k
            if (parseInteger(&val, errStream, "pretty", argv[i],
2722
3.78k
                             0, 2) < 0)
2723
16
                return(XMLLINT_ERR_UNCLASS);
2724
3.77k
            lint->format = val;
2725
3.77k
#ifdef LIBXML_ZLIB_ENABLED
2726
45.7k
        } else if ((!strcmp(argv[i], "-compress")) ||
2727
45.7k
                   (!strcmp(argv[i], "--compress"))) {
2728
2.21k
            lint->appOptions |= XML_LINT_ZLIB_COMPRESSION;
2729
2.21k
#endif
2730
2.21k
#ifdef LIBXML_C14N_ENABLED
2731
43.5k
        } else if ((!strcmp(argv[i], "-c14n")) ||
2732
43.5k
                   (!strcmp(argv[i], "--c14n"))) {
2733
2.85k
            lint->appOptions |= XML_LINT_CANONICAL_V1_0;
2734
2.85k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2735
40.7k
        } else if ((!strcmp(argv[i], "-c14n11")) ||
2736
40.7k
                   (!strcmp(argv[i], "--c14n11"))) {
2737
5.68k
            lint->appOptions |= XML_LINT_CANONICAL_V1_1;
2738
5.68k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2739
35.0k
        } else if ((!strcmp(argv[i], "-exc-c14n")) ||
2740
35.0k
                   (!strcmp(argv[i], "--exc-c14n"))) {
2741
3.20k
            lint->appOptions |= XML_LINT_CANONICAL_EXE;
2742
3.20k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2743
3.20k
#endif /* LIBXML_C14N_ENABLED */
2744
3.20k
#endif /* LIBXML_OUTPUT_ENABLED */
2745
3.20k
#ifdef LIBXML_READER_ENABLED
2746
31.8k
        } else if ((!strcmp(argv[i], "-stream")) ||
2747
31.8k
                   (!strcmp(argv[i], "--stream"))) {
2748
2.88k
             lint->appOptions |= XML_LINT_USE_STREAMING;
2749
28.9k
        } else if ((!strcmp(argv[i], "-walker")) ||
2750
28.9k
                   (!strcmp(argv[i], "--walker"))) {
2751
3.04k
             lint->appOptions |= XML_LINT_USE_WALKER;
2752
3.04k
             lint->noout = 1;
2753
3.04k
#ifdef LIBXML_PATTERN_ENABLED
2754
25.8k
        } else if ((!strcmp(argv[i], "-pattern")) ||
2755
25.8k
                   (!strcmp(argv[i], "--pattern"))) {
2756
1.76k
            i++;
2757
1.76k
            lint->pattern = argv[i];
2758
1.76k
#endif
2759
1.76k
#endif /* LIBXML_READER_ENABLED */
2760
1.76k
#ifdef LIBXML_SAX1_ENABLED
2761
24.1k
        } else if ((!strcmp(argv[i], "-sax1")) ||
2762
24.1k
                   (!strcmp(argv[i], "--sax1"))) {
2763
553
            lint->parseOptions |= XML_PARSE_SAX1;
2764
553
#endif /* LIBXML_SAX1_ENABLED */
2765
23.5k
        } else if ((!strcmp(argv[i], "-sax")) ||
2766
23.5k
                   (!strcmp(argv[i], "--sax"))) {
2767
576
            lint->appOptions |= XML_LINT_SAX_ENABLED;
2768
576
#ifdef LIBXML_RELAXNG_ENABLED
2769
23.0k
        } else if ((!strcmp(argv[i], "-relaxng")) ||
2770
23.0k
                   (!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.0k
        } else if ((!strcmp(argv[i], "-schema")) ||
2777
23.0k
                 (!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.0k
        } else if ((!strcmp(argv[i], "-nonet")) ||
2790
23.0k
                   (!strcmp(argv[i], "--nonet"))) {
2791
2.70k
            lint->parseOptions |= XML_PARSE_NONET;
2792
20.2k
        } else if ((!strcmp(argv[i], "-nocompact")) ||
2793
20.2k
                   (!strcmp(argv[i], "--nocompact"))) {
2794
3.47k
            lint->parseOptions &= ~XML_PARSE_COMPACT;
2795
3.47k
#ifdef LIBXML_HTML_ENABLED
2796
3.47k
            lint->htmlOptions &= ~HTML_PARSE_COMPACT;
2797
3.47k
#endif
2798
16.8k
        } else if ((!strcmp(argv[i], "-load-trace")) ||
2799
16.8k
                   (!strcmp(argv[i], "--load-trace"))) {
2800
3.57k
            lint->appOptions |= XML_LINT_USE_LOAD_TRACE;
2801
13.2k
        } else if ((!strcmp(argv[i], "-path")) ||
2802
13.2k
                   (!strcmp(argv[i], "--path"))) {
2803
0
            i++;
2804
0
            parsePath(lint, BAD_CAST argv[i]);
2805
0
#ifdef LIBXML_XPATH_ENABLED
2806
13.2k
        } else if ((!strcmp(argv[i], "-xpath")) ||
2807
13.2k
                   (!strcmp(argv[i], "--xpath"))) {
2808
8.51k
            i++;
2809
8.51k
            lint->noout++;
2810
8.51k
            lint->xpathquery = argv[i];
2811
8.51k
#endif
2812
8.51k
        } else if ((!strcmp(argv[i], "-oldxml10")) ||
2813
4.74k
                   (!strcmp(argv[i], "--oldxml10"))) {
2814
3.73k
            lint->parseOptions |= XML_PARSE_OLD10;
2815
3.73k
        } else if ((!strcmp(argv[i], "-max-ampl")) ||
2816
1.00k
                   (!strcmp(argv[i], "--max-ampl"))) {
2817
879
            i++;
2818
879
            if (i >= argc) {
2819
0
                fprintf(errStream, "max-ampl: missing integer value\n");
2820
0
                return(XMLLINT_ERR_UNCLASS);
2821
0
            }
2822
879
            if (parseInteger(&val, errStream, "max-ampl", argv[i],
2823
879
                             1, UINT_MAX) < 0)
2824
0
                return(XMLLINT_ERR_UNCLASS);
2825
879
            lint->maxAmpl = val;
2826
879
        } else {
2827
130
            fprintf(errStream, "Unknown option %s\n", argv[i]);
2828
130
            usage(errStream, argv[0]);
2829
130
            return(XMLLINT_ERR_UNCLASS);
2830
130
        }
2831
165k
    }
2832
2833
10.3k
    if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2834
0
        lint->repeat = 1;
2835
2836
10.3k
#ifdef LIBXML_READER_ENABLED
2837
10.3k
    if (lint->appOptions & XML_LINT_USE_STREAMING) {
2838
2.87k
        specialMode = "--stream";
2839
2840
2.87k
        if (lint->appOptions & XML_LINT_SAX_ENABLED)
2841
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--sax");
2842
2.87k
#ifdef LIBXML_PUSH_ENABLED
2843
2.87k
        if (lint->appOptions & XML_LINT_PUSH_ENABLED)
2844
378
            xmllintOptWarnNoSupport(errStream, "--stream", "--push");
2845
2.87k
#endif
2846
2.87k
#ifdef LIBXML_HTML_ENABLED
2847
2.87k
        if (lint->appOptions & XML_LINT_HTML_ENABLED)
2848
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--html");
2849
2.87k
#endif
2850
2.87k
    }
2851
10.3k
#endif /* LIBXML_READER_ENABLED */
2852
2853
10.3k
    if (lint->appOptions & XML_LINT_SAX_ENABLED) {
2854
575
        specialMode = "--sax";
2855
2856
575
#ifdef LIBXML_XINCLUDE_ENABLED
2857
575
        if (lint->appOptions & XML_LINT_XINCLUDE)
2858
504
            xmllintOptWarnNoSupport(errStream, "--sax", "--xinclude");
2859
575
#endif
2860
575
#ifdef LIBXML_RELAXNG_ENABLED
2861
575
        if (lint->relaxng != NULL)
2862
0
            xmllintOptWarnNoSupport(errStream, "--sax", "--relaxng");
2863
575
#endif
2864
575
    }
2865
2866
10.3k
    if (specialMode != NULL) {
2867
3.45k
        if (lint->appOptions & XML_LINT_GENERATE)
2868
3.29k
            xmllintOptWarnNoSupport(errStream, specialMode, "--auto");
2869
3.45k
        if (lint->appOptions & XML_LINT_DROP_DTD)
2870
516
            xmllintOptWarnNoSupport(errStream, specialMode, "--dropdtd");
2871
3.45k
        if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2872
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--shell");
2873
3.45k
        if (lint->appOptions & XML_LINT_COPY_ENABLED)
2874
1.12k
            xmllintOptWarnNoSupport(errStream, specialMode, "--copy");
2875
3.45k
#ifdef LIBXML_XPATH_ENABLED
2876
3.45k
        if (lint->xpathquery != NULL)
2877
2.85k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xpath");
2878
3.45k
#endif
2879
3.45k
#ifdef LIBXML_READER_ENABLED
2880
3.45k
        if (lint->appOptions & XML_LINT_USE_WALKER)
2881
1.41k
            xmllintOptWarnNoSupport(errStream, specialMode, "--walker");
2882
3.45k
#endif
2883
3.45k
#ifdef LIBXML_VALID_ENABLED
2884
3.45k
        if (lint->appOptions & XML_LINT_VALID_INSERTIONS)
2885
1.84k
            xmllintOptWarnNoSupport(errStream, specialMode, "--insert");
2886
3.45k
        if (lint->dtdvalid != NULL)
2887
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalid");
2888
3.45k
        if (lint->dtdvalidfpi != NULL)
2889
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalidfpi");
2890
3.45k
        if (lint->appOptions & XML_LINT_POST_VALIDATION)
2891
700
            xmllintOptWarnNoSupport(errStream, specialMode, "--postvalid");
2892
3.45k
#endif
2893
#ifdef LIBXML_SCHEMATRON_ENABLED
2894
        if (lint->schematron != NULL)
2895
            xmllintOptWarnNoSupport(errStream, specialMode, "--schematron");
2896
#endif
2897
3.45k
#ifdef LIBXML_OUTPUT_ENABLED
2898
3.45k
        if (lint->output != NULL)
2899
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--output");
2900
3.45k
        if (lint->encoding != NULL)
2901
338
            xmllintOptWarnNoSupport(errStream, specialMode, "--encode");
2902
3.45k
        if (lint->format > 0)
2903
1.89k
            xmllintOptWarnNoSupport(errStream, specialMode,
2904
1.89k
                                    "--format or -pretty");
2905
3.45k
#ifdef LIBXML_ZLIB_ENABLED
2906
3.45k
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
2907
708
            xmllintOptWarnNoSupport(errStream, specialMode, "--compress");
2908
3.45k
#endif
2909
3.45k
#ifdef LIBXML_HTML_ENABLED
2910
3.45k
        if (lint->appOptions & XML_LINT_XML_OUT)
2911
1.06k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xmlout");
2912
3.45k
#endif
2913
3.45k
#ifdef LIBXML_C14N_ENABLED
2914
3.45k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_0)
2915
1.00k
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n");
2916
3.45k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_1)
2917
1.76k
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n11");
2918
3.45k
        if (lint->appOptions & XML_LINT_CANONICAL_EXE)
2919
1.07k
            xmllintOptWarnNoSupport(errStream, specialMode, "--exc-c14n");
2920
3.45k
#endif
2921
3.45k
#endif /* LIBXML_OUTPUT_ENABLED */
2922
3.45k
    }
2923
2924
10.3k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2925
10.3k
    if (lint->pattern && !((lint->appOptions & XML_LINT_USE_STREAMING) || (lint->appOptions & XML_LINT_USE_WALKER)))
2926
741
        fprintf(errStream, "Warning: Option %s requires %s\n",
2927
741
                "--pattern", "--stream or --walker");
2928
10.3k
#endif
2929
2930
10.3k
#ifdef LIBXML_HTML_ENABLED
2931
10.3k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
2932
1.21k
        if (lint->parseOptions & XML_PARSE_DTDATTR)
2933
1.12k
            xmllintOptWarnNoSupport(errStream, "--html", "--dtdattr");
2934
1.21k
        if (lint->parseOptions & XML_PARSE_DTDLOAD)
2935
1.09k
            xmllintOptWarnNoSupport(errStream, "--html", "--loaddtd");
2936
1.21k
        if (lint->maxAmpl)
2937
176
            xmllintOptWarnNoSupport(errStream, "--html", "--max-ampl");
2938
1.21k
        if (lint->parseOptions & XML_PARSE_NOCDATA)
2939
696
            xmllintOptWarnNoSupport(errStream, "--html", "--nocdata");
2940
1.21k
        if (lint->parseOptions & XML_PARSE_NODICT)
2941
382
            xmllintOptWarnNoSupport(errStream, "--html", "--nodict");
2942
1.21k
        if (lint->parseOptions & XML_PARSE_NOENT)
2943
1.07k
            xmllintOptWarnNoSupport(errStream, "--html", "--noent");
2944
1.21k
        if (lint->parseOptions & XML_PARSE_NONET)
2945
412
            xmllintOptWarnNoSupport(errStream, "--html", "--nonet");
2946
1.21k
        if (lint->parseOptions & XML_PARSE_NSCLEAN)
2947
380
            xmllintOptWarnNoSupport(errStream, "--html", "--nsclean");
2948
1.21k
        if (lint->parseOptions & XML_PARSE_OLD10)
2949
378
            xmllintOptWarnNoSupport(errStream, "--html", "--oldxml10");
2950
1.21k
        if (lint->parseOptions & XML_PARSE_PEDANTIC)
2951
152
            xmllintOptWarnNoSupport(errStream, "--html", "--pedantic");
2952
1.21k
        if (lint->parseOptions & XML_PARSE_DTDVALID)
2953
708
            xmllintOptWarnNoSupport(errStream, "--html", "--valid");
2954
1.21k
        if (lint->parseOptions & XML_PARSE_SAX1)
2955
76
            xmllintOptWarnNoSupport(errStream, "--html", "--sax1");
2956
9.09k
    } else {
2957
9.09k
        if (lint->htmlOptions & HTML_PARSE_NODEFDTD)
2958
2.15k
            fprintf(errStream, "Warning: Option %s requires %s\n",
2959
2.15k
                    "--nodefdtd", "--html");
2960
9.09k
#ifdef LIBXML_OUTPUT_ENABLED
2961
9.09k
        if (lint->appOptions & XML_LINT_XML_OUT)
2962
1.72k
            fprintf(errStream, "Warning: Option %s requires %s\n",
2963
1.72k
                    "--xmlout", "--html");
2964
9.09k
#endif
2965
9.09k
    }
2966
10.3k
#endif
2967
2968
10.3k
    return(XMLLINT_RETURN_OK);
2969
10.4k
}
2970
2971
int
2972
xmllintMain(int argc, const char **argv, FILE *errStream,
2973
10.4k
            xmlResourceLoader loader) {
2974
10.4k
    xmllintState state, *lint;
2975
10.4k
    int i, j, res;
2976
10.4k
    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.4k
    lint = &state;
2985
10.4k
    xmllintInit(lint);
2986
10.4k
    lint->errStream = errStream;
2987
10.4k
    lint->defaultResourceLoader = loader;
2988
2989
10.4k
    res = xmllintParseOptions(lint, argc, argv);
2990
10.4k
    if (res != XMLLINT_RETURN_OK) {
2991
146
        return(res);
2992
146
    }
2993
2994
    /*
2995
     * Note that we must not make any memory allocations through xmlMalloc
2996
     * before calling xmlMemSetup.
2997
     */
2998
10.3k
    if (lint->maxmem != 0) {
2999
298
        xmllintMaxmem = 0;
3000
298
        xmllintMaxmemReached = 0;
3001
298
        xmllintOom = 0;
3002
298
        xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
3003
298
    }
3004
3005
10.3k
    LIBXML_TEST_VERSION
3006
3007
10.3k
#ifdef LIBXML_CATALOG_ENABLED
3008
10.3k
    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.3k
#endif
3021
3022
10.3k
#ifdef LIBXML_OUTPUT_ENABLED
3023
10.3k
    {
3024
10.3k
        const char *indent = getenv("XMLLINT_INDENT");
3025
10.3k
        if (indent != NULL) {
3026
0
            lint->indentString = indent;
3027
0
        }
3028
10.3k
    }
3029
10.3k
#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.3k
#ifdef LIBXML_RELAXNG_ENABLED
3064
10.3k
    if ((lint->relaxng != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED)
3065
10.3k
#ifdef LIBXML_READER_ENABLED
3066
10.3k
        && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3067
10.3k
#endif /* LIBXML_READER_ENABLED */
3068
10.3k
  ) {
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.3k
#endif /* LIBXML_RELAXNG_ENABLED */
3095
3096
10.3k
#ifdef LIBXML_SCHEMAS_ENABLED
3097
10.3k
    if ((lint->schema != NULL)
3098
10.3k
#ifdef LIBXML_READER_ENABLED
3099
10.3k
        && ((lint->appOptions& XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3100
10.3k
#endif
3101
10.3k
  ) {
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.3k
#endif /* LIBXML_SCHEMAS_ENABLED */
3126
3127
10.3k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3128
10.3k
    if ((lint->pattern != NULL) && ((lint->appOptions & XML_LINT_USE_WALKER) != XML_LINT_USE_WALKER)) {
3129
1.02k
        res = xmlPatternCompileSafe(BAD_CAST lint->pattern, NULL, 0, NULL,
3130
1.02k
                                    &lint->patternc);
3131
1.02k
  if (lint->patternc == NULL) {
3132
599
            if (res < 0) {
3133
55
                lint->progresult = XMLLINT_ERR_MEM;
3134
544
            } else {
3135
544
                fprintf(errStream, "Pattern %s failed to compile\n",
3136
544
                        lint->pattern);
3137
544
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
3138
544
            }
3139
599
            goto error;
3140
599
  }
3141
1.02k
    }
3142
9.70k
#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
3143
3144
    /*
3145
     * The main loop over input documents
3146
     */
3147
175k
    for (i = 1; i < argc ; i++) {
3148
165k
        const char *filename = argv[i];
3149
165k
#if HAVE_DECL_MMAP
3150
165k
        int memoryFd = -1;
3151
165k
#endif
3152
3153
165k
  if ((filename[0] == '-') && (strcmp(filename, "-") != 0)) {
3154
155k
            i += skipArgs(filename);
3155
155k
            continue;
3156
155k
        }
3157
3158
9.70k
#if HAVE_DECL_MMAP
3159
9.70k
        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
9.70k
#endif /* HAVE_DECL_MMAP */
3181
3182
9.70k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1))
3183
309
      startTimer(lint);
3184
3185
9.70k
#ifdef LIBXML_READER_ENABLED
3186
9.70k
        if (lint->appOptions & XML_LINT_USE_STREAMING) {
3187
5.78k
            for (j = 0; j < lint->repeat; j++)
3188
3.07k
                streamFile(lint, filename);
3189
2.71k
        } else
3190
6.99k
#endif /* LIBXML_READER_ENABLED */
3191
6.99k
        {
3192
6.99k
            xmlParserCtxtPtr ctxt;
3193
3194
6.99k
#ifdef LIBXML_HTML_ENABLED
3195
6.99k
            if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3196
1.20k
#ifdef LIBXML_PUSH_ENABLED
3197
1.20k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3198
15
                    ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3199
15
                                                    filename,
3200
15
                                                    XML_CHAR_ENCODING_NONE);
3201
15
                } else
3202
1.18k
#endif /* LIBXML_PUSH_ENABLED */
3203
1.18k
                {
3204
1.18k
                    ctxt = htmlNewParserCtxt();
3205
1.18k
                }
3206
1.20k
                htmlCtxtUseOptions(ctxt, lint->htmlOptions);
3207
1.20k
            } else
3208
5.79k
#endif /* LIBXML_HTML_ENABLED */
3209
5.79k
            {
3210
5.79k
#ifdef LIBXML_PUSH_ENABLED
3211
5.79k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3212
21
                    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3213
21
                                                   filename);
3214
21
                } else
3215
5.77k
#endif /* LIBXML_PUSH_ENABLED */
3216
5.77k
                {
3217
5.77k
                    ctxt = xmlNewParserCtxt();
3218
5.77k
                }
3219
5.79k
                xmlCtxtUseOptions(ctxt, lint->parseOptions);
3220
5.79k
            }
3221
6.99k
            if (ctxt == NULL) {
3222
194
                lint->progresult = XMLLINT_ERR_MEM;
3223
194
                goto error;
3224
194
            }
3225
3226
6.80k
            if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3227
551
                const xmlSAXHandler *handler;
3228
3229
551
                if (lint->noout) {
3230
515
                    handler = &emptySAXHandler;
3231
515
#ifdef LIBXML_SAX1_ENABLED
3232
515
                } else if (lint->parseOptions & XML_PARSE_SAX1) {
3233
7
                    handler = &debugSAXHandler;
3234
7
#endif
3235
29
                } else {
3236
29
                    handler = &debugSAX2Handler;
3237
29
                }
3238
3239
551
                *ctxt->sax = *handler;
3240
551
                ctxt->userData = lint;
3241
551
            }
3242
3243
6.80k
            xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3244
6.80k
            if (lint->maxAmpl > 0)
3245
542
                xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl);
3246
3247
6.80k
            lint->ctxt = ctxt;
3248
3249
14.2k
            for (j = 0; j < lint->repeat; j++) {
3250
7.46k
                if (j > 0) {
3251
663
#ifdef LIBXML_PUSH_ENABLED
3252
663
                    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3253
0
                        xmlCtxtResetPush(ctxt, NULL, 0, NULL, NULL);
3254
0
                    } else
3255
663
#endif
3256
663
                    {
3257
663
                        xmlCtxtReset(ctxt);
3258
663
                    }
3259
663
                }
3260
3261
7.46k
                if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3262
670
                    testSAX(lint, filename);
3263
6.79k
                } else {
3264
6.79k
                    parseAndPrintFile(lint, filename);
3265
6.79k
                }
3266
7.46k
            }
3267
3268
6.80k
            xmlFreeParserCtxt(ctxt);
3269
6.80k
        }
3270
3271
9.51k
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) {
3272
299
            endTimer(lint, "%d iterations", lint->repeat);
3273
299
        }
3274
3275
9.51k
        files += 1;
3276
3277
9.51k
#if HAVE_DECL_MMAP
3278
9.51k
        if (lint->appOptions & XML_LINT_MEMORY) {
3279
0
            munmap(lint->memoryData, lint->memorySize);
3280
0
            close(memoryFd);
3281
0
        }
3282
9.51k
#endif
3283
9.51k
    }
3284
3285
9.51k
    if (lint->appOptions & XML_LINT_GENERATE)
3286
9.24k
  parseAndPrintFile(lint, NULL);
3287
3288
9.51k
    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.3k
error:
3294
3295
#ifdef LIBXML_SCHEMATRON_ENABLED
3296
    if (lint->wxschematron != NULL)
3297
  xmlSchematronFree(lint->wxschematron);
3298
#endif
3299
10.3k
#ifdef LIBXML_RELAXNG_ENABLED
3300
10.3k
    if (lint->relaxngschemas != NULL)
3301
0
  xmlRelaxNGFree(lint->relaxngschemas);
3302
10.3k
#endif
3303
10.3k
#ifdef LIBXML_SCHEMAS_ENABLED
3304
10.3k
    if (lint->wxschemas != NULL)
3305
0
  xmlSchemaFree(lint->wxschemas);
3306
10.3k
#endif
3307
10.3k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3308
10.3k
    if (lint->patternc != NULL)
3309
427
        xmlFreePattern(lint->patternc);
3310
10.3k
#endif
3311
3312
10.3k
    xmlCleanupParser();
3313
3314
10.3k
    if ((lint->maxmem) && (xmllintMaxmemReached)) {
3315
295
        fprintf(errStream, "Maximum memory exceeded (%d bytes)\n",
3316
295
                xmllintMaxmem);
3317
10.0k
    } else if (lint->progresult == XMLLINT_ERR_MEM) {
3318
1.61k
        fprintf(errStream, "Out-of-memory error reported\n");
3319
1.61k
    }
3320
3321
10.3k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
3322
10.3k
    if ((lint->maxmem) &&
3323
10.3k
        (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.3k
#endif
3329
3330
10.3k
    return(lint->progresult);
3331
10.3k
}
3332