Coverage Report

Created: 2025-12-04 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxml2/xmllint.c
Line
Count
Source
1
/*
2
 * xmllint.c : a small tester program for XML input.
3
 *
4
 * See Copyright for the status of this software.
5
 *
6
 * Author: Daniel Veillard
7
 */
8
9
#include "libxml.h"
10
11
#include <string.h>
12
#include <stdarg.h>
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <errno.h>
16
#include <limits.h>
17
#include <fcntl.h>
18
19
#ifdef _WIN32
20
  #include <io.h>
21
  #include <sys/timeb.h>
22
#else
23
  #include <sys/time.h>
24
  #include <unistd.h>
25
#endif
26
27
#if HAVE_DECL_MMAP
28
  #include <sys/mman.h>
29
  #include <sys/stat.h>
30
  /* seems needed for Solaris */
31
  #ifndef MAP_FAILED
32
    #define MAP_FAILED ((void *) -1)
33
  #endif
34
#endif
35
36
#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
8.19k
                      xmlParserInputFlags flags, xmlParserInputPtr *out) {
273
8.19k
    xmllintState *lint = ctxt;
274
8.19k
    xmlParserErrors code;
275
8.19k
    int i;
276
8.19k
    const char *lastsegment = URL;
277
8.19k
    const char *iter = URL;
278
279
8.19k
    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
8.19k
    if (lint->defaultResourceLoader != NULL)
288
8.19k
        code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out);
289
0
    else
290
0
        code = xmlNewInputFromUrl(URL, flags, out);
291
8.19k
    if (code != XML_IO_ENOENT) {
292
8.19k
        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
8.19k
        return(code);
297
8.19k
    }
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.70k
parseXml(xmllintState *lint, const char *filename) {
334
6.70k
    xmlParserCtxtPtr ctxt = lint->ctxt;
335
6.70k
    xmlDocPtr doc;
336
337
6.70k
#ifdef LIBXML_PUSH_ENABLED
338
6.70k
    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.70k
#endif /* LIBXML_PUSH_ENABLED */
366
367
6.70k
#if HAVE_DECL_MMAP
368
6.70k
    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.70k
#endif
382
383
6.70k
    if (strcmp(filename, "-") == 0)
384
0
        doc = xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
385
0
                            lint->parseOptions | XML_PARSE_UNZIP);
386
6.70k
    else
387
6.70k
        doc = xmlCtxtReadFile(ctxt, filename, NULL,
388
6.70k
                              lint->parseOptions | XML_PARSE_UNZIP);
389
390
6.70k
    return(doc);
391
6.70k
}
392
393
#ifdef LIBXML_HTML_ENABLED
394
static xmlDocPtr
395
1.49k
parseHtml(xmllintState *lint, const char *filename) {
396
1.49k
    xmlParserCtxtPtr ctxt = lint->ctxt;
397
1.49k
    xmlDocPtr doc;
398
399
1.49k
#ifdef LIBXML_PUSH_ENABLED
400
1.49k
    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.49k
#endif /* LIBXML_PUSH_ENABLED */
428
429
1.49k
#if HAVE_DECL_MMAP
430
1.49k
    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.49k
#endif
444
445
1.49k
    if (strcmp(filename, "-") == 0)
446
0
        doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
447
0
                             lint->htmlOptions);
448
1.49k
    else
449
1.49k
        doc = htmlCtxtReadFile(ctxt, filename, NULL, lint->htmlOptions);
450
451
1.49k
    return(doc);
452
1.49k
}
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
445
myFreeFunc(void *mem) {
465
445
    xmlMemFree(mem);
466
445
}
467
468
static void *
469
459
myMallocFunc(size_t size) {
470
459
    void *ret;
471
472
459
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
473
#if XMLLINT_ABORT_ON_FAILURE
474
        abort();
475
#endif
476
459
        xmllintMaxmemReached = 1;
477
459
        xmllintOom = 1;
478
459
        return(NULL);
479
459
    }
480
481
0
    ret = xmlMemMalloc(size);
482
0
    if (ret == NULL)
483
0
        xmllintOom = 1;
484
485
0
    return(ret);
486
459
}
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
8.28k
myStrdupFunc(const char *str) {
511
8.28k
    size_t size;
512
8.28k
    char *ret;
513
514
8.28k
    if (str == NULL)
515
0
        return(NULL);
516
517
8.28k
    size = strlen(str) + 1;
518
8.28k
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
519
#if XMLLINT_ABORT_ON_FAILURE
520
        abort();
521
#endif
522
8.28k
        xmllintMaxmemReached = 1;
523
8.28k
        xmllintOom = 1;
524
8.28k
        return(NULL);
525
8.28k
    }
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
23.2k
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
23.2k
    struct timeval tv;
555
556
23.2k
    gettimeofday(&tv, NULL);
557
23.2k
    time->sec = tv.tv_sec;
558
23.2k
    time->usec = tv.tv_usec;
559
23.2k
#endif /* _WIN32 */
560
23.2k
}
561
562
/*
563
 * startTimer: call where you want to start timing
564
 */
565
static void
566
startTimer(xmllintState *lint)
567
12.4k
{
568
12.4k
    getTime(&lint->begin);
569
12.4k
}
570
571
/*
572
 * endTimer: call where you want to stop timing and to print out a
573
 *           message about the timing performed; format is a printf
574
 *           type argument
575
 */
576
static void LIBXML_ATTR_FORMAT(2,3)
577
endTimer(xmllintState *lint, const char *fmt, ...)
578
10.8k
{
579
10.8k
    xmlSeconds msec;
580
10.8k
    va_list ap;
581
582
10.8k
    getTime(&lint->end);
583
10.8k
    msec = lint->end.sec - lint->begin.sec;
584
10.8k
    msec *= 1000;
585
10.8k
    msec += (lint->end.usec - lint->begin.usec) / 1000;
586
587
10.8k
    va_start(ap, fmt);
588
10.8k
    vfprintf(lint->errStream, fmt, ap);
589
10.8k
    va_end(ap);
590
591
10.8k
    fprintf(lint->errStream, " took %ld ms\n", (long) msec);
592
10.8k
}
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
75
{
1015
75
    xmllintState *lint = ctx;
1016
75
    va_list args;
1017
1018
75
    lint->callbacks++;
1019
75
    if (lint->noout)
1020
0
  return;
1021
75
    va_start(args, msg);
1022
75
    fprintf(stdout, "SAX.error: ");
1023
75
    vfprintf(stdout, msg, args);
1024
75
    va_end(args);
1025
75
}
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
676
testSAX(xmllintState *lint, const char *filename) {
1193
676
    lint->callbacks = 0;
1194
1195
676
#ifdef LIBXML_SCHEMAS_ENABLED
1196
676
    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
676
#endif
1236
676
#ifdef LIBXML_HTML_ENABLED
1237
676
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1238
0
        parseHtml(lint, filename);
1239
0
    } else
1240
676
#endif
1241
676
    {
1242
676
        parseXml(lint, filename);
1243
676
    }
1244
676
}
1245
1246
/************************************************************************
1247
 *                  *
1248
 *      Stream Test processing        *
1249
 *                  *
1250
 ************************************************************************/
1251
#ifdef LIBXML_READER_ENABLED
1252
2.73k
static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
1253
2.73k
    const xmlChar *name, *value;
1254
2.73k
    int type, empty;
1255
1256
2.73k
    type = xmlTextReaderNodeType(reader);
1257
2.73k
    empty = xmlTextReaderIsEmptyElement(reader);
1258
1259
2.73k
    if (lint->appOptions & XML_LINT_DEBUG_ENABLED) {
1260
1.90k
  name = xmlTextReaderConstName(reader);
1261
1.90k
  if (name == NULL)
1262
0
      name = BAD_CAST "--";
1263
1264
1.90k
  value = xmlTextReaderConstValue(reader);
1265
1266
1267
1.90k
  printf("%d %d %s %d %d",
1268
1.90k
    xmlTextReaderDepth(reader),
1269
1.90k
    type,
1270
1.90k
    name,
1271
1.90k
    empty,
1272
1.90k
    xmlTextReaderHasValue(reader));
1273
1.90k
  if (value == NULL)
1274
1.27k
      printf("\n");
1275
635
  else {
1276
635
      printf(" %s\n", value);
1277
635
  }
1278
1.90k
    }
1279
2.73k
#ifdef LIBXML_PATTERN_ENABLED
1280
2.73k
    if (lint->patternc) {
1281
1.32k
        xmlChar *path = NULL;
1282
1.32k
        int match = -1;
1283
1284
1.32k
  if (type == XML_READER_TYPE_ELEMENT) {
1285
      /* do the check only on element start */
1286
441
      match = xmlPatternMatch(lint->patternc,
1287
441
                                    xmlTextReaderCurrentNode(reader));
1288
1289
441
      if (match) {
1290
101
    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1291
101
    printf("Node %s matches pattern %s\n", path, lint->pattern);
1292
101
      }
1293
441
  }
1294
1.32k
  if (lint->patstream != NULL) {
1295
1.32k
      int ret;
1296
1297
1.32k
      if (type == XML_READER_TYPE_ELEMENT) {
1298
441
    ret = xmlStreamPush(lint->patstream,
1299
441
                        xmlTextReaderConstLocalName(reader),
1300
441
            xmlTextReaderConstNamespaceUri(reader));
1301
441
    if (ret < 0) {
1302
0
        fprintf(lint->errStream, "xmlStreamPush() failure\n");
1303
0
                    xmlFreeStreamCtxt(lint->patstream);
1304
0
        lint->patstream = NULL;
1305
441
    } else if (ret != match) {
1306
16
        if (path == NULL) {
1307
8
            path = xmlGetNodePath(
1308
8
                           xmlTextReaderCurrentNode(reader));
1309
8
        }
1310
16
        fprintf(lint->errStream,
1311
16
                "xmlPatternMatch and xmlStreamPush disagree\n");
1312
16
                    if (path != NULL)
1313
16
                        fprintf(lint->errStream, "  pattern %s node %s\n",
1314
16
                                lint->pattern, path);
1315
0
                    else
1316
0
            fprintf(lint->errStream, "  pattern %s node %s\n",
1317
0
          lint->pattern, xmlTextReaderConstName(reader));
1318
16
    }
1319
1320
441
      }
1321
1.32k
      if ((type == XML_READER_TYPE_END_ELEMENT) ||
1322
882
          ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1323
441
          ret = xmlStreamPop(lint->patstream);
1324
441
    if (ret < 0) {
1325
0
        fprintf(lint->errStream, "xmlStreamPop() failure\n");
1326
0
                    xmlFreeStreamCtxt(lint->patstream);
1327
0
        lint->patstream = NULL;
1328
0
    }
1329
441
      }
1330
1.32k
  }
1331
1.32k
  if (path != NULL)
1332
109
      xmlFree(path);
1333
1.32k
    }
1334
2.73k
#endif
1335
2.73k
}
1336
1337
3.32k
static void streamFile(xmllintState *lint, const char *filename) {
1338
3.32k
    xmlParserInputBufferPtr input = NULL;
1339
3.32k
    FILE *errStream = lint->errStream;
1340
3.32k
    xmlTextReaderPtr reader;
1341
3.32k
    int ret;
1342
1343
3.32k
#if HAVE_DECL_MMAP
1344
3.32k
    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.32k
#endif
1353
3.32k
    {
1354
3.32k
        xmlResetLastError();
1355
1356
3.32k
        if (strcmp(filename, "-") == 0) {
1357
0
            reader = xmlReaderForFd(STDIN_FILENO, "-", NULL,
1358
0
                                    lint->parseOptions | XML_PARSE_UNZIP);
1359
0
        }
1360
3.32k
        else {
1361
3.32k
            reader = xmlReaderForFile(filename, NULL,
1362
3.32k
                                      lint->parseOptions | XML_PARSE_UNZIP);
1363
3.32k
        }
1364
3.32k
        if (reader == NULL) {
1365
3.32k
            const xmlError *error = xmlGetLastError();
1366
1367
3.32k
            if ((error != NULL) && (error->code == XML_ERR_NO_MEMORY)) {
1368
103
                lint->progresult = XMLLINT_ERR_MEM;
1369
3.21k
            } else {
1370
3.21k
                fprintf(errStream, "Unable to open %s\n", filename);
1371
3.21k
                lint->progresult = XMLLINT_ERR_RDFILE;
1372
3.21k
            }
1373
3.32k
            return;
1374
3.32k
        }
1375
3.32k
    }
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
2.12k
static void walkDoc(xmllintState *lint, xmlDocPtr doc) {
1512
2.12k
    FILE *errStream = lint->errStream;
1513
2.12k
    xmlTextReaderPtr reader;
1514
2.12k
    int ret;
1515
1516
2.12k
#ifdef LIBXML_PATTERN_ENABLED
1517
2.12k
    if (lint->pattern != NULL) {
1518
662
        xmlNodePtr root;
1519
662
        const xmlChar *namespaces[22];
1520
662
        int i;
1521
662
        xmlNsPtr ns;
1522
1523
662
        root = xmlDocGetRootElement(doc);
1524
662
        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
662
        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
662
        namespaces[i++] = NULL;
1535
662
        namespaces[i] = NULL;
1536
1537
662
        ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict,
1538
662
                                    0, &namespaces[0], &lint->patternc);
1539
662
  if (lint->patternc == NULL) {
1540
183
            if (ret < 0) {
1541
0
                lint->progresult = XMLLINT_ERR_MEM;
1542
183
            } else {
1543
183
                fprintf(errStream, "Pattern %s failed to compile\n",
1544
183
                        lint->pattern);
1545
183
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
1546
183
            }
1547
183
            goto error;
1548
183
  }
1549
1550
479
        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
1551
479
        if (lint->patstream == NULL) {
1552
38
            lint->progresult = XMLLINT_ERR_MEM;
1553
38
            goto error;
1554
38
        }
1555
1556
441
        ret = xmlStreamPush(lint->patstream, NULL, NULL);
1557
441
        if (ret < 0) {
1558
0
            fprintf(errStream, "xmlStreamPush() failure\n");
1559
0
            lint->progresult = XMLLINT_ERR_MEM;
1560
0
            goto error;
1561
0
        }
1562
441
    }
1563
1.90k
#endif /* LIBXML_PATTERN_ENABLED */
1564
1.90k
    reader = xmlReaderWalker(doc);
1565
1.90k
    if (reader != NULL) {
1566
1.90k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1567
978
      startTimer(lint);
1568
978
  }
1569
1.90k
  ret = xmlTextReaderRead(reader);
1570
7.63k
  while (ret == 1) {
1571
5.72k
      if ((lint->appOptions & XML_LINT_DEBUG_ENABLED)
1572
3.81k
#ifdef LIBXML_PATTERN_ENABLED
1573
3.81k
          || (lint->patternc)
1574
5.72k
#endif
1575
5.72k
         )
1576
2.73k
    processNode(lint, reader);
1577
5.72k
      ret = xmlTextReaderRead(reader);
1578
5.72k
  }
1579
1.90k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1580
978
      endTimer(lint, "walking through the doc");
1581
978
  }
1582
1.90k
  xmlFreeTextReader(reader);
1583
1.90k
  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.90k
    } 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.90k
#ifdef LIBXML_PATTERN_ENABLED
1593
2.12k
error:
1594
2.12k
    if (lint->patternc != NULL) {
1595
479
        xmlFreePattern(lint->patternc);
1596
479
        lint->patternc = NULL;
1597
479
    }
1598
2.12k
    if (lint->patstream != NULL) {
1599
441
  xmlFreeStreamCtxt(lint->patstream);
1600
441
  lint->patstream = NULL;
1601
441
    }
1602
2.12k
#endif
1603
2.12k
}
1604
#endif /* LIBXML_READER_ENABLED */
1605
1606
#ifdef LIBXML_XPATH_ENABLED
1607
/************************************************************************
1608
 *                  *
1609
 *      XPath Query                                     *
1610
 *                  *
1611
 ************************************************************************/
1612
1613
static void
1614
5.85k
doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) {
1615
5.85k
    switch(cur->type) {
1616
4.14k
        case XPATH_NODESET: {
1617
4.14k
#ifdef LIBXML_OUTPUT_ENABLED
1618
4.14k
            xmlOutputBufferPtr buf;
1619
4.14k
            xmlNodePtr node;
1620
4.14k
            int i;
1621
1622
4.14k
            if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
1623
2.95k
                lint->progresult = XMLLINT_ERR_XPATH_EMPTY;
1624
2.95k
                if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
1625
2.61k
                    fprintf(lint->errStream, "XPath set is empty\n");
1626
2.61k
                }
1627
2.95k
                break;
1628
2.95k
            }
1629
1.19k
            buf = xmlOutputBufferCreateFile(stdout, NULL);
1630
1.19k
            if (buf == NULL) {
1631
0
                lint->progresult = XMLLINT_ERR_MEM;
1632
0
                return;
1633
0
            }
1634
4.03k
            for (i = 0;i < cur->nodesetval->nodeNr;i++) {
1635
2.83k
                node = cur->nodesetval->nodeTab[i];
1636
2.83k
                xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
1637
2.83k
                xmlOutputBufferWrite(buf, 1, "\n");
1638
2.83k
            }
1639
1.19k
            xmlOutputBufferClose(buf);
1640
#else
1641
            printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
1642
#endif
1643
1.19k
      break;
1644
1.19k
        }
1645
697
        case XPATH_BOOLEAN:
1646
697
      if (cur->boolval) printf("true\n");
1647
496
      else printf("false\n");
1648
697
      break;
1649
504
        case XPATH_NUMBER:
1650
504
      switch (xmlXPathIsInf(cur->floatval)) {
1651
29
      case 1:
1652
29
    printf("Infinity\n");
1653
29
    break;
1654
18
      case -1:
1655
18
    printf("-Infinity\n");
1656
18
    break;
1657
457
      default:
1658
457
    if (xmlXPathIsNaN(cur->floatval)) {
1659
287
        printf("NaN\n");
1660
287
    } else {
1661
170
        printf("%0g\n", cur->floatval);
1662
170
    }
1663
504
      }
1664
504
      break;
1665
508
        case XPATH_STRING:
1666
508
      printf("%s\n", (const char *) cur->stringval);
1667
508
      break;
1668
0
        case XPATH_UNDEFINED:
1669
0
      fprintf(lint->errStream, "XPath Object is uninitialized\n");
1670
0
            lint->progresult = XMLLINT_ERR_XPATH;
1671
0
      break;
1672
0
  default:
1673
0
      fprintf(lint->errStream, "XPath object of unexpected type\n");
1674
0
            lint->progresult = XMLLINT_ERR_XPATH;
1675
0
      break;
1676
5.85k
    }
1677
5.85k
}
1678
1679
static void
1680
9.17k
doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) {
1681
9.17k
    xmlXPathContextPtr ctxt = NULL;
1682
9.17k
    xmlXPathCompExprPtr comp = NULL;
1683
9.17k
    xmlXPathObjectPtr res = NULL;
1684
1685
9.17k
    ctxt = xmlXPathNewContext(doc);
1686
9.17k
    if (ctxt == NULL) {
1687
0
        lint->progresult = XMLLINT_ERR_MEM;
1688
0
        goto error;
1689
0
    }
1690
1691
9.17k
    comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query);
1692
9.17k
    if (comp == NULL) {
1693
2.04k
        fprintf(lint->errStream, "XPath compilation failure\n");
1694
2.04k
        lint->progresult = XMLLINT_ERR_XPATH;
1695
2.04k
        goto error;
1696
2.04k
    }
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
7.13k
    ctxt->node = (xmlNodePtr) doc;
1706
7.13k
    res = xmlXPathCompiledEval(comp, ctxt);
1707
7.13k
    if (res == NULL) {
1708
1.27k
        fprintf(lint->errStream, "XPath evaluation failure\n");
1709
1.27k
        lint->progresult = XMLLINT_ERR_XPATH;
1710
1.27k
        goto error;
1711
1.27k
    }
1712
1713
5.85k
    doXPathDump(lint, res);
1714
1715
9.17k
error:
1716
9.17k
    xmlXPathFreeObject(res);
1717
9.17k
    xmlXPathFreeCompExpr(comp);
1718
9.17k
    xmlXPathFreeContext(ctxt);
1719
9.17k
}
1720
#endif /* LIBXML_XPATH_ENABLED */
1721
1722
/************************************************************************
1723
 *                  *
1724
 *      Tree Test processing        *
1725
 *                  *
1726
 ************************************************************************/
1727
1728
static xmlDocPtr
1729
17.6k
parseFile(xmllintState *lint, const char *filename) {
1730
17.6k
    xmlDocPtr doc = NULL;
1731
1732
17.6k
    if ((lint->appOptions & XML_LINT_GENERATE) && (filename == NULL)) {
1733
10.1k
        xmlNodePtr n;
1734
1735
10.1k
        doc = xmlNewDoc(BAD_CAST "1.0");
1736
10.1k
        if (doc == NULL) {
1737
41
            lint->progresult = XMLLINT_ERR_MEM;
1738
41
            return(NULL);
1739
41
        }
1740
10.0k
        n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
1741
10.0k
        if (n == NULL) {
1742
0
            xmlFreeDoc(doc);
1743
0
            lint->progresult = XMLLINT_ERR_MEM;
1744
0
            return(NULL);
1745
0
        }
1746
10.0k
        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
10.0k
        xmlDocSetRootElement(doc, n);
1753
1754
10.0k
        return(doc);
1755
10.0k
    }
1756
1757
7.52k
#ifdef LIBXML_HTML_ENABLED
1758
7.52k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1759
1.49k
        doc = parseHtml(lint, filename);
1760
1.49k
        return(doc);
1761
1.49k
    }
1762
6.02k
#endif /* LIBXML_HTML_ENABLED */
1763
6.02k
    {
1764
6.02k
        doc = parseXml(lint, filename);
1765
6.02k
    }
1766
1767
6.02k
    if (doc == NULL) {
1768
6.02k
        if (lint->ctxt->errNo == XML_ERR_NO_MEMORY)
1769
6.02k
            lint->progresult = XMLLINT_ERR_MEM;
1770
0
        else
1771
0
      lint->progresult = XMLLINT_ERR_RDFILE;
1772
6.02k
    } 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
6.02k
    return(doc);
1785
7.52k
}
1786
1787
static void
1788
17.6k
parseAndPrintFile(xmllintState *lint, const char *filename) {
1789
17.6k
    FILE *errStream = lint->errStream;
1790
17.6k
    xmlDocPtr doc;
1791
1792
    /* Avoid unused variable warning */
1793
17.6k
    (void) errStream;
1794
1795
17.6k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1))
1796
4.17k
  startTimer(lint);
1797
1798
17.6k
    doc = parseFile(lint, filename);
1799
17.6k
    if (doc == NULL) {
1800
7.56k
        if (lint->progresult == XMLLINT_RETURN_OK)
1801
1.38k
            lint->progresult = XMLLINT_ERR_UNCLASS;
1802
7.56k
  return;
1803
7.56k
    }
1804
1805
10.0k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1806
2.54k
  endTimer(lint, "Parsing");
1807
2.54k
    }
1808
1809
10.0k
    if (lint->appOptions & XML_LINT_DROP_DTD) {
1810
1.46k
  xmlDtdPtr dtd;
1811
1812
1.46k
  dtd = xmlGetIntSubset(doc);
1813
1.46k
  if (dtd != NULL) {
1814
0
      xmlUnlinkNode((xmlNodePtr)dtd);
1815
0
            doc->intSubset = dtd;
1816
0
  }
1817
1.46k
    }
1818
1819
10.0k
#ifdef LIBXML_XINCLUDE_ENABLED
1820
10.0k
    if (lint->appOptions & XML_LINT_XINCLUDE) {
1821
7.81k
        xmlXIncludeCtxt *xinc;
1822
7.81k
        int res;
1823
1824
7.81k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1825
2.25k
      startTimer(lint);
1826
2.25k
  }
1827
1828
7.81k
        xinc = xmlXIncludeNewContext(doc);
1829
7.81k
        if (xinc == NULL) {
1830
0
            lint->progresult = XMLLINT_ERR_MEM;
1831
0
            goto done;
1832
0
        }
1833
7.81k
        xmlXIncludeSetResourceLoader(xinc, xmllintResourceLoader, lint);
1834
7.81k
        xmlXIncludeSetFlags(xinc, lint->parseOptions);
1835
7.81k
        res = xmlXIncludeProcessNode(xinc, (xmlNode *) doc);
1836
7.81k
        xmlXIncludeFreeContext(xinc);
1837
7.81k
        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.81k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1846
2.25k
      endTimer(lint, "Xinclude processing");
1847
2.25k
  }
1848
7.81k
    }
1849
10.0k
#endif
1850
1851
    /*
1852
     * shell interaction
1853
     */
1854
10.0k
    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
10.0k
#ifdef LIBXML_XPATH_ENABLED
1863
10.0k
    if (lint->xpathquery != NULL) {
1864
9.17k
  xmlXPathOrderDocElems(doc);
1865
9.17k
        doXPathQuery(lint, doc, lint->xpathquery);
1866
9.17k
    }
1867
10.0k
#endif
1868
1869
    /*
1870
     * test intermediate copy if needed.
1871
     */
1872
10.0k
    if (lint->appOptions & XML_LINT_COPY_ENABLED) {
1873
2.71k
        xmlDocPtr tmp;
1874
1875
2.71k
        tmp = doc;
1876
2.71k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1877
807
      startTimer(lint);
1878
807
  }
1879
2.71k
  doc = xmlCopyDoc(doc, 1);
1880
2.71k
        if (doc == NULL) {
1881
0
            lint->progresult = XMLLINT_ERR_MEM;
1882
0
            xmlFreeDoc(tmp);
1883
0
            return;
1884
0
        }
1885
2.71k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1886
807
      endTimer(lint, "Copying");
1887
807
  }
1888
2.71k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1889
807
      startTimer(lint);
1890
807
  }
1891
2.71k
  xmlFreeDoc(tmp);
1892
2.71k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1893
807
      endTimer(lint, "Freeing original");
1894
807
  }
1895
2.71k
    }
1896
1897
10.0k
#ifdef LIBXML_VALID_ENABLED
1898
10.0k
    if ((lint->appOptions & XML_LINT_VALID_INSERTIONS)
1899
5.22k
#ifdef LIBXML_HTML_ENABLED
1900
5.22k
        && ((lint->appOptions & XML_LINT_HTML_ENABLED) != XML_LINT_HTML_ENABLED)
1901
10.0k
#endif
1902
10.0k
    ) {
1903
4.43k
        const xmlChar* list[256];
1904
4.43k
  int nb, i;
1905
4.43k
  xmlNodePtr node;
1906
1907
4.43k
  if (doc->children != NULL) {
1908
4.43k
      node = doc->children;
1909
4.43k
      while ((node != NULL) &&
1910
4.43k
                   ((node->type != XML_ELEMENT_NODE) ||
1911
4.43k
                    (node->last == NULL)))
1912
0
                node = node->next;
1913
4.43k
      if (node != NULL) {
1914
4.43k
    nb = xmlValidGetValidElements(node->last, NULL, list, 256);
1915
4.43k
    if (nb < 0) {
1916
4.43k
        fprintf(errStream, "could not get valid list of elements\n");
1917
4.43k
    } 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.43k
      }
1927
4.43k
  }
1928
4.43k
    } else
1929
5.65k
#endif /* LIBXML_VALID_ENABLED */
1930
5.65k
#ifdef LIBXML_READER_ENABLED
1931
5.65k
    if (lint->appOptions & XML_LINT_USE_WALKER) {
1932
2.12k
        walkDoc(lint, doc);
1933
2.12k
    }
1934
10.0k
#endif /* LIBXML_READER_ENABLED */
1935
10.0k
#ifdef LIBXML_OUTPUT_ENABLED
1936
10.0k
    if (lint->noout == 0) {
1937
249
#ifdef LIBXML_ZLIB_ENABLED
1938
249
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
1939
51
            xmlSetDocCompressMode(doc, 9);
1940
249
#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
249
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1949
22
    startTimer(lint);
1950
22
      }
1951
249
#ifdef LIBXML_C14N_ENABLED
1952
249
            if (lint->appOptions & XML_LINT_CANONICAL_V1_0) {
1953
60
          xmlChar *result = NULL;
1954
60
    int size;
1955
1956
60
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
1957
60
    if (size >= 0) {
1958
60
        if (write(1, result, size) == -1) {
1959
0
            fprintf(errStream, "Can't write data\n");
1960
0
        }
1961
60
        xmlFree(result);
1962
60
    } else {
1963
0
        fprintf(errStream, "Failed to canonicalize\n");
1964
0
        lint->progresult = XMLLINT_ERR_OUT;
1965
0
    }
1966
189
      } else if (lint->appOptions & XML_LINT_CANONICAL_V1_1) {
1967
48
          xmlChar *result = NULL;
1968
48
    int size;
1969
1970
48
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
1971
48
    if (size >= 0) {
1972
48
        if (write(1, result, size) == -1) {
1973
0
            fprintf(errStream, "Can't write data\n");
1974
0
        }
1975
48
        xmlFree(result);
1976
48
    } else {
1977
0
        fprintf(errStream, "Failed to canonicalize\n");
1978
0
        lint->progresult = XMLLINT_ERR_OUT;
1979
0
    }
1980
141
      } else if (lint->appOptions & XML_LINT_CANONICAL_EXE) {
1981
15
          xmlChar *result = NULL;
1982
15
    int size;
1983
1984
15
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
1985
15
    if (size >= 0) {
1986
15
        if (write(1, result, size) == -1) {
1987
0
            fprintf(errStream, "Can't write data\n");
1988
0
        }
1989
15
        xmlFree(result);
1990
15
    } else {
1991
0
        fprintf(errStream, "Failed to canonicalize\n");
1992
0
        lint->progresult = XMLLINT_ERR_OUT;
1993
0
    }
1994
15
      } else
1995
126
#endif
1996
126
#ifdef LIBXML_ZLIB_ENABLED
1997
126
      if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) {
1998
8
    xmlSaveFile(lint->output ? lint->output : "-", doc);
1999
8
      } else
2000
118
#endif
2001
118
            {
2002
118
          xmlSaveCtxtPtr ctxt;
2003
118
    int saveOpts = 0;
2004
2005
118
                if (lint->format == 1)
2006
51
        saveOpts |= XML_SAVE_FORMAT;
2007
67
                else if (lint->format == 2)
2008
14
                    saveOpts |= XML_SAVE_WSNONSIG;
2009
2010
118
#if defined(LIBXML_HTML_ENABLED)
2011
118
                if (lint->appOptions & XML_LINT_XML_OUT)
2012
16
                    saveOpts |= XML_SAVE_AS_XML;
2013
118
#endif
2014
2015
118
    if (lint->output == NULL)
2016
118
        ctxt = xmlSaveToFd(STDOUT_FILENO, lint->encoding,
2017
118
                                       saveOpts);
2018
0
    else
2019
0
        ctxt = xmlSaveToFilename(lint->output, lint->encoding,
2020
0
                                             saveOpts);
2021
2022
118
    if (ctxt != NULL) {
2023
37
                    if (lint->indentString != NULL)
2024
0
                        xmlSaveSetIndentString(ctxt, lint->indentString);
2025
2026
37
        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
37
        xmlSaveClose(ctxt);
2032
81
    } else {
2033
81
        lint->progresult = XMLLINT_ERR_OUT;
2034
81
    }
2035
118
      }
2036
249
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2037
22
    endTimer(lint, "Saving");
2038
22
      }
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
249
    }
2059
10.0k
#endif /* LIBXML_OUTPUT_ENABLED */
2060
2061
10.0k
#ifdef LIBXML_VALID_ENABLED
2062
    /*
2063
     * A posteriori validation test
2064
     */
2065
10.0k
    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
10.0k
    } else if (lint->appOptions & XML_LINT_POST_VALIDATION) {
2117
1.49k
  xmlValidCtxtPtr cvp;
2118
2119
1.49k
  cvp = xmlNewValidCtxt();
2120
1.49k
  if (cvp == NULL) {
2121
0
            lint->progresult = XMLLINT_ERR_MEM;
2122
0
            xmlFreeDoc(doc);
2123
0
            return;
2124
0
  }
2125
2126
1.49k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2127
498
      startTimer(lint);
2128
498
  }
2129
1.49k
  if (!xmlValidateDocument(cvp, doc)) {
2130
1.49k
      fprintf(errStream,
2131
1.49k
        "Document %s does not validate\n", filename);
2132
1.49k
      lint->progresult = XMLLINT_ERR_VALID;
2133
1.49k
  }
2134
1.49k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2135
498
      endTimer(lint, "Validating");
2136
498
  }
2137
1.49k
  xmlFreeValidCtxt(cvp);
2138
1.49k
    }
2139
10.0k
#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
10.0k
#ifdef LIBXML_RELAXNG_ENABLED
2183
10.0k
    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
10.0k
#endif /* LIBXML_RELAXNG_ENABLED */
2216
2217
10.0k
#ifdef LIBXML_SCHEMAS_ENABLED
2218
10.0k
    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
10.0k
#endif /* LIBXML_SCHEMAS_ENABLED */
2251
2252
    /* Avoid unused label warning */
2253
10.0k
    goto done;
2254
2255
10.0k
done:
2256
    /*
2257
     * free it.
2258
     */
2259
10.0k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2260
2.54k
  startTimer(lint);
2261
2.54k
    }
2262
10.0k
    xmlFreeDoc(doc);
2263
10.0k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2264
2.54k
  endTimer(lint, "Freeing");
2265
2.54k
    }
2266
10.0k
}
2267
2268
/************************************************************************
2269
 *                  *
2270
 *      Usage and Main          *
2271
 *                  *
2272
 ************************************************************************/
2273
2274
2.84k
static void showVersion(FILE *errStream, const char *name) {
2275
2.84k
    fprintf(errStream, "%s: using libxml version %s\n", name, xmlParserVersion);
2276
2.84k
    fprintf(errStream, "   compiled with: ");
2277
2.84k
    if (xmlHasFeature(XML_WITH_THREAD)) fprintf(errStream, "Threads ");
2278
2.84k
    fprintf(errStream, "Tree ");
2279
2.84k
    if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(errStream, "Output ");
2280
2.84k
    if (xmlHasFeature(XML_WITH_PUSH)) fprintf(errStream, "Push ");
2281
2.84k
    if (xmlHasFeature(XML_WITH_READER)) fprintf(errStream, "Reader ");
2282
2.84k
    if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(errStream, "Patterns ");
2283
2.84k
    if (xmlHasFeature(XML_WITH_WRITER)) fprintf(errStream, "Writer ");
2284
2.84k
    if (xmlHasFeature(XML_WITH_SAX1)) fprintf(errStream, "SAXv1 ");
2285
2.84k
    if (xmlHasFeature(XML_WITH_VALID)) fprintf(errStream, "DTDValid ");
2286
2.84k
    if (xmlHasFeature(XML_WITH_HTML)) fprintf(errStream, "HTML ");
2287
2.84k
    if (xmlHasFeature(XML_WITH_C14N)) fprintf(errStream, "C14N ");
2288
2.84k
    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(errStream, "Catalog ");
2289
2.84k
    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(errStream, "XPath ");
2290
2.84k
    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(errStream, "XPointer ");
2291
2.84k
    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(errStream, "XInclude ");
2292
2.84k
    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(errStream, "Iconv ");
2293
2.84k
    if (xmlHasFeature(XML_WITH_ICU)) fprintf(errStream, "ICU ");
2294
2.84k
    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(errStream, "ISO8859X ");
2295
2.84k
    if (xmlHasFeature(XML_WITH_REGEXP))
2296
2.84k
        fprintf(errStream, "Regexps Automata ");
2297
2.84k
    if (xmlHasFeature(XML_WITH_RELAXNG)) fprintf(errStream, "RelaxNG ");
2298
2.84k
    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(errStream, "Schemas ");
2299
2.84k
    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(errStream, "Schematron ");
2300
2.84k
    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(errStream, "Modules ");
2301
2.84k
    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(errStream, "Debug ");
2302
2.84k
    if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(errStream, "Zlib ");
2303
2.84k
    fprintf(errStream, "\n");
2304
2.84k
}
2305
2306
123
static void usage(FILE *f, const char *name) {
2307
123
    fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
2308
123
#ifdef LIBXML_OUTPUT_ENABLED
2309
123
    fprintf(f, "\tParse the XML files and output the result of the parsing\n");
2310
#else
2311
    fprintf(f, "\tParse the XML files\n");
2312
#endif /* LIBXML_OUTPUT_ENABLED */
2313
123
    fprintf(f, "\t--version : display the version of the XML library used\n");
2314
123
    fprintf(f, "\t--shell : run a navigating shell\n");
2315
123
    fprintf(f, "\t--debug : show additional debug information\n");
2316
123
    fprintf(f, "\t--copy : used to test the internal copy implementation\n");
2317
123
    fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
2318
123
    fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
2319
123
    fprintf(f, "\t--noent : substitute entity references by their value\n");
2320
123
    fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
2321
123
    fprintf(f, "\t--noout : don't output the result tree\n");
2322
123
    fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
2323
123
    fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
2324
123
    fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
2325
123
    fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
2326
123
#ifdef LIBXML_VALID_ENABLED
2327
123
    fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
2328
123
    fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
2329
123
    fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
2330
123
    fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
2331
123
    fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
2332
123
#endif /* LIBXML_VALID_ENABLED */
2333
123
    fprintf(f, "\t--strict-namespace : Return application failure if document has any namespace errors\n");
2334
123
    fprintf(f, "\t--quiet : be quiet when succeeded\n");
2335
123
    fprintf(f, "\t--timing : print some timings\n");
2336
123
    fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
2337
123
    fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
2338
123
#ifdef LIBXML_HTML_ENABLED
2339
123
    fprintf(f, "\t--html : use the HTML parser\n");
2340
123
    fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
2341
123
#ifdef LIBXML_OUTPUT_ENABLED
2342
123
    fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
2343
123
#endif
2344
123
#endif
2345
123
#ifdef LIBXML_PUSH_ENABLED
2346
123
    fprintf(f, "\t--push : use the push mode of the parser\n");
2347
123
#endif /* LIBXML_PUSH_ENABLED */
2348
123
#if HAVE_DECL_MMAP
2349
123
    fprintf(f, "\t--memory : parse from memory\n");
2350
123
#endif
2351
123
    fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
2352
123
    fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
2353
123
    fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
2354
123
    fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
2355
123
    fprintf(f, "\t--nodict : create document without dictionary\n");
2356
123
    fprintf(f, "\t--pedantic : enable additional warnings\n");
2357
123
#ifdef LIBXML_OUTPUT_ENABLED
2358
123
    fprintf(f, "\t--output file or -o file: save to a given file\n");
2359
123
    fprintf(f, "\t--format : reformat/reindent the output\n");
2360
123
    fprintf(f, "\t--encode encoding : output in the given encoding\n");
2361
123
    fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
2362
123
    fprintf(f, "\t                 0 Do not pretty print\n");
2363
123
    fprintf(f, "\t                 1 Format the XML content, as --format\n");
2364
123
    fprintf(f, "\t                 2 Add whitespace inside tags, preserving content\n");
2365
123
#ifdef LIBXML_ZLIB_ENABLED
2366
123
    fprintf(f, "\t--compress : turn on gzip compression of output\n");
2367
123
#endif
2368
123
#ifdef LIBXML_C14N_ENABLED
2369
123
    fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
2370
123
    fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
2371
123
    fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
2372
123
#endif /* LIBXML_C14N_ENABLED */
2373
123
#endif /* LIBXML_OUTPUT_ENABLED */
2374
123
    fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
2375
123
#ifdef LIBXML_CATALOG_ENABLED
2376
123
    fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2377
123
    fprintf(f, "\t             otherwise XML Catalogs starting from \n");
2378
123
    fprintf(f, "\t         file://" XML_SYSCONFDIR "/xml/catalog "
2379
123
            "are activated by default\n");
2380
123
    fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
2381
123
#endif
2382
123
    fprintf(f, "\t--auto : generate a small doc on the fly\n");
2383
123
#ifdef LIBXML_XINCLUDE_ENABLED
2384
123
    fprintf(f, "\t--xinclude : do XInclude processing\n");
2385
123
    fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
2386
123
    fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
2387
123
#endif
2388
123
    fprintf(f, "\t--loaddtd : fetch external DTD\n");
2389
123
    fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
2390
123
#ifdef LIBXML_READER_ENABLED
2391
123
    fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
2392
123
    fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
2393
123
#ifdef LIBXML_PATTERN_ENABLED
2394
123
    fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
2395
123
#endif
2396
123
#endif /* LIBXML_READER_ENABLED */
2397
123
#ifdef LIBXML_RELAXNG_ENABLED
2398
123
    fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
2399
123
#endif
2400
123
#ifdef LIBXML_SCHEMAS_ENABLED
2401
123
    fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
2402
123
#endif
2403
#ifdef LIBXML_SCHEMATRON_ENABLED
2404
    fprintf(f, "\t--schematron schema : do validation against a schematron\n");
2405
#endif
2406
123
#ifdef LIBXML_SAX1_ENABLED
2407
123
    fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
2408
123
#endif
2409
123
    fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
2410
123
    fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
2411
123
#ifdef LIBXML_XPATH_ENABLED
2412
123
    fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
2413
123
#endif
2414
123
    fprintf(f, "\t--max-ampl value: set maximum amplification factor\n");
2415
2416
123
    fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
2417
123
}
2418
2419
static int
2420
parseInteger(unsigned long *result, FILE *errStream, const char *ctxt,
2421
5.87k
             const char *str, unsigned long min, unsigned long max) {
2422
5.87k
    char *strEnd;
2423
5.87k
    unsigned long val;
2424
2425
5.87k
    errno = 0;
2426
5.87k
    val = strtoul(str, &strEnd, 10);
2427
5.87k
    if (errno == EINVAL || *strEnd != 0) {
2428
0
        fprintf(errStream, "%s: invalid integer: %s\n", ctxt, str);
2429
0
        return(-1);
2430
0
    }
2431
5.87k
    if (errno != 0 || val < min || val > max) {
2432
22
        fprintf(errStream, "%s: integer out of range: %s\n", ctxt, str);
2433
22
        return(-1);
2434
22
    }
2435
2436
5.84k
    *result = val;
2437
5.84k
    return(0);
2438
5.87k
}
2439
2440
static int
2441
167k
skipArgs(const char *arg) {
2442
167k
    if ((!strcmp(arg, "-path")) ||
2443
167k
        (!strcmp(arg, "--path")) ||
2444
167k
        (!strcmp(arg, "-maxmem")) ||
2445
167k
        (!strcmp(arg, "--maxmem")) ||
2446
167k
#ifdef LIBXML_OUTPUT_ENABLED
2447
167k
        (!strcmp(arg, "-o")) ||
2448
167k
        (!strcmp(arg, "-output")) ||
2449
167k
        (!strcmp(arg, "--output")) ||
2450
167k
        (!strcmp(arg, "-encode")) ||
2451
167k
        (!strcmp(arg, "--encode")) ||
2452
166k
        (!strcmp(arg, "-pretty")) ||
2453
166k
        (!strcmp(arg, "--pretty")) ||
2454
162k
#endif
2455
162k
#ifdef LIBXML_VALID_ENABLED
2456
162k
        (!strcmp(arg, "-dtdvalid")) ||
2457
162k
        (!strcmp(arg, "--dtdvalid")) ||
2458
162k
        (!strcmp(arg, "-dtdvalidfpi")) ||
2459
162k
        (!strcmp(arg, "--dtdvalidfpi")) ||
2460
162k
#endif
2461
162k
#ifdef LIBXML_RELAXNG_ENABLED
2462
162k
        (!strcmp(arg, "-relaxng")) ||
2463
162k
        (!strcmp(arg, "--relaxng")) ||
2464
162k
#endif
2465
162k
#ifdef LIBXML_SCHEMAS_ENABLED
2466
162k
        (!strcmp(arg, "-schema")) ||
2467
162k
        (!strcmp(arg, "--schema")) ||
2468
162k
#endif
2469
#ifdef LIBXML_SCHEMATRON_ENABLED
2470
        (!strcmp(arg, "-schematron")) ||
2471
        (!strcmp(arg, "--schematron")) ||
2472
#endif
2473
162k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2474
162k
        (!strcmp(arg, "-pattern")) ||
2475
162k
        (!strcmp(arg, "--pattern")) ||
2476
161k
#endif
2477
161k
#ifdef LIBXML_XPATH_ENABLED
2478
161k
        (!strcmp(arg, "-xpath")) ||
2479
161k
        (!strcmp(arg, "--xpath")) ||
2480
151k
#endif
2481
151k
        (!strcmp(arg, "-max-ampl")) ||
2482
151k
        (!strcmp(arg, "--max-ampl"))
2483
167k
    ) {
2484
16.2k
        return(1);
2485
16.2k
    }
2486
2487
151k
    return(0);
2488
167k
}
2489
2490
static void
2491
11.3k
xmllintInit(xmllintState *lint) {
2492
11.3k
    memset(lint, 0, sizeof(*lint));
2493
2494
11.3k
    lint->repeat = 1;
2495
11.3k
    lint->progresult = XMLLINT_RETURN_OK;
2496
11.3k
    lint->parseOptions = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
2497
11.3k
#ifdef LIBXML_HTML_ENABLED
2498
11.3k
    lint->htmlOptions = HTML_PARSE_COMPACT | HTML_PARSE_BIG_LINES;
2499
11.3k
#endif
2500
11.3k
}
2501
2502
static void
2503
28.5k
xmllintOptWarnNoSupport(FILE *errStream, const char *opt, const char *nosupp) {
2504
28.5k
    fprintf(errStream, "Warning: Option %s doesn't support %s\n", opt, nosupp);
2505
28.5k
}
2506
2507
static int
2508
11.3k
xmllintParseOptions(xmllintState *lint, int argc, const char **argv) {
2509
11.3k
    FILE *errStream = lint->errStream;
2510
11.3k
    const char *specialMode = NULL;
2511
11.3k
    int i;
2512
2513
11.3k
    if (argc <= 1) {
2514
0
        usage(errStream, argv[0]);
2515
0
        return(XMLLINT_ERR_UNCLASS);
2516
0
    }
2517
2518
198k
    for (i = 1; i < argc ; i++) {
2519
187k
        unsigned long val;
2520
2521
187k
        if (argv[i][0] != '-' || argv[i][1] == 0)
2522
11.2k
            continue;
2523
2524
176k
        if ((!strcmp(argv[i], "-maxmem")) ||
2525
176k
            (!strcmp(argv[i], "--maxmem"))) {
2526
352
            i++;
2527
352
            if (i >= argc) {
2528
0
                fprintf(errStream, "maxmem: missing integer value\n");
2529
0
                return(XMLLINT_ERR_UNCLASS);
2530
0
            }
2531
352
            if (parseInteger(&val, errStream, "maxmem", argv[i],
2532
352
                             0, INT_MAX) < 0)
2533
0
                return(XMLLINT_ERR_UNCLASS);
2534
352
            lint->maxmem = val;
2535
176k
        } else if ((!strcmp(argv[i], "-debug")) ||
2536
176k
                   (!strcmp(argv[i], "--debug"))) {
2537
3.72k
            lint->appOptions |= XML_LINT_DEBUG_ENABLED;
2538
172k
        } else if ((!strcmp(argv[i], "-shell")) ||
2539
172k
                   (!strcmp(argv[i], "--shell"))) {
2540
0
            lint->appOptions |= XML_LINT_NAVIGATING_SHELL;
2541
172k
        } else if ((!strcmp(argv[i], "-copy")) ||
2542
172k
                   (!strcmp(argv[i], "--copy"))) {
2543
3.03k
            lint->appOptions |= XML_LINT_COPY_ENABLED;
2544
169k
        } else if ((!strcmp(argv[i], "-recover")) ||
2545
169k
                   (!strcmp(argv[i], "--recover"))) {
2546
1.88k
            lint->parseOptions |= XML_PARSE_RECOVER;
2547
167k
        } else if ((!strcmp(argv[i], "-huge")) ||
2548
167k
                   (!strcmp(argv[i], "--huge"))) {
2549
4.19k
            lint->parseOptions |= XML_PARSE_HUGE;
2550
4.19k
#ifdef LIBXML_HTML_ENABLED
2551
4.19k
            lint->htmlOptions |= HTML_PARSE_HUGE;
2552
4.19k
#endif
2553
163k
        } else if ((!strcmp(argv[i], "-noent")) ||
2554
163k
                   (!strcmp(argv[i], "--noent"))) {
2555
1.82k
            lint->parseOptions |= XML_PARSE_NOENT;
2556
161k
        } else if ((!strcmp(argv[i], "-noenc")) ||
2557
161k
                   (!strcmp(argv[i], "--noenc"))) {
2558
2.78k
            lint->parseOptions |= XML_PARSE_IGNORE_ENC;
2559
2.78k
#ifdef LIBXML_HTML_ENABLED
2560
2.78k
            lint->htmlOptions |= HTML_PARSE_IGNORE_ENC;
2561
2.78k
#endif
2562
158k
        } else if ((!strcmp(argv[i], "-nsclean")) ||
2563
158k
                   (!strcmp(argv[i], "--nsclean"))) {
2564
4.23k
            lint->parseOptions |= XML_PARSE_NSCLEAN;
2565
154k
        } else if ((!strcmp(argv[i], "-nocdata")) ||
2566
154k
                   (!strcmp(argv[i], "--nocdata"))) {
2567
4.79k
            lint->parseOptions |= XML_PARSE_NOCDATA;
2568
149k
        } else if ((!strcmp(argv[i], "-nodict")) ||
2569
149k
                   (!strcmp(argv[i], "--nodict"))) {
2570
4.19k
            lint->parseOptions |= XML_PARSE_NODICT;
2571
145k
        } else if ((!strcmp(argv[i], "-version")) ||
2572
145k
                   (!strcmp(argv[i], "--version"))) {
2573
2.84k
            showVersion(errStream, argv[0]);
2574
2.84k
            lint->version = 1;
2575
142k
        } else if ((!strcmp(argv[i], "-noout")) ||
2576
142k
                   (!strcmp(argv[i], "--noout"))) {
2577
4.44k
            lint->noout = 1;
2578
4.44k
#ifdef LIBXML_HTML_ENABLED
2579
138k
        } else if ((!strcmp(argv[i], "-html")) ||
2580
138k
                   (!strcmp(argv[i], "--html"))) {
2581
1.42k
            lint->appOptions |= XML_LINT_HTML_ENABLED;
2582
136k
        } else if ((!strcmp(argv[i], "-nodefdtd")) ||
2583
136k
                   (!strcmp(argv[i], "--nodefdtd"))) {
2584
2.79k
            lint->htmlOptions |= HTML_PARSE_NODEFDTD;
2585
2.79k
#ifdef LIBXML_OUTPUT_ENABLED
2586
134k
        } else if ((!strcmp(argv[i], "-xmlout")) ||
2587
134k
                   (!strcmp(argv[i], "--xmlout"))) {
2588
2.98k
            lint->appOptions |= XML_LINT_XML_OUT;
2589
2.98k
#endif
2590
2.98k
#endif /* LIBXML_HTML_ENABLED */
2591
131k
        } else if ((!strcmp(argv[i], "-loaddtd")) ||
2592
131k
                   (!strcmp(argv[i], "--loaddtd"))) {
2593
3.87k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2594
127k
        } else if ((!strcmp(argv[i], "-dtdattr")) ||
2595
127k
                   (!strcmp(argv[i], "--dtdattr"))) {
2596
4.78k
            lint->parseOptions |= XML_PARSE_DTDATTR;
2597
4.78k
#ifdef LIBXML_VALID_ENABLED
2598
122k
        } else if ((!strcmp(argv[i], "-valid")) ||
2599
122k
                   (!strcmp(argv[i], "--valid"))) {
2600
2.92k
            lint->parseOptions |= XML_PARSE_DTDVALID;
2601
119k
        } else if ((!strcmp(argv[i], "-postvalid")) ||
2602
119k
                   (!strcmp(argv[i], "--postvalid"))) {
2603
1.71k
            lint->appOptions |= XML_LINT_POST_VALIDATION;
2604
1.71k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2605
117k
        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
2606
117k
                   (!strcmp(argv[i], "--dtdvalid"))) {
2607
0
            i++;
2608
0
            lint->dtdvalid = argv[i];
2609
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2610
117k
        } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2611
117k
                   (!strcmp(argv[i], "--dtdvalidfpi"))) {
2612
0
            i++;
2613
0
            lint->dtdvalidfpi = argv[i];
2614
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2615
117k
        } else if ((!strcmp(argv[i], "-insert")) ||
2616
117k
                   (!strcmp(argv[i], "--insert"))) {
2617
5.72k
            lint->appOptions |= XML_LINT_VALID_INSERTIONS;
2618
5.72k
#endif /* LIBXML_VALID_ENABLED */
2619
112k
        } else if ((!strcmp(argv[i], "-strict-namespace")) ||
2620
112k
            (!strcmp(argv[i], "--strict-namespace"))) {
2621
0
            lint->appOptions |= XML_LINT_STRICT_NAMESPACE;
2622
112k
        } else if ((!strcmp(argv[i], "-dropdtd")) ||
2623
112k
                   (!strcmp(argv[i], "--dropdtd"))) {
2624
1.64k
            lint->appOptions |= XML_LINT_DROP_DTD;
2625
110k
        } else if ((!strcmp(argv[i], "-quiet")) ||
2626
110k
                   (!strcmp(argv[i], "--quiet"))) {
2627
1.45k
            lint->appOptions |= XML_LINT_QUIET;
2628
108k
        } else if ((!strcmp(argv[i], "-timing")) ||
2629
108k
                   (!strcmp(argv[i], "--timing"))) {
2630
3.05k
            lint->appOptions |= XML_LINT_TIMINGS;
2631
105k
        } else if ((!strcmp(argv[i], "-auto")) ||
2632
105k
                   (!strcmp(argv[i], "--auto"))) {
2633
10.5k
            lint->appOptions |= XML_LINT_GENERATE;
2634
95.3k
        } else if ((!strcmp(argv[i], "-repeat")) ||
2635
95.3k
                   (!strcmp(argv[i], "--repeat"))) {
2636
1.15k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2637
1.15k
            lint->repeat = 2;
2638
#else
2639
            if (lint->repeat > 1)
2640
                lint->repeat *= 10;
2641
            else
2642
                lint->repeat = 100;
2643
#endif
2644
1.15k
#ifdef LIBXML_PUSH_ENABLED
2645
94.1k
        } else if ((!strcmp(argv[i], "-push")) ||
2646
94.1k
                   (!strcmp(argv[i], "--push"))) {
2647
520
            lint->appOptions |= XML_LINT_PUSH_ENABLED;
2648
520
#endif /* LIBXML_PUSH_ENABLED */
2649
520
#if HAVE_DECL_MMAP
2650
93.6k
        } else if ((!strcmp(argv[i], "-memory")) ||
2651
93.6k
                   (!strcmp(argv[i], "--memory"))) {
2652
0
            lint->appOptions |= XML_LINT_MEMORY;
2653
0
#endif
2654
0
#ifdef LIBXML_XINCLUDE_ENABLED
2655
93.6k
        } else if ((!strcmp(argv[i], "-xinclude")) ||
2656
93.6k
                   (!strcmp(argv[i], "--xinclude"))) {
2657
3.98k
            lint->appOptions |= XML_LINT_XINCLUDE;
2658
3.98k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2659
89.6k
        } else if ((!strcmp(argv[i], "-noxincludenode")) ||
2660
89.6k
                   (!strcmp(argv[i], "--noxincludenode"))) {
2661
5.32k
            lint->appOptions |= XML_LINT_XINCLUDE;
2662
5.32k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2663
5.32k
            lint->parseOptions |= XML_PARSE_NOXINCNODE;
2664
84.3k
        } else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
2665
84.3k
                   (!strcmp(argv[i], "--nofixup-base-uris"))) {
2666
3.74k
            lint->appOptions |= XML_LINT_XINCLUDE;
2667
3.74k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2668
3.74k
            lint->parseOptions |= XML_PARSE_NOBASEFIX;
2669
3.74k
#endif
2670
80.6k
        } else if ((!strcmp(argv[i], "-nowarning")) ||
2671
80.6k
                   (!strcmp(argv[i], "--nowarning"))) {
2672
5.03k
            lint->parseOptions |= XML_PARSE_NOWARNING;
2673
5.03k
            lint->parseOptions &= ~XML_PARSE_PEDANTIC;
2674
5.03k
#ifdef LIBXML_HTML_ENABLED
2675
5.03k
            lint->htmlOptions |= HTML_PARSE_NOWARNING;
2676
5.03k
#endif
2677
75.5k
        } else if ((!strcmp(argv[i], "-pedantic")) ||
2678
75.5k
                   (!strcmp(argv[i], "--pedantic"))) {
2679
1.57k
            lint->parseOptions |= XML_PARSE_PEDANTIC;
2680
1.57k
            lint->parseOptions &= ~XML_PARSE_NOWARNING;
2681
1.57k
#ifdef LIBXML_CATALOG_ENABLED
2682
73.9k
        } else if ((!strcmp(argv[i], "-catalogs")) ||
2683
73.9k
                   (!strcmp(argv[i], "--catalogs"))) {
2684
0
            lint->appOptions |= XML_LINT_USE_CATALOGS;
2685
73.9k
        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
2686
73.9k
                   (!strcmp(argv[i], "--nocatalogs"))) {
2687
11.3k
            lint->appOptions |= XML_LINT_USE_NO_CATALOGS;
2688
11.3k
            lint->parseOptions |= XML_PARSE_NO_SYS_CATALOG;
2689
11.3k
#endif
2690
62.6k
        } else if ((!strcmp(argv[i], "-noblanks")) ||
2691
62.6k
                   (!strcmp(argv[i], "--noblanks"))) {
2692
3.27k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2693
3.27k
#ifdef LIBXML_HTML_ENABLED
2694
3.27k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2695
3.27k
#endif
2696
3.27k
#ifdef LIBXML_OUTPUT_ENABLED
2697
59.3k
        } else if ((!strcmp(argv[i], "-o")) ||
2698
59.3k
                   (!strcmp(argv[i], "-output")) ||
2699
59.3k
                   (!strcmp(argv[i], "--output"))) {
2700
0
            i++;
2701
0
            lint->output = argv[i];
2702
59.3k
        } else if ((!strcmp(argv[i], "-format")) ||
2703
59.3k
                   (!strcmp(argv[i], "--format"))) {
2704
5.80k
            lint->format = 1;
2705
5.80k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2706
5.80k
#ifdef LIBXML_HTML_ENABLED
2707
5.80k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2708
5.80k
#endif
2709
53.5k
        } else if ((!strcmp(argv[i], "-encode")) ||
2710
53.5k
                   (!strcmp(argv[i], "--encode"))) {
2711
488
            i++;
2712
488
            lint->encoding = argv[i];
2713
53.0k
        } else if ((!strcmp(argv[i], "-pretty")) ||
2714
53.0k
                   (!strcmp(argv[i], "--pretty"))) {
2715
4.67k
            i++;
2716
4.67k
            if (i >= argc) {
2717
0
                fprintf(errStream, "pretty: missing integer value\n");
2718
0
                return(XMLLINT_ERR_UNCLASS);
2719
0
            }
2720
4.67k
            if (parseInteger(&val, errStream, "pretty", argv[i],
2721
4.67k
                             0, 2) < 0)
2722
22
                return(XMLLINT_ERR_UNCLASS);
2723
4.64k
            lint->format = val;
2724
4.64k
#ifdef LIBXML_ZLIB_ENABLED
2725
48.3k
        } else if ((!strcmp(argv[i], "-compress")) ||
2726
48.3k
                   (!strcmp(argv[i], "--compress"))) {
2727
2.17k
            lint->appOptions |= XML_LINT_ZLIB_COMPRESSION;
2728
2.17k
#endif
2729
2.17k
#ifdef LIBXML_C14N_ENABLED
2730
46.2k
        } else if ((!strcmp(argv[i], "-c14n")) ||
2731
46.2k
                   (!strcmp(argv[i], "--c14n"))) {
2732
3.03k
            lint->appOptions |= XML_LINT_CANONICAL_V1_0;
2733
3.03k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2734
43.1k
        } else if ((!strcmp(argv[i], "-c14n11")) ||
2735
43.1k
                   (!strcmp(argv[i], "--c14n11"))) {
2736
5.46k
            lint->appOptions |= XML_LINT_CANONICAL_V1_1;
2737
5.46k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2738
37.7k
        } else if ((!strcmp(argv[i], "-exc-c14n")) ||
2739
37.7k
                   (!strcmp(argv[i], "--exc-c14n"))) {
2740
3.80k
            lint->appOptions |= XML_LINT_CANONICAL_EXE;
2741
3.80k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2742
3.80k
#endif /* LIBXML_C14N_ENABLED */
2743
3.80k
#endif /* LIBXML_OUTPUT_ENABLED */
2744
3.80k
#ifdef LIBXML_READER_ENABLED
2745
33.9k
        } else if ((!strcmp(argv[i], "-stream")) ||
2746
33.9k
                   (!strcmp(argv[i], "--stream"))) {
2747
3.08k
             lint->appOptions |= XML_LINT_USE_STREAMING;
2748
30.8k
        } else if ((!strcmp(argv[i], "-walker")) ||
2749
30.8k
                   (!strcmp(argv[i], "--walker"))) {
2750
3.19k
             lint->appOptions |= XML_LINT_USE_WALKER;
2751
3.19k
             lint->noout = 1;
2752
3.19k
#ifdef LIBXML_PATTERN_ENABLED
2753
27.6k
        } else if ((!strcmp(argv[i], "-pattern")) ||
2754
27.6k
                   (!strcmp(argv[i], "--pattern"))) {
2755
1.70k
            i++;
2756
1.70k
            lint->pattern = argv[i];
2757
1.70k
#endif
2758
1.70k
#endif /* LIBXML_READER_ENABLED */
2759
1.70k
#ifdef LIBXML_SAX1_ENABLED
2760
25.9k
        } else if ((!strcmp(argv[i], "-sax1")) ||
2761
25.9k
                   (!strcmp(argv[i], "--sax1"))) {
2762
752
            lint->parseOptions |= XML_PARSE_SAX1;
2763
752
#endif /* LIBXML_SAX1_ENABLED */
2764
25.1k
        } else if ((!strcmp(argv[i], "-sax")) ||
2765
25.1k
                   (!strcmp(argv[i], "--sax"))) {
2766
594
            lint->appOptions |= XML_LINT_SAX_ENABLED;
2767
594
#ifdef LIBXML_RELAXNG_ENABLED
2768
24.5k
        } else if ((!strcmp(argv[i], "-relaxng")) ||
2769
24.5k
                   (!strcmp(argv[i], "--relaxng"))) {
2770
0
            i++;
2771
0
            lint->relaxng = argv[i];
2772
0
            lint->parseOptions |= XML_PARSE_NOENT;
2773
0
#endif
2774
0
#ifdef LIBXML_SCHEMAS_ENABLED
2775
24.5k
        } else if ((!strcmp(argv[i], "-schema")) ||
2776
24.5k
                 (!strcmp(argv[i], "--schema"))) {
2777
0
            i++;
2778
0
            lint->schema = argv[i];
2779
0
            lint->parseOptions |= XML_PARSE_NOENT;
2780
0
#endif
2781
#ifdef LIBXML_SCHEMATRON_ENABLED
2782
        } else if ((!strcmp(argv[i], "-schematron")) ||
2783
                   (!strcmp(argv[i], "--schematron"))) {
2784
            i++;
2785
            lint->schematron = argv[i];
2786
            lint->parseOptions |= XML_PARSE_NOENT;
2787
#endif
2788
24.5k
        } else if ((!strcmp(argv[i], "-nonet")) ||
2789
24.5k
                   (!strcmp(argv[i], "--nonet"))) {
2790
3.02k
            lint->parseOptions |= XML_PARSE_NONET;
2791
21.5k
        } else if ((!strcmp(argv[i], "-nocompact")) ||
2792
21.5k
                   (!strcmp(argv[i], "--nocompact"))) {
2793
3.99k
            lint->parseOptions &= ~XML_PARSE_COMPACT;
2794
3.99k
#ifdef LIBXML_HTML_ENABLED
2795
3.99k
            lint->htmlOptions &= ~HTML_PARSE_COMPACT;
2796
3.99k
#endif
2797
17.5k
        } else if ((!strcmp(argv[i], "-load-trace")) ||
2798
17.5k
                   (!strcmp(argv[i], "--load-trace"))) {
2799
3.86k
            lint->appOptions |= XML_LINT_USE_LOAD_TRACE;
2800
13.6k
        } else if ((!strcmp(argv[i], "-path")) ||
2801
13.6k
                   (!strcmp(argv[i], "--path"))) {
2802
0
            i++;
2803
0
            parsePath(lint, BAD_CAST argv[i]);
2804
0
#ifdef LIBXML_XPATH_ENABLED
2805
13.6k
        } else if ((!strcmp(argv[i], "-xpath")) ||
2806
13.6k
                   (!strcmp(argv[i], "--xpath"))) {
2807
9.28k
            i++;
2808
9.28k
            lint->noout++;
2809
9.28k
            lint->xpathquery = argv[i];
2810
9.28k
#endif
2811
9.28k
        } else if ((!strcmp(argv[i], "-oldxml10")) ||
2812
4.41k
                   (!strcmp(argv[i], "--oldxml10"))) {
2813
3.44k
            lint->parseOptions |= XML_PARSE_OLD10;
2814
3.44k
        } else if ((!strcmp(argv[i], "-max-ampl")) ||
2815
971
                   (!strcmp(argv[i], "--max-ampl"))) {
2816
848
            i++;
2817
848
            if (i >= argc) {
2818
0
                fprintf(errStream, "max-ampl: missing integer value\n");
2819
0
                return(XMLLINT_ERR_UNCLASS);
2820
0
            }
2821
848
            if (parseInteger(&val, errStream, "max-ampl", argv[i],
2822
848
                             1, UINT_MAX) < 0)
2823
0
                return(XMLLINT_ERR_UNCLASS);
2824
848
            lint->maxAmpl = val;
2825
848
        } else {
2826
123
            fprintf(errStream, "Unknown option %s\n", argv[i]);
2827
123
            usage(errStream, argv[0]);
2828
123
            return(XMLLINT_ERR_UNCLASS);
2829
123
        }
2830
176k
    }
2831
2832
11.2k
    if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2833
0
        lint->repeat = 1;
2834
2835
11.2k
#ifdef LIBXML_READER_ENABLED
2836
11.2k
    if (lint->appOptions & XML_LINT_USE_STREAMING) {
2837
3.08k
        specialMode = "--stream";
2838
2839
3.08k
        if (lint->appOptions & XML_LINT_SAX_ENABLED)
2840
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--sax");
2841
3.08k
#ifdef LIBXML_PUSH_ENABLED
2842
3.08k
        if (lint->appOptions & XML_LINT_PUSH_ENABLED)
2843
355
            xmllintOptWarnNoSupport(errStream, "--stream", "--push");
2844
3.08k
#endif
2845
3.08k
#ifdef LIBXML_HTML_ENABLED
2846
3.08k
        if (lint->appOptions & XML_LINT_HTML_ENABLED)
2847
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--html");
2848
3.08k
#endif
2849
3.08k
    }
2850
11.2k
#endif /* LIBXML_READER_ENABLED */
2851
2852
11.2k
    if (lint->appOptions & XML_LINT_SAX_ENABLED) {
2853
593
        specialMode = "--sax";
2854
2855
593
#ifdef LIBXML_XINCLUDE_ENABLED
2856
593
        if (lint->appOptions & XML_LINT_XINCLUDE)
2857
537
            xmllintOptWarnNoSupport(errStream, "--sax", "--xinclude");
2858
593
#endif
2859
593
#ifdef LIBXML_RELAXNG_ENABLED
2860
593
        if (lint->relaxng != NULL)
2861
0
            xmllintOptWarnNoSupport(errStream, "--sax", "--relaxng");
2862
593
#endif
2863
593
    }
2864
2865
11.2k
    if (specialMode != NULL) {
2866
3.67k
        if (lint->appOptions & XML_LINT_GENERATE)
2867
3.52k
            xmllintOptWarnNoSupport(errStream, specialMode, "--auto");
2868
3.67k
        if (lint->appOptions & XML_LINT_DROP_DTD)
2869
479
            xmllintOptWarnNoSupport(errStream, specialMode, "--dropdtd");
2870
3.67k
        if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2871
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--shell");
2872
3.67k
        if (lint->appOptions & XML_LINT_COPY_ENABLED)
2873
1.05k
            xmllintOptWarnNoSupport(errStream, specialMode, "--copy");
2874
3.67k
#ifdef LIBXML_XPATH_ENABLED
2875
3.67k
        if (lint->xpathquery != NULL)
2876
3.03k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xpath");
2877
3.67k
#endif
2878
3.67k
#ifdef LIBXML_READER_ENABLED
2879
3.67k
        if (lint->appOptions & XML_LINT_USE_WALKER)
2880
1.36k
            xmllintOptWarnNoSupport(errStream, specialMode, "--walker");
2881
3.67k
#endif
2882
3.67k
#ifdef LIBXML_VALID_ENABLED
2883
3.67k
        if (lint->appOptions & XML_LINT_VALID_INSERTIONS)
2884
1.87k
            xmllintOptWarnNoSupport(errStream, specialMode, "--insert");
2885
3.67k
        if (lint->dtdvalid != NULL)
2886
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalid");
2887
3.67k
        if (lint->dtdvalidfpi != NULL)
2888
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalidfpi");
2889
3.67k
        if (lint->appOptions & XML_LINT_POST_VALIDATION)
2890
668
            xmllintOptWarnNoSupport(errStream, specialMode, "--postvalid");
2891
3.67k
#endif
2892
#ifdef LIBXML_SCHEMATRON_ENABLED
2893
        if (lint->schematron != NULL)
2894
            xmllintOptWarnNoSupport(errStream, specialMode, "--schematron");
2895
#endif
2896
3.67k
#ifdef LIBXML_OUTPUT_ENABLED
2897
3.67k
        if (lint->output != NULL)
2898
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--output");
2899
3.67k
        if (lint->encoding != NULL)
2900
173
            xmllintOptWarnNoSupport(errStream, specialMode, "--encode");
2901
3.67k
        if (lint->format > 0)
2902
2.04k
            xmllintOptWarnNoSupport(errStream, specialMode,
2903
2.04k
                                    "--format or -pretty");
2904
3.67k
#ifdef LIBXML_ZLIB_ENABLED
2905
3.67k
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
2906
754
            xmllintOptWarnNoSupport(errStream, specialMode, "--compress");
2907
3.67k
#endif
2908
3.67k
#ifdef LIBXML_HTML_ENABLED
2909
3.67k
        if (lint->appOptions & XML_LINT_XML_OUT)
2910
1.11k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xmlout");
2911
3.67k
#endif
2912
3.67k
#ifdef LIBXML_C14N_ENABLED
2913
3.67k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_0)
2914
1.06k
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n");
2915
3.67k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_1)
2916
1.81k
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n11");
2917
3.67k
        if (lint->appOptions & XML_LINT_CANONICAL_EXE)
2918
1.19k
            xmllintOptWarnNoSupport(errStream, specialMode, "--exc-c14n");
2919
3.67k
#endif
2920
3.67k
#endif /* LIBXML_OUTPUT_ENABLED */
2921
3.67k
    }
2922
2923
11.2k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2924
11.2k
    if (lint->pattern && !((lint->appOptions & XML_LINT_USE_STREAMING) || (lint->appOptions & XML_LINT_USE_WALKER)))
2925
775
        fprintf(errStream, "Warning: Option %s requires %s\n",
2926
775
                "--pattern", "--stream or --walker");
2927
11.2k
#endif
2928
2929
11.2k
#ifdef LIBXML_HTML_ENABLED
2930
11.2k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
2931
1.42k
        if (lint->parseOptions & XML_PARSE_DTDATTR)
2932
1.26k
            xmllintOptWarnNoSupport(errStream, "--html", "--dtdattr");
2933
1.42k
        if (lint->parseOptions & XML_PARSE_DTDLOAD)
2934
1.27k
            xmllintOptWarnNoSupport(errStream, "--html", "--loaddtd");
2935
1.42k
        if (lint->maxAmpl)
2936
165
            xmllintOptWarnNoSupport(errStream, "--html", "--max-ampl");
2937
1.42k
        if (lint->parseOptions & XML_PARSE_NOCDATA)
2938
669
            xmllintOptWarnNoSupport(errStream, "--html", "--nocdata");
2939
1.42k
        if (lint->parseOptions & XML_PARSE_NODICT)
2940
400
            xmllintOptWarnNoSupport(errStream, "--html", "--nodict");
2941
1.42k
        if (lint->parseOptions & XML_PARSE_NOENT)
2942
1.23k
            xmllintOptWarnNoSupport(errStream, "--html", "--noent");
2943
1.42k
        if (lint->parseOptions & XML_PARSE_NONET)
2944
461
            xmllintOptWarnNoSupport(errStream, "--html", "--nonet");
2945
1.42k
        if (lint->parseOptions & XML_PARSE_NSCLEAN)
2946
507
            xmllintOptWarnNoSupport(errStream, "--html", "--nsclean");
2947
1.42k
        if (lint->parseOptions & XML_PARSE_OLD10)
2948
428
            xmllintOptWarnNoSupport(errStream, "--html", "--oldxml10");
2949
1.42k
        if (lint->parseOptions & XML_PARSE_PEDANTIC)
2950
184
            xmllintOptWarnNoSupport(errStream, "--html", "--pedantic");
2951
1.42k
        if (lint->parseOptions & XML_PARSE_DTDVALID)
2952
809
            xmllintOptWarnNoSupport(errStream, "--html", "--valid");
2953
1.42k
        if (lint->parseOptions & XML_PARSE_SAX1)
2954
107
            xmllintOptWarnNoSupport(errStream, "--html", "--sax1");
2955
9.79k
    } else {
2956
9.79k
        if (lint->htmlOptions & HTML_PARSE_NODEFDTD)
2957
2.44k
            fprintf(errStream, "Warning: Option %s requires %s\n",
2958
2.44k
                    "--nodefdtd", "--html");
2959
9.79k
#ifdef LIBXML_OUTPUT_ENABLED
2960
9.79k
        if (lint->appOptions & XML_LINT_XML_OUT)
2961
2.12k
            fprintf(errStream, "Warning: Option %s requires %s\n",
2962
2.12k
                    "--xmlout", "--html");
2963
9.79k
#endif
2964
9.79k
    }
2965
11.2k
#endif
2966
2967
11.2k
    return(XMLLINT_RETURN_OK);
2968
11.3k
}
2969
2970
int
2971
xmllintMain(int argc, const char **argv, FILE *errStream,
2972
11.3k
            xmlResourceLoader loader) {
2973
11.3k
    xmllintState state, *lint;
2974
11.3k
    int i, j, res;
2975
11.3k
    int files = 0;
2976
2977
#ifdef _WIN32
2978
    _setmode(_fileno(stdin), _O_BINARY);
2979
    _setmode(_fileno(stdout), _O_BINARY);
2980
    _setmode(_fileno(stderr), _O_BINARY);
2981
#endif
2982
2983
11.3k
    lint = &state;
2984
11.3k
    xmllintInit(lint);
2985
11.3k
    lint->errStream = errStream;
2986
11.3k
    lint->defaultResourceLoader = loader;
2987
2988
11.3k
    res = xmllintParseOptions(lint, argc, argv);
2989
11.3k
    if (res != XMLLINT_RETURN_OK) {
2990
145
        return(res);
2991
145
    }
2992
2993
    /*
2994
     * Note that we must not make any memory allocations through xmlMalloc
2995
     * before calling xmlMemSetup.
2996
     */
2997
11.2k
    if (lint->maxmem != 0) {
2998
311
        xmllintMaxmem = 0;
2999
311
        xmllintMaxmemReached = 0;
3000
311
        xmllintOom = 0;
3001
311
        xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
3002
311
    }
3003
3004
11.2k
    LIBXML_TEST_VERSION
3005
3006
11.2k
#ifdef LIBXML_CATALOG_ENABLED
3007
11.2k
    if ((lint->appOptions & XML_LINT_USE_NO_CATALOGS) != XML_LINT_USE_NO_CATALOGS) {
3008
0
  if (lint->appOptions & XML_LINT_USE_CATALOGS) {
3009
0
      const char *catal;
3010
3011
0
      catal = getenv("SGML_CATALOG_FILES");
3012
0
      if (catal != NULL) {
3013
0
    xmlLoadCatalogs(catal);
3014
0
      } else {
3015
0
    fprintf(errStream, "Variable $SGML_CATALOG_FILES not set\n");
3016
0
      }
3017
0
  }
3018
0
    }
3019
11.2k
#endif
3020
3021
11.2k
#ifdef LIBXML_OUTPUT_ENABLED
3022
11.2k
    {
3023
11.2k
        const char *indent = getenv("XMLLINT_INDENT");
3024
11.2k
        if (indent != NULL) {
3025
0
            lint->indentString = indent;
3026
0
        }
3027
11.2k
    }
3028
11.2k
#endif
3029
3030
#ifdef LIBXML_SCHEMATRON_ENABLED
3031
    if ((lint->schematron != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED)
3032
#ifdef LIBXML_READER_ENABLED
3033
        && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3034
#endif /* LIBXML_READER_ENABLED */
3035
  ) {
3036
  xmlSchematronParserCtxtPtr ctxt;
3037
3038
        /* forces loading the DTDs */
3039
  lint->parseOptions |= XML_PARSE_DTDLOAD;
3040
  if (lint->appOptions & XML_LINT_TIMINGS) {
3041
      startTimer(lint);
3042
  }
3043
  ctxt = xmlSchematronNewParserCtxt(lint->schematron);
3044
        if (ctxt == NULL) {
3045
            lint->progresult = XMLLINT_ERR_MEM;
3046
            goto error;
3047
        }
3048
  lint->wxschematron = xmlSchematronParse(ctxt);
3049
  xmlSchematronFreeParserCtxt(ctxt);
3050
  if (lint->wxschematron == NULL) {
3051
      fprintf(errStream, "Schematron schema %s failed to compile\n",
3052
                    lint->schematron);
3053
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
3054
            goto error;
3055
  }
3056
  if (lint->appOptions & XML_LINT_TIMINGS) {
3057
      endTimer(lint, "Compiling the schemas");
3058
  }
3059
    }
3060
#endif
3061
3062
11.2k
#ifdef LIBXML_RELAXNG_ENABLED
3063
11.2k
    if ((lint->relaxng != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED)
3064
0
#ifdef LIBXML_READER_ENABLED
3065
0
        && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3066
11.2k
#endif /* LIBXML_READER_ENABLED */
3067
11.2k
  ) {
3068
0
  xmlRelaxNGParserCtxtPtr ctxt;
3069
3070
        /* forces loading the DTDs */
3071
0
  lint->parseOptions |= XML_PARSE_DTDLOAD;
3072
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3073
0
      startTimer(lint);
3074
0
  }
3075
0
  ctxt = xmlRelaxNGNewParserCtxt(lint->relaxng);
3076
0
        if (ctxt == NULL) {
3077
0
            lint->progresult = XMLLINT_ERR_MEM;
3078
0
            goto error;
3079
0
        }
3080
0
        xmlRelaxNGSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3081
0
  lint->relaxngschemas = xmlRelaxNGParse(ctxt);
3082
0
  xmlRelaxNGFreeParserCtxt(ctxt);
3083
0
  if (lint->relaxngschemas == NULL) {
3084
0
      fprintf(errStream, "Relax-NG schema %s failed to compile\n",
3085
0
                    lint->relaxng);
3086
0
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
3087
0
            goto error;
3088
0
  }
3089
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3090
0
      endTimer(lint, "Compiling the schemas");
3091
0
  }
3092
0
    }
3093
11.2k
#endif /* LIBXML_RELAXNG_ENABLED */
3094
3095
11.2k
#ifdef LIBXML_SCHEMAS_ENABLED
3096
11.2k
    if ((lint->schema != NULL)
3097
0
#ifdef LIBXML_READER_ENABLED
3098
0
        && ((lint->appOptions& XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3099
11.2k
#endif
3100
11.2k
  ) {
3101
0
  xmlSchemaParserCtxtPtr ctxt;
3102
3103
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3104
0
      startTimer(lint);
3105
0
  }
3106
0
  ctxt = xmlSchemaNewParserCtxt(lint->schema);
3107
0
        if (ctxt == NULL) {
3108
0
            lint->progresult = XMLLINT_ERR_MEM;
3109
0
            goto error;
3110
0
        }
3111
0
        xmlSchemaSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3112
0
  lint->wxschemas = xmlSchemaParse(ctxt);
3113
0
  xmlSchemaFreeParserCtxt(ctxt);
3114
0
  if (lint->wxschemas == NULL) {
3115
0
      fprintf(errStream, "WXS schema %s failed to compile\n",
3116
0
                    lint->schema);
3117
0
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
3118
0
            goto error;
3119
0
  }
3120
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3121
0
      endTimer(lint, "Compiling the schemas");
3122
0
  }
3123
0
    }
3124
11.2k
#endif /* LIBXML_SCHEMAS_ENABLED */
3125
3126
11.2k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3127
11.2k
    if ((lint->pattern != NULL) && ((lint->appOptions & XML_LINT_USE_WALKER) != XML_LINT_USE_WALKER)) {
3128
1.02k
        res = xmlPatternCompileSafe(BAD_CAST lint->pattern, NULL, 0, NULL,
3129
1.02k
                                    &lint->patternc);
3130
1.02k
  if (lint->patternc == NULL) {
3131
535
            if (res < 0) {
3132
39
                lint->progresult = XMLLINT_ERR_MEM;
3133
496
            } else {
3134
496
                fprintf(errStream, "Pattern %s failed to compile\n",
3135
496
                        lint->pattern);
3136
496
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
3137
496
            }
3138
535
            goto error;
3139
535
  }
3140
1.02k
    }
3141
10.6k
#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
3142
3143
    /*
3144
     * The main loop over input documents
3145
     */
3146
188k
    for (i = 1; i < argc ; i++) {
3147
178k
        const char *filename = argv[i];
3148
178k
#if HAVE_DECL_MMAP
3149
178k
        int memoryFd = -1;
3150
178k
#endif
3151
3152
178k
  if ((filename[0] == '-') && (strcmp(filename, "-") != 0)) {
3153
167k
            i += skipArgs(filename);
3154
167k
            continue;
3155
167k
        }
3156
3157
10.6k
#if HAVE_DECL_MMAP
3158
10.6k
        if (lint->appOptions & XML_LINT_MEMORY) {
3159
0
            struct stat info;
3160
0
            if (stat(filename, &info) < 0) {
3161
0
                lint->progresult = XMLLINT_ERR_RDFILE;
3162
0
                break;
3163
0
            }
3164
0
            memoryFd = open(filename, O_RDONLY);
3165
0
            if (memoryFd < 0) {
3166
0
                lint->progresult = XMLLINT_ERR_RDFILE;
3167
0
                break;
3168
0
            }
3169
0
            lint->memoryData = mmap(NULL, info.st_size, PROT_READ,
3170
0
                                    MAP_SHARED, memoryFd, 0);
3171
0
            if (lint->memoryData == (void *) MAP_FAILED) {
3172
0
                close(memoryFd);
3173
0
                fprintf(errStream, "mmap failure for file %s\n", filename);
3174
0
                lint->progresult = XMLLINT_ERR_RDFILE;
3175
0
                break;
3176
0
            }
3177
0
            lint->memorySize = info.st_size;
3178
0
        }
3179
10.6k
#endif /* HAVE_DECL_MMAP */
3180
3181
10.6k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1))
3182
390
      startTimer(lint);
3183
3184
10.6k
#ifdef LIBXML_READER_ENABLED
3185
10.6k
        if (lint->appOptions & XML_LINT_USE_STREAMING) {
3186
6.26k
            for (j = 0; j < lint->repeat; j++)
3187
3.32k
                streamFile(lint, filename);
3188
2.94k
        } else
3189
7.73k
#endif /* LIBXML_READER_ENABLED */
3190
7.73k
        {
3191
7.73k
            xmlParserCtxtPtr ctxt;
3192
3193
7.73k
#ifdef LIBXML_HTML_ENABLED
3194
7.73k
            if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3195
1.41k
#ifdef LIBXML_PUSH_ENABLED
3196
1.41k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3197
12
                    ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3198
12
                                                    filename,
3199
12
                                                    XML_CHAR_ENCODING_NONE);
3200
12
                } else
3201
1.40k
#endif /* LIBXML_PUSH_ENABLED */
3202
1.40k
                {
3203
1.40k
                    ctxt = htmlNewParserCtxt();
3204
1.40k
                }
3205
1.41k
                htmlCtxtUseOptions(ctxt, lint->htmlOptions);
3206
1.41k
            } else
3207
6.32k
#endif /* LIBXML_HTML_ENABLED */
3208
6.32k
            {
3209
6.32k
#ifdef LIBXML_PUSH_ENABLED
3210
6.32k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3211
38
                    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3212
38
                                                   filename);
3213
38
                } else
3214
6.28k
#endif /* LIBXML_PUSH_ENABLED */
3215
6.28k
                {
3216
6.28k
                    ctxt = xmlNewParserCtxt();
3217
6.28k
                }
3218
6.32k
                xmlCtxtUseOptions(ctxt, lint->parseOptions);
3219
6.32k
            }
3220
7.73k
            if (ctxt == NULL) {
3221
234
                lint->progresult = XMLLINT_ERR_MEM;
3222
234
                goto error;
3223
234
            }
3224
3225
7.50k
            if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3226
568
                const xmlSAXHandler *handler;
3227
3228
568
                if (lint->noout) {
3229
526
                    handler = &emptySAXHandler;
3230
526
#ifdef LIBXML_SAX1_ENABLED
3231
526
                } else if (lint->parseOptions & XML_PARSE_SAX1) {
3232
13
                    handler = &debugSAXHandler;
3233
13
#endif
3234
29
                } else {
3235
29
                    handler = &debugSAX2Handler;
3236
29
                }
3237
3238
568
                *ctxt->sax = *handler;
3239
568
                ctxt->userData = lint;
3240
568
            }
3241
3242
7.50k
            xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3243
7.50k
            if (lint->maxAmpl > 0)
3244
534
                xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl);
3245
3246
7.50k
            lint->ctxt = ctxt;
3247
3248
15.6k
            for (j = 0; j < lint->repeat; j++) {
3249
8.19k
                if (j > 0) {
3250
695
#ifdef LIBXML_PUSH_ENABLED
3251
695
                    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3252
0
                        xmlCtxtResetPush(ctxt, NULL, 0, NULL, NULL);
3253
0
                    } else
3254
695
#endif
3255
695
                    {
3256
695
                        xmlCtxtReset(ctxt);
3257
695
                    }
3258
695
                }
3259
3260
8.19k
                if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3261
676
                    testSAX(lint, filename);
3262
7.52k
                } else {
3263
7.52k
                    parseAndPrintFile(lint, filename);
3264
7.52k
                }
3265
8.19k
            }
3266
3267
7.50k
            xmlFreeParserCtxt(ctxt);
3268
7.50k
        }
3269
3270
10.4k
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) {
3271
377
            endTimer(lint, "%d iterations", lint->repeat);
3272
377
        }
3273
3274
10.4k
        files += 1;
3275
3276
10.4k
#if HAVE_DECL_MMAP
3277
10.4k
        if (lint->appOptions & XML_LINT_MEMORY) {
3278
0
            munmap(lint->memoryData, lint->memorySize);
3279
0
            close(memoryFd);
3280
0
        }
3281
10.4k
#endif
3282
10.4k
    }
3283
3284
10.4k
    if (lint->appOptions & XML_LINT_GENERATE)
3285
10.1k
  parseAndPrintFile(lint, NULL);
3286
3287
10.4k
    if ((files == 0) && ((lint->appOptions & XML_LINT_GENERATE) != XML_LINT_GENERATE) && (lint->version == 0)) {
3288
0
  usage(errStream, argv[0]);
3289
0
        lint->progresult = XMLLINT_ERR_UNCLASS;
3290
0
    }
3291
3292
11.2k
error:
3293
3294
#ifdef LIBXML_SCHEMATRON_ENABLED
3295
    if (lint->wxschematron != NULL)
3296
  xmlSchematronFree(lint->wxschematron);
3297
#endif
3298
11.2k
#ifdef LIBXML_RELAXNG_ENABLED
3299
11.2k
    if (lint->relaxngschemas != NULL)
3300
0
  xmlRelaxNGFree(lint->relaxngschemas);
3301
11.2k
#endif
3302
11.2k
#ifdef LIBXML_SCHEMAS_ENABLED
3303
11.2k
    if (lint->wxschemas != NULL)
3304
0
  xmlSchemaFree(lint->wxschemas);
3305
11.2k
#endif
3306
11.2k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3307
11.2k
    if (lint->patternc != NULL)
3308
487
        xmlFreePattern(lint->patternc);
3309
11.2k
#endif
3310
3311
11.2k
    xmlCleanupParser();
3312
3313
11.2k
    if ((lint->maxmem) && (xmllintMaxmemReached)) {
3314
309
        fprintf(errStream, "Maximum memory exceeded (%d bytes)\n",
3315
309
                xmllintMaxmem);
3316
10.9k
    } else if (lint->progresult == XMLLINT_ERR_MEM) {
3317
1.93k
        fprintf(errStream, "Out-of-memory error reported\n");
3318
1.93k
    }
3319
3320
11.2k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
3321
11.2k
    if ((lint->maxmem) &&
3322
311
        (xmllintOom != (lint->progresult == XMLLINT_ERR_MEM))) {
3323
0
        fprintf(stderr, "xmllint: malloc failure %s reported\n",
3324
0
                xmllintOom ? "not" : "erroneously");
3325
0
        abort();
3326
0
    }
3327
11.2k
#endif
3328
3329
11.2k
    return(lint->progresult);
3330
11.2k
}
3331