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 | } |