Coverage Report

Created: 2025-08-26 06:41

/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/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
1.99M
xmlIsCatastrophicError(int level, int code) {
39
1.99M
    int fatal = 0;
40
41
1.99M
    if (level != XML_ERR_FATAL)
42
326k
        return(0);
43
44
1.66M
    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.66M
        default:
53
1.66M
            if ((code >= 1500) && (code <= 1599))
54
0
                fatal = 1;
55
1.66M
            break;
56
1.66M
    }
57
58
1.66M
    return(fatal);
59
1.66M
}
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
763k
{
76
763k
    char *message = NULL;
77
763k
    char *fileCopy = NULL;
78
763k
    char *str1Copy = NULL;
79
763k
    char *str2Copy = NULL;
80
763k
    char *str3Copy = NULL;
81
82
763k
    if (code == XML_ERR_OK) {
83
0
        xmlResetError(err);
84
0
        return(0);
85
0
    }
86
87
    /*
88
     * Formatting the message
89
     */
90
763k
    if (fmt == NULL) {
91
0
        message = xmlMemStrdup("No error message provided");
92
763k
    } else {
93
763k
        xmlChar *tmp;
94
763k
        int res;
95
96
763k
        res = xmlStrVASPrintf(&tmp, MAX_ERR_MSG_SIZE, fmt, ap);
97
763k
        if (res < 0)
98
114
            goto err_memory;
99
763k
        message = (char *) tmp;
100
763k
    }
101
763k
    if (message == NULL)
102
0
        goto err_memory;
103
104
763k
    if (file != NULL) {
105
0
        fileCopy = (char *) xmlStrdup((const xmlChar *) file);
106
0
        if (fileCopy == NULL)
107
0
            goto err_memory;
108
0
    }
109
763k
    if (str1 != NULL) {
110
297k
        str1Copy = (char *) xmlStrdup((const xmlChar *) str1);
111
297k
        if (str1Copy == NULL)
112
101
            goto err_memory;
113
297k
    }
114
763k
    if (str2 != NULL) {
115
32.4k
        str2Copy = (char *) xmlStrdup((const xmlChar *) str2);
116
32.4k
        if (str2Copy == NULL)
117
3
            goto err_memory;
118
32.4k
    }
119
763k
    if (str3 != NULL) {
120
15.9k
        str3Copy = (char *) xmlStrdup((const xmlChar *) str3);
121
15.9k
        if (str3Copy == NULL)
122
0
            goto err_memory;
123
15.9k
    }
124
125
763k
    xmlResetError(err);
126
127
763k
    err->domain = domain;
128
763k
    err->code = code;
129
763k
    err->message = message;
130
763k
    err->level = level;
131
763k
    err->file = fileCopy;
132
763k
    err->line = line;
133
763k
    err->str1 = str1Copy;
134
763k
    err->str2 = str2Copy;
135
763k
    err->str3 = str3Copy;
136
763k
    err->int1 = int1;
137
763k
    err->int2 = col;
138
763k
    err->node = node;
139
763k
    err->ctxt = ctxt;
140
141
763k
    return(0);
142
143
218
err_memory:
144
218
    xmlFree(message);
145
218
    xmlFree(fileCopy);
146
218
    xmlFree(str1Copy);
147
218
    xmlFree(str2Copy);
148
218
    xmlFree(str3Copy);
149
218
    return(-1);
150
763k
}
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
373k
{
161
373k
    va_list ap;
162
373k
    int res;
163
164
373k
    va_start(ap, fmt);
165
373k
    res = xmlVSetError(err, ctxt, node, domain, code, level, file, line,
166
373k
                       str1, str2, str3, int1, col, fmt, ap);
167
373k
    va_end(ap);
168
169
373k
    return(res);
170
373k
}
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
389k
{
181
389k
    int res;
182
183
    /*
184
     * Find first element parent.
185
     */
186
389k
    if (node != NULL) {
187
1.26k
        int i;
188
189
1.26k
        for (i = 0; i < 10; i++) {
190
1.26k
            if ((node->type == XML_ELEMENT_NODE) ||
191
1.26k
                (node->parent == NULL))
192
1.26k
                break;
193
0
            node = node->parent;
194
0
        }
195
1.26k
    }
196
197
    /*
198
     * Get file and line from node.
199
     */
200
389k
    if (node != NULL) {
201
1.26k
        if ((file == NULL) && (node->doc != NULL))
202
1.26k
            file = (const char *) node->doc->URL;
203
204
1.26k
        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.26k
    }
211
212
389k
    res = xmlVSetError(err, ctxt, node, domain, code, level, file, line,
213
389k
                       str1, str2, str3, int1, col, fmt, ap);
214
215
389k
    return(res);
216
389k
}
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
434k
    xmlGenericErrorFunc channel, void *data ) {
363
434k
    const xmlChar *start;
364
434k
    int n, col;
365
434k
    xmlChar content[81]; /* space for 80 chars + line terminator */
366
367
434k
    if ((input == NULL) || (input->cur == NULL))
368
0
        return;
369
370
434k
    n = sizeof(content) - 1;
371
434k
    xmlParserInputGetWindow(input, &start, &n, &col);
372
373
434k
    memcpy(content, start, n);
374
434k
    content[n] = 0;
375
    /* print out the selected text */
376
434k
    channel(data ,"%s\n", content);
377
    /* create blank line with problem pointer */
378
11.9M
    for (n = 0; n < col; n++) {
379
11.5M
  if (content[n] != '\t')
380
11.4M
      content[n] = ' ';
381
11.5M
    }
382
434k
    content[n++] = '^';
383
434k
    content[n] = 0;
384
434k
    channel(data ,"%s\n", content);
385
434k
}
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
373k
{
415
373k
    const char *message;
416
373k
    const char *file;
417
373k
    int line;
418
373k
    int code;
419
373k
    int domain;
420
373k
    const xmlChar *name = NULL;
421
373k
    xmlNodePtr node;
422
373k
    xmlErrorLevel level;
423
373k
    xmlParserCtxtPtr ctxt = NULL;
424
373k
    xmlParserInputPtr input = NULL;
425
373k
    xmlParserInputPtr cur = NULL;
426
427
373k
    if ((err == NULL) || (channel == NULL))
428
0
        return;
429
430
373k
    message = err->message;
431
373k
    file = err->file;
432
373k
    line = err->line;
433
373k
    code = err->code;
434
373k
    domain = err->domain;
435
373k
    level = err->level;
436
373k
    node = err->node;
437
438
373k
    if (code == XML_ERR_OK)
439
0
        return;
440
441
373k
    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
442
373k
        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
443
373k
  (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
444
373k
  ctxt = err->ctxt;
445
373k
    }
446
447
373k
    if ((node != NULL) && (node->type == XML_ELEMENT_NODE) &&
448
373k
        (domain != XML_FROM_SCHEMASV))
449
1.26k
        name = node->name;
450
451
    /*
452
     * Maintain the compatibility with the legacy error handling
453
     */
454
373k
    if ((ctxt != NULL) && (ctxt->input != NULL)) {
455
373k
        input = ctxt->input;
456
373k
        if ((input->filename == NULL) &&
457
373k
            (ctxt->inputNr > 1)) {
458
60.9k
            cur = input;
459
60.9k
            input = ctxt->inputTab[ctxt->inputNr - 2];
460
60.9k
        }
461
373k
        if (input->filename)
462
0
            channel(data, "%s:%d: ", input->filename, input->line);
463
373k
        else if ((line != 0) && (domain == XML_FROM_PARSER))
464
327k
            channel(data, "Entity: line %d: ", input->line);
465
373k
    } 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
373k
    if (name != NULL) {
475
1.26k
        channel(data, "element %s: ", name);
476
1.26k
    }
477
373k
    switch (domain) {
478
327k
        case XML_FROM_PARSER:
479
327k
            channel(data, "parser ");
480
327k
            break;
481
37.5k
        case XML_FROM_NAMESPACE:
482
37.5k
            channel(data, "namespace ");
483
37.5k
            break;
484
0
        case XML_FROM_DTD:
485
1.26k
        case XML_FROM_VALID:
486
1.26k
            channel(data, "validity ");
487
1.26k
            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.01k
        case XML_FROM_IO:
498
7.01k
            channel(data, "I/O ");
499
7.01k
            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
373k
    }
551
373k
    switch (level) {
552
0
        case XML_ERR_NONE:
553
0
            channel(data, ": ");
554
0
            break;
555
16.7k
        case XML_ERR_WARNING:
556
16.7k
            channel(data, "warning : ");
557
16.7k
            break;
558
32.8k
        case XML_ERR_ERROR:
559
32.8k
            channel(data, "error : ");
560
32.8k
            break;
561
324k
        case XML_ERR_FATAL:
562
324k
            channel(data, "error : ");
563
324k
            break;
564
373k
    }
565
373k
    if (message != NULL) {
566
373k
        int len;
567
373k
  len = xmlStrlen((const xmlChar *) message);
568
373k
  if ((len > 0) && (message[len - 1] != '\n'))
569
3.96k
      channel(data, "%s\n", message);
570
369k
  else
571
369k
      channel(data, "%s", message);
572
373k
    } else {
573
0
        channel(data, "%s\n", "No error message provided");
574
0
    }
575
576
373k
    if (ctxt != NULL) {
577
373k
        if ((input != NULL) &&
578
373k
            ((input->buf == NULL) || (input->buf->encoder == NULL)) &&
579
373k
            (code == XML_ERR_INVALID_ENCODING) &&
580
373k
            (input->cur < input->end)) {
581
6.95k
            int i;
582
583
6.95k
            channel(data, "Bytes:");
584
33.7k
            for (i = 0; i < 4; i++) {
585
27.3k
                if (input->cur + i >= input->end)
586
631
                    break;
587
26.7k
                channel(data, " 0x%02X", input->cur[i]);
588
26.7k
            }
589
6.95k
            channel(data, "\n");
590
6.95k
        }
591
592
373k
        xmlParserPrintFileContextInternal(input, channel, data);
593
594
373k
        if (cur != NULL) {
595
60.9k
            if (cur->filename)
596
0
                channel(data, "%s:%d: \n", cur->filename, cur->line);
597
60.9k
            else if ((line != 0) &&
598
60.9k
                     ((domain == XML_FROM_PARSER) ||
599
60.9k
                      (domain == XML_FROM_SCHEMASV) ||
600
60.9k
                      (domain == XML_FROM_SCHEMASP) ||
601
60.9k
                      (domain == XML_FROM_DTD) ||
602
60.9k
                      (domain == XML_FROM_RELAXNGP) ||
603
60.9k
                      (domain == XML_FROM_RELAXNGV)))
604
59.4k
                channel(data, "Entity: line %d: \n", cur->line);
605
60.9k
            xmlParserPrintFileContextInternal(cur, channel, data);
606
60.9k
        }
607
373k
    }
608
373k
    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
609
373k
        (err->int1 < 100) &&
610
373k
  (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
373k
}
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
2.93k
{
640
2.93k
    xmlError *lastError = xmlGetLastErrorInternal();
641
642
2.93k
    xmlResetLastError();
643
2.93k
    lastError->domain = domain;
644
2.93k
    lastError->code = XML_ERR_NO_MEMORY;
645
2.93k
    lastError->level = XML_ERR_FATAL;
646
647
2.93k
    if (error != NULL) {
648
2.93k
        xmlResetError(error);
649
2.93k
        error->domain = domain;
650
2.93k
        error->code = XML_ERR_NO_MEMORY;
651
2.93k
        error->level = XML_ERR_FATAL;
652
2.93k
    }
653
654
2.93k
    if (schannel != NULL) {
655
0
        schannel(data, lastError);
656
2.93k
    } else if (xmlStructuredError != NULL) {
657
0
        xmlStructuredError(xmlStructuredErrorContext, lastError);
658
2.93k
    } else if (channel != NULL) {
659
0
        channel(data, "libxml2: out of memory\n");
660
0
    }
661
2.93k
}
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
389k
{
695
389k
    xmlParserCtxtPtr ctxt = NULL;
696
    /* xmlLastError is a macro retrieving the per-thread global. */
697
389k
    xmlErrorPtr lastError = xmlGetLastErrorInternal();
698
389k
    xmlErrorPtr to = lastError;
699
700
389k
    if (code == XML_ERR_OK)
701
0
        return(0);
702
389k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
703
389k
    if (code == XML_ERR_INTERNAL_ERROR)
704
0
        xmlAbort("Unexpected internal error: %s\n", msg);
705
389k
#endif
706
389k
    if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
707
0
        return(0);
708
709
389k
    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
710
389k
        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
711
389k
  (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
712
373k
  ctxt = (xmlParserCtxtPtr) ctx;
713
714
373k
        if (ctxt != NULL)
715
373k
            to = &ctxt->lastError;
716
373k
    }
717
718
389k
    if (xmlVUpdateError(to, ctxt, node, domain, code, level, file, line,
719
389k
                        str1, str2, str3, int1, col, msg, ap))
720
218
        return(-1);
721
722
389k
    if (to != lastError) {
723
373k
        if (xmlCopyError(to, lastError) < 0)
724
0
            return(-1);
725
373k
    }
726
727
389k
    if (schannel != NULL) {
728
0
  schannel(data, to);
729
389k
    } else if (xmlStructuredError != NULL) {
730
0
        xmlStructuredError(xmlStructuredErrorContext, to);
731
389k
    } else if (channel != NULL) {
732
        /* Don't invoke legacy error handlers */
733
388k
        if ((channel == xmlGenericErrorDefaultFunc) ||
734
388k
            (channel == xmlParserError) ||
735
388k
            (channel == xmlParserWarning) ||
736
388k
            (channel == xmlParserValidityError) ||
737
388k
            (channel == xmlParserValidityWarning))
738
373k
            xmlFormatError(to, xmlGenericError, xmlGenericErrorContext);
739
15.1k
        else
740
15.1k
      channel(data, "%s", to->message);
741
388k
    }
742
743
389k
    return(0);
744
389k
}
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
1.01k
{
778
1.01k
    va_list ap;
779
1.01k
    int res;
780
781
1.01k
    va_start(ap, msg);
782
1.01k
    res = xmlVRaiseError(schannel, channel, data, ctx, node, domain, code,
783
1.01k
                         level, file, line, str1, str2, str3, int1, col, msg,
784
1.01k
                         ap);
785
1.01k
    va_end(ap);
786
787
1.01k
    return(res);
788
1.01k
}
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
860k
{
952
860k
    if (err == NULL)
953
0
        return;
954
860k
    if (err->code == XML_ERR_OK)
955
99.5k
        return;
956
760k
    if (err->message != NULL)
957
738k
        xmlFree(err->message);
958
760k
    if (err->file != NULL)
959
0
        xmlFree(err->file);
960
760k
    if (err->str1 != NULL)
961
299k
        xmlFree(err->str1);
962
760k
    if (err->str2 != NULL)
963
32.1k
        xmlFree(err->str2);
964
760k
    if (err->str3 != NULL)
965
15.9k
        xmlFree(err->str3);
966
760k
    memset(err, 0, sizeof(xmlError));
967
760k
    err->code = XML_ERR_OK;
968
760k
}
969
970
/**
971
 * Reset the last error to success.
972
 */
973
void
974
xmlResetLastError(void)
975
27.9k
{
976
27.9k
    xmlError *error = xmlGetLastErrorInternal();
977
978
27.9k
    if (error->code != XML_ERR_OK)
979
27.8k
        xmlResetError(error);
980
27.9k
}
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
373k
xmlCopyError(const xmlError *from, xmlError *to) {
991
373k
    const char *fmt = NULL;
992
993
373k
    if ((from == NULL) || (to == NULL))
994
0
        return(-1);
995
996
373k
    if (from->message != NULL)
997
373k
        fmt = "%s";
998
999
373k
    return(xmlSetError(to, from->ctxt, from->node,
1000
373k
                       from->domain, from->code, from->level,
1001
373k
                       from->file, from->line,
1002
373k
                       from->str1, from->str2, from->str3,
1003
373k
                       from->int1, from->int2,
1004
373k
                       fmt, from->message));
1005
373k
}
1006
1007
/**
1008
 * @param code  an xmlParserErrors code
1009
 * @returns an error message for a code.
1010
 */
1011
const char *
1012
152k
xmlErrString(xmlParserErrors code) {
1013
152k
    const char *errmsg;
1014
1015
152k
    switch (code) {
1016
1.86k
        case XML_ERR_INVALID_HEX_CHARREF:
1017
1.86k
            errmsg = "CharRef: invalid hexadecimal value";
1018
1.86k
            break;
1019
2.45k
        case XML_ERR_INVALID_DEC_CHARREF:
1020
2.45k
            errmsg = "CharRef: invalid decimal value";
1021
2.45k
            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
11.2k
        case XML_ERR_PEREF_SEMICOL_MISSING:
1041
11.2k
            errmsg = "PEReference: expecting ';'";
1042
11.2k
            break;
1043
68
        case XML_ERR_ENTITY_LOOP:
1044
68
            errmsg = "Detected an entity reference loop";
1045
68
            break;
1046
0
        case XML_ERR_ENTITY_NOT_STARTED:
1047
0
            errmsg = "EntityValue: \" or ' expected";
1048
0
            break;
1049
489
        case XML_ERR_ENTITY_PE_INTERNAL:
1050
489
            errmsg = "PEReferences forbidden in internal subset";
1051
489
            break;
1052
0
        case XML_ERR_ENTITY_NOT_FINISHED:
1053
0
            errmsg = "EntityValue: \" or ' expected";
1054
0
            break;
1055
2.43k
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
1056
2.43k
            errmsg = "AttValue: \" or ' expected";
1057
2.43k
            break;
1058
19.5k
        case XML_ERR_LT_IN_ATTRIBUTE:
1059
19.5k
            errmsg = "Unescaped '<' not allowed in attributes values";
1060
19.5k
            break;
1061
1.25k
        case XML_ERR_LITERAL_NOT_STARTED:
1062
1.25k
            errmsg = "SystemLiteral \" or ' expected";
1063
1.25k
            break;
1064
2.07k
        case XML_ERR_LITERAL_NOT_FINISHED:
1065
2.07k
            errmsg = "Unfinished System or Public ID \" or ' expected";
1066
2.07k
            break;
1067
610
        case XML_ERR_MISPLACED_CDATA_END:
1068
610
            errmsg = "Sequence ']]>' not allowed in content";
1069
610
            break;
1070
819
        case XML_ERR_URI_REQUIRED:
1071
819
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
1072
819
            break;
1073
439
        case XML_ERR_PUBID_REQUIRED:
1074
439
            errmsg = "PUBLIC, the Public Identifier is missing";
1075
439
            break;
1076
6.37k
        case XML_ERR_HYPHEN_IN_COMMENT:
1077
6.37k
            errmsg = "Comment must not contain '--' (double-hyphen)";
1078
6.37k
            break;
1079
1.26k
        case XML_ERR_PI_NOT_STARTED:
1080
1.26k
            errmsg = "xmlParsePI : no target name";
1081
1.26k
            break;
1082
572
        case XML_ERR_RESERVED_XML_NAME:
1083
572
            errmsg = "Invalid PI name";
1084
572
            break;
1085
541
        case XML_ERR_NOTATION_NOT_STARTED:
1086
541
            errmsg = "NOTATION: Name expected here";
1087
541
            break;
1088
1.97k
        case XML_ERR_NOTATION_NOT_FINISHED:
1089
1.97k
            errmsg = "'>' required to close NOTATION declaration";
1090
1.97k
            break;
1091
3.28k
        case XML_ERR_VALUE_REQUIRED:
1092
3.28k
            errmsg = "Entity value required";
1093
3.28k
            break;
1094
384
        case XML_ERR_URI_FRAGMENT:
1095
384
            errmsg = "Fragment not allowed";
1096
384
            break;
1097
847
        case XML_ERR_ATTLIST_NOT_STARTED:
1098
847
            errmsg = "'(' required to start ATTLIST enumeration";
1099
847
            break;
1100
251
        case XML_ERR_NMTOKEN_REQUIRED:
1101
251
            errmsg = "NmToken expected in ATTLIST enumeration";
1102
251
            break;
1103
1.14k
        case XML_ERR_ATTLIST_NOT_FINISHED:
1104
1.14k
            errmsg = "')' required to finish ATTLIST enumeration";
1105
1.14k
            break;
1106
1.18k
        case XML_ERR_MIXED_NOT_STARTED:
1107
1.18k
            errmsg = "MixedContentDecl : '|' or ')*' expected";
1108
1.18k
            break;
1109
0
        case XML_ERR_PCDATA_REQUIRED:
1110
0
            errmsg = "MixedContentDecl : '#PCDATA' expected";
1111
0
            break;
1112
858
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
1113
858
            errmsg = "ContentDecl : Name or '(' expected";
1114
858
            break;
1115
2.55k
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
1116
2.55k
            errmsg = "ContentDecl : ',' '|' or ')' expected";
1117
2.55k
            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
6.38k
        case XML_ERR_GT_REQUIRED:
1123
6.38k
            errmsg = "expected '>'";
1124
6.38k
            break;
1125
0
        case XML_ERR_CONDSEC_INVALID:
1126
0
            errmsg = "XML conditional section '[' expected";
1127
0
            break;
1128
8.26k
        case XML_ERR_INT_SUBSET_NOT_FINISHED:
1129
8.26k
            errmsg = "Content error in the internal subset";
1130
8.26k
            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
769
        case XML_ERR_XMLDECL_NOT_FINISHED:
1145
769
            errmsg = "parsing XML declaration: '?>' expected";
1146
769
            break;
1147
0
        case XML_ERR_EXT_ENTITY_STANDALONE:
1148
0
            errmsg = "external parsed entities cannot be standalone";
1149
0
            break;
1150
7.35k
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
1151
7.35k
            errmsg = "EntityRef: expecting ';'";
1152
7.35k
            break;
1153
357
        case XML_ERR_DOCTYPE_NOT_FINISHED:
1154
357
            errmsg = "DOCTYPE improperly terminated";
1155
357
            break;
1156
49
        case XML_ERR_LTSLASH_REQUIRED:
1157
49
            errmsg = "EndTag: '</' not found";
1158
49
            break;
1159
13
        case XML_ERR_EQUAL_REQUIRED:
1160
13
            errmsg = "expected '='";
1161
13
            break;
1162
142
        case XML_ERR_STRING_NOT_CLOSED:
1163
142
            errmsg = "String not closed expecting \" or '";
1164
142
            break;
1165
13
        case XML_ERR_STRING_NOT_STARTED:
1166
13
            errmsg = "String not started expecting ' or \"";
1167
13
            break;
1168
4
        case XML_ERR_ENCODING_NAME:
1169
4
            errmsg = "Invalid XML encoding name";
1170
4
            break;
1171
10
        case XML_ERR_STANDALONE_VALUE:
1172
10
            errmsg = "standalone accepts only 'yes' or 'no'";
1173
10
            break;
1174
30
        case XML_ERR_DOCUMENT_EMPTY:
1175
30
            errmsg = "Document is empty";
1176
30
            break;
1177
8
        case XML_ERR_DOCUMENT_END:
1178
8
            errmsg = "Extra content at the end of the document";
1179
8
            break;
1180
101
        case XML_ERR_NOT_WELL_BALANCED:
1181
101
            errmsg = "chunk is not well balanced";
1182
101
            break;
1183
0
        case XML_ERR_EXTRA_CONTENT:
1184
0
            errmsg = "extra content at the end of well balanced chunk";
1185
0
            break;
1186
754
        case XML_ERR_VERSION_MISSING:
1187
754
            errmsg = "Malformed declaration expecting version";
1188
754
            break;
1189
0
        case XML_ERR_NAME_TOO_LONG:
1190
0
            errmsg = "Name too long";
1191
0
            break;
1192
7.09k
        case XML_ERR_INVALID_ENCODING:
1193
7.09k
            errmsg = "Invalid bytes in character encoding";
1194
7.09k
            break;
1195
6
        case XML_ERR_RESOURCE_LIMIT:
1196
6
            errmsg = "Resource limit exceeded";
1197
6
            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
34
        case XML_ERR_UNSUPPORTED_ENCODING:
1208
34
            errmsg = "Unsupported encoding";
1209
34
            break;
1210
54.9k
        case XML_ERR_INVALID_CHAR:
1211
54.9k
            errmsg = "Invalid character";
1212
54.9k
            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
1.07k
        default:
1332
1.07k
            errmsg = "Unregistered error message";
1333
152k
    }
1334
1335
152k
    return(errmsg);
1336
152k
}
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
}