parser.c 427 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
 *            implemented on top of the SAX interfaces
 *
 * References:
 *   The XML specification:
 *     http://www.w3.org/TR/REC-xml
 *   Original 1.0 version:
 *     http://www.w3.org/TR/1998/REC-xml-19980210
 *   XML second edition working draft
 *     http://www.w3.org/TR/2000/WD-xml-2e-20000814
 *
 * Okay this is a big file, the parser core is around 7000 lines, then it
 * is followed by the progressive parser top routines, then the various
15
 * high level APIs to call the parser and a few miscellaneous functions.
16 17 18 19
 * A number of helper functions and deprecated ones have been moved to
 * parserInternals.c to reduce this file size.
 * As much as possible the functions are associated with their relative
 * production in the XML specification. A few productions defining the
Daniel Veillard's avatar
Daniel Veillard committed
20
 * different ranges of character are actually implanted either in
21 22 23 24
 * parserInternals.h or parserInternals.c
 * The DOM tree build is realized from the default SAX callbacks in
 * the module SAX.c.
 * The routines doing the validation checks are in valid.c and called either
25
 * from the SAX callbacks or as standalone functions using a preparsed
26 27 28 29
 * document.
 *
 * See Copyright for the status of this software.
 *
30
 * daniel@veillard.com
31 32
 */

33 34 35 36 37
/* To avoid EBCDIC trouble when parsing on zOS */
#if defined(__MVS__)
#pragma convert("ISO8859-1")
#endif

38
#define IN_LIBXML
Bjorn Reese's avatar
Bjorn Reese committed
39 40
#include "libxml.h"

Nick Wellnhofer's avatar
Nick Wellnhofer committed
41
#if defined(_WIN32) && !defined (__CYGWIN__)
42 43 44 45 46 47
#define XML_DIR_SEP '\\'
#else
#define XML_DIR_SEP '/'
#endif

#include <stdlib.h>
48
#include <limits.h>
49
#include <string.h>
50
#include <stdarg.h>
51
#include <stddef.h>
52
#include <libxml/xmlmemory.h>
53 54
#include <libxml/threads.h>
#include <libxml/globals.h>
55 56 57 58 59 60 61 62 63
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/valid.h>
#include <libxml/entities.h>
#include <libxml/xmlerror.h>
#include <libxml/encoding.h>
#include <libxml/xmlIO.h>
#include <libxml/uri.h>
64 65 66
#ifdef LIBXML_CATALOG_ENABLED
#include <libxml/catalog.h>
#endif
67 68 69 70
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/xmlschemastypes.h>
#include <libxml/relaxng.h>
#endif
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
89 90 91
#ifdef HAVE_LZMA_H
#include <lzma.h>
#endif
92

93 94 95
#include "buf.h"
#include "enc.h"

96 97 98
static void
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);

99 100 101 102
static xmlParserCtxtPtr
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
	                  const xmlChar *base, xmlParserCtxtPtr pctx);

103 104
static void xmlHaltParser(xmlParserCtxtPtr ctxt);

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/************************************************************************
 *									*
 *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
 *									*
 ************************************************************************/

#define XML_PARSER_BIG_ENTITY 1000
#define XML_PARSER_LOT_ENTITY 5000

/*
 * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
 *    replacement over the size in byte of the input indicates that you have
 *    and eponential behaviour. A value of 10 correspond to at least 3 entity
 *    replacement per byte of input.
 */
#define XML_PARSER_NON_LINEAR 10

/*
 * xmlParserEntityCheck
 *
 * Function to check non-linear entity expansion behaviour
 * This is here to detect and stop exponential linear entity expansion
 * This is not a limitation of the parser but a safety
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
 * parser option.
 */
static int
132
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
133
                     xmlEntityPtr ent, size_t replacement)
134
{
135
    size_t consumed = 0;
136 137 138 139 140

    if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
        return (0);
    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
        return (1);
Daniel Veillard's avatar
Daniel Veillard committed
141 142 143 144 145 146

    /*
     * This may look absurd but is needed to detect
     * entities problems
     */
    if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
147 148
	(ent->content != NULL) && (ent->checked == 0) &&
	(ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
Daniel Veillard's avatar
Daniel Veillard committed
149 150 151 152 153
	unsigned long oldnbent = ctxt->nbentities;
	xmlChar *rep;

	ent->checked = 1;

154
        ++ctxt->depth;
Daniel Veillard's avatar
Daniel Veillard committed
155 156
	rep = xmlStringDecodeEntities(ctxt, ent->content,
				  XML_SUBSTITUTE_REF, 0, 0, 0);
157
        --ctxt->depth;
158 159 160
	if (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
	    ent->content[0] = 0;
	}
Daniel Veillard's avatar
Daniel Veillard committed
161 162 163 164 165 166 167 168 169

	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
	if (rep != NULL) {
	    if (xmlStrchr(rep, '<'))
		ent->checked |= 1;
	    xmlFree(rep);
	    rep = NULL;
	}
    }
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    if (replacement != 0) {
	if (replacement < XML_MAX_TEXT_LENGTH)
	    return(0);

        /*
	 * If the volume of entity copy reaches 10 times the
	 * amount of parsed data and over the large text threshold
	 * then that's very likely to be an abuse.
	 */
        if (ctxt->input != NULL) {
	    consumed = ctxt->input->consumed +
	               (ctxt->input->cur - ctxt->input->base);
	}
        consumed += ctxt->sizeentities;

        if (replacement < XML_PARSER_NON_LINEAR * consumed)
	    return(0);
    } else if (size != 0) {
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
        /*
         * Do the check based on the replacement size of the entity
         */
        if (size < XML_PARSER_BIG_ENTITY)
	    return(0);

        /*
         * A limit on the amount of text data reasonably used
         */
        if (ctxt->input != NULL) {
            consumed = ctxt->input->consumed +
                (ctxt->input->cur - ctxt->input->base);
        }
        consumed += ctxt->sizeentities;

        if ((size < XML_PARSER_NON_LINEAR * consumed) &&
	    (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
            return (0);
    } else if (ent != NULL) {
        /*
         * use the number of parsed entities in the replacement
         */
210
        size = ent->checked / 2;
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228

        /*
         * The amount of data parsed counting entities size only once
         */
        if (ctxt->input != NULL) {
            consumed = ctxt->input->consumed +
                (ctxt->input->cur - ctxt->input->base);
        }
        consumed += ctxt->sizeentities;

        /*
         * Check the density of entities for the amount of data
	 * knowing an entity reference will take at least 3 bytes
         */
        if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
            return (0);
    } else {
        /*
Daniel Veillard's avatar
Daniel Veillard committed
229
         * strange we got no data for checking
230
         */
Daniel Veillard's avatar
Daniel Veillard committed
231 232 233 234
	if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
	     (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
	    (ctxt->nbentities <= 10000))
	    return (0);
235 236 237 238 239
    }
    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
    return (1);
}

240
/**
241
 * xmlParserMaxDepth:
242
 *
243 244 245 246
 * arbitrary depth limit for the XML documents that we allow to
 * process. This is not a limitation of the parser but a safety
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
 * parser option.
247
 */
248
unsigned int xmlParserMaxDepth = 256;
249

250

251 252

#define SAX2 1
253
#define XML_PARSER_BIG_BUFFER_SIZE 300
254
#define XML_PARSER_BUFFER_SIZE 100
255 256
#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"

257 258 259 260 261 262 263 264 265 266 267
/**
 * XML_PARSER_CHUNK_SIZE
 *
 * When calling GROW that's the minimal amount of data
 * the parser expected to have received. It is not a hard
 * limit but an optimization when reading strings like Names
 * It is not strictly needed as long as inputs available characters
 * are followed by 0, which should be provided by the I/O level
 */
#define XML_PARSER_CHUNK_SIZE 100

268 269 270 271
/*
 * List of XML prefixed PI allowed by W3C specs
 */

272
static const char *xmlW3CPIs[] = {
273
    "xml-stylesheet",
274
    "xml-model",
275 276 277
    NULL
};

278

279
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
280 281
static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
                                              const xmlChar **str);
282

283
static xmlParserErrors
284 285
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
	              xmlSAXHandlerPtr sax,
286
		      void *user_data, int depth, const xmlChar *URL,
287
		      const xmlChar *ID, xmlNodePtr *list);
288

289 290 291
static int
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
                          const char *encoding);
292
#ifdef LIBXML_LEGACY_ENABLED
293 294 295
static void
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
                      xmlNodePtr lastNode);
296
#endif /* LIBXML_LEGACY_ENABLED */
297

298
static xmlParserErrors
299 300
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
		      const xmlChar *string, void *user_data, xmlNodePtr *lst);
301

302 303 304
static int
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);

305 306
/************************************************************************
 *									*
Daniel Veillard's avatar
Daniel Veillard committed
307
 *		Some factorized error routines				*
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
 *									*
 ************************************************************************/

/**
 * xmlErrAttributeDup:
 * @ctxt:  an XML parser context
 * @prefix:  the attribute prefix
 * @localname:  the attribute localname
 *
 * Handle a redefinition of attribute error
 */
static void
xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
                   const xmlChar * localname)
{
323 324 325
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
326 327
    if (ctxt != NULL)
	ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
328

329
    if (prefix == NULL)
330
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
331
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
332 333
                        (const char *) localname, NULL, NULL, 0, 0,
                        "Attribute %s redefined\n", localname);
334
    else
335
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
336
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
337 338 339
                        (const char *) prefix, (const char *) localname,
                        NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
                        localname);
340 341 342 343 344
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
345 346 347 348 349 350 351 352 353 354 355
}

/**
 * xmlFatalErr:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @extra:  extra information string
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
static void
356
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
357 358 359
{
    const char *errmsg;

360 361 362
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
363 364
    switch (error) {
        case XML_ERR_INVALID_HEX_CHARREF:
365
            errmsg = "CharRef: invalid hexadecimal value";
366
            break;
367
        case XML_ERR_INVALID_DEC_CHARREF:
368
            errmsg = "CharRef: invalid decimal value";
369
            break;
370
        case XML_ERR_INVALID_CHARREF:
371
            errmsg = "CharRef: invalid value";
372
            break;
373
        case XML_ERR_INTERNAL_ERROR:
374 375
            errmsg = "internal error";
            break;
376
        case XML_ERR_PEREF_AT_EOF:
377
            errmsg = "PEReference at end of document";
378
            break;
379
        case XML_ERR_PEREF_IN_PROLOG:
380
            errmsg = "PEReference in prolog";
381
            break;
382
        case XML_ERR_PEREF_IN_EPILOG:
383
            errmsg = "PEReference in epilog";
384
            break;
385
        case XML_ERR_PEREF_NO_NAME:
386
            errmsg = "PEReference: no name";
387
            break;
388
        case XML_ERR_PEREF_SEMICOL_MISSING:
389
            errmsg = "PEReference: expecting ';'";
390
            break;
391
        case XML_ERR_ENTITY_LOOP:
392
            errmsg = "Detected an entity reference loop";
393
            break;
394
        case XML_ERR_ENTITY_NOT_STARTED:
395
            errmsg = "EntityValue: \" or ' expected";
396
            break;
397
        case XML_ERR_ENTITY_PE_INTERNAL:
398
            errmsg = "PEReferences forbidden in internal subset";
399
            break;
400
        case XML_ERR_ENTITY_NOT_FINISHED:
401
            errmsg = "EntityValue: \" or ' expected";
402
            break;
403
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
404
            errmsg = "AttValue: \" or ' expected";
405
            break;
406
        case XML_ERR_LT_IN_ATTRIBUTE:
407
            errmsg = "Unescaped '<' not allowed in attributes values";
408
            break;
409
        case XML_ERR_LITERAL_NOT_STARTED:
410
            errmsg = "SystemLiteral \" or ' expected";
411
            break;
412
        case XML_ERR_LITERAL_NOT_FINISHED:
413
            errmsg = "Unfinished System or Public ID \" or ' expected";
414
            break;
415
        case XML_ERR_MISPLACED_CDATA_END:
416
            errmsg = "Sequence ']]>' not allowed in content";
417
            break;
418
        case XML_ERR_URI_REQUIRED:
419
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
420
            break;
421
        case XML_ERR_PUBID_REQUIRED:
422
            errmsg = "PUBLIC, the Public Identifier is missing";
423
            break;
424
        case XML_ERR_HYPHEN_IN_COMMENT:
425
            errmsg = "Comment must not contain '--' (double-hyphen)";
426
            break;
427
        case XML_ERR_PI_NOT_STARTED:
428
            errmsg = "xmlParsePI : no target name";
429
            break;
430
        case XML_ERR_RESERVED_XML_NAME:
431
            errmsg = "Invalid PI name";
432
            break;
433
        case XML_ERR_NOTATION_NOT_STARTED:
434
            errmsg = "NOTATION: Name expected here";
435
            break;
436
        case XML_ERR_NOTATION_NOT_FINISHED:
437
            errmsg = "'>' required to close NOTATION declaration";
438
            break;
439
        case XML_ERR_VALUE_REQUIRED:
440
            errmsg = "Entity value required";
441
            break;
442
        case XML_ERR_URI_FRAGMENT:
443 444
            errmsg = "Fragment not allowed";
            break;
445
        case XML_ERR_ATTLIST_NOT_STARTED:
446
            errmsg = "'(' required to start ATTLIST enumeration";
447
            break;
448
        case XML_ERR_NMTOKEN_REQUIRED:
449
            errmsg = "NmToken expected in ATTLIST enumeration";
450
            break;
451
        case XML_ERR_ATTLIST_NOT_FINISHED:
452
            errmsg = "')' required to finish ATTLIST enumeration";
453
            break;
454
        case XML_ERR_MIXED_NOT_STARTED:
455
            errmsg = "MixedContentDecl : '|' or ')*' expected";
456
            break;
457
        case XML_ERR_PCDATA_REQUIRED:
458
            errmsg = "MixedContentDecl : '#PCDATA' expected";
459
            break;
460
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
461
            errmsg = "ContentDecl : Name or '(' expected";
462
            break;
463
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
464
            errmsg = "ContentDecl : ',' '|' or ')' expected";
465
            break;
466
        case XML_ERR_PEREF_IN_INT_SUBSET:
467
            errmsg =
468
                "PEReference: forbidden within markup decl in internal subset";
469
            break;
470
        case XML_ERR_GT_REQUIRED:
471
            errmsg = "expected '>'";
472
            break;
473
        case XML_ERR_CONDSEC_INVALID:
474
            errmsg = "XML conditional section '[' expected";
475
            break;
476
        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
477
            errmsg = "Content error in the external subset";
478 479 480
            break;
        case XML_ERR_CONDSEC_INVALID_KEYWORD:
            errmsg =
481
                "conditional section INCLUDE or IGNORE keyword expected";
482
            break;
483
        case XML_ERR_CONDSEC_NOT_FINISHED:
484
            errmsg = "XML conditional section not closed";
485
            break;
486
        case XML_ERR_XMLDECL_NOT_STARTED:
487
            errmsg = "Text declaration '<?xml' required";
488
            break;
489
        case XML_ERR_XMLDECL_NOT_FINISHED:
490
            errmsg = "parsing XML declaration: '?>' expected";
491
            break;
492
        case XML_ERR_EXT_ENTITY_STANDALONE:
493
            errmsg = "external parsed entities cannot be standalone";
494
            break;
495
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
496
            errmsg = "EntityRef: expecting ';'";
497
            break;
498
        case XML_ERR_DOCTYPE_NOT_FINISHED:
499
            errmsg = "DOCTYPE improperly terminated";
500
            break;
501
        case XML_ERR_LTSLASH_REQUIRED:
502
            errmsg = "EndTag: '</' not found";
503
            break;
504
        case XML_ERR_EQUAL_REQUIRED:
505
            errmsg = "expected '='";
506
            break;
507
        case XML_ERR_STRING_NOT_CLOSED:
508
            errmsg = "String not closed expecting \" or '";
509
            break;
510
        case XML_ERR_STRING_NOT_STARTED:
511
            errmsg = "String not started expecting ' or \"";
512
            break;
513
        case XML_ERR_ENCODING_NAME:
514
            errmsg = "Invalid XML encoding name";
515
            break;
516
        case XML_ERR_STANDALONE_VALUE:
517
            errmsg = "standalone accepts only 'yes' or 'no'";
518
            break;
519
        case XML_ERR_DOCUMENT_EMPTY:
520
            errmsg = "Document is empty";
521
            break;
522
        case XML_ERR_DOCUMENT_END:
523
            errmsg = "Extra content at the end of the document";
524
            break;
525
        case XML_ERR_NOT_WELL_BALANCED:
526
            errmsg = "chunk is not well balanced";
527
            break;
528
        case XML_ERR_EXTRA_CONTENT:
529
            errmsg = "extra content at the end of well balanced chunk";
530
            break;
531
        case XML_ERR_VERSION_MISSING:
532
            errmsg = "Malformed declaration expecting version";
533
            break;
534
        case XML_ERR_NAME_TOO_LONG:
535
            errmsg = "Name too long use XML_PARSE_HUGE option";
536
            break;
537
#if 0
538
        case:
539
            errmsg = "";
540
            break;
541
#endif
542
        default:
543
            errmsg = "Unregistered error message";
544
    }
545 546
    if (ctxt != NULL)
	ctxt->errNo = error;
547 548 549 550 551 552 553 554 555
    if (info == NULL) {
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
                        errmsg);
    } else {
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
                        errmsg, info);
    }
556 557 558 559 560
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
561 562
}

563 564 565 566 567 568 569 570
/**
 * xmlFatalErrMsg:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
571
static void LIBXML_ATTR_FORMAT(3,0)
572 573
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg)
574
{
575 576 577
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
578 579
    if (ctxt != NULL)
	ctxt->errNo = error;
580
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
581
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
582 583 584 585 586
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
587 588
}

589 590 591 592 593 594 595 596 597 598
/**
 * xmlWarningMsg:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 * @str1:  extra data
 * @str2:  extra data
 *
 * Handle a warning.
 */
599
static void LIBXML_ATTR_FORMAT(3,0)
600 601 602
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, const xmlChar *str1, const xmlChar *str2)
{
Daniel Veillard's avatar
Daniel Veillard committed
603
    xmlStructuredErrorFunc schannel = NULL;
604

605 606 607
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
608 609
    if ((ctxt != NULL) && (ctxt->sax != NULL) &&
        (ctxt->sax->initialized == XML_SAX2_MAGIC))
Daniel Veillard's avatar
Daniel Veillard committed
610
        schannel = ctxt->sax->serror;
611 612
    if (ctxt != NULL) {
        __xmlRaiseError(schannel,
613 614
                    (ctxt->sax) ? ctxt->sax->warning : NULL,
                    ctxt->userData,
615 616 617 618
                    ctxt, NULL, XML_FROM_PARSER, error,
                    XML_ERR_WARNING, NULL, 0,
		    (const char *) str1, (const char *) str2, NULL, 0, 0,
		    msg, (const char *) str1, (const char *) str2);
619 620 621 622 623 624 625
    } else {
        __xmlRaiseError(schannel, NULL, NULL,
                    ctxt, NULL, XML_FROM_PARSER, error,
                    XML_ERR_WARNING, NULL, 0,
		    (const char *) str1, (const char *) str2, NULL, 0, 0,
		    msg, (const char *) str1, (const char *) str2);
    }
626 627 628 629 630 631 632 633 634
}

/**
 * xmlValidityError:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 * @str1:  extra data
 *
635
 * Handle a validity error.
636
 */
637
static void LIBXML_ATTR_FORMAT(3,0)
638
xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
639
              const char *msg, const xmlChar *str1, const xmlChar *str2)
640
{
Daniel Veillard's avatar
Daniel Veillard committed
641
    xmlStructuredErrorFunc schannel = NULL;
642 643 644 645

    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
646 647 648 649 650
    if (ctxt != NULL) {
	ctxt->errNo = error;
	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
	    schannel = ctxt->sax->serror;
    }
651 652
    if (ctxt != NULL) {
        __xmlRaiseError(schannel,
653
                    ctxt->vctxt.error, ctxt->vctxt.userData,
654 655
                    ctxt, NULL, XML_FROM_DTD, error,
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
656 657
		    (const char *) str2, NULL, 0, 0,
		    msg, (const char *) str1, (const char *) str2);
658
	ctxt->valid = 0;
659 660 661 662 663 664
    } else {
        __xmlRaiseError(schannel, NULL, NULL,
                    ctxt, NULL, XML_FROM_DTD, error,
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
		    (const char *) str2, NULL, 0, 0,
		    msg, (const char *) str1, (const char *) str2);
665
    }
666 667
}

668 669 670 671 672 673 674 675 676
/**
 * xmlFatalErrMsgInt:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 * @val:  an integer value
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
677
static void LIBXML_ATTR_FORMAT(3,0)
678
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
679
                  const char *msg, int val)
680
{
681 682 683
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
684 685
    if (ctxt != NULL)
	ctxt->errNo = error;
686
    __xmlRaiseError(NULL, NULL, NULL,
687 688
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
689 690 691 692 693
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
694 695
}

696 697 698 699 700 701 702 703 704 705 706
/**
 * xmlFatalErrMsgStrIntStr:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 * @str1:  an string info
 * @val:  an integer value
 * @str2:  an string info
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
707
static void LIBXML_ATTR_FORMAT(3,0)
708
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
Daniel Veillard's avatar
Daniel Veillard committed
709
                  const char *msg, const xmlChar *str1, int val,
710 711
		  const xmlChar *str2)
{
712 713 714
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
715 716
    if (ctxt != NULL)
	ctxt->errNo = error;
717
    __xmlRaiseError(NULL, NULL, NULL,
718 719 720
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    NULL, 0, (const char *) str1, (const char *) str2,
		    NULL, val, 0, msg, str1, val, str2);
721 722 723 724 725
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
726 727
}

728 729 730 731 732 733 734 735 736
/**
 * xmlFatalErrMsgStr:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 * @val:  a string value
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
737
static void LIBXML_ATTR_FORMAT(3,0)
738
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
739
                  const char *msg, const xmlChar * val)
740
{
741 742 743
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
744 745
    if (ctxt != NULL)
	ctxt->errNo = error;
746
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
747 748 749
                    XML_FROM_PARSER, error, XML_ERR_FATAL,
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    val);
750 751 752 753 754
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
755 756
}

757 758 759 760 761 762 763 764 765
/**
 * xmlErrMsgStr:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the error message
 * @val:  a string value
 *
 * Handle a non fatal parser error
 */
766
static void LIBXML_ATTR_FORMAT(3,0)
767 768 769
xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                  const char *msg, const xmlChar * val)
{
770 771 772
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
773 774
    if (ctxt != NULL)
	ctxt->errNo = error;
775
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
776 777 778 779 780
                    XML_FROM_PARSER, error, XML_ERR_ERROR,
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    val);
}

781 782 783 784 785 786 787 788 789 790
/**
 * xmlNsErr:
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the message
 * @info1:  extra information string
 * @info2:  extra information string
 *
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
 */
791
static void LIBXML_ATTR_FORMAT(3,0)
792 793
xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
         const char *msg,
794 795
         const xmlChar * info1, const xmlChar * info2,
         const xmlChar * info3)
796
{
797 798 799
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
800 801
    if (ctxt != NULL)
	ctxt->errNo = error;
802
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
803 804 805
                    XML_ERR_ERROR, NULL, 0, (const char *) info1,
                    (const char *) info2, (const char *) info3, 0, 0, msg,
                    info1, info2, info3);
806 807
    if (ctxt != NULL)
	ctxt->nsWellFormed = 0;
808 809
}

810 811 812 813 814 815 816 817
/**
 * xmlNsWarn
 * @ctxt:  an XML parser context
 * @error:  the error number
 * @msg:  the message
 * @info1:  extra information string
 * @info2:  extra information string
 *
Daniel Veillard's avatar
Daniel Veillard committed
818
 * Handle a namespace warning error
819
 */
820
static void LIBXML_ATTR_FORMAT(3,0)
821 822 823 824 825 826 827 828 829 830 831 832 833 834
xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
         const char *msg,
         const xmlChar * info1, const xmlChar * info2,
         const xmlChar * info3)
{
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                    XML_ERR_WARNING, NULL, 0, (const char *) info1,
                    (const char *) info2, (const char *) info3, 0, 0, msg,
                    info1, info2, info3);
}

835 836
/************************************************************************
 *									*
Daniel Veillard's avatar
Daniel Veillard committed
837
 *		Library wide options					*
838 839 840 841 842 843 844 845