Coverage Report

Created: 2025-07-01 06:26

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