Coverage Report

Created: 2025-08-11 06:22

/src/libxml2/xmllint.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * xmllint.c : a small tester program for XML input.
3
 *
4
 * See Copyright for the status of this software.
5
 *
6
 * Author: Daniel Veillard
7
 */
8
9
#include "libxml.h"
10
11
#include <string.h>
12
#include <stdarg.h>
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <errno.h>
16
#include <limits.h>
17
#include <fcntl.h>
18
19
#ifdef _WIN32
20
  #include <io.h>
21
  #include <sys/timeb.h>
22
#else
23
  #include <sys/time.h>
24
  #include <unistd.h>
25
#endif
26
27
#if HAVE_DECL_MMAP
28
  #include <sys/mman.h>
29
  #include <sys/stat.h>
30
  /* seems needed for Solaris */
31
  #ifndef MAP_FAILED
32
    #define MAP_FAILED ((void *) -1)
33
  #endif
34
#endif
35
36
#include <libxml/xmlmemory.h>
37
#include <libxml/parser.h>
38
#include <libxml/parserInternals.h>
39
#include <libxml/HTMLparser.h>
40
#include <libxml/HTMLtree.h>
41
#include <libxml/tree.h>
42
#include <libxml/xpath.h>
43
#include <libxml/xpathInternals.h>
44
#include <libxml/debugXML.h>
45
#include <libxml/xmlerror.h>
46
#ifdef LIBXML_XINCLUDE_ENABLED
47
#include <libxml/xinclude.h>
48
#endif
49
#ifdef LIBXML_CATALOG_ENABLED
50
#include <libxml/catalog.h>
51
#endif
52
#include <libxml/xmlreader.h>
53
#ifdef LIBXML_SCHEMATRON_ENABLED
54
#include <libxml/schematron.h>
55
#endif
56
#ifdef LIBXML_RELAXNG_ENABLED
57
#include <libxml/relaxng.h>
58
#endif
59
#ifdef LIBXML_SCHEMAS_ENABLED
60
#include <libxml/xmlschemas.h>
61
#endif
62
#ifdef LIBXML_PATTERN_ENABLED
63
#include <libxml/pattern.h>
64
#endif
65
#ifdef LIBXML_C14N_ENABLED
66
#include <libxml/c14n.h>
67
#endif
68
#ifdef LIBXML_OUTPUT_ENABLED
69
#include <libxml/xmlsave.h>
70
#endif
71
72
#include "private/lint.h"
73
74
#ifndef STDIN_FILENO
75
  #define STDIN_FILENO 0
76
#endif
77
#ifndef STDOUT_FILENO
78
  #define STDOUT_FILENO 1
79
#endif
80
81
0
#define MAX_PATHS 64
82
83
#ifdef _WIN32
84
  #define PATH_SEPARATOR ';'
85
#else
86
0
  #define PATH_SEPARATOR ':'
87
#endif
88
89
typedef enum {
90
    XMLLINT_RETURN_OK = 0,      /* No error */
91
    XMLLINT_ERR_UNCLASS = 1,      /* Unclassified */
92
    XMLLINT_ERR_DTD = 2,      /* Error in DTD */
93
    XMLLINT_ERR_VALID = 3,      /* Validation error */
94
    XMLLINT_ERR_RDFILE = 4,     /* Wellformedness or IO error */
95
    XMLLINT_ERR_SCHEMACOMP = 5,     /* Schema compilation */
96
    XMLLINT_ERR_OUT = 6,      /* Error writing output */
97
    XMLLINT_ERR_SCHEMAPAT = 7,      /* Error in schema pattern */
98
    /*XMLLINT_ERR_RDREGIS = 8,*/
99
    XMLLINT_ERR_MEM = 9,      /* Out of memory error */
100
    XMLLINT_ERR_XPATH = 10,     /* XPath evaluation error */
101
    XMLLINT_ERR_XPATH_EMPTY = 11    /* XPath result is empty */
102
} xmllintReturnCode;
103
104
#ifdef _WIN32
105
typedef __time64_t xmlSeconds;
106
#else
107
typedef time_t xmlSeconds;
108
#endif
109
110
typedef struct {
111
   xmlSeconds sec;
112
   int usec;
113
} xmlTime;
114
115
/* Boolean xmllint application options */
116
typedef enum {
117
    /** Do not build a tree but work just at the SAX level */
118
    XML_LINT_SAX_ENABLED = (1 << 0),
119
    /** run a navigating shell */
120
    XML_LINT_NAVIGATING_SHELL = (1 << 1),
121
    /** Show additional debug information */
122
    XML_LINT_DEBUG_ENABLED = (1 << 2),
123
    /** Test the internal copy implementation */
124
    XML_LINT_COPY_ENABLED = (1 << 3),
125
    /** Turn on gzip compression of output */
126
    XML_LINT_ZLIB_COMPRESSION = (1 << 4),
127
    /** Save in W3C canonical format v1.0 (with comments) */
128
    XML_LINT_CANONICAL_V1_0 = (1 << 5),
129
    /** Save in W3C canonical format v1.1 (with comments) */
130
    XML_LINT_CANONICAL_V1_1 = (1 << 6),
131
    /** Save exclusive canonical format (with comments) */
132
    XML_LINT_CANONICAL_EXE = (1 << 7),
133
    /** Do a posteriori validation, i.e after parsing */
134
    XML_LINT_POST_VALIDATION = (1 << 8),
135
    /** Ad-hoc test for valid insertions */
136
    XML_LINT_VALID_INSERTIONS = (1 << 9),
137
    /** Use the HTML parser */
138
    XML_LINT_HTML_ENABLED = (1 << 10),
139
    /** Force to use the XML serializer when using XML_LINT_HTML_ENABLED */
140
    XML_LINT_XML_OUT = (1 << 11),
141
    /** Use the push mode of the parser */
142
    XML_LINT_PUSH_ENABLED = (1 << 12),
143
    /** Parse from memory */
144
    XML_LINT_MEMORY = (1 << 13),
145
    /** Do XInclude processing */
146
    XML_LINT_XINCLUDE = (1 << 14),
147
    /** Be quiet when succeeded */
148
    XML_LINT_QUIET = (1 << 15),
149
    /** Print some timings */
150
    XML_LINT_TIMINGS = (1 << 16),
151
    /** Generate a small doc on the fly */
152
    XML_LINT_GENERATE = (1 << 17),
153
    /** Remove the DOCTYPE of the input docs */
154
    XML_LINT_DROP_DTD = (1 << 18),
155
    /** Use the streaming interface to process very large files */
156
    XML_LINT_USE_STREAMING = (1 << 19),
157
    /** Create a reader and walk though the resulting doc */
158
    XML_LINT_USE_WALKER = (1 << 20),
159
    /** use SGML catalogs from $SGML_CATALOG_FILES */
160
    XML_LINT_USE_CATALOGS = (1 << 21),
161
    /** Deactivate all catalogs */
162
    XML_LINT_USE_NO_CATALOGS = (1 << 22),
163
    /** Print trace of all external entities loaded */
164
    XML_LINT_USE_LOAD_TRACE = (1 << 23),
165
    /** Return application failure if document has any namespace errors */
166
    XML_LINT_STRICT_NAMESPACE = (1 << 24)
167
168
169
} xmllintAppOptions;
170
171
typedef struct {
172
    FILE *errStream;
173
    xmlParserCtxtPtr ctxt;
174
    xmlResourceLoader defaultResourceLoader;
175
176
    int version;
177
    int maxmem;
178
    int callbacks;
179
    int noout;
180
#ifdef LIBXML_OUTPUT_ENABLED
181
    const char *output;
182
    const char *encoding;
183
    const char *indentString;
184
    int format;
185
#endif /* LIBXML_OUTPUT_ENABLED */
186
#ifdef LIBXML_VALID_ENABLED
187
    const char *dtdvalid;
188
    const char *dtdvalidfpi;
189
#endif
190
#ifdef LIBXML_RELAXNG_ENABLED
191
    const char *relaxng;
192
    xmlRelaxNGPtr relaxngschemas;
193
#endif
194
#ifdef LIBXML_SCHEMAS_ENABLED
195
    const char *schema;
196
    xmlSchemaPtr wxschemas;
197
#endif
198
#ifdef LIBXML_SCHEMATRON_ENABLED
199
    const char *schematron;
200
    xmlSchematronPtr wxschematron;
201
#endif
202
    int repeat;
203
#ifdef LIBXML_HTML_ENABLED
204
    int htmlOptions;
205
#endif
206
#if HAVE_DECL_MMAP
207
    char *memoryData;
208
    size_t memorySize;
209
#endif
210
    xmllintReturnCode progresult;
211
#ifdef LIBXML_READER_ENABLED
212
#ifdef LIBXML_PATTERN_ENABLED
213
    const char *pattern;
214
    xmlPatternPtr patternc;
215
    xmlStreamCtxtPtr patstream;
216
#endif
217
#endif /* LIBXML_READER_ENABLED */
218
#ifdef LIBXML_XPATH_ENABLED
219
    const char *xpathquery;
220
#endif
221
    int parseOptions;
222
    unsigned appOptions;
223
    unsigned maxAmpl;
224
225
    xmlChar *paths[MAX_PATHS + 1];
226
    int nbpaths;
227
228
    xmlTime begin;
229
    xmlTime end;
230
} xmllintState;
231
232
static int xmllintMaxmem;
233
static int xmllintMaxmemReached;
234
static int xmllintOom;
235
236
/************************************************************************
237
 *                  *
238
 *     Entity loading control and customization.    *
239
 *                  *
240
 ************************************************************************/
241
242
static void
243
0
parsePath(xmllintState *lint, const xmlChar *path) {
244
0
    const xmlChar *cur;
245
246
0
    if (path == NULL)
247
0
  return;
248
0
    while (*path != 0) {
249
0
  if (lint->nbpaths >= MAX_PATHS) {
250
0
      fprintf(lint->errStream, "MAX_PATHS reached: too many paths\n");
251
0
            lint->progresult = XMLLINT_ERR_UNCLASS;
252
0
      return;
253
0
  }
254
0
  cur = path;
255
0
  while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
256
0
      cur++;
257
0
  path = cur;
258
0
  while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
259
0
      cur++;
260
0
  if (cur != path) {
261
0
      lint->paths[lint->nbpaths] = xmlStrndup(path, cur - path);
262
0
      if (lint->paths[lint->nbpaths] != NULL)
263
0
    lint->nbpaths++;
264
0
      path = cur;
265
0
  }
266
0
    }
267
0
}
268
269
static xmlParserErrors
270
xmllintResourceLoader(void *ctxt, const char *URL,
271
                      const char *ID, xmlResourceType type,
272
7.53k
                      xmlParserInputFlags flags, xmlParserInputPtr *out) {
273
7.53k
    xmllintState *lint = ctxt;
274
7.53k
    xmlParserErrors code;
275
7.53k
    int i;
276
7.53k
    const char *lastsegment = URL;
277
7.53k
    const char *iter = URL;
278
279
7.53k
    if ((lint->nbpaths > 0) && (iter != NULL)) {
280
0
  while (*iter != 0) {
281
0
      if (*iter == '/')
282
0
    lastsegment = iter + 1;
283
0
      iter++;
284
0
  }
285
0
    }
286
287
7.53k
    if (lint->defaultResourceLoader != NULL)
288
7.53k
        code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out);
289
0
    else
290
0
        code = xmlNewInputFromUrl(URL, flags, out);
291
7.53k
    if (code != XML_IO_ENOENT) {
292
7.53k
        if ((lint->appOptions & XML_LINT_USE_LOAD_TRACE) && (code == XML_ERR_OK)) {
293
0
            fprintf(lint->errStream, "Loaded URL=\"%s\" ID=\"%s\"\n",
294
0
                    URL, ID ? ID : "(null)");
295
0
        }
296
7.53k
        return(code);
297
7.53k
    }
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.24k
parseXml(xmllintState *lint, const char *filename) {
334
6.24k
    xmlParserCtxtPtr ctxt = lint->ctxt;
335
6.24k
    xmlDocPtr doc;
336
337
6.24k
#ifdef LIBXML_PUSH_ENABLED
338
6.24k
    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.24k
#endif /* LIBXML_PUSH_ENABLED */
366
367
6.24k
#if HAVE_DECL_MMAP
368
6.24k
    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.24k
#endif
382
383
6.24k
    if (strcmp(filename, "-") == 0)
384
0
        doc = xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
385
0
                            lint->parseOptions | XML_PARSE_UNZIP);
386
6.24k
    else
387
6.24k
        doc = xmlCtxtReadFile(ctxt, filename, NULL,
388
6.24k
                              lint->parseOptions | XML_PARSE_UNZIP);
389
390
6.24k
    return(doc);
391
6.24k
}
392
393
#ifdef LIBXML_HTML_ENABLED
394
static xmlDocPtr
395
1.28k
parseHtml(xmllintState *lint, const char *filename) {
396
1.28k
    xmlParserCtxtPtr ctxt = lint->ctxt;
397
1.28k
    xmlDocPtr doc;
398
399
1.28k
#ifdef LIBXML_PUSH_ENABLED
400
1.28k
    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.28k
#endif /* LIBXML_PUSH_ENABLED */
428
429
1.28k
#if HAVE_DECL_MMAP
430
1.28k
    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.28k
#endif
444
445
1.28k
    if (strcmp(filename, "-") == 0)
446
0
        doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL,
447
0
                             lint->htmlOptions);
448
1.28k
    else
449
1.28k
        doc = htmlCtxtReadFile(ctxt, filename, NULL, lint->htmlOptions);
450
451
1.28k
    return(doc);
452
1.28k
}
453
#endif /* LIBXML_HTML_ENABLED */
454
455
/************************************************************************
456
 *                  *
457
 * Memory allocation consumption debugging        *
458
 *                  *
459
 ************************************************************************/
460
461
#define XMLLINT_ABORT_ON_FAILURE 0
462
463
static void
464
390
myFreeFunc(void *mem) {
465
390
    xmlMemFree(mem);
466
390
}
467
468
static void *
469
438
myMallocFunc(size_t size) {
470
438
    void *ret;
471
472
438
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
473
#if XMLLINT_ABORT_ON_FAILURE
474
        abort();
475
#endif
476
438
        xmllintMaxmemReached = 1;
477
438
        xmllintOom = 1;
478
438
        return(NULL);
479
438
    }
480
481
0
    ret = xmlMemMalloc(size);
482
0
    if (ret == NULL)
483
0
        xmllintOom = 1;
484
485
0
    return(ret);
486
438
}
487
488
static void *
489
0
myReallocFunc(void *mem, size_t size) {
490
0
    void *ret;
491
0
    size_t oldsize = xmlMemSize(mem);
492
493
0
    if (xmlMemUsed() + size - oldsize > (size_t) xmllintMaxmem) {
494
#if XMLLINT_ABORT_ON_FAILURE
495
        abort();
496
#endif
497
0
        xmllintMaxmemReached = 1;
498
0
        xmllintOom = 1;
499
0
        return(NULL);
500
0
    }
501
502
0
    ret = xmlMemRealloc(mem, size);
503
0
    if (ret == NULL)
504
0
        xmllintOom = 1;
505
506
0
    return(ret);
507
0
}
508
509
static char *
510
7.62k
myStrdupFunc(const char *str) {
511
7.62k
    size_t size;
512
7.62k
    char *ret;
513
514
7.62k
    if (str == NULL)
515
0
        return(NULL);
516
517
7.62k
    size = strlen(str) + 1;
518
7.62k
    if (xmlMemUsed() + size > (size_t) xmllintMaxmem) {
519
#if XMLLINT_ABORT_ON_FAILURE
520
        abort();
521
#endif
522
7.62k
        xmllintMaxmemReached = 1;
523
7.62k
        xmllintOom = 1;
524
7.62k
        return(NULL);
525
7.62k
    }
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
22.6k
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
22.6k
    struct timeval tv;
555
556
22.6k
    gettimeofday(&tv, NULL);
557
22.6k
    time->sec = tv.tv_sec;
558
22.6k
    time->usec = tv.tv_usec;
559
22.6k
#endif /* _WIN32 */
560
22.6k
}
561
562
/*
563
 * startTimer: call where you want to start timing
564
 */
565
static void
566
startTimer(xmllintState *lint)
567
12.0k
{
568
12.0k
    getTime(&lint->begin);
569
12.0k
}
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.5k
{
579
10.5k
    xmlSeconds msec;
580
10.5k
    va_list ap;
581
582
10.5k
    getTime(&lint->end);
583
10.5k
    msec = lint->end.sec - lint->begin.sec;
584
10.5k
    msec *= 1000;
585
10.5k
    msec += (lint->end.usec - lint->begin.usec) / 1000;
586
587
10.5k
    va_start(ap, fmt);
588
10.5k
    vfprintf(lint->errStream, fmt, ap);
589
10.5k
    va_end(ap);
590
591
10.5k
    fprintf(lint->errStream, " took %ld ms\n", (long) msec);
592
10.5k
}
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
97
{
1015
97
    xmllintState *lint = ctx;
1016
97
    va_list args;
1017
1018
97
    lint->callbacks++;
1019
97
    if (lint->noout)
1020
0
  return;
1021
97
    va_start(args, msg);
1022
97
    fprintf(stdout, "SAX.error: ");
1023
97
    vfprintf(stdout, msg, args);
1024
97
    va_end(args);
1025
97
}
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
711
testSAX(xmllintState *lint, const char *filename) {
1193
711
    lint->callbacks = 0;
1194
1195
711
#ifdef LIBXML_SCHEMAS_ENABLED
1196
711
    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
711
#endif
1236
711
#ifdef LIBXML_HTML_ENABLED
1237
711
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1238
0
        parseHtml(lint, filename);
1239
0
    } else
1240
711
#endif
1241
711
    {
1242
711
        parseXml(lint, filename);
1243
711
    }
1244
711
}
1245
1246
/************************************************************************
1247
 *                  *
1248
 *      Stream Test processing        *
1249
 *                  *
1250
 ************************************************************************/
1251
#ifdef LIBXML_READER_ENABLED
1252
2.65k
static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
1253
2.65k
    const xmlChar *name, *value;
1254
2.65k
    int type, empty;
1255
1256
2.65k
    type = xmlTextReaderNodeType(reader);
1257
2.65k
    empty = xmlTextReaderIsEmptyElement(reader);
1258
1259
2.65k
    if (lint->appOptions & XML_LINT_DEBUG_ENABLED) {
1260
1.83k
  name = xmlTextReaderConstName(reader);
1261
1.83k
  if (name == NULL)
1262
0
      name = BAD_CAST "--";
1263
1264
1.83k
  value = xmlTextReaderConstValue(reader);
1265
1266
1267
1.83k
  printf("%d %d %s %d %d",
1268
1.83k
    xmlTextReaderDepth(reader),
1269
1.83k
    type,
1270
1.83k
    name,
1271
1.83k
    empty,
1272
1.83k
    xmlTextReaderHasValue(reader));
1273
1.83k
  if (value == NULL)
1274
1.22k
      printf("\n");
1275
611
  else {
1276
611
      printf(" %s\n", value);
1277
611
  }
1278
1.83k
    }
1279
2.65k
#ifdef LIBXML_PATTERN_ENABLED
1280
2.65k
    if (lint->patternc) {
1281
1.33k
        xmlChar *path = NULL;
1282
1.33k
        int match = -1;
1283
1284
1.33k
  if (type == XML_READER_TYPE_ELEMENT) {
1285
      /* do the check only on element start */
1286
445
      match = xmlPatternMatch(lint->patternc,
1287
445
                                    xmlTextReaderCurrentNode(reader));
1288
1289
445
      if (match) {
1290
109
    path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1291
109
    printf("Node %s matches pattern %s\n", path, lint->pattern);
1292
109
      }
1293
445
  }
1294
1.33k
  if (lint->patstream != NULL) {
1295
1.33k
      int ret;
1296
1297
1.33k
      if (type == XML_READER_TYPE_ELEMENT) {
1298
445
    ret = xmlStreamPush(lint->patstream,
1299
445
                        xmlTextReaderConstLocalName(reader),
1300
445
            xmlTextReaderConstNamespaceUri(reader));
1301
445
    if (ret < 0) {
1302
0
        fprintf(lint->errStream, "xmlStreamPush() failure\n");
1303
0
                    xmlFreeStreamCtxt(lint->patstream);
1304
0
        lint->patstream = NULL;
1305
445
    } else if (ret != match) {
1306
18
        if (path == NULL) {
1307
11
            path = xmlGetNodePath(
1308
11
                           xmlTextReaderCurrentNode(reader));
1309
11
        }
1310
18
        fprintf(lint->errStream,
1311
18
                "xmlPatternMatch and xmlStreamPush disagree\n");
1312
18
                    if (path != NULL)
1313
18
                        fprintf(lint->errStream, "  pattern %s node %s\n",
1314
18
                                lint->pattern, path);
1315
0
                    else
1316
0
            fprintf(lint->errStream, "  pattern %s node %s\n",
1317
0
          lint->pattern, xmlTextReaderConstName(reader));
1318
18
    }
1319
1320
445
      }
1321
1.33k
      if ((type == XML_READER_TYPE_END_ELEMENT) ||
1322
1.33k
          ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1323
445
          ret = xmlStreamPop(lint->patstream);
1324
445
    if (ret < 0) {
1325
0
        fprintf(lint->errStream, "xmlStreamPop() failure\n");
1326
0
                    xmlFreeStreamCtxt(lint->patstream);
1327
0
        lint->patstream = NULL;
1328
0
    }
1329
445
      }
1330
1.33k
  }
1331
1.33k
  if (path != NULL)
1332
120
      xmlFree(path);
1333
1.33k
    }
1334
2.65k
#endif
1335
2.65k
}
1336
1337
3.39k
static void streamFile(xmllintState *lint, const char *filename) {
1338
3.39k
    xmlParserInputBufferPtr input = NULL;
1339
3.39k
    FILE *errStream = lint->errStream;
1340
3.39k
    xmlTextReaderPtr reader;
1341
3.39k
    int ret;
1342
1343
3.39k
#if HAVE_DECL_MMAP
1344
3.39k
    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.39k
#endif
1353
3.39k
    {
1354
3.39k
        xmlResetLastError();
1355
1356
3.39k
        if (strcmp(filename, "-") == 0) {
1357
0
            reader = xmlReaderForFd(STDIN_FILENO, "-", NULL,
1358
0
                                    lint->parseOptions | XML_PARSE_UNZIP);
1359
0
        }
1360
3.39k
        else {
1361
3.39k
            reader = xmlReaderForFile(filename, NULL,
1362
3.39k
                                      lint->parseOptions | XML_PARSE_UNZIP);
1363
3.39k
        }
1364
3.39k
        if (reader == NULL) {
1365
3.39k
            const xmlError *error = xmlGetLastError();
1366
1367
3.39k
            if ((error != NULL) && (error->code == XML_ERR_NO_MEMORY)) {
1368
93
                lint->progresult = XMLLINT_ERR_MEM;
1369
3.30k
            } else {
1370
3.30k
                fprintf(errStream, "Unable to open %s\n", filename);
1371
3.30k
                lint->progresult = XMLLINT_ERR_RDFILE;
1372
3.30k
            }
1373
3.39k
            return;
1374
3.39k
        }
1375
3.39k
    }
1376
1377
0
#ifdef LIBXML_PATTERN_ENABLED
1378
0
    if (lint->patternc != NULL) {
1379
0
        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
1380
0
  if (lint->patstream != NULL) {
1381
0
      ret = xmlStreamPush(lint->patstream, NULL, NULL);
1382
0
      if (ret < 0) {
1383
0
    fprintf(errStream, "xmlStreamPush() failure\n");
1384
0
    xmlFreeStreamCtxt(lint->patstream);
1385
0
    lint->patstream = NULL;
1386
0
            }
1387
0
  }
1388
0
    }
1389
0
#endif
1390
1391
1392
0
    xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, lint);
1393
0
    if (lint->maxAmpl > 0)
1394
0
        xmlTextReaderSetMaxAmplification(reader, lint->maxAmpl);
1395
1396
0
#ifdef LIBXML_RELAXNG_ENABLED
1397
0
    if (lint->relaxng != NULL) {
1398
0
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1399
0
            startTimer(lint);
1400
0
        }
1401
0
        ret = xmlTextReaderRelaxNGValidate(reader, lint->relaxng);
1402
0
        if (ret < 0) {
1403
0
            fprintf(errStream, "Relax-NG schema %s failed to compile\n",
1404
0
                    lint->relaxng);
1405
0
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
1406
0
            lint->relaxng = NULL;
1407
0
        }
1408
0
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1409
0
            endTimer(lint, "Compiling the schemas");
1410
0
        }
1411
0
    }
1412
0
#endif
1413
0
#ifdef LIBXML_SCHEMAS_ENABLED
1414
0
    if (lint->schema != NULL) {
1415
0
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1416
0
            startTimer(lint);
1417
0
        }
1418
0
        ret = xmlTextReaderSchemaValidate(reader, lint->schema);
1419
0
        if (ret < 0) {
1420
0
            fprintf(errStream, "XSD schema %s failed to compile\n",
1421
0
                    lint->schema);
1422
0
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
1423
0
            lint->schema = NULL;
1424
0
        }
1425
0
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1426
0
            endTimer(lint, "Compiling the schemas");
1427
0
        }
1428
0
    }
1429
0
#endif
1430
1431
    /*
1432
     * Process all nodes in sequence
1433
     */
1434
0
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1435
0
        startTimer(lint);
1436
0
    }
1437
0
    ret = xmlTextReaderRead(reader);
1438
0
    while (ret == 1) {
1439
0
        if ((lint->appOptions & XML_LINT_DEBUG_ENABLED)
1440
0
#ifdef LIBXML_PATTERN_ENABLED
1441
0
            || (lint->patternc)
1442
0
#endif
1443
0
           )
1444
0
            processNode(lint, reader);
1445
0
        ret = xmlTextReaderRead(reader);
1446
0
    }
1447
0
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1448
0
#ifdef LIBXML_RELAXNG_ENABLED
1449
0
        if (lint->relaxng != NULL)
1450
0
            endTimer(lint, "Parsing and validating");
1451
0
        else
1452
0
#endif
1453
0
#ifdef LIBXML_VALID_ENABLED
1454
0
        if (lint->parseOptions & XML_PARSE_DTDVALID)
1455
0
            endTimer(lint, "Parsing and validating");
1456
0
        else
1457
0
#endif
1458
0
        endTimer(lint, "Parsing");
1459
0
    }
1460
1461
0
#ifdef LIBXML_VALID_ENABLED
1462
0
    if (lint->parseOptions & XML_PARSE_DTDVALID) {
1463
0
        if (xmlTextReaderIsValid(reader) != 1) {
1464
0
            fprintf(errStream,
1465
0
                    "Document %s does not validate\n", filename);
1466
0
            lint->progresult = XMLLINT_ERR_VALID;
1467
0
        }
1468
0
    }
1469
0
#endif /* LIBXML_VALID_ENABLED */
1470
0
#if defined(LIBXML_RELAXNG_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
1471
0
    {
1472
0
        int hasSchema = 0;
1473
1474
0
#ifdef LIBXML_RELAXNG_ENABLED
1475
0
        if (lint->relaxng != NULL)
1476
0
            hasSchema = 1;
1477
0
#endif
1478
0
#ifdef LIBXML_SCHEMAS_ENABLED
1479
0
        if (lint->schema != NULL)
1480
0
            hasSchema = 1;
1481
0
#endif
1482
0
        if (hasSchema) {
1483
0
            if (xmlTextReaderIsValid(reader) != 1) {
1484
0
                fprintf(errStream, "%s fails to validate\n", filename);
1485
0
                lint->progresult = XMLLINT_ERR_VALID;
1486
0
            } else {
1487
0
                if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
1488
0
                    fprintf(errStream, "%s validates\n", filename);
1489
0
                }
1490
0
            }
1491
0
        }
1492
0
    }
1493
0
#endif
1494
    /*
1495
     * Done, cleanup and status
1496
     */
1497
0
    xmlFreeTextReader(reader);
1498
0
    xmlFreeParserInputBuffer(input);
1499
0
    if (ret != 0) {
1500
0
        fprintf(errStream, "%s : failed to parse\n", filename);
1501
0
        lint->progresult = XMLLINT_ERR_UNCLASS;
1502
0
    }
1503
0
#ifdef LIBXML_PATTERN_ENABLED
1504
0
    if (lint->patstream != NULL) {
1505
0
  xmlFreeStreamCtxt(lint->patstream);
1506
0
  lint->patstream = NULL;
1507
0
    }
1508
0
#endif
1509
0
}
1510
1511
1.97k
static void walkDoc(xmllintState *lint, xmlDocPtr doc) {
1512
1.97k
    FILE *errStream = lint->errStream;
1513
1.97k
    xmlTextReaderPtr reader;
1514
1.97k
    int ret;
1515
1516
1.97k
#ifdef LIBXML_PATTERN_ENABLED
1517
1.97k
    if (lint->pattern != NULL) {
1518
678
        xmlNodePtr root;
1519
678
        const xmlChar *namespaces[22];
1520
678
        int i;
1521
678
        xmlNsPtr ns;
1522
1523
678
        root = xmlDocGetRootElement(doc);
1524
678
        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
678
        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
678
        namespaces[i++] = NULL;
1535
678
        namespaces[i] = NULL;
1536
1537
678
        ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict,
1538
678
                                    0, &namespaces[0], &lint->patternc);
1539
678
  if (lint->patternc == NULL) {
1540
202
            if (ret < 0) {
1541
0
                lint->progresult = XMLLINT_ERR_MEM;
1542
202
            } else {
1543
202
                fprintf(errStream, "Pattern %s failed to compile\n",
1544
202
                        lint->pattern);
1545
202
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
1546
202
            }
1547
202
            goto error;
1548
202
  }
1549
1550
476
        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
1551
476
        if (lint->patstream == NULL) {
1552
31
            lint->progresult = XMLLINT_ERR_MEM;
1553
31
            goto error;
1554
31
        }
1555
1556
445
        ret = xmlStreamPush(lint->patstream, NULL, NULL);
1557
445
        if (ret < 0) {
1558
0
            fprintf(errStream, "xmlStreamPush() failure\n");
1559
0
            lint->progresult = XMLLINT_ERR_MEM;
1560
0
            goto error;
1561
0
        }
1562
445
    }
1563
1.74k
#endif /* LIBXML_PATTERN_ENABLED */
1564
1.74k
    reader = xmlReaderWalker(doc);
1565
1.74k
    if (reader != NULL) {
1566
1.74k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1567
950
      startTimer(lint);
1568
950
  }
1569
1.74k
  ret = xmlTextReaderRead(reader);
1570
6.98k
  while (ret == 1) {
1571
5.23k
      if ((lint->appOptions & XML_LINT_DEBUG_ENABLED)
1572
5.23k
#ifdef LIBXML_PATTERN_ENABLED
1573
5.23k
          || (lint->patternc)
1574
5.23k
#endif
1575
5.23k
         )
1576
2.65k
    processNode(lint, reader);
1577
5.23k
      ret = xmlTextReaderRead(reader);
1578
5.23k
  }
1579
1.74k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1580
950
      endTimer(lint, "walking through the doc");
1581
950
  }
1582
1.74k
  xmlFreeTextReader(reader);
1583
1.74k
  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.74k
    } 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.74k
#ifdef LIBXML_PATTERN_ENABLED
1593
1.97k
error:
1594
1.97k
    if (lint->patternc != NULL) {
1595
476
        xmlFreePattern(lint->patternc);
1596
476
        lint->patternc = NULL;
1597
476
    }
1598
1.97k
    if (lint->patstream != NULL) {
1599
445
  xmlFreeStreamCtxt(lint->patstream);
1600
445
  lint->patstream = NULL;
1601
445
    }
1602
1.97k
#endif
1603
1.97k
}
1604
#endif /* LIBXML_READER_ENABLED */
1605
1606
#ifdef LIBXML_XPATH_ENABLED
1607
/************************************************************************
1608
 *                  *
1609
 *      XPath Query                                     *
1610
 *                  *
1611
 ************************************************************************/
1612
1613
static void
1614
5.24k
doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) {
1615
5.24k
    switch(cur->type) {
1616
3.64k
        case XPATH_NODESET: {
1617
3.64k
#ifdef LIBXML_OUTPUT_ENABLED
1618
3.64k
            xmlOutputBufferPtr buf;
1619
3.64k
            xmlNodePtr node;
1620
3.64k
            int i;
1621
1622
3.64k
            if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
1623
2.60k
                lint->progresult = XMLLINT_ERR_XPATH_EMPTY;
1624
2.60k
                if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
1625
2.24k
                    fprintf(lint->errStream, "XPath set is empty\n");
1626
2.24k
                }
1627
2.60k
                break;
1628
2.60k
            }
1629
1.04k
            buf = xmlOutputBufferCreateFile(stdout, NULL);
1630
1.04k
            if (buf == NULL) {
1631
0
                lint->progresult = XMLLINT_ERR_MEM;
1632
0
                return;
1633
0
            }
1634
3.45k
            for (i = 0;i < cur->nodesetval->nodeNr;i++) {
1635
2.41k
                node = cur->nodesetval->nodeTab[i];
1636
2.41k
                xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
1637
2.41k
                xmlOutputBufferWrite(buf, 1, "\n");
1638
2.41k
            }
1639
1.04k
            xmlOutputBufferClose(buf);
1640
#else
1641
            printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
1642
#endif
1643
1.04k
      break;
1644
1.04k
        }
1645
635
        case XPATH_BOOLEAN:
1646
635
      if (cur->boolval) printf("true\n");
1647
395
      else printf("false\n");
1648
635
      break;
1649
497
        case XPATH_NUMBER:
1650
497
      switch (xmlXPathIsInf(cur->floatval)) {
1651
23
      case 1:
1652
23
    printf("Infinity\n");
1653
23
    break;
1654
30
      case -1:
1655
30
    printf("-Infinity\n");
1656
30
    break;
1657
444
      default:
1658
444
    if (xmlXPathIsNaN(cur->floatval)) {
1659
283
        printf("NaN\n");
1660
283
    } else {
1661
161
        printf("%0g\n", cur->floatval);
1662
161
    }
1663
497
      }
1664
497
      break;
1665
497
        case XPATH_STRING:
1666
467
      printf("%s\n", (const char *) cur->stringval);
1667
467
      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.24k
    }
1677
5.24k
}
1678
1679
static void
1680
8.65k
doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) {
1681
8.65k
    xmlXPathContextPtr ctxt = NULL;
1682
8.65k
    xmlXPathCompExprPtr comp = NULL;
1683
8.65k
    xmlXPathObjectPtr res = NULL;
1684
1685
8.65k
    ctxt = xmlXPathNewContext(doc);
1686
8.65k
    if (ctxt == NULL) {
1687
0
        lint->progresult = XMLLINT_ERR_MEM;
1688
0
        goto error;
1689
0
    }
1690
1691
8.65k
    comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query);
1692
8.65k
    if (comp == NULL) {
1693
2.03k
        fprintf(lint->errStream, "XPath compilation failure\n");
1694
2.03k
        lint->progresult = XMLLINT_ERR_XPATH;
1695
2.03k
        goto error;
1696
2.03k
    }
1697
1698
#ifdef LIBXML_DEBUG_ENABLED
1699
    if (lint->appOptions & XML_LINT_DEBUG_ENABLED) {
1700
        xmlXPathDebugDumpCompExpr(stdout, comp, 0);
1701
        printf("\n");
1702
    }
1703
#endif
1704
1705
6.61k
    ctxt->node = (xmlNodePtr) doc;
1706
6.61k
    res = xmlXPathCompiledEval(comp, ctxt);
1707
6.61k
    if (res == NULL) {
1708
1.37k
        fprintf(lint->errStream, "XPath evaluation failure\n");
1709
1.37k
        lint->progresult = XMLLINT_ERR_XPATH;
1710
1.37k
        goto error;
1711
1.37k
    }
1712
1713
5.24k
    doXPathDump(lint, res);
1714
1715
8.65k
error:
1716
8.65k
    xmlXPathFreeObject(res);
1717
8.65k
    xmlXPathFreeCompExpr(comp);
1718
8.65k
    xmlXPathFreeContext(ctxt);
1719
8.65k
}
1720
#endif /* LIBXML_XPATH_ENABLED */
1721
1722
/************************************************************************
1723
 *                  *
1724
 *      Tree Test processing        *
1725
 *                  *
1726
 ************************************************************************/
1727
1728
static xmlDocPtr
1729
16.4k
parseFile(xmllintState *lint, const char *filename) {
1730
16.4k
    xmlDocPtr doc = NULL;
1731
1732
16.4k
    if ((lint->appOptions & XML_LINT_GENERATE) && (filename == NULL)) {
1733
9.62k
        xmlNodePtr n;
1734
1735
9.62k
        doc = xmlNewDoc(BAD_CAST "1.0");
1736
9.62k
        if (doc == NULL) {
1737
39
            lint->progresult = XMLLINT_ERR_MEM;
1738
39
            return(NULL);
1739
39
        }
1740
9.58k
        n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
1741
9.58k
        if (n == NULL) {
1742
0
            xmlFreeDoc(doc);
1743
0
            lint->progresult = XMLLINT_ERR_MEM;
1744
0
            return(NULL);
1745
0
        }
1746
9.58k
        if (xmlNodeSetContent(n, BAD_CAST "abc") < 0) {
1747
0
            xmlFreeNode(n);
1748
0
            xmlFreeDoc(doc);
1749
0
            lint->progresult = XMLLINT_ERR_MEM;
1750
0
            return(NULL);
1751
0
        }
1752
9.58k
        xmlDocSetRootElement(doc, n);
1753
1754
9.58k
        return(doc);
1755
9.58k
    }
1756
1757
6.81k
#ifdef LIBXML_HTML_ENABLED
1758
6.81k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
1759
1.28k
        doc = parseHtml(lint, filename);
1760
1.28k
        return(doc);
1761
1.28k
    }
1762
5.53k
#endif /* LIBXML_HTML_ENABLED */
1763
5.53k
    {
1764
5.53k
        doc = parseXml(lint, filename);
1765
5.53k
    }
1766
1767
5.53k
    if (doc == NULL) {
1768
5.53k
        if (lint->ctxt->errNo == XML_ERR_NO_MEMORY)
1769
5.53k
            lint->progresult = XMLLINT_ERR_MEM;
1770
0
        else
1771
0
      lint->progresult = XMLLINT_ERR_RDFILE;
1772
5.53k
    } else {
1773
0
        xmlParserStatus status = xmlCtxtGetStatus(lint->ctxt);
1774
0
        if ((lint->parseOptions & XML_PARSE_DTDVALID) &&
1775
0
            (status & XML_STATUS_DTD_VALIDATION_FAILED))
1776
0
            lint->progresult = XMLLINT_ERR_VALID;
1777
1778
0
        if ((lint->appOptions & XML_LINT_STRICT_NAMESPACE) &&
1779
0
            (status & XML_STATUS_NOT_NS_WELL_FORMED)) {
1780
0
            lint->progresult = XMLLINT_ERR_RDFILE;
1781
0
        }
1782
0
    }
1783
1784
5.53k
    return(doc);
1785
6.81k
}
1786
1787
static void
1788
16.4k
parseAndPrintFile(xmllintState *lint, const char *filename) {
1789
16.4k
    FILE *errStream = lint->errStream;
1790
16.4k
    xmlDocPtr doc;
1791
1792
    /* Avoid unused variable warning */
1793
16.4k
    (void) errStream;
1794
1795
16.4k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1))
1796
3.88k
  startTimer(lint);
1797
1798
16.4k
    doc = parseFile(lint, filename);
1799
16.4k
    if (doc == NULL) {
1800
6.85k
        if (lint->progresult == XMLLINT_RETURN_OK)
1801
1.18k
            lint->progresult = XMLLINT_ERR_UNCLASS;
1802
6.85k
  return;
1803
6.85k
    }
1804
1805
9.58k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1806
2.46k
  endTimer(lint, "Parsing");
1807
2.46k
    }
1808
1809
9.58k
    if (lint->appOptions & XML_LINT_DROP_DTD) {
1810
1.38k
  xmlDtdPtr dtd;
1811
1812
1.38k
  dtd = xmlGetIntSubset(doc);
1813
1.38k
  if (dtd != NULL) {
1814
0
      xmlUnlinkNode((xmlNodePtr)dtd);
1815
0
            doc->intSubset = dtd;
1816
0
  }
1817
1.38k
    }
1818
1819
9.58k
#ifdef LIBXML_XINCLUDE_ENABLED
1820
9.58k
    if (lint->appOptions & XML_LINT_XINCLUDE) {
1821
7.82k
        xmlXIncludeCtxt *xinc;
1822
7.82k
        int res;
1823
1824
7.82k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1825
2.19k
      startTimer(lint);
1826
2.19k
  }
1827
1828
7.82k
        xinc = xmlXIncludeNewContext(doc);
1829
7.82k
        if (xinc == NULL) {
1830
0
            lint->progresult = XMLLINT_ERR_MEM;
1831
0
            goto done;
1832
0
        }
1833
7.82k
        xmlXIncludeSetResourceLoader(xinc, xmllintResourceLoader, lint);
1834
7.82k
        xmlXIncludeSetFlags(xinc, lint->parseOptions);
1835
7.82k
        res = xmlXIncludeProcessNode(xinc, (xmlNode *) doc);
1836
7.82k
        xmlXIncludeFreeContext(xinc);
1837
7.82k
        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.82k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1846
2.19k
      endTimer(lint, "Xinclude processing");
1847
2.19k
  }
1848
7.82k
    }
1849
9.58k
#endif
1850
1851
    /*
1852
     * shell interaction
1853
     */
1854
9.58k
    if (lint->appOptions & XML_LINT_NAVIGATING_SHELL) {
1855
0
#ifdef LIBXML_XPATH_ENABLED
1856
0
        xmlXPathOrderDocElems(doc);
1857
0
#endif
1858
0
        xmllintShell(doc, filename, stdout);
1859
0
        goto done;
1860
0
    }
1861
1862
9.58k
#ifdef LIBXML_XPATH_ENABLED
1863
9.58k
    if (lint->xpathquery != NULL) {
1864
8.65k
  xmlXPathOrderDocElems(doc);
1865
8.65k
        doXPathQuery(lint, doc, lint->xpathquery);
1866
8.65k
    }
1867
9.58k
#endif
1868
1869
    /*
1870
     * test intermediate copy if needed.
1871
     */
1872
9.58k
    if (lint->appOptions & XML_LINT_COPY_ENABLED) {
1873
2.80k
        xmlDocPtr tmp;
1874
1875
2.80k
        tmp = doc;
1876
2.80k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1877
834
      startTimer(lint);
1878
834
  }
1879
2.80k
  doc = xmlCopyDoc(doc, 1);
1880
2.80k
        if (doc == NULL) {
1881
0
            lint->progresult = XMLLINT_ERR_MEM;
1882
0
            xmlFreeDoc(tmp);
1883
0
            return;
1884
0
        }
1885
2.80k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1886
834
      endTimer(lint, "Copying");
1887
834
  }
1888
2.80k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1889
834
      startTimer(lint);
1890
834
  }
1891
2.80k
  xmlFreeDoc(tmp);
1892
2.80k
  if (lint->appOptions & XML_LINT_TIMINGS) {
1893
834
      endTimer(lint, "Freeing original");
1894
834
  }
1895
2.80k
    }
1896
1897
9.58k
#ifdef LIBXML_VALID_ENABLED
1898
9.58k
    if ((lint->appOptions & XML_LINT_VALID_INSERTIONS)
1899
9.58k
#ifdef LIBXML_HTML_ENABLED
1900
9.58k
        && ((lint->appOptions & XML_LINT_HTML_ENABLED) != XML_LINT_HTML_ENABLED)
1901
9.58k
#endif
1902
9.58k
    ) {
1903
4.84k
        const xmlChar* list[256];
1904
4.84k
  int nb, i;
1905
4.84k
  xmlNodePtr node;
1906
1907
4.84k
  if (doc->children != NULL) {
1908
4.84k
      node = doc->children;
1909
4.84k
      while ((node != NULL) &&
1910
4.84k
                   ((node->type != XML_ELEMENT_NODE) ||
1911
4.84k
                    (node->last == NULL)))
1912
0
                node = node->next;
1913
4.84k
      if (node != NULL) {
1914
4.84k
    nb = xmlValidGetValidElements(node->last, NULL, list, 256);
1915
4.84k
    if (nb < 0) {
1916
4.84k
        fprintf(errStream, "could not get valid list of elements\n");
1917
4.84k
    } 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.84k
      }
1927
4.84k
  }
1928
4.84k
    } else
1929
4.74k
#endif /* LIBXML_VALID_ENABLED */
1930
4.74k
#ifdef LIBXML_READER_ENABLED
1931
4.74k
    if (lint->appOptions & XML_LINT_USE_WALKER) {
1932
1.97k
        walkDoc(lint, doc);
1933
1.97k
    }
1934
9.58k
#endif /* LIBXML_READER_ENABLED */
1935
9.58k
#ifdef LIBXML_OUTPUT_ENABLED
1936
9.58k
    if (lint->noout == 0) {
1937
256
#ifdef LIBXML_ZLIB_ENABLED
1938
256
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
1939
44
            xmlSetDocCompressMode(doc, 9);
1940
256
#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
256
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
1949
26
    startTimer(lint);
1950
26
      }
1951
256
#ifdef LIBXML_C14N_ENABLED
1952
256
            if (lint->appOptions & XML_LINT_CANONICAL_V1_0) {
1953
54
          xmlChar *result = NULL;
1954
54
    int size;
1955
1956
54
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
1957
54
    if (size >= 0) {
1958
54
        if (write(1, result, size) == -1) {
1959
0
            fprintf(errStream, "Can't write data\n");
1960
0
        }
1961
54
        xmlFree(result);
1962
54
    } else {
1963
0
        fprintf(errStream, "Failed to canonicalize\n");
1964
0
        lint->progresult = XMLLINT_ERR_OUT;
1965
0
    }
1966
202
      } else if (lint->appOptions & XML_LINT_CANONICAL_V1_1) {
1967
41
          xmlChar *result = NULL;
1968
41
    int size;
1969
1970
41
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
1971
41
    if (size >= 0) {
1972
41
        if (write(1, result, size) == -1) {
1973
0
            fprintf(errStream, "Can't write data\n");
1974
0
        }
1975
41
        xmlFree(result);
1976
41
    } else {
1977
0
        fprintf(errStream, "Failed to canonicalize\n");
1978
0
        lint->progresult = XMLLINT_ERR_OUT;
1979
0
    }
1980
161
      } else if (lint->appOptions & XML_LINT_CANONICAL_EXE) {
1981
10
          xmlChar *result = NULL;
1982
10
    int size;
1983
1984
10
    size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
1985
10
    if (size >= 0) {
1986
10
        if (write(1, result, size) == -1) {
1987
0
            fprintf(errStream, "Can't write data\n");
1988
0
        }
1989
10
        xmlFree(result);
1990
10
    } else {
1991
0
        fprintf(errStream, "Failed to canonicalize\n");
1992
0
        lint->progresult = XMLLINT_ERR_OUT;
1993
0
    }
1994
10
      } else
1995
151
#endif
1996
151
#ifdef LIBXML_ZLIB_ENABLED
1997
151
      if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION) {
1998
5
    xmlSaveFile(lint->output ? lint->output : "-", doc);
1999
5
      } else
2000
146
#endif
2001
146
            {
2002
146
          xmlSaveCtxtPtr ctxt;
2003
146
    int saveOpts = 0;
2004
2005
146
                if (lint->format == 1)
2006
60
        saveOpts |= XML_SAVE_FORMAT;
2007
86
                else if (lint->format == 2)
2008
19
                    saveOpts |= XML_SAVE_WSNONSIG;
2009
2010
146
#if defined(LIBXML_HTML_ENABLED)
2011
146
                if (lint->appOptions & XML_LINT_XML_OUT)
2012
31
                    saveOpts |= XML_SAVE_AS_XML;
2013
146
#endif
2014
2015
146
    if (lint->output == NULL)
2016
146
        ctxt = xmlSaveToFd(STDOUT_FILENO, lint->encoding,
2017
146
                                       saveOpts);
2018
0
    else
2019
0
        ctxt = xmlSaveToFilename(lint->output, lint->encoding,
2020
0
                                             saveOpts);
2021
2022
146
    if (ctxt != NULL) {
2023
41
                    if (lint->indentString != NULL)
2024
0
                        xmlSaveSetIndentString(ctxt, lint->indentString);
2025
2026
41
        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
41
        xmlSaveClose(ctxt);
2032
105
    } else {
2033
105
        lint->progresult = XMLLINT_ERR_OUT;
2034
105
    }
2035
146
      }
2036
256
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2037
26
    endTimer(lint, "Saving");
2038
26
      }
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
256
    }
2059
9.58k
#endif /* LIBXML_OUTPUT_ENABLED */
2060
2061
9.58k
#ifdef LIBXML_VALID_ENABLED
2062
    /*
2063
     * A posteriori validation test
2064
     */
2065
9.58k
    if ((lint->dtdvalid != NULL) || (lint->dtdvalidfpi != NULL)) {
2066
0
  xmlDtdPtr dtd;
2067
2068
0
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2069
0
      startTimer(lint);
2070
0
  }
2071
0
  if (lint->dtdvalid != NULL)
2072
0
      dtd = xmlParseDTD(NULL, BAD_CAST lint->dtdvalid);
2073
0
  else
2074
0
      dtd = xmlParseDTD(BAD_CAST lint->dtdvalidfpi, NULL);
2075
0
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2076
0
      endTimer(lint, "Parsing DTD");
2077
0
  }
2078
0
  if (dtd == NULL) {
2079
0
      if (lint->dtdvalid != NULL)
2080
0
    fprintf(errStream, "Could not parse DTD %s\n",
2081
0
                        lint->dtdvalid);
2082
0
      else
2083
0
    fprintf(errStream, "Could not parse DTD %s\n",
2084
0
                        lint->dtdvalidfpi);
2085
0
      lint->progresult = XMLLINT_ERR_DTD;
2086
0
  } else {
2087
0
      xmlValidCtxtPtr cvp;
2088
2089
0
      cvp = xmlNewValidCtxt();
2090
0
      if (cvp == NULL) {
2091
0
                lint->progresult = XMLLINT_ERR_MEM;
2092
0
                xmlFreeDtd(dtd);
2093
0
                return;
2094
0
      }
2095
2096
0
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2097
0
    startTimer(lint);
2098
0
      }
2099
0
      if (!xmlValidateDtd(cvp, doc, dtd)) {
2100
0
    if (lint->dtdvalid != NULL)
2101
0
        fprintf(errStream,
2102
0
          "Document %s does not validate against %s\n",
2103
0
          filename, lint->dtdvalid);
2104
0
    else
2105
0
        fprintf(errStream,
2106
0
          "Document %s does not validate against %s\n",
2107
0
          filename, lint->dtdvalidfpi);
2108
0
    lint->progresult = XMLLINT_ERR_VALID;
2109
0
      }
2110
0
      if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2111
0
    endTimer(lint, "Validating against DTD");
2112
0
      }
2113
0
      xmlFreeValidCtxt(cvp);
2114
0
      xmlFreeDtd(dtd);
2115
0
  }
2116
9.58k
    } else if (lint->appOptions & XML_LINT_POST_VALIDATION) {
2117
1.48k
  xmlValidCtxtPtr cvp;
2118
2119
1.48k
  cvp = xmlNewValidCtxt();
2120
1.48k
  if (cvp == NULL) {
2121
0
            lint->progresult = XMLLINT_ERR_MEM;
2122
0
            xmlFreeDoc(doc);
2123
0
            return;
2124
0
  }
2125
2126
1.48k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2127
477
      startTimer(lint);
2128
477
  }
2129
1.48k
  if (!xmlValidateDocument(cvp, doc)) {
2130
1.48k
      fprintf(errStream,
2131
1.48k
        "Document %s does not validate\n", filename);
2132
1.48k
      lint->progresult = XMLLINT_ERR_VALID;
2133
1.48k
  }
2134
1.48k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2135
477
      endTimer(lint, "Validating");
2136
477
  }
2137
1.48k
  xmlFreeValidCtxt(cvp);
2138
1.48k
    }
2139
9.58k
#endif /* LIBXML_VALID_ENABLED */
2140
#ifdef LIBXML_SCHEMATRON_ENABLED
2141
    if (lint->wxschematron != NULL) {
2142
  xmlSchematronValidCtxtPtr ctxt;
2143
  int ret;
2144
  int flag;
2145
2146
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2147
      startTimer(lint);
2148
  }
2149
2150
  if (lint->appOptions & XML_LINT_DEBUG_ENABLED)
2151
      flag = XML_SCHEMATRON_OUT_XML;
2152
  else
2153
      flag = XML_SCHEMATRON_OUT_TEXT;
2154
  if (lint->noout)
2155
      flag |= XML_SCHEMATRON_OUT_QUIET;
2156
  ctxt = xmlSchematronNewValidCtxt(lint->wxschematron, flag);
2157
        if (ctxt == NULL) {
2158
            lint->progresult = XMLLINT_ERR_MEM;
2159
            xmlFreeDoc(doc);
2160
            return;
2161
        }
2162
  ret = xmlSchematronValidateDoc(ctxt, doc);
2163
  if (ret == 0) {
2164
      if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
2165
          fprintf(errStream, "%s validates\n", filename);
2166
      }
2167
  } else if (ret > 0) {
2168
      fprintf(errStream, "%s fails to validate\n", filename);
2169
      lint->progresult = XMLLINT_ERR_VALID;
2170
  } else {
2171
      fprintf(errStream, "%s validation generated an internal error\n",
2172
       filename);
2173
      lint->progresult = XMLLINT_ERR_VALID;
2174
  }
2175
  xmlSchematronFreeValidCtxt(ctxt);
2176
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2177
      endTimer(lint, "Validating");
2178
  }
2179
    }
2180
#endif
2181
2182
9.58k
#ifdef LIBXML_RELAXNG_ENABLED
2183
9.58k
    if (lint->relaxngschemas != NULL) {
2184
0
  xmlRelaxNGValidCtxtPtr ctxt;
2185
0
  int ret;
2186
2187
0
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2188
0
      startTimer(lint);
2189
0
  }
2190
2191
0
  ctxt = xmlRelaxNGNewValidCtxt(lint->relaxngschemas);
2192
0
        if (ctxt == NULL) {
2193
0
            lint->progresult = XMLLINT_ERR_MEM;
2194
0
            xmlFreeDoc(doc);
2195
0
            return;
2196
0
        }
2197
0
  ret = xmlRelaxNGValidateDoc(ctxt, doc);
2198
0
  if (ret == 0) {
2199
0
      if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
2200
0
          fprintf(errStream, "%s validates\n", filename);
2201
0
      }
2202
0
  } else if (ret > 0) {
2203
0
      fprintf(errStream, "%s fails to validate\n", filename);
2204
0
      lint->progresult = XMLLINT_ERR_VALID;
2205
0
  } else {
2206
0
      fprintf(errStream, "%s validation generated an internal error\n",
2207
0
       filename);
2208
0
      lint->progresult = XMLLINT_ERR_VALID;
2209
0
  }
2210
0
  xmlRelaxNGFreeValidCtxt(ctxt);
2211
0
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2212
0
      endTimer(lint, "Validating");
2213
0
  }
2214
0
    }
2215
9.58k
#endif /* LIBXML_RELAXNG_ENABLED */
2216
2217
9.58k
#ifdef LIBXML_SCHEMAS_ENABLED
2218
9.58k
    if (lint->wxschemas != NULL) {
2219
0
  xmlSchemaValidCtxtPtr ctxt;
2220
0
  int ret;
2221
2222
0
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2223
0
      startTimer(lint);
2224
0
  }
2225
2226
0
  ctxt = xmlSchemaNewValidCtxt(lint->wxschemas);
2227
0
        if (ctxt == NULL) {
2228
0
            lint->progresult = XMLLINT_ERR_MEM;
2229
0
            xmlFreeDoc(doc);
2230
0
            return;
2231
0
        }
2232
0
  ret = xmlSchemaValidateDoc(ctxt, doc);
2233
0
  if (ret == 0) {
2234
0
      if ((lint->appOptions & XML_LINT_QUIET) != XML_LINT_QUIET) {
2235
0
          fprintf(errStream, "%s validates\n", filename);
2236
0
      }
2237
0
  } else if (ret > 0) {
2238
0
      fprintf(errStream, "%s fails to validate\n", filename);
2239
0
      lint->progresult = XMLLINT_ERR_VALID;
2240
0
  } else {
2241
0
      fprintf(errStream, "%s validation generated an internal error\n",
2242
0
       filename);
2243
0
      lint->progresult = XMLLINT_ERR_VALID;
2244
0
  }
2245
0
  xmlSchemaFreeValidCtxt(ctxt);
2246
0
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2247
0
      endTimer(lint, "Validating");
2248
0
  }
2249
0
    }
2250
9.58k
#endif /* LIBXML_SCHEMAS_ENABLED */
2251
2252
    /* Avoid unused label warning */
2253
9.58k
    goto done;
2254
2255
9.58k
done:
2256
    /*
2257
     * free it.
2258
     */
2259
9.58k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2260
2.46k
  startTimer(lint);
2261
2.46k
    }
2262
9.58k
    xmlFreeDoc(doc);
2263
9.58k
    if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat == 1)) {
2264
2.46k
  endTimer(lint, "Freeing");
2265
2.46k
    }
2266
9.58k
}
2267
2268
/************************************************************************
2269
 *                  *
2270
 *      Usage and Main          *
2271
 *                  *
2272
 ************************************************************************/
2273
2274
2.87k
static void showVersion(FILE *errStream, const char *name) {
2275
2.87k
    fprintf(errStream, "%s: using libxml version %s\n", name, xmlParserVersion);
2276
2.87k
    fprintf(errStream, "   compiled with: ");
2277
2.87k
    if (xmlHasFeature(XML_WITH_THREAD)) fprintf(errStream, "Threads ");
2278
2.87k
    fprintf(errStream, "Tree ");
2279
2.87k
    if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(errStream, "Output ");
2280
2.87k
    if (xmlHasFeature(XML_WITH_PUSH)) fprintf(errStream, "Push ");
2281
2.87k
    if (xmlHasFeature(XML_WITH_READER)) fprintf(errStream, "Reader ");
2282
2.87k
    if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(errStream, "Patterns ");
2283
2.87k
    if (xmlHasFeature(XML_WITH_WRITER)) fprintf(errStream, "Writer ");
2284
2.87k
    if (xmlHasFeature(XML_WITH_SAX1)) fprintf(errStream, "SAXv1 ");
2285
2.87k
    if (xmlHasFeature(XML_WITH_VALID)) fprintf(errStream, "DTDValid ");
2286
2.87k
    if (xmlHasFeature(XML_WITH_HTML)) fprintf(errStream, "HTML ");
2287
2.87k
    if (xmlHasFeature(XML_WITH_C14N)) fprintf(errStream, "C14N ");
2288
2.87k
    if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(errStream, "Catalog ");
2289
2.87k
    if (xmlHasFeature(XML_WITH_XPATH)) fprintf(errStream, "XPath ");
2290
2.87k
    if (xmlHasFeature(XML_WITH_XPTR)) fprintf(errStream, "XPointer ");
2291
2.87k
    if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(errStream, "XInclude ");
2292
2.87k
    if (xmlHasFeature(XML_WITH_ICONV)) fprintf(errStream, "Iconv ");
2293
2.87k
    if (xmlHasFeature(XML_WITH_ICU)) fprintf(errStream, "ICU ");
2294
2.87k
    if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(errStream, "ISO8859X ");
2295
2.87k
    if (xmlHasFeature(XML_WITH_REGEXP))
2296
2.87k
        fprintf(errStream, "Regexps Automata ");
2297
2.87k
    if (xmlHasFeature(XML_WITH_RELAXNG)) fprintf(errStream, "RelaxNG ");
2298
2.87k
    if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(errStream, "Schemas ");
2299
2.87k
    if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(errStream, "Schematron ");
2300
2.87k
    if (xmlHasFeature(XML_WITH_MODULES)) fprintf(errStream, "Modules ");
2301
2.87k
    if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(errStream, "Debug ");
2302
2.87k
    if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(errStream, "Zlib ");
2303
2.87k
    if (xmlHasFeature(XML_WITH_LZMA)) fprintf(errStream, "Lzma ");
2304
2.87k
    fprintf(errStream, "\n");
2305
2.87k
}
2306
2307
126
static void usage(FILE *f, const char *name) {
2308
126
    fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
2309
126
#ifdef LIBXML_OUTPUT_ENABLED
2310
126
    fprintf(f, "\tParse the XML files and output the result of the parsing\n");
2311
#else
2312
    fprintf(f, "\tParse the XML files\n");
2313
#endif /* LIBXML_OUTPUT_ENABLED */
2314
126
    fprintf(f, "\t--version : display the version of the XML library used\n");
2315
126
    fprintf(f, "\t--shell : run a navigating shell\n");
2316
126
    fprintf(f, "\t--debug : show additional debug information\n");
2317
126
    fprintf(f, "\t--copy : used to test the internal copy implementation\n");
2318
126
    fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
2319
126
    fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
2320
126
    fprintf(f, "\t--noent : substitute entity references by their value\n");
2321
126
    fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
2322
126
    fprintf(f, "\t--noout : don't output the result tree\n");
2323
126
    fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
2324
126
    fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
2325
126
    fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
2326
126
    fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
2327
126
#ifdef LIBXML_VALID_ENABLED
2328
126
    fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
2329
126
    fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
2330
126
    fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
2331
126
    fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
2332
126
    fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
2333
126
#endif /* LIBXML_VALID_ENABLED */
2334
126
    fprintf(f, "\t--strict-namespace : Return application failure if document has any namespace errors\n");
2335
126
    fprintf(f, "\t--quiet : be quiet when succeeded\n");
2336
126
    fprintf(f, "\t--timing : print some timings\n");
2337
126
    fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
2338
126
    fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
2339
126
#ifdef LIBXML_HTML_ENABLED
2340
126
    fprintf(f, "\t--html : use the HTML parser\n");
2341
126
    fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
2342
126
#ifdef LIBXML_OUTPUT_ENABLED
2343
126
    fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
2344
126
#endif
2345
126
#endif
2346
126
#ifdef LIBXML_PUSH_ENABLED
2347
126
    fprintf(f, "\t--push : use the push mode of the parser\n");
2348
126
#endif /* LIBXML_PUSH_ENABLED */
2349
126
#if HAVE_DECL_MMAP
2350
126
    fprintf(f, "\t--memory : parse from memory\n");
2351
126
#endif
2352
126
    fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
2353
126
    fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
2354
126
    fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
2355
126
    fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
2356
126
    fprintf(f, "\t--nodict : create document without dictionary\n");
2357
126
    fprintf(f, "\t--pedantic : enable additional warnings\n");
2358
126
#ifdef LIBXML_OUTPUT_ENABLED
2359
126
    fprintf(f, "\t--output file or -o file: save to a given file\n");
2360
126
    fprintf(f, "\t--format : reformat/reindent the output\n");
2361
126
    fprintf(f, "\t--encode encoding : output in the given encoding\n");
2362
126
    fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
2363
126
    fprintf(f, "\t                 0 Do not pretty print\n");
2364
126
    fprintf(f, "\t                 1 Format the XML content, as --format\n");
2365
126
    fprintf(f, "\t                 2 Add whitespace inside tags, preserving content\n");
2366
126
#ifdef LIBXML_ZLIB_ENABLED
2367
126
    fprintf(f, "\t--compress : turn on gzip compression of output\n");
2368
126
#endif
2369
126
#ifdef LIBXML_C14N_ENABLED
2370
126
    fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
2371
126
    fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
2372
126
    fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
2373
126
#endif /* LIBXML_C14N_ENABLED */
2374
126
#endif /* LIBXML_OUTPUT_ENABLED */
2375
126
    fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
2376
126
#ifdef LIBXML_CATALOG_ENABLED
2377
126
    fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2378
126
    fprintf(f, "\t             otherwise XML Catalogs starting from \n");
2379
126
    fprintf(f, "\t         file://" XML_SYSCONFDIR "/xml/catalog "
2380
126
            "are activated by default\n");
2381
126
    fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
2382
126
#endif
2383
126
    fprintf(f, "\t--auto : generate a small doc on the fly\n");
2384
126
#ifdef LIBXML_XINCLUDE_ENABLED
2385
126
    fprintf(f, "\t--xinclude : do XInclude processing\n");
2386
126
    fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
2387
126
    fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
2388
126
#endif
2389
126
    fprintf(f, "\t--loaddtd : fetch external DTD\n");
2390
126
    fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
2391
126
#ifdef LIBXML_READER_ENABLED
2392
126
    fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
2393
126
    fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
2394
126
#ifdef LIBXML_PATTERN_ENABLED
2395
126
    fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
2396
126
#endif
2397
126
#endif /* LIBXML_READER_ENABLED */
2398
126
#ifdef LIBXML_RELAXNG_ENABLED
2399
126
    fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
2400
126
#endif
2401
126
#ifdef LIBXML_SCHEMAS_ENABLED
2402
126
    fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
2403
126
#endif
2404
#ifdef LIBXML_SCHEMATRON_ENABLED
2405
    fprintf(f, "\t--schematron schema : do validation against a schematron\n");
2406
#endif
2407
126
#ifdef LIBXML_SAX1_ENABLED
2408
126
    fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
2409
126
#endif
2410
126
    fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
2411
126
    fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
2412
126
#ifdef LIBXML_XPATH_ENABLED
2413
126
    fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
2414
126
#endif
2415
126
    fprintf(f, "\t--max-ampl value: set maximum amplification factor\n");
2416
2417
126
    fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
2418
126
}
2419
2420
static int
2421
parseInteger(unsigned long *result, FILE *errStream, const char *ctxt,
2422
5.42k
             const char *str, unsigned long min, unsigned long max) {
2423
5.42k
    char *strEnd;
2424
5.42k
    unsigned long val;
2425
2426
5.42k
    errno = 0;
2427
5.42k
    val = strtoul(str, &strEnd, 10);
2428
5.42k
    if (errno == EINVAL || *strEnd != 0) {
2429
0
        fprintf(errStream, "%s: invalid integer: %s\n", ctxt, str);
2430
0
        return(-1);
2431
0
    }
2432
5.42k
    if (errno != 0 || val < min || val > max) {
2433
24
        fprintf(errStream, "%s: integer out of range: %s\n", ctxt, str);
2434
24
        return(-1);
2435
24
    }
2436
2437
5.40k
    *result = val;
2438
5.40k
    return(0);
2439
5.42k
}
2440
2441
static int
2442
163k
skipArgs(const char *arg) {
2443
163k
    if ((!strcmp(arg, "-path")) ||
2444
163k
        (!strcmp(arg, "--path")) ||
2445
163k
        (!strcmp(arg, "-maxmem")) ||
2446
163k
        (!strcmp(arg, "--maxmem")) ||
2447
163k
#ifdef LIBXML_OUTPUT_ENABLED
2448
163k
        (!strcmp(arg, "-o")) ||
2449
163k
        (!strcmp(arg, "-output")) ||
2450
163k
        (!strcmp(arg, "--output")) ||
2451
163k
        (!strcmp(arg, "-encode")) ||
2452
163k
        (!strcmp(arg, "--encode")) ||
2453
163k
        (!strcmp(arg, "-pretty")) ||
2454
163k
        (!strcmp(arg, "--pretty")) ||
2455
163k
#endif
2456
163k
#ifdef LIBXML_VALID_ENABLED
2457
163k
        (!strcmp(arg, "-dtdvalid")) ||
2458
163k
        (!strcmp(arg, "--dtdvalid")) ||
2459
163k
        (!strcmp(arg, "-dtdvalidfpi")) ||
2460
163k
        (!strcmp(arg, "--dtdvalidfpi")) ||
2461
163k
#endif
2462
163k
#ifdef LIBXML_RELAXNG_ENABLED
2463
163k
        (!strcmp(arg, "-relaxng")) ||
2464
163k
        (!strcmp(arg, "--relaxng")) ||
2465
163k
#endif
2466
163k
#ifdef LIBXML_SCHEMAS_ENABLED
2467
163k
        (!strcmp(arg, "-schema")) ||
2468
163k
        (!strcmp(arg, "--schema")) ||
2469
163k
#endif
2470
#ifdef LIBXML_SCHEMATRON_ENABLED
2471
        (!strcmp(arg, "-schematron")) ||
2472
        (!strcmp(arg, "--schematron")) ||
2473
#endif
2474
163k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2475
163k
        (!strcmp(arg, "-pattern")) ||
2476
163k
        (!strcmp(arg, "--pattern")) ||
2477
163k
#endif
2478
163k
#ifdef LIBXML_XPATH_ENABLED
2479
163k
        (!strcmp(arg, "-xpath")) ||
2480
163k
        (!strcmp(arg, "--xpath")) ||
2481
163k
#endif
2482
163k
        (!strcmp(arg, "-max-ampl")) ||
2483
163k
        (!strcmp(arg, "--max-ampl"))
2484
163k
    ) {
2485
15.4k
        return(1);
2486
15.4k
    }
2487
2488
147k
    return(0);
2489
163k
}
2490
2491
static void
2492
10.8k
xmllintInit(xmllintState *lint) {
2493
10.8k
    memset(lint, 0, sizeof(*lint));
2494
2495
10.8k
    lint->repeat = 1;
2496
10.8k
    lint->progresult = XMLLINT_RETURN_OK;
2497
10.8k
    lint->parseOptions = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
2498
10.8k
#ifdef LIBXML_HTML_ENABLED
2499
10.8k
    lint->htmlOptions = HTML_PARSE_COMPACT | HTML_PARSE_BIG_LINES;
2500
10.8k
#endif
2501
10.8k
}
2502
2503
static void
2504
28.4k
xmllintOptWarnNoSupport(FILE *errStream, const char *opt, const char *nosupp) {
2505
28.4k
    fprintf(errStream, "Warning: Option %s doesn't support %s\n", opt, nosupp);
2506
28.4k
}
2507
2508
static int
2509
10.8k
xmllintParseOptions(xmllintState *lint, int argc, const char **argv) {
2510
10.8k
    FILE *errStream = lint->errStream;
2511
10.8k
    const char *specialMode = NULL;
2512
10.8k
    int i;
2513
2514
10.8k
    if (argc <= 1) {
2515
0
        usage(errStream, argv[0]);
2516
0
        return(XMLLINT_ERR_UNCLASS);
2517
0
    }
2518
2519
194k
    for (i = 1; i < argc ; i++) {
2520
183k
        unsigned long val;
2521
2522
183k
        if (argv[i][0] != '-' || argv[i][1] == 0)
2523
10.7k
            continue;
2524
2525
172k
        if ((!strcmp(argv[i], "-maxmem")) ||
2526
172k
            (!strcmp(argv[i], "--maxmem"))) {
2527
341
            i++;
2528
341
            if (i >= argc) {
2529
0
                fprintf(errStream, "maxmem: missing integer value\n");
2530
0
                return(XMLLINT_ERR_UNCLASS);
2531
0
            }
2532
341
            if (parseInteger(&val, errStream, "maxmem", argv[i],
2533
341
                             0, INT_MAX) < 0)
2534
0
                return(XMLLINT_ERR_UNCLASS);
2535
341
            lint->maxmem = val;
2536
172k
        } else if ((!strcmp(argv[i], "-debug")) ||
2537
172k
                   (!strcmp(argv[i], "--debug"))) {
2538
3.68k
            lint->appOptions |= XML_LINT_DEBUG_ENABLED;
2539
168k
        } else if ((!strcmp(argv[i], "-shell")) ||
2540
168k
                   (!strcmp(argv[i], "--shell"))) {
2541
0
            lint->appOptions |= XML_LINT_NAVIGATING_SHELL;
2542
168k
        } else if ((!strcmp(argv[i], "-copy")) ||
2543
168k
                   (!strcmp(argv[i], "--copy"))) {
2544
3.14k
            lint->appOptions |= XML_LINT_COPY_ENABLED;
2545
165k
        } else if ((!strcmp(argv[i], "-recover")) ||
2546
165k
                   (!strcmp(argv[i], "--recover"))) {
2547
1.82k
            lint->parseOptions |= XML_PARSE_RECOVER;
2548
163k
        } else if ((!strcmp(argv[i], "-huge")) ||
2549
163k
                   (!strcmp(argv[i], "--huge"))) {
2550
3.86k
            lint->parseOptions |= XML_PARSE_HUGE;
2551
3.86k
#ifdef LIBXML_HTML_ENABLED
2552
3.86k
            lint->htmlOptions |= HTML_PARSE_HUGE;
2553
3.86k
#endif
2554
160k
        } else if ((!strcmp(argv[i], "-noent")) ||
2555
160k
                   (!strcmp(argv[i], "--noent"))) {
2556
1.84k
            lint->parseOptions |= XML_PARSE_NOENT;
2557
158k
        } else if ((!strcmp(argv[i], "-noenc")) ||
2558
158k
                   (!strcmp(argv[i], "--noenc"))) {
2559
2.74k
            lint->parseOptions |= XML_PARSE_IGNORE_ENC;
2560
2.74k
#ifdef LIBXML_HTML_ENABLED
2561
2.74k
            lint->htmlOptions |= HTML_PARSE_IGNORE_ENC;
2562
2.74k
#endif
2563
155k
        } else if ((!strcmp(argv[i], "-nsclean")) ||
2564
155k
                   (!strcmp(argv[i], "--nsclean"))) {
2565
4.26k
            lint->parseOptions |= XML_PARSE_NSCLEAN;
2566
151k
        } else if ((!strcmp(argv[i], "-nocdata")) ||
2567
151k
                   (!strcmp(argv[i], "--nocdata"))) {
2568
4.62k
            lint->parseOptions |= XML_PARSE_NOCDATA;
2569
146k
        } else if ((!strcmp(argv[i], "-nodict")) ||
2570
146k
                   (!strcmp(argv[i], "--nodict"))) {
2571
4.10k
            lint->parseOptions |= XML_PARSE_NODICT;
2572
142k
        } else if ((!strcmp(argv[i], "-version")) ||
2573
142k
                   (!strcmp(argv[i], "--version"))) {
2574
2.87k
            showVersion(errStream, argv[0]);
2575
2.87k
            lint->version = 1;
2576
139k
        } else if ((!strcmp(argv[i], "-noout")) ||
2577
139k
                   (!strcmp(argv[i], "--noout"))) {
2578
4.49k
            lint->noout = 1;
2579
4.49k
#ifdef LIBXML_HTML_ENABLED
2580
135k
        } else if ((!strcmp(argv[i], "-html")) ||
2581
135k
                   (!strcmp(argv[i], "--html"))) {
2582
1.23k
            lint->appOptions |= XML_LINT_HTML_ENABLED;
2583
133k
        } else if ((!strcmp(argv[i], "-nodefdtd")) ||
2584
133k
                   (!strcmp(argv[i], "--nodefdtd"))) {
2585
2.75k
            lint->htmlOptions |= HTML_PARSE_NODEFDTD;
2586
2.75k
#ifdef LIBXML_OUTPUT_ENABLED
2587
131k
        } else if ((!strcmp(argv[i], "-xmlout")) ||
2588
131k
                   (!strcmp(argv[i], "--xmlout"))) {
2589
2.62k
            lint->appOptions |= XML_LINT_XML_OUT;
2590
2.62k
#endif
2591
2.62k
#endif /* LIBXML_HTML_ENABLED */
2592
128k
        } else if ((!strcmp(argv[i], "-loaddtd")) ||
2593
128k
                   (!strcmp(argv[i], "--loaddtd"))) {
2594
3.30k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2595
125k
        } else if ((!strcmp(argv[i], "-dtdattr")) ||
2596
125k
                   (!strcmp(argv[i], "--dtdattr"))) {
2597
4.75k
            lint->parseOptions |= XML_PARSE_DTDATTR;
2598
4.75k
#ifdef LIBXML_VALID_ENABLED
2599
120k
        } else if ((!strcmp(argv[i], "-valid")) ||
2600
120k
                   (!strcmp(argv[i], "--valid"))) {
2601
2.81k
            lint->parseOptions |= XML_PARSE_DTDVALID;
2602
117k
        } else if ((!strcmp(argv[i], "-postvalid")) ||
2603
117k
                   (!strcmp(argv[i], "--postvalid"))) {
2604
1.74k
            lint->appOptions |= XML_LINT_POST_VALIDATION;
2605
1.74k
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2606
115k
        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
2607
115k
                   (!strcmp(argv[i], "--dtdvalid"))) {
2608
0
            i++;
2609
0
            lint->dtdvalid = argv[i];
2610
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2611
115k
        } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2612
115k
                   (!strcmp(argv[i], "--dtdvalidfpi"))) {
2613
0
            i++;
2614
0
            lint->dtdvalidfpi = argv[i];
2615
0
            lint->parseOptions |= XML_PARSE_DTDLOAD;
2616
115k
        } else if ((!strcmp(argv[i], "-insert")) ||
2617
115k
                   (!strcmp(argv[i], "--insert"))) {
2618
5.95k
            lint->appOptions |= XML_LINT_VALID_INSERTIONS;
2619
5.95k
#endif /* LIBXML_VALID_ENABLED */
2620
109k
        } else if ((!strcmp(argv[i], "-strict-namespace")) ||
2621
109k
            (!strcmp(argv[i], "--strict-namespace"))) {
2622
0
            lint->appOptions |= XML_LINT_STRICT_NAMESPACE;
2623
109k
        } else if ((!strcmp(argv[i], "-dropdtd")) ||
2624
109k
                   (!strcmp(argv[i], "--dropdtd"))) {
2625
1.55k
            lint->appOptions |= XML_LINT_DROP_DTD;
2626
108k
        } else if ((!strcmp(argv[i], "-quiet")) ||
2627
108k
                   (!strcmp(argv[i], "--quiet"))) {
2628
1.52k
            lint->appOptions |= XML_LINT_QUIET;
2629
106k
        } else if ((!strcmp(argv[i], "-timing")) ||
2630
106k
                   (!strcmp(argv[i], "--timing"))) {
2631
2.95k
            lint->appOptions |= XML_LINT_TIMINGS;
2632
103k
        } else if ((!strcmp(argv[i], "-auto")) ||
2633
103k
                   (!strcmp(argv[i], "--auto"))) {
2634
10.0k
            lint->appOptions |= XML_LINT_GENERATE;
2635
93.8k
        } else if ((!strcmp(argv[i], "-repeat")) ||
2636
93.8k
                   (!strcmp(argv[i], "--repeat"))) {
2637
1.10k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2638
1.10k
            lint->repeat = 2;
2639
#else
2640
            if (lint->repeat > 1)
2641
                lint->repeat *= 10;
2642
            else
2643
                lint->repeat = 100;
2644
#endif
2645
1.10k
#ifdef LIBXML_PUSH_ENABLED
2646
92.7k
        } else if ((!strcmp(argv[i], "-push")) ||
2647
92.7k
                   (!strcmp(argv[i], "--push"))) {
2648
520
            lint->appOptions |= XML_LINT_PUSH_ENABLED;
2649
520
#endif /* LIBXML_PUSH_ENABLED */
2650
520
#if HAVE_DECL_MMAP
2651
92.1k
        } else if ((!strcmp(argv[i], "-memory")) ||
2652
92.1k
                   (!strcmp(argv[i], "--memory"))) {
2653
0
            lint->appOptions |= XML_LINT_MEMORY;
2654
0
#endif
2655
0
#ifdef LIBXML_XINCLUDE_ENABLED
2656
92.1k
        } else if ((!strcmp(argv[i], "-xinclude")) ||
2657
92.1k
                   (!strcmp(argv[i], "--xinclude"))) {
2658
3.67k
            lint->appOptions |= XML_LINT_XINCLUDE;
2659
3.67k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2660
88.5k
        } else if ((!strcmp(argv[i], "-noxincludenode")) ||
2661
88.5k
                   (!strcmp(argv[i], "--noxincludenode"))) {
2662
5.60k
            lint->appOptions |= XML_LINT_XINCLUDE;
2663
5.60k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2664
5.60k
            lint->parseOptions |= XML_PARSE_NOXINCNODE;
2665
82.9k
        } else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
2666
82.9k
                   (!strcmp(argv[i], "--nofixup-base-uris"))) {
2667
3.74k
            lint->appOptions |= XML_LINT_XINCLUDE;
2668
3.74k
            lint->parseOptions |= XML_PARSE_XINCLUDE;
2669
3.74k
            lint->parseOptions |= XML_PARSE_NOBASEFIX;
2670
3.74k
#endif
2671
79.1k
        } else if ((!strcmp(argv[i], "-nowarning")) ||
2672
79.1k
                   (!strcmp(argv[i], "--nowarning"))) {
2673
5.30k
            lint->parseOptions |= XML_PARSE_NOWARNING;
2674
5.30k
            lint->parseOptions &= ~XML_PARSE_PEDANTIC;
2675
5.30k
#ifdef LIBXML_HTML_ENABLED
2676
5.30k
            lint->htmlOptions |= HTML_PARSE_NOWARNING;
2677
5.30k
#endif
2678
73.8k
        } else if ((!strcmp(argv[i], "-pedantic")) ||
2679
73.8k
                   (!strcmp(argv[i], "--pedantic"))) {
2680
1.57k
            lint->parseOptions |= XML_PARSE_PEDANTIC;
2681
1.57k
            lint->parseOptions &= ~XML_PARSE_NOWARNING;
2682
1.57k
#ifdef LIBXML_CATALOG_ENABLED
2683
72.2k
        } else if ((!strcmp(argv[i], "-catalogs")) ||
2684
72.2k
                   (!strcmp(argv[i], "--catalogs"))) {
2685
0
            lint->appOptions |= XML_LINT_USE_CATALOGS;
2686
72.2k
        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
2687
72.2k
                   (!strcmp(argv[i], "--nocatalogs"))) {
2688
10.8k
            lint->appOptions |= XML_LINT_USE_NO_CATALOGS;
2689
10.8k
            lint->parseOptions |= XML_PARSE_NO_SYS_CATALOG;
2690
10.8k
#endif
2691
61.4k
        } else if ((!strcmp(argv[i], "-noblanks")) ||
2692
61.4k
                   (!strcmp(argv[i], "--noblanks"))) {
2693
3.29k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2694
3.29k
#ifdef LIBXML_HTML_ENABLED
2695
3.29k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2696
3.29k
#endif
2697
3.29k
#ifdef LIBXML_OUTPUT_ENABLED
2698
58.1k
        } else if ((!strcmp(argv[i], "-o")) ||
2699
58.1k
                   (!strcmp(argv[i], "-output")) ||
2700
58.1k
                   (!strcmp(argv[i], "--output"))) {
2701
0
            i++;
2702
0
            lint->output = argv[i];
2703
58.1k
        } else if ((!strcmp(argv[i], "-format")) ||
2704
58.1k
                   (!strcmp(argv[i], "--format"))) {
2705
5.78k
            lint->format = 1;
2706
5.78k
            lint->parseOptions |= XML_PARSE_NOBLANKS;
2707
5.78k
#ifdef LIBXML_HTML_ENABLED
2708
5.78k
            lint->htmlOptions |= HTML_PARSE_NOBLANKS;
2709
5.78k
#endif
2710
52.3k
        } else if ((!strcmp(argv[i], "-encode")) ||
2711
52.3k
                   (!strcmp(argv[i], "--encode"))) {
2712
692
            i++;
2713
692
            lint->encoding = argv[i];
2714
51.6k
        } else if ((!strcmp(argv[i], "-pretty")) ||
2715
51.6k
                   (!strcmp(argv[i], "--pretty"))) {
2716
4.23k
            i++;
2717
4.23k
            if (i >= argc) {
2718
0
                fprintf(errStream, "pretty: missing integer value\n");
2719
0
                return(XMLLINT_ERR_UNCLASS);
2720
0
            }
2721
4.23k
            if (parseInteger(&val, errStream, "pretty", argv[i],
2722
4.23k
                             0, 2) < 0)
2723
24
                return(XMLLINT_ERR_UNCLASS);
2724
4.20k
            lint->format = val;
2725
4.20k
#ifdef LIBXML_ZLIB_ENABLED
2726
47.4k
        } else if ((!strcmp(argv[i], "-compress")) ||
2727
47.4k
                   (!strcmp(argv[i], "--compress"))) {
2728
2.25k
            lint->appOptions |= XML_LINT_ZLIB_COMPRESSION;
2729
2.25k
#endif
2730
2.25k
#ifdef LIBXML_C14N_ENABLED
2731
45.1k
        } else if ((!strcmp(argv[i], "-c14n")) ||
2732
45.1k
                   (!strcmp(argv[i], "--c14n"))) {
2733
2.99k
            lint->appOptions |= XML_LINT_CANONICAL_V1_0;
2734
2.99k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2735
42.1k
        } else if ((!strcmp(argv[i], "-c14n11")) ||
2736
42.1k
                   (!strcmp(argv[i], "--c14n11"))) {
2737
5.70k
            lint->appOptions |= XML_LINT_CANONICAL_V1_1;
2738
5.70k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2739
36.4k
        } else if ((!strcmp(argv[i], "-exc-c14n")) ||
2740
36.4k
                   (!strcmp(argv[i], "--exc-c14n"))) {
2741
3.40k
            lint->appOptions |= XML_LINT_CANONICAL_EXE;
2742
3.40k
            lint->parseOptions |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
2743
3.40k
#endif /* LIBXML_C14N_ENABLED */
2744
3.40k
#endif /* LIBXML_OUTPUT_ENABLED */
2745
3.40k
#ifdef LIBXML_READER_ENABLED
2746
33.0k
        } else if ((!strcmp(argv[i], "-stream")) ||
2747
33.0k
                   (!strcmp(argv[i], "--stream"))) {
2748
3.16k
             lint->appOptions |= XML_LINT_USE_STREAMING;
2749
29.9k
        } else if ((!strcmp(argv[i], "-walker")) ||
2750
29.9k
                   (!strcmp(argv[i], "--walker"))) {
2751
3.12k
             lint->appOptions |= XML_LINT_USE_WALKER;
2752
3.12k
             lint->noout = 1;
2753
3.12k
#ifdef LIBXML_PATTERN_ENABLED
2754
26.7k
        } else if ((!strcmp(argv[i], "-pattern")) ||
2755
26.7k
                   (!strcmp(argv[i], "--pattern"))) {
2756
1.76k
            i++;
2757
1.76k
            lint->pattern = argv[i];
2758
1.76k
#endif
2759
1.76k
#endif /* LIBXML_READER_ENABLED */
2760
1.76k
#ifdef LIBXML_SAX1_ENABLED
2761
25.0k
        } else if ((!strcmp(argv[i], "-sax1")) ||
2762
25.0k
                   (!strcmp(argv[i], "--sax1"))) {
2763
583
            lint->parseOptions |= XML_PARSE_SAX1;
2764
583
#endif /* LIBXML_SAX1_ENABLED */
2765
24.4k
        } else if ((!strcmp(argv[i], "-sax")) ||
2766
24.4k
                   (!strcmp(argv[i], "--sax"))) {
2767
610
            lint->appOptions |= XML_LINT_SAX_ENABLED;
2768
610
#ifdef LIBXML_RELAXNG_ENABLED
2769
23.8k
        } else if ((!strcmp(argv[i], "-relaxng")) ||
2770
23.8k
                   (!strcmp(argv[i], "--relaxng"))) {
2771
0
            i++;
2772
0
            lint->relaxng = argv[i];
2773
0
            lint->parseOptions |= XML_PARSE_NOENT;
2774
0
#endif
2775
0
#ifdef LIBXML_SCHEMAS_ENABLED
2776
23.8k
        } else if ((!strcmp(argv[i], "-schema")) ||
2777
23.8k
                 (!strcmp(argv[i], "--schema"))) {
2778
0
            i++;
2779
0
            lint->schema = argv[i];
2780
0
            lint->parseOptions |= XML_PARSE_NOENT;
2781
0
#endif
2782
#ifdef LIBXML_SCHEMATRON_ENABLED
2783
        } else if ((!strcmp(argv[i], "-schematron")) ||
2784
                   (!strcmp(argv[i], "--schematron"))) {
2785
            i++;
2786
            lint->schematron = argv[i];
2787
            lint->parseOptions |= XML_PARSE_NOENT;
2788
#endif
2789
23.8k
        } else if ((!strcmp(argv[i], "-nonet")) ||
2790
23.8k
                   (!strcmp(argv[i], "--nonet"))) {
2791
2.90k
            lint->parseOptions |= XML_PARSE_NONET;
2792
20.9k
        } else if ((!strcmp(argv[i], "-nocompact")) ||
2793
20.9k
                   (!strcmp(argv[i], "--nocompact"))) {
2794
3.91k
            lint->parseOptions &= ~XML_PARSE_COMPACT;
2795
3.91k
#ifdef LIBXML_HTML_ENABLED
2796
3.91k
            lint->htmlOptions &= ~HTML_PARSE_COMPACT;
2797
3.91k
#endif
2798
17.0k
        } else if ((!strcmp(argv[i], "-load-trace")) ||
2799
17.0k
                   (!strcmp(argv[i], "--load-trace"))) {
2800
3.67k
            lint->appOptions |= XML_LINT_USE_LOAD_TRACE;
2801
13.3k
        } else if ((!strcmp(argv[i], "-path")) ||
2802
13.3k
                   (!strcmp(argv[i], "--path"))) {
2803
0
            i++;
2804
0
            parsePath(lint, BAD_CAST argv[i]);
2805
0
#ifdef LIBXML_XPATH_ENABLED
2806
13.3k
        } else if ((!strcmp(argv[i], "-xpath")) ||
2807
13.3k
                   (!strcmp(argv[i], "--xpath"))) {
2808
8.76k
            i++;
2809
8.76k
            lint->noout++;
2810
8.76k
            lint->xpathquery = argv[i];
2811
8.76k
#endif
2812
8.76k
        } else if ((!strcmp(argv[i], "-oldxml10")) ||
2813
4.57k
                   (!strcmp(argv[i], "--oldxml10"))) {
2814
3.59k
            lint->parseOptions |= XML_PARSE_OLD10;
2815
3.59k
        } else if ((!strcmp(argv[i], "-max-ampl")) ||
2816
977
                   (!strcmp(argv[i], "--max-ampl"))) {
2817
851
            i++;
2818
851
            if (i >= argc) {
2819
0
                fprintf(errStream, "max-ampl: missing integer value\n");
2820
0
                return(XMLLINT_ERR_UNCLASS);
2821
0
            }
2822
851
            if (parseInteger(&val, errStream, "max-ampl", argv[i],
2823
851
                             1, UINT_MAX) < 0)
2824
0
                return(XMLLINT_ERR_UNCLASS);
2825
851
            lint->maxAmpl = val;
2826
851
        } else {
2827
126
            fprintf(errStream, "Unknown option %s\n", argv[i]);
2828
126
            usage(errStream, argv[0]);
2829
126
            return(XMLLINT_ERR_UNCLASS);
2830
126
        }
2831
172k
    }
2832
2833
10.7k
    if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2834
0
        lint->repeat = 1;
2835
2836
10.7k
#ifdef LIBXML_READER_ENABLED
2837
10.7k
    if (lint->appOptions & XML_LINT_USE_STREAMING) {
2838
3.16k
        specialMode = "--stream";
2839
2840
3.16k
        if (lint->appOptions & XML_LINT_SAX_ENABLED)
2841
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--sax");
2842
3.16k
#ifdef LIBXML_PUSH_ENABLED
2843
3.16k
        if (lint->appOptions & XML_LINT_PUSH_ENABLED)
2844
374
            xmllintOptWarnNoSupport(errStream, "--stream", "--push");
2845
3.16k
#endif
2846
3.16k
#ifdef LIBXML_HTML_ENABLED
2847
3.16k
        if (lint->appOptions & XML_LINT_HTML_ENABLED)
2848
0
            xmllintOptWarnNoSupport(errStream, "--stream", "--html");
2849
3.16k
#endif
2850
3.16k
    }
2851
10.7k
#endif /* LIBXML_READER_ENABLED */
2852
2853
10.7k
    if (lint->appOptions & XML_LINT_SAX_ENABLED) {
2854
610
        specialMode = "--sax";
2855
2856
610
#ifdef LIBXML_XINCLUDE_ENABLED
2857
610
        if (lint->appOptions & XML_LINT_XINCLUDE)
2858
554
            xmllintOptWarnNoSupport(errStream, "--sax", "--xinclude");
2859
610
#endif
2860
610
#ifdef LIBXML_RELAXNG_ENABLED
2861
610
        if (lint->relaxng != NULL)
2862
0
            xmllintOptWarnNoSupport(errStream, "--sax", "--relaxng");
2863
610
#endif
2864
610
    }
2865
2866
10.7k
    if (specialMode != NULL) {
2867
3.77k
        if (lint->appOptions & XML_LINT_GENERATE)
2868
3.59k
            xmllintOptWarnNoSupport(errStream, specialMode, "--auto");
2869
3.77k
        if (lint->appOptions & XML_LINT_DROP_DTD)
2870
520
            xmllintOptWarnNoSupport(errStream, specialMode, "--dropdtd");
2871
3.77k
        if (lint->appOptions & XML_LINT_NAVIGATING_SHELL)
2872
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--shell");
2873
3.77k
        if (lint->appOptions & XML_LINT_COPY_ENABLED)
2874
1.12k
            xmllintOptWarnNoSupport(errStream, specialMode, "--copy");
2875
3.77k
#ifdef LIBXML_XPATH_ENABLED
2876
3.77k
        if (lint->xpathquery != NULL)
2877
3.05k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xpath");
2878
3.77k
#endif
2879
3.77k
#ifdef LIBXML_READER_ENABLED
2880
3.77k
        if (lint->appOptions & XML_LINT_USE_WALKER)
2881
1.42k
            xmllintOptWarnNoSupport(errStream, specialMode, "--walker");
2882
3.77k
#endif
2883
3.77k
#ifdef LIBXML_VALID_ENABLED
2884
3.77k
        if (lint->appOptions & XML_LINT_VALID_INSERTIONS)
2885
2.04k
            xmllintOptWarnNoSupport(errStream, specialMode, "--insert");
2886
3.77k
        if (lint->dtdvalid != NULL)
2887
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalid");
2888
3.77k
        if (lint->dtdvalidfpi != NULL)
2889
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--dtdvalidfpi");
2890
3.77k
        if (lint->appOptions & XML_LINT_POST_VALIDATION)
2891
686
            xmllintOptWarnNoSupport(errStream, specialMode, "--postvalid");
2892
3.77k
#endif
2893
#ifdef LIBXML_SCHEMATRON_ENABLED
2894
        if (lint->schematron != NULL)
2895
            xmllintOptWarnNoSupport(errStream, specialMode, "--schematron");
2896
#endif
2897
3.77k
#ifdef LIBXML_OUTPUT_ENABLED
2898
3.77k
        if (lint->output != NULL)
2899
0
            xmllintOptWarnNoSupport(errStream, specialMode, "--output");
2900
3.77k
        if (lint->encoding != NULL)
2901
274
            xmllintOptWarnNoSupport(errStream, specialMode, "--encode");
2902
3.77k
        if (lint->format > 0)
2903
2.05k
            xmllintOptWarnNoSupport(errStream, specialMode,
2904
2.05k
                                    "--format or -pretty");
2905
3.77k
#ifdef LIBXML_ZLIB_ENABLED
2906
3.77k
        if (lint->appOptions & XML_LINT_ZLIB_COMPRESSION)
2907
727
            xmllintOptWarnNoSupport(errStream, specialMode, "--compress");
2908
3.77k
#endif
2909
3.77k
#ifdef LIBXML_HTML_ENABLED
2910
3.77k
        if (lint->appOptions & XML_LINT_XML_OUT)
2911
1.13k
            xmllintOptWarnNoSupport(errStream, specialMode, "--xmlout");
2912
3.77k
#endif
2913
3.77k
#ifdef LIBXML_C14N_ENABLED
2914
3.77k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_0)
2915
1.08k
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n");
2916
3.77k
        if (lint->appOptions & XML_LINT_CANONICAL_V1_1)
2917
1.91k
            xmllintOptWarnNoSupport(errStream, specialMode, "--c14n11");
2918
3.77k
        if (lint->appOptions & XML_LINT_CANONICAL_EXE)
2919
1.13k
            xmllintOptWarnNoSupport(errStream, specialMode, "--exc-c14n");
2920
3.77k
#endif
2921
3.77k
#endif /* LIBXML_OUTPUT_ENABLED */
2922
3.77k
    }
2923
2924
10.7k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
2925
10.7k
    if (lint->pattern && !((lint->appOptions & XML_LINT_USE_STREAMING) || (lint->appOptions & XML_LINT_USE_WALKER)))
2926
727
        fprintf(errStream, "Warning: Option %s requires %s\n",
2927
727
                "--pattern", "--stream or --walker");
2928
10.7k
#endif
2929
2930
10.7k
#ifdef LIBXML_HTML_ENABLED
2931
10.7k
    if (lint->appOptions & XML_LINT_HTML_ENABLED) {
2932
1.23k
        if (lint->parseOptions & XML_PARSE_DTDATTR)
2933
1.14k
            xmllintOptWarnNoSupport(errStream, "--html", "--dtdattr");
2934
1.23k
        if (lint->parseOptions & XML_PARSE_DTDLOAD)
2935
1.13k
            xmllintOptWarnNoSupport(errStream, "--html", "--loaddtd");
2936
1.23k
        if (lint->maxAmpl)
2937
166
            xmllintOptWarnNoSupport(errStream, "--html", "--max-ampl");
2938
1.23k
        if (lint->parseOptions & XML_PARSE_NOCDATA)
2939
657
            xmllintOptWarnNoSupport(errStream, "--html", "--nocdata");
2940
1.23k
        if (lint->parseOptions & XML_PARSE_NODICT)
2941
395
            xmllintOptWarnNoSupport(errStream, "--html", "--nodict");
2942
1.23k
        if (lint->parseOptions & XML_PARSE_NOENT)
2943
1.11k
            xmllintOptWarnNoSupport(errStream, "--html", "--noent");
2944
1.23k
        if (lint->parseOptions & XML_PARSE_NONET)
2945
440
            xmllintOptWarnNoSupport(errStream, "--html", "--nonet");
2946
1.23k
        if (lint->parseOptions & XML_PARSE_NSCLEAN)
2947
417
            xmllintOptWarnNoSupport(errStream, "--html", "--nsclean");
2948
1.23k
        if (lint->parseOptions & XML_PARSE_OLD10)
2949
354
            xmllintOptWarnNoSupport(errStream, "--html", "--oldxml10");
2950
1.23k
        if (lint->parseOptions & XML_PARSE_PEDANTIC)
2951
147
            xmllintOptWarnNoSupport(errStream, "--html", "--pedantic");
2952
1.23k
        if (lint->parseOptions & XML_PARSE_DTDVALID)
2953
730
            xmllintOptWarnNoSupport(errStream, "--html", "--valid");
2954
1.23k
        if (lint->parseOptions & XML_PARSE_SAX1)
2955
82
            xmllintOptWarnNoSupport(errStream, "--html", "--sax1");
2956
9.46k
    } else {
2957
9.46k
        if (lint->htmlOptions & HTML_PARSE_NODEFDTD)
2958
2.42k
            fprintf(errStream, "Warning: Option %s requires %s\n",
2959
2.42k
                    "--nodefdtd", "--html");
2960
9.46k
#ifdef LIBXML_OUTPUT_ENABLED
2961
9.46k
        if (lint->appOptions & XML_LINT_XML_OUT)
2962
1.81k
            fprintf(errStream, "Warning: Option %s requires %s\n",
2963
1.81k
                    "--xmlout", "--html");
2964
9.46k
#endif
2965
9.46k
    }
2966
10.7k
#endif
2967
2968
10.7k
    return(XMLLINT_RETURN_OK);
2969
10.8k
}
2970
2971
int
2972
xmllintMain(int argc, const char **argv, FILE *errStream,
2973
10.8k
            xmlResourceLoader loader) {
2974
10.8k
    xmllintState state, *lint;
2975
10.8k
    int i, j, res;
2976
10.8k
    int files = 0;
2977
2978
#ifdef _WIN32
2979
    _setmode(_fileno(stdin), _O_BINARY);
2980
    _setmode(_fileno(stdout), _O_BINARY);
2981
    _setmode(_fileno(stderr), _O_BINARY);
2982
#endif
2983
2984
10.8k
    lint = &state;
2985
10.8k
    xmllintInit(lint);
2986
10.8k
    lint->errStream = errStream;
2987
10.8k
    lint->defaultResourceLoader = loader;
2988
2989
10.8k
    res = xmllintParseOptions(lint, argc, argv);
2990
10.8k
    if (res != XMLLINT_RETURN_OK) {
2991
150
        return(res);
2992
150
    }
2993
2994
    /*
2995
     * Note that we must not make any memory allocations through xmlMalloc
2996
     * before calling xmlMemSetup.
2997
     */
2998
10.7k
    if (lint->maxmem != 0) {
2999
307
        xmllintMaxmem = 0;
3000
307
        xmllintMaxmemReached = 0;
3001
307
        xmllintOom = 0;
3002
307
        xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
3003
307
    }
3004
3005
10.7k
    LIBXML_TEST_VERSION
3006
3007
10.7k
#ifdef LIBXML_CATALOG_ENABLED
3008
10.7k
    if ((lint->appOptions & XML_LINT_USE_NO_CATALOGS) != XML_LINT_USE_NO_CATALOGS) {
3009
0
  if (lint->appOptions & XML_LINT_USE_CATALOGS) {
3010
0
      const char *catal;
3011
3012
0
      catal = getenv("SGML_CATALOG_FILES");
3013
0
      if (catal != NULL) {
3014
0
    xmlLoadCatalogs(catal);
3015
0
      } else {
3016
0
    fprintf(errStream, "Variable $SGML_CATALOG_FILES not set\n");
3017
0
      }
3018
0
  }
3019
0
    }
3020
10.7k
#endif
3021
3022
10.7k
#ifdef LIBXML_OUTPUT_ENABLED
3023
10.7k
    {
3024
10.7k
        const char *indent = getenv("XMLLINT_INDENT");
3025
10.7k
        if (indent != NULL) {
3026
0
            lint->indentString = indent;
3027
0
        }
3028
10.7k
    }
3029
10.7k
#endif
3030
3031
#ifdef LIBXML_SCHEMATRON_ENABLED
3032
    if ((lint->schematron != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED)
3033
#ifdef LIBXML_READER_ENABLED
3034
        && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3035
#endif /* LIBXML_READER_ENABLED */
3036
  ) {
3037
  xmlSchematronParserCtxtPtr ctxt;
3038
3039
        /* forces loading the DTDs */
3040
  lint->parseOptions |= XML_PARSE_DTDLOAD;
3041
  if (lint->appOptions & XML_LINT_TIMINGS) {
3042
      startTimer(lint);
3043
  }
3044
  ctxt = xmlSchematronNewParserCtxt(lint->schematron);
3045
        if (ctxt == NULL) {
3046
            lint->progresult = XMLLINT_ERR_MEM;
3047
            goto error;
3048
        }
3049
  lint->wxschematron = xmlSchematronParse(ctxt);
3050
  xmlSchematronFreeParserCtxt(ctxt);
3051
  if (lint->wxschematron == NULL) {
3052
      fprintf(errStream, "Schematron schema %s failed to compile\n",
3053
                    lint->schematron);
3054
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
3055
            goto error;
3056
  }
3057
  if (lint->appOptions & XML_LINT_TIMINGS) {
3058
      endTimer(lint, "Compiling the schemas");
3059
  }
3060
    }
3061
#endif
3062
3063
10.7k
#ifdef LIBXML_RELAXNG_ENABLED
3064
10.7k
    if ((lint->relaxng != NULL) && ((lint->appOptions & XML_LINT_SAX_ENABLED) != XML_LINT_SAX_ENABLED)
3065
10.7k
#ifdef LIBXML_READER_ENABLED
3066
10.7k
        && ((lint->appOptions & XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3067
10.7k
#endif /* LIBXML_READER_ENABLED */
3068
10.7k
  ) {
3069
0
  xmlRelaxNGParserCtxtPtr ctxt;
3070
3071
        /* forces loading the DTDs */
3072
0
  lint->parseOptions |= XML_PARSE_DTDLOAD;
3073
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3074
0
      startTimer(lint);
3075
0
  }
3076
0
  ctxt = xmlRelaxNGNewParserCtxt(lint->relaxng);
3077
0
        if (ctxt == NULL) {
3078
0
            lint->progresult = XMLLINT_ERR_MEM;
3079
0
            goto error;
3080
0
        }
3081
0
        xmlRelaxNGSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3082
0
  lint->relaxngschemas = xmlRelaxNGParse(ctxt);
3083
0
  xmlRelaxNGFreeParserCtxt(ctxt);
3084
0
  if (lint->relaxngschemas == NULL) {
3085
0
      fprintf(errStream, "Relax-NG schema %s failed to compile\n",
3086
0
                    lint->relaxng);
3087
0
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
3088
0
            goto error;
3089
0
  }
3090
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3091
0
      endTimer(lint, "Compiling the schemas");
3092
0
  }
3093
0
    }
3094
10.7k
#endif /* LIBXML_RELAXNG_ENABLED */
3095
3096
10.7k
#ifdef LIBXML_SCHEMAS_ENABLED
3097
10.7k
    if ((lint->schema != NULL)
3098
10.7k
#ifdef LIBXML_READER_ENABLED
3099
10.7k
        && ((lint->appOptions& XML_LINT_USE_STREAMING) != XML_LINT_USE_STREAMING)
3100
10.7k
#endif
3101
10.7k
  ) {
3102
0
  xmlSchemaParserCtxtPtr ctxt;
3103
3104
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3105
0
      startTimer(lint);
3106
0
  }
3107
0
  ctxt = xmlSchemaNewParserCtxt(lint->schema);
3108
0
        if (ctxt == NULL) {
3109
0
            lint->progresult = XMLLINT_ERR_MEM;
3110
0
            goto error;
3111
0
        }
3112
0
        xmlSchemaSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3113
0
  lint->wxschemas = xmlSchemaParse(ctxt);
3114
0
  xmlSchemaFreeParserCtxt(ctxt);
3115
0
  if (lint->wxschemas == NULL) {
3116
0
      fprintf(errStream, "WXS schema %s failed to compile\n",
3117
0
                    lint->schema);
3118
0
            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
3119
0
            goto error;
3120
0
  }
3121
0
  if (lint->appOptions & XML_LINT_TIMINGS) {
3122
0
      endTimer(lint, "Compiling the schemas");
3123
0
  }
3124
0
    }
3125
10.7k
#endif /* LIBXML_SCHEMAS_ENABLED */
3126
3127
10.7k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3128
10.7k
    if ((lint->pattern != NULL) && ((lint->appOptions & XML_LINT_USE_WALKER) != XML_LINT_USE_WALKER)) {
3129
1.04k
        res = xmlPatternCompileSafe(BAD_CAST lint->pattern, NULL, 0, NULL,
3130
1.04k
                                    &lint->patternc);
3131
1.04k
  if (lint->patternc == NULL) {
3132
567
            if (res < 0) {
3133
50
                lint->progresult = XMLLINT_ERR_MEM;
3134
517
            } else {
3135
517
                fprintf(errStream, "Pattern %s failed to compile\n",
3136
517
                        lint->pattern);
3137
517
                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
3138
517
            }
3139
567
            goto error;
3140
567
  }
3141
1.04k
    }
3142
10.1k
#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
3143
3144
    /*
3145
     * The main loop over input documents
3146
     */
3147
183k
    for (i = 1; i < argc ; i++) {
3148
173k
        const char *filename = argv[i];
3149
173k
#if HAVE_DECL_MMAP
3150
173k
        int memoryFd = -1;
3151
173k
#endif
3152
3153
173k
  if ((filename[0] == '-') && (strcmp(filename, "-") != 0)) {
3154
163k
            i += skipArgs(filename);
3155
163k
            continue;
3156
163k
        }
3157
3158
10.1k
#if HAVE_DECL_MMAP
3159
10.1k
        if (lint->appOptions & XML_LINT_MEMORY) {
3160
0
            struct stat info;
3161
0
            if (stat(filename, &info) < 0) {
3162
0
                lint->progresult = XMLLINT_ERR_RDFILE;
3163
0
                break;
3164
0
            }
3165
0
            memoryFd = open(filename, O_RDONLY);
3166
0
            if (memoryFd < 0) {
3167
0
                lint->progresult = XMLLINT_ERR_RDFILE;
3168
0
                break;
3169
0
            }
3170
0
            lint->memoryData = mmap(NULL, info.st_size, PROT_READ,
3171
0
                                    MAP_SHARED, memoryFd, 0);
3172
0
            if (lint->memoryData == (void *) MAP_FAILED) {
3173
0
                close(memoryFd);
3174
0
                fprintf(errStream, "mmap failure for file %s\n", filename);
3175
0
                lint->progresult = XMLLINT_ERR_RDFILE;
3176
0
                break;
3177
0
            }
3178
0
            lint->memorySize = info.st_size;
3179
0
        }
3180
10.1k
#endif /* HAVE_DECL_MMAP */
3181
3182
10.1k
  if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1))
3183
371
      startTimer(lint);
3184
3185
10.1k
#ifdef LIBXML_READER_ENABLED
3186
10.1k
        if (lint->appOptions & XML_LINT_USE_STREAMING) {
3187
6.41k
            for (j = 0; j < lint->repeat; j++)
3188
3.39k
                streamFile(lint, filename);
3189
3.01k
        } else
3190
7.12k
#endif /* LIBXML_READER_ENABLED */
3191
7.12k
        {
3192
7.12k
            xmlParserCtxtPtr ctxt;
3193
3194
7.12k
#ifdef LIBXML_HTML_ENABLED
3195
7.12k
            if (lint->appOptions & XML_LINT_HTML_ENABLED) {
3196
1.21k
#ifdef LIBXML_PUSH_ENABLED
3197
1.21k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3198
18
                    ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3199
18
                                                    filename,
3200
18
                                                    XML_CHAR_ENCODING_NONE);
3201
18
                } else
3202
1.20k
#endif /* LIBXML_PUSH_ENABLED */
3203
1.20k
                {
3204
1.20k
                    ctxt = htmlNewParserCtxt();
3205
1.20k
                }
3206
1.21k
                htmlCtxtUseOptions(ctxt, lint->htmlOptions);
3207
1.21k
            } else
3208
5.90k
#endif /* LIBXML_HTML_ENABLED */
3209
5.90k
            {
3210
5.90k
#ifdef LIBXML_PUSH_ENABLED
3211
5.90k
                if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3212
34
                    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0,
3213
34
                                                   filename);
3214
34
                } else
3215
5.86k
#endif /* LIBXML_PUSH_ENABLED */
3216
5.86k
                {
3217
5.86k
                    ctxt = xmlNewParserCtxt();
3218
5.86k
                }
3219
5.90k
                xmlCtxtUseOptions(ctxt, lint->parseOptions);
3220
5.90k
            }
3221
7.12k
            if (ctxt == NULL) {
3222
220
                lint->progresult = XMLLINT_ERR_MEM;
3223
220
                goto error;
3224
220
            }
3225
3226
6.90k
            if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3227
581
                const xmlSAXHandler *handler;
3228
3229
581
                if (lint->noout) {
3230
525
                    handler = &emptySAXHandler;
3231
525
#ifdef LIBXML_SAX1_ENABLED
3232
525
                } else if (lint->parseOptions & XML_PARSE_SAX1) {
3233
13
                    handler = &debugSAXHandler;
3234
13
#endif
3235
43
                } else {
3236
43
                    handler = &debugSAX2Handler;
3237
43
                }
3238
3239
581
                *ctxt->sax = *handler;
3240
581
                ctxt->userData = lint;
3241
581
            }
3242
3243
6.90k
            xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint);
3244
6.90k
            if (lint->maxAmpl > 0)
3245
528
                xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl);
3246
3247
6.90k
            lint->ctxt = ctxt;
3248
3249
14.4k
            for (j = 0; j < lint->repeat; j++) {
3250
7.53k
                if (j > 0) {
3251
628
#ifdef LIBXML_PUSH_ENABLED
3252
628
                    if (lint->appOptions & XML_LINT_PUSH_ENABLED) {
3253
0
                        xmlCtxtResetPush(ctxt, NULL, 0, NULL, NULL);
3254
0
                    } else
3255
628
#endif
3256
628
                    {
3257
628
                        xmlCtxtReset(ctxt);
3258
628
                    }
3259
628
                }
3260
3261
7.53k
                if (lint->appOptions & XML_LINT_SAX_ENABLED) {
3262
711
                    testSAX(lint, filename);
3263
6.81k
                } else {
3264
6.81k
                    parseAndPrintFile(lint, filename);
3265
6.81k
                }
3266
7.53k
            }
3267
3268
6.90k
            xmlFreeParserCtxt(ctxt);
3269
6.90k
        }
3270
3271
9.91k
        if ((lint->appOptions & XML_LINT_TIMINGS) && (lint->repeat > 1)) {
3272
351
            endTimer(lint, "%d iterations", lint->repeat);
3273
351
        }
3274
3275
9.91k
        files += 1;
3276
3277
9.91k
#if HAVE_DECL_MMAP
3278
9.91k
        if (lint->appOptions & XML_LINT_MEMORY) {
3279
0
            munmap(lint->memoryData, lint->memorySize);
3280
0
            close(memoryFd);
3281
0
        }
3282
9.91k
#endif
3283
9.91k
    }
3284
3285
9.91k
    if (lint->appOptions & XML_LINT_GENERATE)
3286
9.62k
  parseAndPrintFile(lint, NULL);
3287
3288
9.91k
    if ((files == 0) && ((lint->appOptions & XML_LINT_GENERATE) != XML_LINT_GENERATE) && (lint->version == 0)) {
3289
0
  usage(errStream, argv[0]);
3290
0
        lint->progresult = XMLLINT_ERR_UNCLASS;
3291
0
    }
3292
3293
10.7k
error:
3294
3295
#ifdef LIBXML_SCHEMATRON_ENABLED
3296
    if (lint->wxschematron != NULL)
3297
  xmlSchematronFree(lint->wxschematron);
3298
#endif
3299
10.7k
#ifdef LIBXML_RELAXNG_ENABLED
3300
10.7k
    if (lint->relaxngschemas != NULL)
3301
0
  xmlRelaxNGFree(lint->relaxngschemas);
3302
10.7k
#endif
3303
10.7k
#ifdef LIBXML_SCHEMAS_ENABLED
3304
10.7k
    if (lint->wxschemas != NULL)
3305
0
  xmlSchemaFree(lint->wxschemas);
3306
10.7k
#endif
3307
10.7k
#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3308
10.7k
    if (lint->patternc != NULL)
3309
479
        xmlFreePattern(lint->patternc);
3310
10.7k
#endif
3311
3312
10.7k
    xmlCleanupParser();
3313
3314
10.7k
    if ((lint->maxmem) && (xmllintMaxmemReached)) {
3315
306
        fprintf(errStream, "Maximum memory exceeded (%d bytes)\n",
3316
306
                xmllintMaxmem);
3317
10.3k
    } else if (lint->progresult == XMLLINT_ERR_MEM) {
3318
1.62k
        fprintf(errStream, "Out-of-memory error reported\n");
3319
1.62k
    }
3320
3321
10.7k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
3322
10.7k
    if ((lint->maxmem) &&
3323
10.7k
        (xmllintOom != (lint->progresult == XMLLINT_ERR_MEM))) {
3324
0
        fprintf(stderr, "xmllint: malloc failure %s reported\n",
3325
0
                xmllintOom ? "not" : "erroneously");
3326
0
        abort();
3327
0
    }
3328
10.7k
#endif
3329
3330
10.7k
    return(lint->progresult);
3331
10.7k
}
3332