Coverage Report

Created: 2026-03-21 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxml2/error.c
Line
Count
Source
1
/*
2
 * error.c: module displaying/handling XML parser errors
3
 *
4
 * See Copyright for the status of this software.
5
 *
6
 * Author: Daniel Veillard
7
 */
8
9
#define IN_LIBXML
10
#include "libxml.h"
11
12
#include <string.h>
13
#include <stdarg.h>
14
#include <stdlib.h>
15
#include <libxml/parser.h>
16
#include <libxml/xmlerror.h>
17
#include <libxml/xmlmemory.h>
18
19
#include "private/error.h"
20
#include "private/globals.h"
21
#include "private/parser.h"
22
#include "private/string.h"
23
24
/**
25
 * This currently comprises
26
 *
27
 * - OOM errors
28
 * - assertion failures
29
 * - invalid argument errors
30
 * - I/O errors
31
 * - unexpected errors from external libraries
32
 *
33
 * @param level  error level
34
 * @param code  error code
35
 * @returns true if an error is catastrophic.
36
 */
37
int
38
2.07M
xmlIsCatastrophicError(int level, int code) {
39
2.07M
    int fatal = 0;
40
41
2.07M
    if (level != XML_ERR_FATAL)
42
353k
        return(0);
43
44
1.72M
    switch (code) {
45
0
        case XML_ERR_NO_MEMORY:
46
        /* case XML_ERR_RESOURCE_LIMIT: */
47
0
        case XML_ERR_SYSTEM:
48
0
        case XML_ERR_ARGUMENT:
49
0
        case XML_ERR_INTERNAL_ERROR:
50
0
            fatal = 1;
51
0
            break;
52
1.72M
        default:
53
1.72M
            if ((code >= 1500) && (code <= 1599))
54
0
                fatal = 1;
55
1.72M
            break;
56
1.72M
    }
57
58
1.72M
    return(fatal);
59
1.72M
}
60
61
/************************************************************************
62
 *                  *
63
 *      Error struct          *
64
 *                  *
65
 ************************************************************************/
66
67
static int
68
xmlVSetError(xmlError *err,
69
             void *ctxt, xmlNodePtr node,
70
             int domain, int code, xmlErrorLevel level,
71
             const char *file, int line,
72
             const char *str1, const char *str2, const char *str3,
73
             int int1, int col,
74
             const char *fmt, va_list ap)
75
796k
{
76
796k
    char *message = NULL;
77
796k
    char *fileCopy = NULL;
78
796k
    char *str1Copy = NULL;
79
796k
    char *str2Copy = NULL;
80
796k
    char *str3Copy = NULL;
81
82
796k
    if (code == XML_ERR_OK) {
83
0
        xmlResetError(err);
84
0
        return(0);
85
0
    }
86
87
    /*
88
     * Formatting the message
89
     */
90
796k
    if (fmt == NULL) {
91
0
        message = xmlMemStrdup("No error message provided");
92
796k
    } else {
93
796k
        xmlChar *tmp;
94
796k
        int res;
95
96
796k
        res = xmlStrVASPrintf(&tmp, MAX_ERR_MSG_SIZE, fmt, ap);
97
796k
        if (res < 0)
98
149
            goto err_memory;
99
795k
        message = (char *) tmp;
100
795k
    }
101
795k
    if (message == NULL)
102
0
        goto err_memory;
103
104
795k
    if (file != NULL) {
105
0
        fileCopy = (char *) xmlStrdup((const xmlChar *) file);
106
0
        if (fileCopy == NULL)
107
0
            goto err_memory;
108
0
    }
109
795k
    if (str1 != NULL) {
110
317k
        str1Copy = (char *) xmlStrdup((const xmlChar *) str1);
111
317k
        if (str1Copy == NULL)
112
109
            goto err_memory;
113
317k
    }
114
795k
    if (str2 != NULL) {
115
31.7k
        str2Copy = (char *) xmlStrdup((const xmlChar *) str2);
116
31.7k
        if (str2Copy == NULL)
117
4
            goto err_memory;
118
31.7k
    }
119
795k
    if (str3 != NULL) {
120
15.3k
        str3Copy = (char *) xmlStrdup((const xmlChar *) str3);
121
15.3k
        if (str3Copy == NULL)
122
0
            goto err_memory;
123
15.3k
    }
124
125
795k
    xmlResetError(err);
126
127
795k
    err->domain = domain;
128
795k
    err->code = code;
129
795k
    err->message = message;
130
795k
    err->level = level;
131
795k
    err->file = fileCopy;
132
795k
    err->line = line;
133
795k
    err->str1 = str1Copy;
134
795k
    err->str2 = str2Copy;
135
795k
    err->str3 = str3Copy;
136
795k
    err->int1 = int1;
137
795k
    err->int2 = col;
138
795k
    err->node = node;
139
795k
    err->ctxt = ctxt;
140
141
795k
    return(0);
142
143
262
err_memory:
144
262
    xmlFree(message);
145
262
    xmlFree(fileCopy);
146
262
    xmlFree(str1Copy);
147
262
    xmlFree(str2Copy);
148
262
    xmlFree(str3Copy);
149
262
    return(-1);
150
795k
}
151
152
static int LIBXML_ATTR_FORMAT(14,15)
153
xmlSetError(xmlError *err,
154
            void *ctxt, xmlNodePtr node,
155
            int domain, int code, xmlErrorLevel level,
156
            const char *file, int line,
157
            const char *str1, const char *str2, const char *str3,
158
            int int1, int col,
159
            const char *fmt, ...)
160
389k
{
161
389k
    va_list ap;
162
389k
    int res;
163
164
389k
    va_start(ap, fmt);
165
389k
    res = xmlVSetError(err, ctxt, node, domain, code, level, file, line,
166
389k
                       str1, str2, str3, int1, col, fmt, ap);
167
389k
    va_end(ap);
168
169
389k
    return(res);
170
389k
}
171
172
static int
173
xmlVUpdateError(xmlError *err,
174
                void *ctxt, xmlNodePtr node,
175
                int domain, int code, xmlErrorLevel level,
176
                const char *file, int line,
177
                const char *str1, const char *str2, const char *str3,
178
                int int1, int col,
179
                const char *fmt, va_list ap)
180
406k
{
181
406k
    int res;
182
183
    /*
184
     * Find first element parent.
185
     */
186
406k
    if (node != NULL) {
187
1.24k
        int i;
188
189
1.24k
        for (i = 0; i < 10; i++) {
190
1.24k
            if ((node->type == XML_ELEMENT_NODE) ||
191
0
                (node->parent == NULL))
192
1.24k
                break;
193
0
            node = node->parent;
194
0
        }
195
1.24k
    }
196
197
    /*
198
     * Get file and line from node.
199
     */
200
406k
    if (node != NULL) {
201
1.24k
        if ((file == NULL) && (node->doc != NULL))
202
1.24k
            file = (const char *) node->doc->URL;
203
204
1.24k
        if (line == 0) {
205
0
            if (node->type == XML_ELEMENT_NODE)
206
0
                line = node->line;
207
0
            if ((line == 0) || (line == 65535))
208
0
                line = xmlGetLineNo(node);
209
0
        }
210
1.24k
    }
211
212
406k
    res = xmlVSetError(err, ctxt, node, domain, code, level, file, line,
213
406k
                       str1, str2, str3, int1, col, fmt, ap);
214
215
406k
    return(res);
216
406k
}
217
218
/************************************************************************
219
 *                  *
220
 *      Handling of out of context errors   *
221
 *                  *
222
 ************************************************************************/
223
224
/**
225
 * Default handler for out-of-context error messages.
226
 *
227
 * @param ctx  user data (unused)
228
 * @param msg  printf-like format string
229
 * @param ...  arguments to format
230
 */
231
void
232
0
xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
233
0
    va_list args;
234
235
0
    if (xmlGenericErrorContext == NULL)
236
0
  xmlGenericErrorContext = (void *) stderr;
237
238
0
    va_start(args, msg);
239
0
    vfprintf((FILE *)xmlGenericErrorContext, msg, args);
240
0
    va_end(args);
241
0
}
242
243
/**
244
 * Set the thread-local "generic" handler and context for error
245
 * messages.
246
 *
247
 * @deprecated See #xmlSetStructuredErrorFunc for alternatives.
248
 *
249
 * If you only want to disable parser errors being printed to
250
 * stderr, use xmlParserOption XML_PARSE_NOERROR.
251
 *
252
 * The generic error handler will only receive fragments of
253
 * error messages which should be concatenated or printed to a
254
 * stream.
255
 *
256
 * If `handler` is NULL, use the built-in default handler which prints
257
 * to stderr.
258
 *
259
 * Since this is a thread-local setting, it's a good idea to reset
260
 * the error handler to its default value after collecting the
261
 * errors you're interested in. To get the original values, you
262
 * have to access xmlGenericError and xmlGenericErrorContext
263
 * directly, making this function kind of useless.
264
 *
265
 * For multi-threaded applications, this must be set separately for
266
 * each thread.
267
 *
268
 * @param ctx  the new error handling context
269
 * @param handler  the new handler function
270
 */
271
void
272
2
xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
273
2
    xmlGenericErrorContext = ctx;
274
2
    if (handler != NULL)
275
2
  xmlGenericError = handler;
276
0
    else
277
0
  xmlGenericError = xmlGenericErrorDefaultFunc;
278
2
}
279
280
/**
281
 * Set the thread-local "structured" handler and context for error
282
 * messages.
283
 *
284
 * @deprecated Use a per-context error handler.
285
 *
286
 * If you only want to disable parser errors being printed to
287
 * stderr, use xmlParserOption XML_PARSE_NOERROR.
288
 *
289
 * It's recommended to use the per-context error handlers instead:
290
 *
291
 * - #xmlCtxtSetErrorHandler (since 2.13.0)
292
 * - #xmlTextReaderSetStructuredErrorHandler
293
 * - #xmlXPathSetErrorHandler (since 2.13.0)
294
 * - #xmlXIncludeSetErrorHandler (since 2.13.0)
295
 * - #xmlSchemaSetParserStructuredErrors
296
 * - #xmlSchemaSetValidStructuredErrors
297
 * - #xmlRelaxNGSetParserStructuredErrors
298
 * - #xmlRelaxNGSetValidStructuredErrors
299
 *
300
 * If `handler` is NULL, the error handler is deactivated.
301
 *
302
 * The structured error handler takes precedence over "generic"
303
 * handlers, even per-context generic handlers.
304
 *
305
 * Since this is a thread-local setting, it's a good idea to reset
306
 * the error handler to its default value after collecting the
307
 * errors you're interested in. To get the original values, you
308
 * have to access xmlStructuredError and xmlStructuredErrorContext
309
 * directly, making this function kind of useless.
310
 *
311
 * For multi-threaded applications, this must be set separately for
312
 * each thread.
313
 *
314
 * @param ctx  the new error handling context
315
 * @param handler  the new handler function
316
 */
317
void
318
0
xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
319
0
    xmlStructuredErrorContext = ctx;
320
0
    xmlStructuredError = handler;
321
0
}
322
323
/************************************************************************
324
 *                  *
325
 *      Handling of parsing errors      *
326
 *                  *
327
 ************************************************************************/
328
329
/**
330
 * Displays the associated file and line information for the
331
 * current input.
332
 *
333
 * @deprecated Use #xmlFormatError.
334
 *
335
 * @param input  an xmlParserInput input
336
 */
337
338
void
339
0
xmlParserPrintFileInfo(struct _xmlParserInput *input) {
340
0
    if (input != NULL) {
341
0
  if (input->filename)
342
0
      xmlGenericError(xmlGenericErrorContext,
343
0
        "%s:%d: ", input->filename,
344
0
        input->line);
345
0
  else
346
0
      xmlGenericError(xmlGenericErrorContext,
347
0
        "Entity: line %d: ", input->line);
348
0
    }
349
0
}
350
351
/**
352
 * Displays current context within the input content for
353
 * error reporting.
354
 *
355
 * @param input  an xmlParserInput input
356
 * @param channel  output callback
357
 * @param data  user data for output callback
358
 */
359
360
static void
361
xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
362
455k
    xmlGenericErrorFunc channel, void *data ) {
363
455k
    const xmlChar *start;
364
455k
    int n, col;
365
455k
    xmlChar content[81]; /* space for 80 chars + line terminator */
366
367
455k
    if ((input == NULL) || (input->cur == NULL))
368
0
        return;
369
370
455k
    n = sizeof(content) - 1;
371
455k
    xmlParserInputGetWindow(input, &start, &n, &col);
372
373
455k
    memcpy(content, start, n);
374
455k
    content[n] = 0;
375
    /* print out the selected text */
376
455k
    channel(data ,"%s\n", content);
377
    /* create blank line with problem pointer */
378
12.6M
    for (n = 0; n < col; n++) {
379
12.2M
  if (content[n] != '\t')
380
12.2M
      content[n] = ' ';
381
12.2M
    }
382
455k
    content[n++] = '^';
383
455k
    content[n] = 0;
384
455k
    channel(data ,"%s\n", content);
385
455k
}
386
387
/**
388
 * Displays current context within the input content for
389
 * error reporting.
390
 *
391
 * @deprecated Use #xmlFormatError.
392
 *
393
 * @param input  an xmlParserInput input
394
 */
395
void
396
0
xmlParserPrintFileContext(struct _xmlParserInput *input) {
397
0
   xmlParserPrintFileContextInternal(input, xmlGenericError,
398
0
                                     xmlGenericErrorContext);
399
0
}
400
401
/**
402
 * Report a formatted error to a printf-like callback.
403
 *
404
 * This can result in a verbose multi-line report including additional
405
 * information from the parser context.
406
 *
407
 * @since 2.13.0
408
 * @param err  the error
409
 * @param channel  callback
410
 * @param data  user data for callback
411
 */
412
void
413
xmlFormatError(const xmlError *err, xmlGenericErrorFunc channel, void *data)
414
389k
{
415
389k
    const char *message;
416
389k
    const char *file;
417
389k
    int line;
418
389k
    int code;
419
389k
    int domain;
420
389k
    const xmlChar *name = NULL;
421
389k
    xmlNodePtr node;
422
389k
    xmlErrorLevel level;
423
389k
    xmlParserCtxtPtr ctxt = NULL;
424
389k
    xmlParserInputPtr input = NULL;
425
389k
    xmlParserInputPtr cur = NULL;
426
427
389k
    if ((err == NULL) || (channel == NULL))
428
0
        return;
429
430
389k
    message = err->message;
431
389k
    file = err->file;
432
389k
    line = err->line;
433
389k
    code = err->code;
434
389k
    domain = err->domain;
435
389k
    level = err->level;
436
389k
    node = err->node;
437
438
389k
    if (code == XML_ERR_OK)
439
0
        return;
440
441
389k
    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
442
47.2k
        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
443
389k
  (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
444
389k
  ctxt = err->ctxt;
445
389k
    }
446
447
389k
    if ((node != NULL) && (node->type == XML_ELEMENT_NODE) &&
448
1.24k
        (domain != XML_FROM_SCHEMASV))
449
1.24k
        name = node->name;
450
451
    /*
452
     * Maintain the compatibility with the legacy error handling
453
     */
454
389k
    if ((ctxt != NULL) && (ctxt->input != NULL)) {
455
389k
        input = ctxt->input;
456
389k
        if ((input->filename == NULL) &&
457
389k
            (ctxt->inputNr > 1)) {
458
65.8k
            cur = input;
459
65.8k
            input = ctxt->inputTab[ctxt->inputNr - 2];
460
65.8k
        }
461
389k
        if (input->filename)
462
0
            channel(data, "%s:%d: ", input->filename, input->line);
463
389k
        else if ((line != 0) && (domain == XML_FROM_PARSER))
464
342k
            channel(data, "Entity: line %d: ", input->line);
465
389k
    } else {
466
0
        if (file != NULL)
467
0
            channel(data, "%s:%d: ", file, line);
468
0
        else if ((line != 0) &&
469
0
           ((domain == XML_FROM_PARSER) || (domain == XML_FROM_SCHEMASV)||
470
0
      (domain == XML_FROM_SCHEMASP)||(domain == XML_FROM_DTD) ||
471
0
      (domain == XML_FROM_RELAXNGP)||(domain == XML_FROM_RELAXNGV)))
472
0
            channel(data, "Entity: line %d: ", line);
473
0
    }
474
389k
    if (name != NULL) {
475
1.24k
        channel(data, "element %s: ", name);
476
1.24k
    }
477
389k
    switch (domain) {
478
342k
        case XML_FROM_PARSER:
479
342k
            channel(data, "parser ");
480
342k
            break;
481
38.7k
        case XML_FROM_NAMESPACE:
482
38.7k
            channel(data, "namespace ");
483
38.7k
            break;
484
0
        case XML_FROM_DTD:
485
1.24k
        case XML_FROM_VALID:
486
1.24k
            channel(data, "validity ");
487
1.24k
            break;
488
0
        case XML_FROM_HTML:
489
0
            channel(data, "HTML parser ");
490
0
            break;
491
0
        case XML_FROM_MEMORY:
492
0
            channel(data, "memory ");
493
0
            break;
494
0
        case XML_FROM_OUTPUT:
495
0
            channel(data, "output ");
496
0
            break;
497
7.25k
        case XML_FROM_IO:
498
7.25k
            channel(data, "I/O ");
499
7.25k
            break;
500
0
        case XML_FROM_XINCLUDE:
501
0
            channel(data, "XInclude ");
502
0
            break;
503
0
        case XML_FROM_XPATH:
504
0
            channel(data, "XPath ");
505
0
            break;
506
0
        case XML_FROM_XPOINTER:
507
0
            channel(data, "parser ");
508
0
            break;
509
0
        case XML_FROM_REGEXP:
510
0
            channel(data, "regexp ");
511
0
            break;
512
0
        case XML_FROM_MODULE:
513
0
            channel(data, "module ");
514
0
            break;
515
0
        case XML_FROM_SCHEMASV:
516
0
            channel(data, "Schemas validity ");
517
0
            break;
518
0
        case XML_FROM_SCHEMASP:
519
0
            channel(data, "Schemas parser ");
520
0
            break;
521
0
        case XML_FROM_RELAXNGP:
522
0
            channel(data, "Relax-NG parser ");
523
0
            break;
524
0
        case XML_FROM_RELAXNGV:
525
0
            channel(data, "Relax-NG validity ");
526
0
            break;
527
0
        case XML_FROM_CATALOG:
528
0
            channel(data, "Catalog ");
529
0
            break;
530
0
        case XML_FROM_C14N:
531
0
            channel(data, "C14N ");
532
0
            break;
533
0
        case XML_FROM_XSLT:
534
0
            channel(data, "XSLT ");
535
0
            break;
536
0
        case XML_FROM_I18N:
537
0
            channel(data, "encoding ");
538
0
            break;
539
0
        case XML_FROM_SCHEMATRONV:
540
0
            channel(data, "schematron ");
541
0
            break;
542
0
        case XML_FROM_BUFFER:
543
0
            channel(data, "internal buffer ");
544
0
            break;
545
0
        case XML_FROM_URI:
546
0
            channel(data, "URI ");
547
0
            break;
548
0
        default:
549
0
            break;
550
389k
    }
551
389k
    switch (level) {
552
0
        case XML_ERR_NONE:
553
0
            channel(data, ": ");
554
0
            break;
555
17.6k
        case XML_ERR_WARNING:
556
17.6k
            channel(data, "warning : ");
557
17.6k
            break;
558
32.1k
        case XML_ERR_ERROR:
559
32.1k
            channel(data, "error : ");
560
32.1k
            break;
561
339k
        case XML_ERR_FATAL:
562
339k
            channel(data, "error : ");
563
339k
            break;
564
389k
    }
565
389k
    if (message != NULL) {
566
389k
        int len;
567
389k
  len = xmlStrlen((const xmlChar *) message);
568
389k
  if ((len > 0) && (message[len - 1] != '\n'))
569
3.19k
      channel(data, "%s\n", message);
570
386k
  else
571
386k
      channel(data, "%s", message);
572
389k
    } else {
573
0
        channel(data, "%s\n", "No error message provided");
574
0
    }
575
576
389k
    if (ctxt != NULL) {
577
389k
        if ((input != NULL) &&
578
389k
            ((input->buf == NULL) || (input->buf->encoder == NULL)) &&
579
379k
            (code == XML_ERR_INVALID_ENCODING) &&
580
7.17k
            (input->cur < input->end)) {
581
7.08k
            int i;
582
583
7.08k
            channel(data, "Bytes:");
584
34.2k
            for (i = 0; i < 4; i++) {
585
27.8k
                if (input->cur + i >= input->end)
586
690
                    break;
587
27.1k
                channel(data, " 0x%02X", input->cur[i]);
588
27.1k
            }
589
7.08k
            channel(data, "\n");
590
7.08k
        }
591
592
389k
        xmlParserPrintFileContextInternal(input, channel, data);
593
594
389k
        if (cur != NULL) {
595
65.8k
            if (cur->filename)
596
0
                channel(data, "%s:%d: \n", cur->filename, cur->line);
597
65.8k
            else if ((line != 0) &&
598
65.8k
                     ((domain == XML_FROM_PARSER) ||
599
2.01k
                      (domain == XML_FROM_SCHEMASV) ||
600
2.01k
                      (domain == XML_FROM_SCHEMASP) ||
601
2.01k
                      (domain == XML_FROM_DTD) ||
602
2.01k
                      (domain == XML_FROM_RELAXNGP) ||
603
2.01k
                      (domain == XML_FROM_RELAXNGV)))
604
63.8k
                channel(data, "Entity: line %d: \n", cur->line);
605
65.8k
            xmlParserPrintFileContextInternal(cur, channel, data);
606
65.8k
        }
607
389k
    }
608
389k
    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
609
0
        (err->int1 < 100) &&
610
0
  (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
611
0
  xmlChar buf[150];
612
0
  int i;
613
614
0
  channel(data, "%s\n", err->str1);
615
0
  for (i=0;i < err->int1;i++)
616
0
       buf[i] = ' ';
617
0
  buf[i++] = '^';
618
0
  buf[i] = 0;
619
0
  channel(data, "%s\n", buf);
620
0
    }
621
389k
}
622
623
/**
624
 * Update the global and optional error structure, then forward the
625
 * error to an error handler.
626
 *
627
 * This function doesn't make memory allocations which are likely
628
 * to fail after an OOM error.
629
 *
630
 * @param schannel  the structured callback channel
631
 * @param channel  the old callback channel
632
 * @param data  the callback data
633
 * @param domain  the domain for the error
634
 * @param error  optional error struct to be filled
635
 */
636
void
637
xmlRaiseMemoryError(xmlStructuredErrorFunc schannel, xmlGenericErrorFunc channel,
638
                    void *data, int domain, xmlError *error)
639
3.26k
{
640
3.26k
    xmlError *lastError = xmlGetLastErrorInternal();
641
642
3.26k
    xmlResetLastError();
643
3.26k
    lastError->domain = domain;
644
3.26k
    lastError->code = XML_ERR_NO_MEMORY;
645
3.26k
    lastError->level = XML_ERR_FATAL;
646
647
3.26k
    if (error != NULL) {
648
3.26k
        xmlResetError(error);
649
3.26k
        error->domain = domain;
650
3.26k
        error->code = XML_ERR_NO_MEMORY;
651
3.26k
        error->level = XML_ERR_FATAL;
652
3.26k
    }
653
654
3.26k
    if (schannel != NULL) {
655
0
        schannel(data, lastError);
656
3.26k
    } else if (xmlStructuredError != NULL) {
657
0
        xmlStructuredError(xmlStructuredErrorContext, lastError);
658
3.26k
    } else if (channel != NULL) {
659
0
        channel(data, "libxml2: out of memory\n");
660
0
    }
661
3.26k
}
662
663
/**
664
 * Update the appropriate global or contextual error structure,
665
 * then forward the error message down the parser or generic
666
 * error callback handler
667
 *
668
 * @param schannel  the structured callback channel
669
 * @param channel  the old callback channel
670
 * @param data  the callback data
671
 * @param ctx  the parser context or NULL
672
 * @param node  the current node or NULL
673
 * @param domain  the domain for the error
674
 * @param code  the code for the error
675
 * @param level  the xmlErrorLevel for the error
676
 * @param file  the file source of the error (or NULL)
677
 * @param line  the line of the error or 0 if N/A
678
 * @param str1  extra string info
679
 * @param str2  extra string info
680
 * @param str3  extra string info
681
 * @param int1  extra int info
682
 * @param col  column number of the error or 0 if N/A
683
 * @param msg  the message to display/transmit
684
 * @param ap  extra parameters for the message display
685
 * @returns 0 on success, -1 if a memory allocation failed.
686
 */
687
int
688
xmlVRaiseError(xmlStructuredErrorFunc schannel,
689
               xmlGenericErrorFunc channel, void *data, void *ctx,
690
               xmlNode *node, int domain, int code, xmlErrorLevel level,
691
               const char *file, int line, const char *str1,
692
               const char *str2, const char *str3, int int1, int col,
693
               const char *msg, va_list ap)
694
406k
{
695
406k
    xmlParserCtxtPtr ctxt = NULL;
696
    /* xmlLastError is a macro retrieving the per-thread global. */
697
406k
    xmlErrorPtr lastError = xmlGetLastErrorInternal();
698
406k
    xmlErrorPtr to = lastError;
699
700
406k
    if (code == XML_ERR_OK)
701
0
        return(0);
702
406k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
703
406k
    if (code == XML_ERR_INTERNAL_ERROR)
704
0
        xmlAbort("Unexpected internal error: %s\n", msg);
705
406k
#endif
706
406k
    if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
707
0
        return(0);
708
709
406k
    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
710
64.4k
        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
711
389k
  (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
712
389k
  ctxt = (xmlParserCtxtPtr) ctx;
713
714
389k
        if (ctxt != NULL)
715
389k
            to = &ctxt->lastError;
716
389k
    }
717
718
406k
    if (xmlVUpdateError(to, ctxt, node, domain, code, level, file, line,
719
406k
                        str1, str2, str3, int1, col, msg, ap))
720
262
        return(-1);
721
722
406k
    if (to != lastError) {
723
389k
        if (xmlCopyError(to, lastError) < 0)
724
0
            return(-1);
725
389k
    }
726
727
406k
    if (schannel != NULL) {
728
0
  schannel(data, to);
729
406k
    } else if (xmlStructuredError != NULL) {
730
0
        xmlStructuredError(xmlStructuredErrorContext, to);
731
406k
    } else if (channel != NULL) {
732
        /* Don't invoke legacy error handlers */
733
405k
        if ((channel == xmlGenericErrorDefaultFunc) ||
734
405k
            (channel == xmlParserError) ||
735
34.8k
            (channel == xmlParserWarning) ||
736
17.2k
            (channel == xmlParserValidityError) ||
737
15.9k
            (channel == xmlParserValidityWarning))
738
389k
            xmlFormatError(to, xmlGenericError, xmlGenericErrorContext);
739
15.9k
        else
740
15.9k
      channel(data, "%s", to->message);
741
405k
    }
742
743
406k
    return(0);
744
406k
}
745
746
/**
747
 * Update the appropriate global or contextual error structure,
748
 * then forward the error message down the parser or generic
749
 * error callback handler
750
 *
751
 * @param schannel  the structured callback channel
752
 * @param channel  the old callback channel
753
 * @param data  the callback data
754
 * @param ctx  the parser context or NULL
755
 * @param node  the node or NULL
756
 * @param domain  the domain for the error
757
 * @param code  the code for the error
758
 * @param level  the xmlErrorLevel for the error
759
 * @param file  the file source of the error (or NULL)
760
 * @param line  the line of the error or 0 if N/A
761
 * @param str1  extra string info
762
 * @param str2  extra string info
763
 * @param str3  extra string info
764
 * @param int1  extra int info
765
 * @param col  column number of the error or 0 if N/A
766
 * @param msg  printf-like format string
767
 * @param ...  arguments to format
768
 * @returns 0 on success, -1 if a memory allocation failed.
769
 */
770
int
771
xmlRaiseError(xmlStructuredErrorFunc schannel,
772
              xmlGenericErrorFunc channel, void *data, void *ctx,
773
              xmlNode *node, int domain, int code, xmlErrorLevel level,
774
              const char *file, int line, const char *str1,
775
              const char *str2, const char *str3, int int1, int col,
776
              const char *msg, ...)
777
952
{
778
952
    va_list ap;
779
952
    int res;
780
781
952
    va_start(ap, msg);
782
952
    res = xmlVRaiseError(schannel, channel, data, ctx, node, domain, code,
783
952
                         level, file, line, str1, str2, str3, int1, col, msg,
784
952
                         ap);
785
952
    va_end(ap);
786
787
952
    return(res);
788
952
}
789
790
static void
791
xmlVFormatLegacyError(void *ctx, const char *level,
792
0
                      const char *fmt, va_list ap) {
793
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
794
0
    xmlParserInputPtr input = NULL;
795
0
    xmlParserInputPtr cur = NULL;
796
0
    xmlChar *str = NULL;
797
798
0
    if (ctxt != NULL) {
799
0
  input = ctxt->input;
800
0
  if ((input != NULL) && (input->filename == NULL) &&
801
0
      (ctxt->inputNr > 1)) {
802
0
      cur = input;
803
0
      input = ctxt->inputTab[ctxt->inputNr - 2];
804
0
  }
805
0
  xmlParserPrintFileInfo(input);
806
0
    }
807
808
0
    xmlGenericError(xmlGenericErrorContext, "%s: ", level);
809
810
0
    xmlStrVASPrintf(&str, MAX_ERR_MSG_SIZE, fmt, ap);
811
0
    if (str != NULL) {
812
0
        xmlGenericError(xmlGenericErrorContext, "%s", (char *) str);
813
0
  xmlFree(str);
814
0
    }
815
816
0
    if (ctxt != NULL) {
817
0
  xmlParserPrintFileContext(input);
818
0
  if (cur != NULL) {
819
0
      xmlParserPrintFileInfo(cur);
820
0
      xmlGenericError(xmlGenericErrorContext, "\n");
821
0
      xmlParserPrintFileContext(cur);
822
0
  }
823
0
    }
824
0
}
825
826
/**
827
 * This is the default SAX error handler, but it will never be
828
 * called. If it isn't replaced by the user, errors will be
829
 * handled by #xmlFormatError.
830
 *
831
 * @deprecated Do not call directly.
832
 *
833
 * Format an error message with additional detail from the
834
 * parser context and print to generic error handler.
835
 *
836
 * @param ctx  an XML parser context
837
 * @param msg  printf-like format string
838
 * @param ...  arguments to format
839
 */
840
void
841
xmlParserError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
842
0
{
843
0
    va_list ap;
844
845
0
    va_start(ap, msg);
846
0
    xmlVFormatLegacyError(ctx, "error", msg, ap);
847
0
    va_end(ap);
848
0
}
849
850
/**
851
 * This is the default SAX warning handler, but it will never be
852
 * called. If it isn't replaced by the user, warnings will be
853
 * handled by #xmlFormatError.
854
 *
855
 * @deprecated Do not call directly.
856
 *
857
 * Format an warning message with additional detail from the
858
 * parser context and print to generic error handler.
859
 *
860
 * @param ctx  an XML parser context
861
 * @param msg  printf-like format string
862
 * @param ...  arguments to format
863
 */
864
void
865
xmlParserWarning(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
866
0
{
867
0
    va_list ap;
868
869
0
    va_start(ap, msg);
870
0
    xmlVFormatLegacyError(ctx, "warning", msg, ap);
871
0
    va_end(ap);
872
0
}
873
874
/**
875
 * This is the default validity error handler, but it will never be
876
 * called. If it isn't replaced by the user, errors will be
877
 * handled by #xmlFormatError.
878
 *
879
 * @deprecated Do not call directly.
880
 *
881
 * Format an error message with additional detail from the
882
 * parser context and print to generic error handler.
883
 *
884
 * @param ctx  an XML parser context
885
 * @param msg  printf-like format string
886
 * @param ...  arguments to format
887
 */
888
void
889
xmlParserValidityError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
890
0
{
891
0
    va_list ap;
892
893
0
    va_start(ap, msg);
894
0
    xmlVFormatLegacyError(ctx, "validity error", msg, ap);
895
0
    va_end(ap);
896
0
}
897
898
/**
899
 * This is the default validity warning handler, but it will never
900
 * be called. If it isn't replaced by the user, warnings will be
901
 * handled by #xmlFormatError.
902
 *
903
 * @deprecated Do not call directly.
904
 *
905
 * Format an warning message with additional detail from the
906
 * parser context and print to generic error handler.
907
 *
908
 * @param ctx  an XML parser context
909
 * @param msg  printf-like format string
910
 * @param ...  arguments to format
911
 */
912
void
913
xmlParserValidityWarning(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
914
0
{
915
0
    va_list ap;
916
917
0
    va_start(ap, msg);
918
0
    xmlVFormatLegacyError(ctx, "validity warning", msg, ap);
919
0
    va_end(ap);
920
0
}
921
922
923
/************************************************************************
924
 *                  *
925
 *      Extended Error Handling       *
926
 *                  *
927
 ************************************************************************/
928
929
/**
930
 * Get the last error raised in this thread.
931
 *
932
 * @returns a pointer to the error
933
 */
934
const xmlError *
935
xmlGetLastError(void)
936
0
{
937
0
    const xmlError *error = xmlGetLastErrorInternal();
938
939
0
    if (error->code == XML_ERR_OK)
940
0
        return(NULL);
941
0
    return(error);
942
0
}
943
944
/**
945
 * Reset the error to success.
946
 *
947
 * @param err  pointer to the error
948
 */
949
void
950
xmlResetError(xmlError *err)
951
897k
{
952
897k
    if (err == NULL)
953
0
        return;
954
897k
    if (err->code == XML_ERR_OK)
955
103k
        return;
956
793k
    if (err->message != NULL)
957
769k
        xmlFree(err->message);
958
793k
    if (err->file != NULL)
959
0
        xmlFree(err->file);
960
793k
    if (err->str1 != NULL)
961
319k
        xmlFree(err->str1);
962
793k
    if (err->str2 != NULL)
963
31.3k
        xmlFree(err->str2);
964
793k
    if (err->str3 != NULL)
965
15.2k
        xmlFree(err->str3);
966
793k
    memset(err, 0, sizeof(xmlError));
967
793k
    err->code = XML_ERR_OK;
968
793k
}
969
970
/**
971
 * Reset the last error to success.
972
 */
973
void
974
xmlResetLastError(void)
975
29.3k
{
976
29.3k
    xmlError *error = xmlGetLastErrorInternal();
977
978
29.3k
    if (error->code != XML_ERR_OK)
979
29.2k
        xmlResetError(error);
980
29.3k
}
981
982
/**
983
 * Copy an error.
984
 *
985
 * @param from  a source error
986
 * @param to  a target error
987
 * @returns 0 in case of success and -1 in case of error.
988
 */
989
int
990
389k
xmlCopyError(const xmlError *from, xmlError *to) {
991
389k
    const char *fmt = NULL;
992
993
389k
    if ((from == NULL) || (to == NULL))
994
0
        return(-1);
995
996
389k
    if (from->message != NULL)
997
389k
        fmt = "%s";
998
999
389k
    return(xmlSetError(to, from->ctxt, from->node,
1000
389k
                       from->domain, from->code, from->level,
1001
389k
                       from->file, from->line,
1002
389k
                       from->str1, from->str2, from->str3,
1003
389k
                       from->int1, from->int2,
1004
389k
                       fmt, from->message));
1005
389k
}
1006
1007
/**
1008
 * @param code  an xmlParserErrors code
1009
 * @returns an error message for a code.
1010
 */
1011
const char *
1012
128k
xmlErrString(xmlParserErrors code) {
1013
128k
    const char *errmsg;
1014
1015
128k
    switch (code) {
1016
1.64k
        case XML_ERR_INVALID_HEX_CHARREF:
1017
1.64k
            errmsg = "CharRef: invalid hexadecimal value";
1018
1.64k
            break;
1019
2.16k
        case XML_ERR_INVALID_DEC_CHARREF:
1020
2.16k
            errmsg = "CharRef: invalid decimal value";
1021
2.16k
            break;
1022
0
        case XML_ERR_INVALID_CHARREF:
1023
0
            errmsg = "CharRef: invalid value";
1024
0
            break;
1025
0
        case XML_ERR_INTERNAL_ERROR:
1026
0
            errmsg = "internal error";
1027
0
            break;
1028
0
        case XML_ERR_PEREF_AT_EOF:
1029
0
            errmsg = "PEReference at end of document";
1030
0
            break;
1031
0
        case XML_ERR_PEREF_IN_PROLOG:
1032
0
            errmsg = "PEReference in prolog";
1033
0
            break;
1034
0
        case XML_ERR_PEREF_IN_EPILOG:
1035
0
            errmsg = "PEReference in epilog";
1036
0
            break;
1037
0
        case XML_ERR_PEREF_NO_NAME:
1038
0
            errmsg = "PEReference: no name";
1039
0
            break;
1040
7.60k
        case XML_ERR_PEREF_SEMICOL_MISSING:
1041
7.60k
            errmsg = "PEReference: expecting ';'";
1042
7.60k
            break;
1043
80
        case XML_ERR_ENTITY_LOOP:
1044
80
            errmsg = "Detected an entity reference loop";
1045
80
            break;
1046
0
        case XML_ERR_ENTITY_NOT_STARTED:
1047
0
            errmsg = "EntityValue: \" or ' expected";
1048
0
            break;
1049
571
        case XML_ERR_ENTITY_PE_INTERNAL:
1050
571
            errmsg = "PEReferences forbidden in internal subset";
1051
571
            break;
1052
0
        case XML_ERR_ENTITY_NOT_FINISHED:
1053
0
            errmsg = "EntityValue: \" or ' expected";
1054
0
            break;
1055
1.55k
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
1056
1.55k
            errmsg = "AttValue: \" or ' expected";
1057
1.55k
            break;
1058
10.8k
        case XML_ERR_LT_IN_ATTRIBUTE:
1059
10.8k
            errmsg = "Unescaped '<' not allowed in attributes values";
1060
10.8k
            break;
1061
805
        case XML_ERR_LITERAL_NOT_STARTED:
1062
805
            errmsg = "SystemLiteral \" or ' expected";
1063
805
            break;
1064
2.40k
        case XML_ERR_LITERAL_NOT_FINISHED:
1065
2.40k
            errmsg = "Unfinished System or Public ID \" or ' expected";
1066
2.40k
            break;
1067
449
        case XML_ERR_MISPLACED_CDATA_END:
1068
449
            errmsg = "Sequence ']]>' not allowed in content";
1069
449
            break;
1070
555
        case XML_ERR_URI_REQUIRED:
1071
555
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
1072
555
            break;
1073
250
        case XML_ERR_PUBID_REQUIRED:
1074
250
            errmsg = "PUBLIC, the Public Identifier is missing";
1075
250
            break;
1076
3.31k
        case XML_ERR_HYPHEN_IN_COMMENT:
1077
3.31k
            errmsg = "Comment must not contain '--' (double-hyphen)";
1078
3.31k
            break;
1079
1.41k
        case XML_ERR_PI_NOT_STARTED:
1080
1.41k
            errmsg = "xmlParsePI : no target name";
1081
1.41k
            break;
1082
531
        case XML_ERR_RESERVED_XML_NAME:
1083
531
            errmsg = "Invalid PI name";
1084
531
            break;
1085
389
        case XML_ERR_NOTATION_NOT_STARTED:
1086
389
            errmsg = "NOTATION: Name expected here";
1087
389
            break;
1088
1.72k
        case XML_ERR_NOTATION_NOT_FINISHED:
1089
1.72k
            errmsg = "'>' required to close NOTATION declaration";
1090
1.72k
            break;
1091
4.32k
        case XML_ERR_VALUE_REQUIRED:
1092
4.32k
            errmsg = "Entity value required";
1093
4.32k
            break;
1094
276
        case XML_ERR_URI_FRAGMENT:
1095
276
            errmsg = "Fragment not allowed";
1096
276
            break;
1097
784
        case XML_ERR_ATTLIST_NOT_STARTED:
1098
784
            errmsg = "'(' required to start ATTLIST enumeration";
1099
784
            break;
1100
197
        case XML_ERR_NMTOKEN_REQUIRED:
1101
197
            errmsg = "NmToken expected in ATTLIST enumeration";
1102
197
            break;
1103
1.02k
        case XML_ERR_ATTLIST_NOT_FINISHED:
1104
1.02k
            errmsg = "')' required to finish ATTLIST enumeration";
1105
1.02k
            break;
1106
1.06k
        case XML_ERR_MIXED_NOT_STARTED:
1107
1.06k
            errmsg = "MixedContentDecl : '|' or ')*' expected";
1108
1.06k
            break;
1109
0
        case XML_ERR_PCDATA_REQUIRED:
1110
0
            errmsg = "MixedContentDecl : '#PCDATA' expected";
1111
0
            break;
1112
1.09k
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
1113
1.09k
            errmsg = "ContentDecl : Name or '(' expected";
1114
1.09k
            break;
1115
2.90k
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
1116
2.90k
            errmsg = "ContentDecl : ',' '|' or ')' expected";
1117
2.90k
            break;
1118
0
        case XML_ERR_PEREF_IN_INT_SUBSET:
1119
0
            errmsg =
1120
0
                "PEReference: forbidden within markup decl in internal subset";
1121
0
            break;
1122
7.84k
        case XML_ERR_GT_REQUIRED:
1123
7.84k
            errmsg = "expected '>'";
1124
7.84k
            break;
1125
0
        case XML_ERR_CONDSEC_INVALID:
1126
0
            errmsg = "XML conditional section '[' expected";
1127
0
            break;
1128
9.12k
        case XML_ERR_INT_SUBSET_NOT_FINISHED:
1129
9.12k
            errmsg = "Content error in the internal subset";
1130
9.12k
            break;
1131
0
        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
1132
0
            errmsg = "Content error in the external subset";
1133
0
            break;
1134
0
        case XML_ERR_CONDSEC_INVALID_KEYWORD:
1135
0
            errmsg =
1136
0
                "conditional section INCLUDE or IGNORE keyword expected";
1137
0
            break;
1138
0
        case XML_ERR_CONDSEC_NOT_FINISHED:
1139
0
            errmsg = "XML conditional section not closed";
1140
0
            break;
1141
0
        case XML_ERR_XMLDECL_NOT_STARTED:
1142
0
            errmsg = "Text declaration '<?xml' required";
1143
0
            break;
1144
741
        case XML_ERR_XMLDECL_NOT_FINISHED:
1145
741
            errmsg = "parsing XML declaration: '?>' expected";
1146
741
            break;
1147
0
        case XML_ERR_EXT_ENTITY_STANDALONE:
1148
0
            errmsg = "external parsed entities cannot be standalone";
1149
0
            break;
1150
7.00k
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
1151
7.00k
            errmsg = "EntityRef: expecting ';'";
1152
7.00k
            break;
1153
415
        case XML_ERR_DOCTYPE_NOT_FINISHED:
1154
415
            errmsg = "DOCTYPE improperly terminated";
1155
415
            break;
1156
35
        case XML_ERR_LTSLASH_REQUIRED:
1157
35
            errmsg = "EndTag: '</' not found";
1158
35
            break;
1159
10
        case XML_ERR_EQUAL_REQUIRED:
1160
10
            errmsg = "expected '='";
1161
10
            break;
1162
135
        case XML_ERR_STRING_NOT_CLOSED:
1163
135
            errmsg = "String not closed expecting \" or '";
1164
135
            break;
1165
23
        case XML_ERR_STRING_NOT_STARTED:
1166
23
            errmsg = "String not started expecting ' or \"";
1167
23
            break;
1168
5
        case XML_ERR_ENCODING_NAME:
1169
5
            errmsg = "Invalid XML encoding name";
1170
5
            break;
1171
13
        case XML_ERR_STANDALONE_VALUE:
1172
13
            errmsg = "standalone accepts only 'yes' or 'no'";
1173
13
            break;
1174
36
        case XML_ERR_DOCUMENT_EMPTY:
1175
36
            errmsg = "Document is empty";
1176
36
            break;
1177
9
        case XML_ERR_DOCUMENT_END:
1178
9
            errmsg = "Extra content at the end of the document";
1179
9
            break;
1180
62
        case XML_ERR_NOT_WELL_BALANCED:
1181
62
            errmsg = "chunk is not well balanced";
1182
62
            break;
1183
0
        case XML_ERR_EXTRA_CONTENT:
1184
0
            errmsg = "extra content at the end of well balanced chunk";
1185
0
            break;
1186
731
        case XML_ERR_VERSION_MISSING:
1187
731
            errmsg = "Malformed declaration expecting version";
1188
731
            break;
1189
0
        case XML_ERR_NAME_TOO_LONG:
1190
0
            errmsg = "Name too long";
1191
0
            break;
1192
7.49k
        case XML_ERR_INVALID_ENCODING:
1193
7.49k
            errmsg = "Invalid bytes in character encoding";
1194
7.49k
            break;
1195
1
        case XML_ERR_RESOURCE_LIMIT:
1196
1
            errmsg = "Resource limit exceeded";
1197
1
            break;
1198
0
        case XML_ERR_ARGUMENT:
1199
0
            errmsg = "Invalid argument";
1200
0
            break;
1201
0
        case XML_ERR_SYSTEM:
1202
0
            errmsg = "Out of system resources";
1203
0
            break;
1204
0
        case XML_ERR_REDECL_PREDEF_ENTITY:
1205
0
            errmsg = "Invalid redeclaration of predefined entity";
1206
0
            break;
1207
30
        case XML_ERR_UNSUPPORTED_ENCODING:
1208
30
            errmsg = "Unsupported encoding";
1209
30
            break;
1210
46.3k
        case XML_ERR_INVALID_CHAR:
1211
46.3k
            errmsg = "Invalid character";
1212
46.3k
            break;
1213
1214
0
        case XML_IO_UNKNOWN:
1215
0
            errmsg = "Unknown IO error"; break;
1216
0
        case XML_IO_EACCES:
1217
0
            errmsg = "Permission denied"; break;
1218
0
        case XML_IO_EAGAIN:
1219
0
            errmsg = "Resource temporarily unavailable"; break;
1220
0
        case XML_IO_EBADF:
1221
0
            errmsg = "Bad file descriptor"; break;
1222
0
        case XML_IO_EBADMSG:
1223
0
            errmsg = "Bad message"; break;
1224
0
        case XML_IO_EBUSY:
1225
0
            errmsg = "Resource busy"; break;
1226
0
        case XML_IO_ECANCELED:
1227
0
            errmsg = "Operation canceled"; break;
1228
0
        case XML_IO_ECHILD:
1229
0
            errmsg = "No child processes"; break;
1230
0
        case XML_IO_EDEADLK:
1231
0
            errmsg = "Resource deadlock avoided"; break;
1232
0
        case XML_IO_EDOM:
1233
0
            errmsg = "Domain error"; break;
1234
0
        case XML_IO_EEXIST:
1235
0
            errmsg = "File exists"; break;
1236
0
        case XML_IO_EFAULT:
1237
0
            errmsg = "Bad address"; break;
1238
0
        case XML_IO_EFBIG:
1239
0
            errmsg = "File too large"; break;
1240
0
        case XML_IO_EINPROGRESS:
1241
0
            errmsg = "Operation in progress"; break;
1242
0
        case XML_IO_EINTR:
1243
0
            errmsg = "Interrupted function call"; break;
1244
0
        case XML_IO_EINVAL:
1245
0
            errmsg = "Invalid argument"; break;
1246
0
        case XML_IO_EIO:
1247
0
            errmsg = "Input/output error"; break;
1248
0
        case XML_IO_EISDIR:
1249
0
            errmsg = "Is a directory"; break;
1250
0
        case XML_IO_EMFILE:
1251
0
            errmsg = "Too many open files"; break;
1252
0
        case XML_IO_EMLINK:
1253
0
            errmsg = "Too many links"; break;
1254
0
        case XML_IO_EMSGSIZE:
1255
0
            errmsg = "Inappropriate message buffer length"; break;
1256
0
        case XML_IO_ENAMETOOLONG:
1257
0
            errmsg = "Filename too long"; break;
1258
0
        case XML_IO_ENFILE:
1259
0
            errmsg = "Too many open files in system"; break;
1260
0
        case XML_IO_ENODEV:
1261
0
            errmsg = "No such device"; break;
1262
0
        case XML_IO_ENOENT:
1263
0
            errmsg = "No such file or directory"; break;
1264
0
        case XML_IO_ENOEXEC:
1265
0
            errmsg = "Exec format error"; break;
1266
0
        case XML_IO_ENOLCK:
1267
0
            errmsg = "No locks available"; break;
1268
0
        case XML_IO_ENOMEM:
1269
0
            errmsg = "Not enough space"; break;
1270
0
        case XML_IO_ENOSPC:
1271
0
            errmsg = "No space left on device"; break;
1272
0
        case XML_IO_ENOSYS:
1273
0
            errmsg = "Function not implemented"; break;
1274
0
        case XML_IO_ENOTDIR:
1275
0
            errmsg = "Not a directory"; break;
1276
0
        case XML_IO_ENOTEMPTY:
1277
0
            errmsg = "Directory not empty"; break;
1278
0
        case XML_IO_ENOTSUP:
1279
0
            errmsg = "Not supported"; break;
1280
0
        case XML_IO_ENOTTY:
1281
0
            errmsg = "Inappropriate I/O control operation"; break;
1282
0
        case XML_IO_ENXIO:
1283
0
            errmsg = "No such device or address"; break;
1284
0
        case XML_IO_EPERM:
1285
0
            errmsg = "Operation not permitted"; break;
1286
0
        case XML_IO_EPIPE:
1287
0
            errmsg = "Broken pipe"; break;
1288
0
        case XML_IO_ERANGE:
1289
0
            errmsg = "Result too large"; break;
1290
0
        case XML_IO_EROFS:
1291
0
            errmsg = "Read-only file system"; break;
1292
0
        case XML_IO_ESPIPE:
1293
0
            errmsg = "Invalid seek"; break;
1294
0
        case XML_IO_ESRCH:
1295
0
            errmsg = "No such process"; break;
1296
0
        case XML_IO_ETIMEDOUT:
1297
0
            errmsg = "Operation timed out"; break;
1298
0
        case XML_IO_EXDEV:
1299
0
            errmsg = "Improper link"; break;
1300
0
        case XML_IO_NETWORK_ATTEMPT:
1301
0
            errmsg = "Attempt to load network entity"; break;
1302
0
        case XML_IO_ENCODER:
1303
0
            errmsg = "encoder error"; break;
1304
0
        case XML_IO_FLUSH:
1305
0
            errmsg = "flush error"; break;
1306
0
        case XML_IO_WRITE:
1307
0
            errmsg = "write error"; break;
1308
0
        case XML_IO_NO_INPUT:
1309
0
            errmsg = "no input"; break;
1310
0
        case XML_IO_BUFFER_FULL:
1311
0
            errmsg = "buffer full"; break;
1312
0
        case XML_IO_LOAD_ERROR:
1313
0
            errmsg = "loading error"; break;
1314
0
        case XML_IO_ENOTSOCK:
1315
0
            errmsg = "not a socket"; break;
1316
0
        case XML_IO_EISCONN:
1317
0
            errmsg = "already connected"; break;
1318
0
        case XML_IO_ECONNREFUSED:
1319
0
            errmsg = "connection refused"; break;
1320
0
        case XML_IO_ENETUNREACH:
1321
0
            errmsg = "unreachable network"; break;
1322
0
        case XML_IO_EADDRINUSE:
1323
0
            errmsg = "address in use"; break;
1324
0
        case XML_IO_EALREADY:
1325
0
            errmsg = "already in use"; break;
1326
0
        case XML_IO_EAFNOSUPPORT:
1327
0
            errmsg = "unknown address family"; break;
1328
0
        case XML_IO_UNSUPPORTED_PROTOCOL:
1329
0
            errmsg = "unsupported protocol"; break;
1330
1331
913
        default:
1332
913
            errmsg = "Unregistered error message";
1333
128k
    }
1334
1335
128k
    return(errmsg);
1336
128k
}
1337
1338
/**
1339
 * Prints to stderr.
1340
 *
1341
 * @param fmt  printf-like format string
1342
 * @param ap  arguments
1343
 */
1344
void
1345
0
xmlVPrintErrorMessage(const char *fmt, va_list ap) {
1346
0
    vfprintf(stderr, fmt, ap);
1347
0
}
1348
1349
/**
1350
 * Prints to stderr.
1351
 *
1352
 * @param fmt  printf-like format string
1353
 * @param ...  arguments
1354
 */
1355
void
1356
0
xmlPrintErrorMessage(const char *fmt, ...) {
1357
0
    va_list ap;
1358
1359
0
    va_start(ap, fmt);
1360
0
    xmlVPrintErrorMessage(fmt, ap);
1361
0
    va_end(ap);
1362
0
}
1363
1364
/**
1365
 * Print message to stderr and abort.
1366
 *
1367
 * @param fmt  printf-like format string
1368
 * @param ...  arguments
1369
 */
1370
void
1371
0
xmlAbort(const char *fmt, ...) {
1372
0
    va_list ap;
1373
1374
0
    va_start(ap, fmt);
1375
0
    xmlVPrintErrorMessage(fmt, ap);
1376
0
    va_end(ap);
1377
1378
0
    abort();
1379
0
}