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
#define IN_LIBXML
Bjorn Reese's avatar
Bjorn Reese committed
34 35
#include "libxml.h"

36
#if defined(WIN32) && !defined (__CYGWIN__)
37 38 39 40 41 42
#define XML_DIR_SEP '\\'
#else
#define XML_DIR_SEP '/'
#endif

#include <stdlib.h>
43
#include <limits.h>
44
#include <string.h>
45
#include <stdarg.h>
46
#include <stddef.h>
47
#include <libxml/xmlmemory.h>
48 49
#include <libxml/threads.h>
#include <libxml/globals.h>
50 51 52 53 54 55 56 57 58
#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>
59 60 61
#ifdef LIBXML_CATALOG_ENABLED
#include <libxml/catalog.h>
#endif
62 63 64 65
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/xmlschemastypes.h>
#include <libxml/relaxng.h>
#endif
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#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
84 85 86
#ifdef HAVE_LZMA_H
#include <lzma.h>
#endif
87

88 89 90
#include "buf.h"
#include "enc.h"

91 92 93
static void
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);

94 95 96 97
static xmlParserCtxtPtr
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
	                  const xmlChar *base, xmlParserCtxtPtr pctx);

98 99
static void xmlHaltParser(xmlParserCtxtPtr ctxt);

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/************************************************************************
 *									*
 *	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
127
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
128
                     xmlEntityPtr ent, size_t replacement)
129
{
130
    size_t consumed = 0;
131 132 133 134 135

    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
136 137 138 139 140 141

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

	ent->checked = 1;

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

	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
	if (rep != NULL) {
	    if (xmlStrchr(rep, '<'))
		ent->checked |= 1;
	    xmlFree(rep);
	    rep = NULL;
	}
    }
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    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) {
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
        /*
         * 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
         */
205
        size = ent->checked / 2;
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

        /*
         * 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
224
         * strange we got no data for checking
225
         */
Daniel Veillard's avatar
Daniel Veillard committed
226 227 228 229
	if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
	     (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
	    (ctxt->nbentities <= 10000))
	    return (0);
230 231 232 233 234
    }
    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
    return (1);
}

235
/**
236
 * xmlParserMaxDepth:
237
 *
238 239 240 241
 * 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.
242
 */
243
unsigned int xmlParserMaxDepth = 256;
244

245

246 247

#define SAX2 1
248
#define XML_PARSER_BIG_BUFFER_SIZE 300
249
#define XML_PARSER_BUFFER_SIZE 100
250 251
#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"

252 253 254 255 256 257 258 259 260 261 262
/**
 * 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

263 264 265 266
/*
 * List of XML prefixed PI allowed by W3C specs
 */

267
static const char *xmlW3CPIs[] = {
268
    "xml-stylesheet",
269
    "xml-model",
270 271 272
    NULL
};

273

274
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
275 276
static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
                                              const xmlChar **str);
277

278
static xmlParserErrors
279 280
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
	              xmlSAXHandlerPtr sax,
281
		      void *user_data, int depth, const xmlChar *URL,
282
		      const xmlChar *ID, xmlNodePtr *list);
283

284 285 286
static int
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
                          const char *encoding);
287
#ifdef LIBXML_LEGACY_ENABLED
288 289 290
static void
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
                      xmlNodePtr lastNode);
291
#endif /* LIBXML_LEGACY_ENABLED */
292

293
static xmlParserErrors
294 295
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
		      const xmlChar *string, void *user_data, xmlNodePtr *lst);
296

297 298 299
static int
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);

300 301
/************************************************************************
 *									*
Daniel Veillard's avatar
Daniel Veillard committed
302
 *		Some factorized error routines				*
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
 *									*
 ************************************************************************/

/**
 * 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)
{
318 319 320
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
321 322
    if (ctxt != NULL)
	ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
323

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

/**
 * 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
351
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
352 353 354
{
    const char *errmsg;

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

558 559 560 561 562 563 564 565
/**
 * 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
 */
566
static void LIBXML_ATTR_FORMAT(3,0)
567 568
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg)
569
{
570 571 572
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
573 574
    if (ctxt != NULL)
	ctxt->errNo = error;
575
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
576
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
577 578 579 580 581
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
582 583
}

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

600 601 602
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
603 604
    if ((ctxt != NULL) && (ctxt->sax != NULL) &&
        (ctxt->sax->initialized == XML_SAX2_MAGIC))
Daniel Veillard's avatar
Daniel Veillard committed
605
        schannel = ctxt->sax->serror;
606 607
    if (ctxt != NULL) {
        __xmlRaiseError(schannel,
608 609
                    (ctxt->sax) ? ctxt->sax->warning : NULL,
                    ctxt->userData,
610 611 612 613
                    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);
614 615 616 617 618 619 620
    } 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);
    }
621 622 623 624 625 626 627 628 629
}

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

    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
641 642 643 644 645
    if (ctxt != NULL) {
	ctxt->errNo = error;
	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
	    schannel = ctxt->sax->serror;
    }
646 647
    if (ctxt != NULL) {
        __xmlRaiseError(schannel,
648
                    ctxt->vctxt.error, ctxt->vctxt.userData,
649 650
                    ctxt, NULL, XML_FROM_DTD, error,
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
651 652
		    (const char *) str2, NULL, 0, 0,
		    msg, (const char *) str1, (const char *) str2);
653
	ctxt->valid = 0;
654 655 656 657 658 659
    } 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);
660
    }
661 662
}

663 664 665 666 667 668 669 670 671
/**
 * 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
 */
672
static void LIBXML_ATTR_FORMAT(3,0)
673
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
674
                  const char *msg, int val)
675
{
676 677 678
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
679 680
    if (ctxt != NULL)
	ctxt->errNo = error;
681
    __xmlRaiseError(NULL, NULL, NULL,
682 683
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
684 685 686 687 688
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
689 690
}

691 692 693 694 695 696 697 698 699 700 701
/**
 * 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
 */
702
static void LIBXML_ATTR_FORMAT(3,0)
703
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
Daniel Veillard's avatar
Daniel Veillard committed
704
                  const char *msg, const xmlChar *str1, int val,
705 706
		  const xmlChar *str2)
{
707 708 709
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
710 711
    if (ctxt != NULL)
	ctxt->errNo = error;
712
    __xmlRaiseError(NULL, NULL, NULL,
713 714 715
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    NULL, 0, (const char *) str1, (const char *) str2,
		    NULL, val, 0, msg, str1, val, str2);
716 717 718 719 720
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
721 722
}

723 724 725 726 727 728 729 730 731
/**
 * 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
 */
732
static void LIBXML_ATTR_FORMAT(3,0)
733
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
734
                  const char *msg, const xmlChar * val)
735
{
736 737 738
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
739 740
    if (ctxt != NULL)
	ctxt->errNo = error;
741
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
742 743 744
                    XML_FROM_PARSER, error, XML_ERR_FATAL,
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    val);
745 746 747 748 749
    if (ctxt != NULL) {
	ctxt->wellFormed = 0;
	if (ctxt->recovery == 0)
	    ctxt->disableSAX = 1;
    }
750 751
}

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

776 777 778 779 780 781 782 783 784 785
/**
 * 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
 */
786
static void LIBXML_ATTR_FORMAT(3,0)
787 788
xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
         const char *msg,
789 790
         const xmlChar * info1, const xmlChar * info2,
         const xmlChar * info3)
791
{
792 793 794
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
        (ctxt->instate == XML_PARSER_EOF))
	return;
795 796
    if (ctxt != NULL)
	ctxt->errNo = error;
797
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
798 799 800
                    XML_ERR_ERROR, NULL, 0, (const char *) info1,
                    (const char *) info2, (const char *) info3, 0, 0, msg,
                    info1, info2, info3);
801 802
    if (ctxt != NULL)
	ctxt->nsWellFormed = 0;
803 804
}

805 806 807 808 809 810 811 812
/**
 * 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
813
 * Handle a namespace warning error
814
 */
815
static void LIBXML_ATTR_FORMAT(3,0)
816 817 818 819 820 821 822 823 824 825 826 827 828 829
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);
}

830 831
/************************************************************************
 *									*
Daniel Veillard's avatar
Daniel Veillard committed
832
 *		Library wide options					*
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
 *									*
 ************************************************************************/

/**
  * xmlHasFeature:
  * @feature: the feature to be examined
  *
  * Examines if the library has been