parser.c 428 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
#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

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

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

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

97 98
static void xmlHaltParser(xmlParserCtxtPtr ctxt);

99 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
/************************************************************************
 *									*
 *	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
126
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
127
                     xmlEntityPtr ent, size_t replacement)
128
{
129
    size_t consumed = 0;
130 131 132 133 134

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

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

	ent->checked = 1;

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

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

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

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

244

245 246

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

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

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

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

272

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
  * xmlHasFeature:
  * @feature: the feature to be examined
  *
  * Examines if the library has been compiled with a given feature.
  *
  * Returns a non-zero value if the feature exist, otherwise zero.
  * Returns zero (0) if the feature does not exist or an unknown
  * unknown feature is requested, non-zero otherwise.