Home | History | Annotate | Download | only in libxml2
      1 /*
      2  * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
      3  *            implemented on top of the SAX interfaces
      4  *
      5  * References:
      6  *   The XML specification:
      7  *     http://www.w3.org/TR/REC-xml
      8  *   Original 1.0 version:
      9  *     http://www.w3.org/TR/1998/REC-xml-19980210
     10  *   XML second edition working draft
     11  *     http://www.w3.org/TR/2000/WD-xml-2e-20000814
     12  *
     13  * Okay this is a big file, the parser core is around 7000 lines, then it
     14  * 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  * A number of helper functions and deprecated ones have been moved to
     17  * parserInternals.c to reduce this file size.
     18  * As much as possible the functions are associated with their relative
     19  * production in the XML specification. A few productions defining the
     20  * different ranges of character are actually implanted either in
     21  * parserInternals.h or parserInternals.c
     22  * The DOM tree build is realized from the default SAX callbacks in
     23  * the module SAX.c.
     24  * 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  * document.
     27  *
     28  * See Copyright for the status of this software.
     29  *
     30  * daniel (at) veillard.com
     31  */
     32 
     33 #define IN_LIBXML
     34 #include "libxml.h"
     35 
     36 #if defined(WIN32) && !defined (__CYGWIN__)
     37 #define XML_DIR_SEP '\\'
     38 #else
     39 #define XML_DIR_SEP '/'
     40 #endif
     41 
     42 #include <stdlib.h>
     43 #include <limits.h>
     44 #include <string.h>
     45 #include <stdarg.h>
     46 #include <libxml/xmlmemory.h>
     47 #include <libxml/threads.h>
     48 #include <libxml/globals.h>
     49 #include <libxml/tree.h>
     50 #include <libxml/parser.h>
     51 #include <libxml/parserInternals.h>
     52 #include <libxml/valid.h>
     53 #include <libxml/entities.h>
     54 #include <libxml/xmlerror.h>
     55 #include <libxml/encoding.h>
     56 #include <libxml/xmlIO.h>
     57 #include <libxml/uri.h>
     58 #ifdef LIBXML_CATALOG_ENABLED
     59 #include <libxml/catalog.h>
     60 #endif
     61 #ifdef LIBXML_SCHEMAS_ENABLED
     62 #include <libxml/xmlschemastypes.h>
     63 #include <libxml/relaxng.h>
     64 #endif
     65 #ifdef HAVE_CTYPE_H
     66 #include <ctype.h>
     67 #endif
     68 #ifdef HAVE_STDLIB_H
     69 #include <stdlib.h>
     70 #endif
     71 #ifdef HAVE_SYS_STAT_H
     72 #include <sys/stat.h>
     73 #endif
     74 #ifdef HAVE_FCNTL_H
     75 #include <fcntl.h>
     76 #endif
     77 #ifdef HAVE_UNISTD_H
     78 #include <unistd.h>
     79 #endif
     80 #ifdef HAVE_ZLIB_H
     81 #include <zlib.h>
     82 #endif
     83 #ifdef HAVE_LZMA_H
     84 #include <lzma.h>
     85 #endif
     86 
     87 #include "buf.h"
     88 #include "enc.h"
     89 
     90 static void
     91 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
     92 
     93 static xmlParserCtxtPtr
     94 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
     95 	                  const xmlChar *base, xmlParserCtxtPtr pctx);
     96 
     97 /************************************************************************
     98  *									*
     99  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
    100  *									*
    101  ************************************************************************/
    102 
    103 #define XML_PARSER_BIG_ENTITY 1000
    104 #define XML_PARSER_LOT_ENTITY 5000
    105 
    106 /*
    107  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
    108  *    replacement over the size in byte of the input indicates that you have
    109  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
    110  *    replacement per byte of input.
    111  */
    112 #define XML_PARSER_NON_LINEAR 10
    113 
    114 /*
    115  * xmlParserEntityCheck
    116  *
    117  * Function to check non-linear entity expansion behaviour
    118  * This is here to detect and stop exponential linear entity expansion
    119  * This is not a limitation of the parser but a safety
    120  * boundary feature. It can be disabled with the XML_PARSE_HUGE
    121  * parser option.
    122  */
    123 static int
    124 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
    125                      xmlEntityPtr ent, size_t replacement)
    126 {
    127     size_t consumed = 0;
    128 
    129     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
    130         return (0);
    131     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
    132         return (1);
    133     if (replacement != 0) {
    134 	if (replacement < XML_MAX_TEXT_LENGTH)
    135 	    return(0);
    136 
    137         /*
    138 	 * If the volume of entity copy reaches 10 times the
    139 	 * amount of parsed data and over the large text threshold
    140 	 * then that's very likely to be an abuse.
    141 	 */
    142         if (ctxt->input != NULL) {
    143 	    consumed = ctxt->input->consumed +
    144 	               (ctxt->input->cur - ctxt->input->base);
    145 	}
    146         consumed += ctxt->sizeentities;
    147 
    148         if (replacement < XML_PARSER_NON_LINEAR * consumed)
    149 	    return(0);
    150     } else if (size != 0) {
    151         /*
    152          * Do the check based on the replacement size of the entity
    153          */
    154         if (size < XML_PARSER_BIG_ENTITY)
    155 	    return(0);
    156 
    157         /*
    158          * A limit on the amount of text data reasonably used
    159          */
    160         if (ctxt->input != NULL) {
    161             consumed = ctxt->input->consumed +
    162                 (ctxt->input->cur - ctxt->input->base);
    163         }
    164         consumed += ctxt->sizeentities;
    165 
    166         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
    167 	    (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
    168             return (0);
    169     } else if (ent != NULL) {
    170         /*
    171          * use the number of parsed entities in the replacement
    172          */
    173         size = ent->checked / 2;
    174 
    175         /*
    176          * The amount of data parsed counting entities size only once
    177          */
    178         if (ctxt->input != NULL) {
    179             consumed = ctxt->input->consumed +
    180                 (ctxt->input->cur - ctxt->input->base);
    181         }
    182         consumed += ctxt->sizeentities;
    183 
    184         /*
    185          * Check the density of entities for the amount of data
    186 	 * knowing an entity reference will take at least 3 bytes
    187          */
    188         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
    189             return (0);
    190     } else {
    191         /*
    192          * strange we got no data for checking just return
    193          */
    194         return (0);
    195     }
    196     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
    197     return (1);
    198 }
    199 
    200 /**
    201  * xmlParserMaxDepth:
    202  *
    203  * arbitrary depth limit for the XML documents that we allow to
    204  * process. This is not a limitation of the parser but a safety
    205  * boundary feature. It can be disabled with the XML_PARSE_HUGE
    206  * parser option.
    207  */
    208 unsigned int xmlParserMaxDepth = 256;
    209 
    210 
    211 
    212 #define SAX2 1
    213 #define XML_PARSER_BIG_BUFFER_SIZE 300
    214 #define XML_PARSER_BUFFER_SIZE 100
    215 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
    216 
    217 /**
    218  * XML_PARSER_CHUNK_SIZE
    219  *
    220  * When calling GROW that's the minimal amount of data
    221  * the parser expected to have received. It is not a hard
    222  * limit but an optimization when reading strings like Names
    223  * It is not strictly needed as long as inputs available characters
    224  * are followed by 0, which should be provided by the I/O level
    225  */
    226 #define XML_PARSER_CHUNK_SIZE 100
    227 
    228 /*
    229  * List of XML prefixed PI allowed by W3C specs
    230  */
    231 
    232 static const char *xmlW3CPIs[] = {
    233     "xml-stylesheet",
    234     "xml-model",
    235     NULL
    236 };
    237 
    238 
    239 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
    240 static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
    241                                               const xmlChar **str);
    242 
    243 static xmlParserErrors
    244 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
    245 	              xmlSAXHandlerPtr sax,
    246 		      void *user_data, int depth, const xmlChar *URL,
    247 		      const xmlChar *ID, xmlNodePtr *list);
    248 
    249 static int
    250 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
    251                           const char *encoding);
    252 #ifdef LIBXML_LEGACY_ENABLED
    253 static void
    254 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
    255                       xmlNodePtr lastNode);
    256 #endif /* LIBXML_LEGACY_ENABLED */
    257 
    258 static xmlParserErrors
    259 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
    260 		      const xmlChar *string, void *user_data, xmlNodePtr *lst);
    261 
    262 static int
    263 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
    264 
    265 /************************************************************************
    266  *									*
    267  *		Some factorized error routines				*
    268  *									*
    269  ************************************************************************/
    270 
    271 /**
    272  * xmlErrAttributeDup:
    273  * @ctxt:  an XML parser context
    274  * @prefix:  the attribute prefix
    275  * @localname:  the attribute localname
    276  *
    277  * Handle a redefinition of attribute error
    278  */
    279 static void
    280 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
    281                    const xmlChar * localname)
    282 {
    283     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    284         (ctxt->instate == XML_PARSER_EOF))
    285 	return;
    286     if (ctxt != NULL)
    287 	ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
    288 
    289     if (prefix == NULL)
    290         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
    291                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
    292                         (const char *) localname, NULL, NULL, 0, 0,
    293                         "Attribute %s redefined\n", localname);
    294     else
    295         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
    296                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
    297                         (const char *) prefix, (const char *) localname,
    298                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
    299                         localname);
    300     if (ctxt != NULL) {
    301 	ctxt->wellFormed = 0;
    302 	if (ctxt->recovery == 0)
    303 	    ctxt->disableSAX = 1;
    304     }
    305 }
    306 
    307 /**
    308  * xmlFatalErr:
    309  * @ctxt:  an XML parser context
    310  * @error:  the error number
    311  * @extra:  extra information string
    312  *
    313  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
    314  */
    315 static void
    316 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
    317 {
    318     const char *errmsg;
    319     char errstr[129] = "";
    320 
    321     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    322         (ctxt->instate == XML_PARSER_EOF))
    323 	return;
    324     switch (error) {
    325         case XML_ERR_INVALID_HEX_CHARREF:
    326             errmsg = "CharRef: invalid hexadecimal value";
    327             break;
    328         case XML_ERR_INVALID_DEC_CHARREF:
    329             errmsg = "CharRef: invalid decimal value";
    330             break;
    331         case XML_ERR_INVALID_CHARREF:
    332             errmsg = "CharRef: invalid value";
    333             break;
    334         case XML_ERR_INTERNAL_ERROR:
    335             errmsg = "internal error";
    336             break;
    337         case XML_ERR_PEREF_AT_EOF:
    338             errmsg = "PEReference at end of document";
    339             break;
    340         case XML_ERR_PEREF_IN_PROLOG:
    341             errmsg = "PEReference in prolog";
    342             break;
    343         case XML_ERR_PEREF_IN_EPILOG:
    344             errmsg = "PEReference in epilog";
    345             break;
    346         case XML_ERR_PEREF_NO_NAME:
    347             errmsg = "PEReference: no name";
    348             break;
    349         case XML_ERR_PEREF_SEMICOL_MISSING:
    350             errmsg = "PEReference: expecting ';'";
    351             break;
    352         case XML_ERR_ENTITY_LOOP:
    353             errmsg = "Detected an entity reference loop";
    354             break;
    355         case XML_ERR_ENTITY_NOT_STARTED:
    356             errmsg = "EntityValue: \" or ' expected";
    357             break;
    358         case XML_ERR_ENTITY_PE_INTERNAL:
    359             errmsg = "PEReferences forbidden in internal subset";
    360             break;
    361         case XML_ERR_ENTITY_NOT_FINISHED:
    362             errmsg = "EntityValue: \" or ' expected";
    363             break;
    364         case XML_ERR_ATTRIBUTE_NOT_STARTED:
    365             errmsg = "AttValue: \" or ' expected";
    366             break;
    367         case XML_ERR_LT_IN_ATTRIBUTE:
    368             errmsg = "Unescaped '<' not allowed in attributes values";
    369             break;
    370         case XML_ERR_LITERAL_NOT_STARTED:
    371             errmsg = "SystemLiteral \" or ' expected";
    372             break;
    373         case XML_ERR_LITERAL_NOT_FINISHED:
    374             errmsg = "Unfinished System or Public ID \" or ' expected";
    375             break;
    376         case XML_ERR_MISPLACED_CDATA_END:
    377             errmsg = "Sequence ']]>' not allowed in content";
    378             break;
    379         case XML_ERR_URI_REQUIRED:
    380             errmsg = "SYSTEM or PUBLIC, the URI is missing";
    381             break;
    382         case XML_ERR_PUBID_REQUIRED:
    383             errmsg = "PUBLIC, the Public Identifier is missing";
    384             break;
    385         case XML_ERR_HYPHEN_IN_COMMENT:
    386             errmsg = "Comment must not contain '--' (double-hyphen)";
    387             break;
    388         case XML_ERR_PI_NOT_STARTED:
    389             errmsg = "xmlParsePI : no target name";
    390             break;
    391         case XML_ERR_RESERVED_XML_NAME:
    392             errmsg = "Invalid PI name";
    393             break;
    394         case XML_ERR_NOTATION_NOT_STARTED:
    395             errmsg = "NOTATION: Name expected here";
    396             break;
    397         case XML_ERR_NOTATION_NOT_FINISHED:
    398             errmsg = "'>' required to close NOTATION declaration";
    399             break;
    400         case XML_ERR_VALUE_REQUIRED:
    401             errmsg = "Entity value required";
    402             break;
    403         case XML_ERR_URI_FRAGMENT:
    404             errmsg = "Fragment not allowed";
    405             break;
    406         case XML_ERR_ATTLIST_NOT_STARTED:
    407             errmsg = "'(' required to start ATTLIST enumeration";
    408             break;
    409         case XML_ERR_NMTOKEN_REQUIRED:
    410             errmsg = "NmToken expected in ATTLIST enumeration";
    411             break;
    412         case XML_ERR_ATTLIST_NOT_FINISHED:
    413             errmsg = "')' required to finish ATTLIST enumeration";
    414             break;
    415         case XML_ERR_MIXED_NOT_STARTED:
    416             errmsg = "MixedContentDecl : '|' or ')*' expected";
    417             break;
    418         case XML_ERR_PCDATA_REQUIRED:
    419             errmsg = "MixedContentDecl : '#PCDATA' expected";
    420             break;
    421         case XML_ERR_ELEMCONTENT_NOT_STARTED:
    422             errmsg = "ContentDecl : Name or '(' expected";
    423             break;
    424         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
    425             errmsg = "ContentDecl : ',' '|' or ')' expected";
    426             break;
    427         case XML_ERR_PEREF_IN_INT_SUBSET:
    428             errmsg =
    429                 "PEReference: forbidden within markup decl in internal subset";
    430             break;
    431         case XML_ERR_GT_REQUIRED:
    432             errmsg = "expected '>'";
    433             break;
    434         case XML_ERR_CONDSEC_INVALID:
    435             errmsg = "XML conditional section '[' expected";
    436             break;
    437         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
    438             errmsg = "Content error in the external subset";
    439             break;
    440         case XML_ERR_CONDSEC_INVALID_KEYWORD:
    441             errmsg =
    442                 "conditional section INCLUDE or IGNORE keyword expected";
    443             break;
    444         case XML_ERR_CONDSEC_NOT_FINISHED:
    445             errmsg = "XML conditional section not closed";
    446             break;
    447         case XML_ERR_XMLDECL_NOT_STARTED:
    448             errmsg = "Text declaration '<?xml' required";
    449             break;
    450         case XML_ERR_XMLDECL_NOT_FINISHED:
    451             errmsg = "parsing XML declaration: '?>' expected";
    452             break;
    453         case XML_ERR_EXT_ENTITY_STANDALONE:
    454             errmsg = "external parsed entities cannot be standalone";
    455             break;
    456         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
    457             errmsg = "EntityRef: expecting ';'";
    458             break;
    459         case XML_ERR_DOCTYPE_NOT_FINISHED:
    460             errmsg = "DOCTYPE improperly terminated";
    461             break;
    462         case XML_ERR_LTSLASH_REQUIRED:
    463             errmsg = "EndTag: '</' not found";
    464             break;
    465         case XML_ERR_EQUAL_REQUIRED:
    466             errmsg = "expected '='";
    467             break;
    468         case XML_ERR_STRING_NOT_CLOSED:
    469             errmsg = "String not closed expecting \" or '";
    470             break;
    471         case XML_ERR_STRING_NOT_STARTED:
    472             errmsg = "String not started expecting ' or \"";
    473             break;
    474         case XML_ERR_ENCODING_NAME:
    475             errmsg = "Invalid XML encoding name";
    476             break;
    477         case XML_ERR_STANDALONE_VALUE:
    478             errmsg = "standalone accepts only 'yes' or 'no'";
    479             break;
    480         case XML_ERR_DOCUMENT_EMPTY:
    481             errmsg = "Document is empty";
    482             break;
    483         case XML_ERR_DOCUMENT_END:
    484             errmsg = "Extra content at the end of the document";
    485             break;
    486         case XML_ERR_NOT_WELL_BALANCED:
    487             errmsg = "chunk is not well balanced";
    488             break;
    489         case XML_ERR_EXTRA_CONTENT:
    490             errmsg = "extra content at the end of well balanced chunk";
    491             break;
    492         case XML_ERR_VERSION_MISSING:
    493             errmsg = "Malformed declaration expecting version";
    494             break;
    495         case XML_ERR_NAME_TOO_LONG:
    496             errmsg = "Name too long use XML_PARSE_HUGE option";
    497             break;
    498 #if 0
    499         case:
    500             errmsg = "";
    501             break;
    502 #endif
    503         default:
    504             errmsg = "Unregistered error message";
    505     }
    506     if (info == NULL)
    507         snprintf(errstr, 128, "%s\n", errmsg);
    508     else
    509         snprintf(errstr, 128, "%s: %%s\n", errmsg);
    510     if (ctxt != NULL)
    511 	ctxt->errNo = error;
    512     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
    513                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0],
    514                     info);
    515     if (ctxt != NULL) {
    516 	ctxt->wellFormed = 0;
    517 	if (ctxt->recovery == 0)
    518 	    ctxt->disableSAX = 1;
    519     }
    520 }
    521 
    522 /**
    523  * xmlFatalErrMsg:
    524  * @ctxt:  an XML parser context
    525  * @error:  the error number
    526  * @msg:  the error message
    527  *
    528  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
    529  */
    530 static void
    531 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    532                const char *msg)
    533 {
    534     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    535         (ctxt->instate == XML_PARSER_EOF))
    536 	return;
    537     if (ctxt != NULL)
    538 	ctxt->errNo = error;
    539     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
    540                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
    541     if (ctxt != NULL) {
    542 	ctxt->wellFormed = 0;
    543 	if (ctxt->recovery == 0)
    544 	    ctxt->disableSAX = 1;
    545     }
    546 }
    547 
    548 /**
    549  * xmlWarningMsg:
    550  * @ctxt:  an XML parser context
    551  * @error:  the error number
    552  * @msg:  the error message
    553  * @str1:  extra data
    554  * @str2:  extra data
    555  *
    556  * Handle a warning.
    557  */
    558 static void
    559 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    560               const char *msg, const xmlChar *str1, const xmlChar *str2)
    561 {
    562     xmlStructuredErrorFunc schannel = NULL;
    563 
    564     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    565         (ctxt->instate == XML_PARSER_EOF))
    566 	return;
    567     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
    568         (ctxt->sax->initialized == XML_SAX2_MAGIC))
    569         schannel = ctxt->sax->serror;
    570     if (ctxt != NULL) {
    571         __xmlRaiseError(schannel,
    572                     (ctxt->sax) ? ctxt->sax->warning : NULL,
    573                     ctxt->userData,
    574                     ctxt, NULL, XML_FROM_PARSER, error,
    575                     XML_ERR_WARNING, NULL, 0,
    576 		    (const char *) str1, (const char *) str2, NULL, 0, 0,
    577 		    msg, (const char *) str1, (const char *) str2);
    578     } else {
    579         __xmlRaiseError(schannel, NULL, NULL,
    580                     ctxt, NULL, XML_FROM_PARSER, error,
    581                     XML_ERR_WARNING, NULL, 0,
    582 		    (const char *) str1, (const char *) str2, NULL, 0, 0,
    583 		    msg, (const char *) str1, (const char *) str2);
    584     }
    585 }
    586 
    587 /**
    588  * xmlValidityError:
    589  * @ctxt:  an XML parser context
    590  * @error:  the error number
    591  * @msg:  the error message
    592  * @str1:  extra data
    593  *
    594  * Handle a validity error.
    595  */
    596 static void
    597 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    598               const char *msg, const xmlChar *str1, const xmlChar *str2)
    599 {
    600     xmlStructuredErrorFunc schannel = NULL;
    601 
    602     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    603         (ctxt->instate == XML_PARSER_EOF))
    604 	return;
    605     if (ctxt != NULL) {
    606 	ctxt->errNo = error;
    607 	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
    608 	    schannel = ctxt->sax->serror;
    609     }
    610     if (ctxt != NULL) {
    611         __xmlRaiseError(schannel,
    612                     ctxt->vctxt.error, ctxt->vctxt.userData,
    613                     ctxt, NULL, XML_FROM_DTD, error,
    614                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
    615 		    (const char *) str2, NULL, 0, 0,
    616 		    msg, (const char *) str1, (const char *) str2);
    617 	ctxt->valid = 0;
    618     } else {
    619         __xmlRaiseError(schannel, NULL, NULL,
    620                     ctxt, NULL, XML_FROM_DTD, error,
    621                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
    622 		    (const char *) str2, NULL, 0, 0,
    623 		    msg, (const char *) str1, (const char *) str2);
    624     }
    625 }
    626 
    627 /**
    628  * xmlFatalErrMsgInt:
    629  * @ctxt:  an XML parser context
    630  * @error:  the error number
    631  * @msg:  the error message
    632  * @val:  an integer value
    633  *
    634  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
    635  */
    636 static void
    637 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    638                   const char *msg, int val)
    639 {
    640     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    641         (ctxt->instate == XML_PARSER_EOF))
    642 	return;
    643     if (ctxt != NULL)
    644 	ctxt->errNo = error;
    645     __xmlRaiseError(NULL, NULL, NULL,
    646                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
    647                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
    648     if (ctxt != NULL) {
    649 	ctxt->wellFormed = 0;
    650 	if (ctxt->recovery == 0)
    651 	    ctxt->disableSAX = 1;
    652     }
    653 }
    654 
    655 /**
    656  * xmlFatalErrMsgStrIntStr:
    657  * @ctxt:  an XML parser context
    658  * @error:  the error number
    659  * @msg:  the error message
    660  * @str1:  an string info
    661  * @val:  an integer value
    662  * @str2:  an string info
    663  *
    664  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
    665  */
    666 static void
    667 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    668                   const char *msg, const xmlChar *str1, int val,
    669 		  const xmlChar *str2)
    670 {
    671     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    672         (ctxt->instate == XML_PARSER_EOF))
    673 	return;
    674     if (ctxt != NULL)
    675 	ctxt->errNo = error;
    676     __xmlRaiseError(NULL, NULL, NULL,
    677                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
    678                     NULL, 0, (const char *) str1, (const char *) str2,
    679 		    NULL, val, 0, msg, str1, val, str2);
    680     if (ctxt != NULL) {
    681 	ctxt->wellFormed = 0;
    682 	if (ctxt->recovery == 0)
    683 	    ctxt->disableSAX = 1;
    684     }
    685 }
    686 
    687 /**
    688  * xmlFatalErrMsgStr:
    689  * @ctxt:  an XML parser context
    690  * @error:  the error number
    691  * @msg:  the error message
    692  * @val:  a string value
    693  *
    694  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
    695  */
    696 static void
    697 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    698                   const char *msg, const xmlChar * val)
    699 {
    700     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    701         (ctxt->instate == XML_PARSER_EOF))
    702 	return;
    703     if (ctxt != NULL)
    704 	ctxt->errNo = error;
    705     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
    706                     XML_FROM_PARSER, error, XML_ERR_FATAL,
    707                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
    708                     val);
    709     if (ctxt != NULL) {
    710 	ctxt->wellFormed = 0;
    711 	if (ctxt->recovery == 0)
    712 	    ctxt->disableSAX = 1;
    713     }
    714 }
    715 
    716 /**
    717  * xmlErrMsgStr:
    718  * @ctxt:  an XML parser context
    719  * @error:  the error number
    720  * @msg:  the error message
    721  * @val:  a string value
    722  *
    723  * Handle a non fatal parser error
    724  */
    725 static void
    726 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    727                   const char *msg, const xmlChar * val)
    728 {
    729     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    730         (ctxt->instate == XML_PARSER_EOF))
    731 	return;
    732     if (ctxt != NULL)
    733 	ctxt->errNo = error;
    734     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
    735                     XML_FROM_PARSER, error, XML_ERR_ERROR,
    736                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
    737                     val);
    738 }
    739 
    740 /**
    741  * xmlNsErr:
    742  * @ctxt:  an XML parser context
    743  * @error:  the error number
    744  * @msg:  the message
    745  * @info1:  extra information string
    746  * @info2:  extra information string
    747  *
    748  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
    749  */
    750 static void
    751 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    752          const char *msg,
    753          const xmlChar * info1, const xmlChar * info2,
    754          const xmlChar * info3)
    755 {
    756     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    757         (ctxt->instate == XML_PARSER_EOF))
    758 	return;
    759     if (ctxt != NULL)
    760 	ctxt->errNo = error;
    761     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
    762                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
    763                     (const char *) info2, (const char *) info3, 0, 0, msg,
    764                     info1, info2, info3);
    765     if (ctxt != NULL)
    766 	ctxt->nsWellFormed = 0;
    767 }
    768 
    769 /**
    770  * xmlNsWarn
    771  * @ctxt:  an XML parser context
    772  * @error:  the error number
    773  * @msg:  the message
    774  * @info1:  extra information string
    775  * @info2:  extra information string
    776  *
    777  * Handle a namespace warning error
    778  */
    779 static void
    780 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
    781          const char *msg,
    782          const xmlChar * info1, const xmlChar * info2,
    783          const xmlChar * info3)
    784 {
    785     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
    786         (ctxt->instate == XML_PARSER_EOF))
    787 	return;
    788     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
    789                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
    790                     (const char *) info2, (const char *) info3, 0, 0, msg,
    791                     info1, info2, info3);
    792 }
    793 
    794 /************************************************************************
    795  *									*
    796  *		Library wide options					*
    797  *									*
    798  ************************************************************************/
    799 
    800 /**
    801   * xmlHasFeature:
    802   * @feature: the feature to be examined
    803   *
    804   * Examines if the library has been compiled with a given feature.
    805   *
    806   * Returns a non-zero value if the feature exist, otherwise zero.
    807   * Returns zero (0) if the feature does not exist or an unknown
    808   * unknown feature is requested, non-zero otherwise.
    809   */
    810 int
    811 xmlHasFeature(xmlFeature feature)
    812 {
    813     switch (feature) {
    814 	case XML_WITH_THREAD:
    815 #ifdef LIBXML_THREAD_ENABLED
    816 	    return(1);
    817 #else
    818 	    return(0);
    819 #endif
    820         case XML_WITH_TREE:
    821 #ifdef LIBXML_TREE_ENABLED
    822             return(1);
    823 #else
    824             return(0);
    825 #endif
    826         case XML_WITH_OUTPUT:
    827 #ifdef LIBXML_OUTPUT_ENABLED
    828             return(1);
    829 #else
    830             return(0);
    831 #endif
    832         case XML_WITH_PUSH:
    833 #ifdef LIBXML_PUSH_ENABLED
    834             return(1);
    835 #else
    836             return(0);
    837 #endif
    838         case XML_WITH_READER:
    839 #ifdef LIBXML_READER_ENABLED
    840             return(1);
    841 #else
    842             return(0);
    843 #endif
    844         case XML_WITH_PATTERN:
    845 #ifdef LIBXML_PATTERN_ENABLED
    846             return(1);
    847 #else
    848             return(0);
    849 #endif
    850         case XML_WITH_WRITER:
    851 #ifdef LIBXML_WRITER_ENABLED
    852             return(1);
    853 #else
    854             return(0);
    855 #endif
    856         case XML_WITH_SAX1:
    857 #ifdef LIBXML_SAX1_ENABLED
    858             return(1);
    859 #else
    860             return(0);
    861 #endif
    862         case XML_WITH_FTP:
    863 #ifdef LIBXML_FTP_ENABLED
    864             return(1);
    865 #else
    866             return(0);
    867 #endif
    868         case XML_WITH_HTTP:
    869 #ifdef LIBXML_HTTP_ENABLED
    870             return(1);
    871 #else
    872             return(0);
    873 #endif
    874         case XML_WITH_VALID:
    875 #ifdef LIBXML_VALID_ENABLED
    876             return(1);
    877 #else
    878             return(0);
    879 #endif
    880         case XML_WITH_HTML:
    881 #ifdef LIBXML_HTML_ENABLED
    882             return(1);
    883 #else
    884             return(0);
    885 #endif
    886         case XML_WITH_LEGACY:
    887 #ifdef LIBXML_LEGACY_ENABLED
    888             return(1);
    889 #else
    890             return(0);
    891 #endif
    892         case XML_WITH_C14N:
    893 #ifdef LIBXML_C14N_ENABLED
    894             return(1);
    895 #else
    896             return(0);
    897 #endif
    898         case XML_WITH_CATALOG:
    899 #ifdef LIBXML_CATALOG_ENABLED
    900             return(1);
    901 #else
    902             return(0);
    903 #endif
    904         case XML_WITH_XPATH:
    905 #ifdef LIBXML_XPATH_ENABLED
    906             return(1);
    907 #else
    908             return(0);
    909 #endif
    910         case XML_WITH_XPTR:
    911 #ifdef LIBXML_XPTR_ENABLED
    912             return(1);
    913 #else
    914             return(0);
    915 #endif
    916         case XML_WITH_XINCLUDE:
    917 #ifdef LIBXML_XINCLUDE_ENABLED
    918             return(1);
    919 #else
    920             return(0);
    921 #endif
    922         case XML_WITH_ICONV:
    923 #ifdef LIBXML_ICONV_ENABLED
    924             return(1);
    925 #else
    926             return(0);
    927 #endif
    928         case XML_WITH_ISO8859X:
    929 #ifdef LIBXML_ISO8859X_ENABLED
    930             return(1);
    931 #else
    932             return(0);
    933 #endif
    934         case XML_WITH_UNICODE:
    935 #ifdef LIBXML_UNICODE_ENABLED
    936             return(1);
    937 #else
    938             return(0);
    939 #endif
    940         case XML_WITH_REGEXP:
    941 #ifdef LIBXML_REGEXP_ENABLED
    942             return(1);
    943 #else
    944             return(0);
    945 #endif
    946         case XML_WITH_AUTOMATA:
    947 #ifdef LIBXML_AUTOMATA_ENABLED
    948             return(1);
    949 #else
    950             return(0);
    951 #endif
    952         case XML_WITH_EXPR:
    953 #ifdef LIBXML_EXPR_ENABLED
    954             return(1);
    955 #else
    956             return(0);
    957 #endif
    958         case XML_WITH_SCHEMAS:
    959 #ifdef LIBXML_SCHEMAS_ENABLED
    960             return(1);
    961 #else
    962             return(0);
    963 #endif
    964         case XML_WITH_SCHEMATRON:
    965 #ifdef LIBXML_SCHEMATRON_ENABLED
    966             return(1);
    967 #else
    968             return(0);
    969 #endif
    970         case XML_WITH_MODULES:
    971 #ifdef LIBXML_MODULES_ENABLED
    972             return(1);
    973 #else
    974             return(0);
    975 #endif
    976         case XML_WITH_DEBUG:
    977 #ifdef LIBXML_DEBUG_ENABLED
    978             return(1);
    979 #else
    980             return(0);
    981 #endif
    982         case XML_WITH_DEBUG_MEM:
    983 #ifdef DEBUG_MEMORY_LOCATION
    984             return(1);
    985 #else
    986             return(0);
    987 #endif
    988         case XML_WITH_DEBUG_RUN:
    989 #ifdef LIBXML_DEBUG_RUNTIME
    990             return(1);
    991 #else
    992             return(0);
    993 #endif
    994         case XML_WITH_ZLIB:
    995 #ifdef LIBXML_ZLIB_ENABLED
    996             return(1);
    997 #else
    998             return(0);
    999 #endif
   1000         case XML_WITH_LZMA:
   1001 #ifdef LIBXML_LZMA_ENABLED
   1002             return(1);
   1003 #else
   1004             return(0);
   1005 #endif
   1006         case XML_WITH_ICU:
   1007 #ifdef LIBXML_ICU_ENABLED
   1008             return(1);
   1009 #else
   1010             return(0);
   1011 #endif
   1012         default:
   1013 	    break;
   1014      }
   1015      return(0);
   1016 }
   1017 
   1018 /************************************************************************
   1019  *									*
   1020  *		SAX2 defaulted attributes handling			*
   1021  *									*
   1022  ************************************************************************/
   1023 
   1024 /**
   1025  * xmlDetectSAX2:
   1026  * @ctxt:  an XML parser context
   1027  *
   1028  * Do the SAX2 detection and specific intialization
   1029  */
   1030 static void
   1031 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
   1032     if (ctxt == NULL) return;
   1033 #ifdef LIBXML_SAX1_ENABLED
   1034     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
   1035         ((ctxt->sax->startElementNs != NULL) ||
   1036          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
   1037 #else
   1038     ctxt->sax2 = 1;
   1039 #endif /* LIBXML_SAX1_ENABLED */
   1040 
   1041     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
   1042     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
   1043     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
   1044     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
   1045 		(ctxt->str_xml_ns == NULL)) {
   1046         xmlErrMemory(ctxt, NULL);
   1047     }
   1048 }
   1049 
   1050 typedef struct _xmlDefAttrs xmlDefAttrs;
   1051 typedef xmlDefAttrs *xmlDefAttrsPtr;
   1052 struct _xmlDefAttrs {
   1053     int nbAttrs;	/* number of defaulted attributes on that element */
   1054     int maxAttrs;       /* the size of the array */
   1055     const xmlChar *values[5]; /* array of localname/prefix/values/external */
   1056 };
   1057 
   1058 /**
   1059  * xmlAttrNormalizeSpace:
   1060  * @src: the source string
   1061  * @dst: the target string
   1062  *
   1063  * Normalize the space in non CDATA attribute values:
   1064  * If the attribute type is not CDATA, then the XML processor MUST further
   1065  * process the normalized attribute value by discarding any leading and
   1066  * trailing space (#x20) characters, and by replacing sequences of space
   1067  * (#x20) characters by a single space (#x20) character.
   1068  * Note that the size of dst need to be at least src, and if one doesn't need
   1069  * to preserve dst (and it doesn't come from a dictionary or read-only) then
   1070  * passing src as dst is just fine.
   1071  *
   1072  * Returns a pointer to the normalized value (dst) or NULL if no conversion
   1073  *         is needed.
   1074  */
   1075 static xmlChar *
   1076 xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
   1077 {
   1078     if ((src == NULL) || (dst == NULL))
   1079         return(NULL);
   1080 
   1081     while (*src == 0x20) src++;
   1082     while (*src != 0) {
   1083 	if (*src == 0x20) {
   1084 	    while (*src == 0x20) src++;
   1085 	    if (*src != 0)
   1086 		*dst++ = 0x20;
   1087 	} else {
   1088 	    *dst++ = *src++;
   1089 	}
   1090     }
   1091     *dst = 0;
   1092     if (dst == src)
   1093        return(NULL);
   1094     return(dst);
   1095 }
   1096 
   1097 /**
   1098  * xmlAttrNormalizeSpace2:
   1099  * @src: the source string
   1100  *
   1101  * Normalize the space in non CDATA attribute values, a slightly more complex
   1102  * front end to avoid allocation problems when running on attribute values
   1103  * coming from the input.
   1104  *
   1105  * Returns a pointer to the normalized value (dst) or NULL if no conversion
   1106  *         is needed.
   1107  */
   1108 static const xmlChar *
   1109 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
   1110 {
   1111     int i;
   1112     int remove_head = 0;
   1113     int need_realloc = 0;
   1114     const xmlChar *cur;
   1115 
   1116     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
   1117         return(NULL);
   1118     i = *len;
   1119     if (i <= 0)
   1120         return(NULL);
   1121 
   1122     cur = src;
   1123     while (*cur == 0x20) {
   1124         cur++;
   1125 	remove_head++;
   1126     }
   1127     while (*cur != 0) {
   1128 	if (*cur == 0x20) {
   1129 	    cur++;
   1130 	    if ((*cur == 0x20) || (*cur == 0)) {
   1131 	        need_realloc = 1;
   1132 		break;
   1133 	    }
   1134 	} else
   1135 	    cur++;
   1136     }
   1137     if (need_realloc) {
   1138         xmlChar *ret;
   1139 
   1140 	ret = xmlStrndup(src + remove_head, i - remove_head + 1);
   1141 	if (ret == NULL) {
   1142 	    xmlErrMemory(ctxt, NULL);
   1143 	    return(NULL);
   1144 	}
   1145 	xmlAttrNormalizeSpace(ret, ret);
   1146 	*len = (int) strlen((const char *)ret);
   1147         return(ret);
   1148     } else if (remove_head) {
   1149         *len -= remove_head;
   1150         memmove(src, src + remove_head, 1 + *len);
   1151 	return(src);
   1152     }
   1153     return(NULL);
   1154 }
   1155 
   1156 /**
   1157  * xmlAddDefAttrs:
   1158  * @ctxt:  an XML parser context
   1159  * @fullname:  the element fullname
   1160  * @fullattr:  the attribute fullname
   1161  * @value:  the attribute value
   1162  *
   1163  * Add a defaulted attribute for an element
   1164  */
   1165 static void
   1166 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
   1167                const xmlChar *fullname,
   1168                const xmlChar *fullattr,
   1169                const xmlChar *value) {
   1170     xmlDefAttrsPtr defaults;
   1171     int len;
   1172     const xmlChar *name;
   1173     const xmlChar *prefix;
   1174 
   1175     /*
   1176      * Allows to detect attribute redefinitions
   1177      */
   1178     if (ctxt->attsSpecial != NULL) {
   1179         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
   1180 	    return;
   1181     }
   1182 
   1183     if (ctxt->attsDefault == NULL) {
   1184         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
   1185 	if (ctxt->attsDefault == NULL)
   1186 	    goto mem_error;
   1187     }
   1188 
   1189     /*
   1190      * split the element name into prefix:localname , the string found
   1191      * are within the DTD and then not associated to namespace names.
   1192      */
   1193     name = xmlSplitQName3(fullname, &len);
   1194     if (name == NULL) {
   1195         name = xmlDictLookup(ctxt->dict, fullname, -1);
   1196 	prefix = NULL;
   1197     } else {
   1198         name = xmlDictLookup(ctxt->dict, name, -1);
   1199 	prefix = xmlDictLookup(ctxt->dict, fullname, len);
   1200     }
   1201 
   1202     /*
   1203      * make sure there is some storage
   1204      */
   1205     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
   1206     if (defaults == NULL) {
   1207         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
   1208 	                   (4 * 5) * sizeof(const xmlChar *));
   1209 	if (defaults == NULL)
   1210 	    goto mem_error;
   1211 	defaults->nbAttrs = 0;
   1212 	defaults->maxAttrs = 4;
   1213 	if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
   1214 	                        defaults, NULL) < 0) {
   1215 	    xmlFree(defaults);
   1216 	    goto mem_error;
   1217 	}
   1218     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
   1219         xmlDefAttrsPtr temp;
   1220 
   1221         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
   1222 		       (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
   1223 	if (temp == NULL)
   1224 	    goto mem_error;
   1225 	defaults = temp;
   1226 	defaults->maxAttrs *= 2;
   1227 	if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
   1228 	                        defaults, NULL) < 0) {
   1229 	    xmlFree(defaults);
   1230 	    goto mem_error;
   1231 	}
   1232     }
   1233 
   1234     /*
   1235      * Split the element name into prefix:localname , the string found
   1236      * are within the DTD and hen not associated to namespace names.
   1237      */
   1238     name = xmlSplitQName3(fullattr, &len);
   1239     if (name == NULL) {
   1240         name = xmlDictLookup(ctxt->dict, fullattr, -1);
   1241 	prefix = NULL;
   1242     } else {
   1243         name = xmlDictLookup(ctxt->dict, name, -1);
   1244 	prefix = xmlDictLookup(ctxt->dict, fullattr, len);
   1245     }
   1246 
   1247     defaults->values[5 * defaults->nbAttrs] = name;
   1248     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
   1249     /* intern the string and precompute the end */
   1250     len = xmlStrlen(value);
   1251     value = xmlDictLookup(ctxt->dict, value, len);
   1252     defaults->values[5 * defaults->nbAttrs + 2] = value;
   1253     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
   1254     if (ctxt->external)
   1255         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
   1256     else
   1257         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
   1258     defaults->nbAttrs++;
   1259 
   1260     return;
   1261 
   1262 mem_error:
   1263     xmlErrMemory(ctxt, NULL);
   1264     return;
   1265 }
   1266 
   1267 /**
   1268  * xmlAddSpecialAttr:
   1269  * @ctxt:  an XML parser context
   1270  * @fullname:  the element fullname
   1271  * @fullattr:  the attribute fullname
   1272  * @type:  the attribute type
   1273  *
   1274  * Register this attribute type
   1275  */
   1276 static void
   1277 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
   1278 		  const xmlChar *fullname,
   1279 		  const xmlChar *fullattr,
   1280 		  int type)
   1281 {
   1282     if (ctxt->attsSpecial == NULL) {
   1283         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
   1284 	if (ctxt->attsSpecial == NULL)
   1285 	    goto mem_error;
   1286     }
   1287 
   1288     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
   1289         return;
   1290 
   1291     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
   1292                      (void *) (long) type);
   1293     return;
   1294 
   1295 mem_error:
   1296     xmlErrMemory(ctxt, NULL);
   1297     return;
   1298 }
   1299 
   1300 /**
   1301  * xmlCleanSpecialAttrCallback:
   1302  *
   1303  * Removes CDATA attributes from the special attribute table
   1304  */
   1305 static void
   1306 xmlCleanSpecialAttrCallback(void *payload, void *data,
   1307                             const xmlChar *fullname, const xmlChar *fullattr,
   1308                             const xmlChar *unused ATTRIBUTE_UNUSED) {
   1309     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
   1310 
   1311     if (((long) payload) == XML_ATTRIBUTE_CDATA) {
   1312         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
   1313     }
   1314 }
   1315 
   1316 /**
   1317  * xmlCleanSpecialAttr:
   1318  * @ctxt:  an XML parser context
   1319  *
   1320  * Trim the list of attributes defined to remove all those of type
   1321  * CDATA as they are not special. This call should be done when finishing
   1322  * to parse the DTD and before starting to parse the document root.
   1323  */
   1324 static void
   1325 xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
   1326 {
   1327     if (ctxt->attsSpecial == NULL)
   1328         return;
   1329 
   1330     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
   1331 
   1332     if (xmlHashSize(ctxt->attsSpecial) == 0) {
   1333         xmlHashFree(ctxt->attsSpecial, NULL);
   1334         ctxt->attsSpecial = NULL;
   1335     }
   1336     return;
   1337 }
   1338 
   1339 /**
   1340  * xmlCheckLanguageID:
   1341  * @lang:  pointer to the string value
   1342  *
   1343  * Checks that the value conforms to the LanguageID production:
   1344  *
   1345  * NOTE: this is somewhat deprecated, those productions were removed from
   1346  *       the XML Second edition.
   1347  *
   1348  * [33] LanguageID ::= Langcode ('-' Subcode)*
   1349  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
   1350  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
   1351  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
   1352  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
   1353  * [38] Subcode ::= ([a-z] | [A-Z])+
   1354  *
   1355  * The current REC reference the sucessors of RFC 1766, currently 5646
   1356  *
   1357  * http://www.rfc-editor.org/rfc/rfc5646.txt
   1358  * langtag       = language
   1359  *                 ["-" script]
   1360  *                 ["-" region]
   1361  *                 *("-" variant)
   1362  *                 *("-" extension)
   1363  *                 ["-" privateuse]
   1364  * language      = 2*3ALPHA            ; shortest ISO 639 code
   1365  *                 ["-" extlang]       ; sometimes followed by
   1366  *                                     ; extended language subtags
   1367  *               / 4ALPHA              ; or reserved for future use
   1368  *               / 5*8ALPHA            ; or registered language subtag
   1369  *
   1370  * extlang       = 3ALPHA              ; selected ISO 639 codes
   1371  *                 *2("-" 3ALPHA)      ; permanently reserved
   1372  *
   1373  * script        = 4ALPHA              ; ISO 15924 code
   1374  *
   1375  * region        = 2ALPHA              ; ISO 3166-1 code
   1376  *               / 3DIGIT              ; UN M.49 code
   1377  *
   1378  * variant       = 5*8alphanum         ; registered variants
   1379  *               / (DIGIT 3alphanum)
   1380  *
   1381  * extension     = singleton 1*("-" (2*8alphanum))
   1382  *
   1383  *                                     ; Single alphanumerics
   1384  *                                     ; "x" reserved for private use
   1385  * singleton     = DIGIT               ; 0 - 9
   1386  *               / %x41-57             ; A - W
   1387  *               / %x59-5A             ; Y - Z
   1388  *               / %x61-77             ; a - w
   1389  *               / %x79-7A             ; y - z
   1390  *
   1391  * it sounds right to still allow Irregular i-xxx IANA and user codes too
   1392  * The parser below doesn't try to cope with extension or privateuse
   1393  * that could be added but that's not interoperable anyway
   1394  *
   1395  * Returns 1 if correct 0 otherwise
   1396  **/
   1397 int
   1398 xmlCheckLanguageID(const xmlChar * lang)
   1399 {
   1400     const xmlChar *cur = lang, *nxt;
   1401 
   1402     if (cur == NULL)
   1403         return (0);
   1404     if (((cur[0] == 'i') && (cur[1] == '-')) ||
   1405         ((cur[0] == 'I') && (cur[1] == '-')) ||
   1406         ((cur[0] == 'x') && (cur[1] == '-')) ||
   1407         ((cur[0] == 'X') && (cur[1] == '-'))) {
   1408         /*
   1409          * Still allow IANA code and user code which were coming
   1410          * from the previous version of the XML-1.0 specification
   1411          * it's deprecated but we should not fail
   1412          */
   1413         cur += 2;
   1414         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
   1415                ((cur[0] >= 'a') && (cur[0] <= 'z')))
   1416             cur++;
   1417         return(cur[0] == 0);
   1418     }
   1419     nxt = cur;
   1420     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
   1421            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
   1422            nxt++;
   1423     if (nxt - cur >= 4) {
   1424         /*
   1425          * Reserved
   1426          */
   1427         if ((nxt - cur > 8) || (nxt[0] != 0))
   1428             return(0);
   1429         return(1);
   1430     }
   1431     if (nxt - cur < 2)
   1432         return(0);
   1433     /* we got an ISO 639 code */
   1434     if (nxt[0] == 0)
   1435         return(1);
   1436     if (nxt[0] != '-')
   1437         return(0);
   1438 
   1439     nxt++;
   1440     cur = nxt;
   1441     /* now we can have extlang or script or region or variant */
   1442     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
   1443         goto region_m49;
   1444 
   1445     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
   1446            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
   1447            nxt++;
   1448     if (nxt - cur == 4)
   1449         goto script;
   1450     if (nxt - cur == 2)
   1451         goto region;
   1452     if ((nxt - cur >= 5) && (nxt - cur <= 8))
   1453         goto variant;
   1454     if (nxt - cur != 3)
   1455         return(0);
   1456     /* we parsed an extlang */
   1457     if (nxt[0] == 0)
   1458         return(1);
   1459     if (nxt[0] != '-')
   1460         return(0);
   1461 
   1462     nxt++;
   1463     cur = nxt;
   1464     /* now we can have script or region or variant */
   1465     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
   1466         goto region_m49;
   1467 
   1468     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
   1469            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
   1470            nxt++;
   1471     if (nxt - cur == 2)
   1472         goto region;
   1473     if ((nxt - cur >= 5) && (nxt - cur <= 8))
   1474         goto variant;
   1475     if (nxt - cur != 4)
   1476         return(0);
   1477     /* we parsed a script */
   1478 script:
   1479     if (nxt[0] == 0)
   1480         return(1);
   1481     if (nxt[0] != '-')
   1482         return(0);
   1483 
   1484     nxt++;
   1485     cur = nxt;
   1486     /* now we can have region or variant */
   1487     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
   1488         goto region_m49;
   1489 
   1490     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
   1491            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
   1492            nxt++;
   1493 
   1494     if ((nxt - cur >= 5) && (nxt - cur <= 8))
   1495         goto variant;
   1496     if (nxt - cur != 2)
   1497         return(0);
   1498     /* we parsed a region */
   1499 region:
   1500     if (nxt[0] == 0)
   1501         return(1);
   1502     if (nxt[0] != '-')
   1503         return(0);
   1504 
   1505     nxt++;
   1506     cur = nxt;
   1507     /* now we can just have a variant */
   1508     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
   1509            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
   1510            nxt++;
   1511 
   1512     if ((nxt - cur < 5) || (nxt - cur > 8))
   1513         return(0);
   1514 
   1515     /* we parsed a variant */
   1516 variant:
   1517     if (nxt[0] == 0)
   1518         return(1);
   1519     if (nxt[0] != '-')
   1520         return(0);
   1521     /* extensions and private use subtags not checked */
   1522     return (1);
   1523 
   1524 region_m49:
   1525     if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
   1526         ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
   1527         nxt += 3;
   1528         goto region;
   1529     }
   1530     return(0);
   1531 }
   1532 
   1533 /************************************************************************
   1534  *									*
   1535  *		Parser stacks related functions and macros		*
   1536  *									*
   1537  ************************************************************************/
   1538 
   1539 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
   1540                                             const xmlChar ** str);
   1541 
   1542 #ifdef SAX2
   1543 /**
   1544  * nsPush:
   1545  * @ctxt:  an XML parser context
   1546  * @prefix:  the namespace prefix or NULL
   1547  * @URL:  the namespace name
   1548  *
   1549  * Pushes a new parser namespace on top of the ns stack
   1550  *
   1551  * Returns -1 in case of error, -2 if the namespace should be discarded
   1552  *	   and the index in the stack otherwise.
   1553  */
   1554 static int
   1555 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
   1556 {
   1557     if (ctxt->options & XML_PARSE_NSCLEAN) {
   1558         int i;
   1559 	for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
   1560 	    if (ctxt->nsTab[i] == prefix) {
   1561 		/* in scope */
   1562 	        if (ctxt->nsTab[i + 1] == URL)
   1563 		    return(-2);
   1564 		/* out of scope keep it */
   1565 		break;
   1566 	    }
   1567 	}
   1568     }
   1569     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
   1570 	ctxt->nsMax = 10;
   1571 	ctxt->nsNr = 0;
   1572 	ctxt->nsTab = (const xmlChar **)
   1573 	              xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
   1574 	if (ctxt->nsTab == NULL) {
   1575 	    xmlErrMemory(ctxt, NULL);
   1576 	    ctxt->nsMax = 0;
   1577             return (-1);
   1578 	}
   1579     } else if (ctxt->nsNr >= ctxt->nsMax) {
   1580         const xmlChar ** tmp;
   1581         ctxt->nsMax *= 2;
   1582         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
   1583 				    ctxt->nsMax * sizeof(ctxt->nsTab[0]));
   1584         if (tmp == NULL) {
   1585             xmlErrMemory(ctxt, NULL);
   1586 	    ctxt->nsMax /= 2;
   1587             return (-1);
   1588         }
   1589 	ctxt->nsTab = tmp;
   1590     }
   1591     ctxt->nsTab[ctxt->nsNr++] = prefix;
   1592     ctxt->nsTab[ctxt->nsNr++] = URL;
   1593     return (ctxt->nsNr);
   1594 }
   1595 /**
   1596  * nsPop:
   1597  * @ctxt: an XML parser context
   1598  * @nr:  the number to pop
   1599  *
   1600  * Pops the top @nr parser prefix/namespace from the ns stack
   1601  *
   1602  * Returns the number of namespaces removed
   1603  */
   1604 static int
   1605 nsPop(xmlParserCtxtPtr ctxt, int nr)
   1606 {
   1607     int i;
   1608 
   1609     if (ctxt->nsTab == NULL) return(0);
   1610     if (ctxt->nsNr < nr) {
   1611         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
   1612         nr = ctxt->nsNr;
   1613     }
   1614     if (ctxt->nsNr <= 0)
   1615         return (0);
   1616 
   1617     for (i = 0;i < nr;i++) {
   1618          ctxt->nsNr--;
   1619 	 ctxt->nsTab[ctxt->nsNr] = NULL;
   1620     }
   1621     return(nr);
   1622 }
   1623 #endif
   1624 
   1625 static int
   1626 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
   1627     const xmlChar **atts;
   1628     int *attallocs;
   1629     int maxatts;
   1630 
   1631     if (ctxt->atts == NULL) {
   1632 	maxatts = 55; /* allow for 10 attrs by default */
   1633 	atts = (const xmlChar **)
   1634 	       xmlMalloc(maxatts * sizeof(xmlChar *));
   1635 	if (atts == NULL) goto mem_error;
   1636 	ctxt->atts = atts;
   1637 	attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
   1638 	if (attallocs == NULL) goto mem_error;
   1639 	ctxt->attallocs = attallocs;
   1640 	ctxt->maxatts = maxatts;
   1641     } else if (nr + 5 > ctxt->maxatts) {
   1642 	maxatts = (nr + 5) * 2;
   1643 	atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
   1644 				     maxatts * sizeof(const xmlChar *));
   1645 	if (atts == NULL) goto mem_error;
   1646 	ctxt->atts = atts;
   1647 	attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
   1648 	                             (maxatts / 5) * sizeof(int));
   1649 	if (attallocs == NULL) goto mem_error;
   1650 	ctxt->attallocs = attallocs;
   1651 	ctxt->maxatts = maxatts;
   1652     }
   1653     return(ctxt->maxatts);
   1654 mem_error:
   1655     xmlErrMemory(ctxt, NULL);
   1656     return(-1);
   1657 }
   1658 
   1659 /**
   1660  * inputPush:
   1661  * @ctxt:  an XML parser context
   1662  * @value:  the parser input
   1663  *
   1664  * Pushes a new parser input on top of the input stack
   1665  *
   1666  * Returns -1 in case of error, the index in the stack otherwise
   1667  */
   1668 int
   1669 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
   1670 {
   1671     if ((ctxt == NULL) || (value == NULL))
   1672         return(-1);
   1673     if (ctxt->inputNr >= ctxt->inputMax) {
   1674         ctxt->inputMax *= 2;
   1675         ctxt->inputTab =
   1676             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
   1677                                              ctxt->inputMax *
   1678                                              sizeof(ctxt->inputTab[0]));
   1679         if (ctxt->inputTab == NULL) {
   1680             xmlErrMemory(ctxt, NULL);
   1681 	    xmlFreeInputStream(value);
   1682 	    ctxt->inputMax /= 2;
   1683 	    value = NULL;
   1684             return (-1);
   1685         }
   1686     }
   1687     ctxt->inputTab[ctxt->inputNr] = value;
   1688     ctxt->input = value;
   1689     return (ctxt->inputNr++);
   1690 }
   1691 /**
   1692  * inputPop:
   1693  * @ctxt: an XML parser context
   1694  *
   1695  * Pops the top parser input from the input stack
   1696  *
   1697  * Returns the input just removed
   1698  */
   1699 xmlParserInputPtr
   1700 inputPop(xmlParserCtxtPtr ctxt)
   1701 {
   1702     xmlParserInputPtr ret;
   1703 
   1704     if (ctxt == NULL)
   1705         return(NULL);
   1706     if (ctxt->inputNr <= 0)
   1707         return (NULL);
   1708     ctxt->inputNr--;
   1709     if (ctxt->inputNr > 0)
   1710         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
   1711     else
   1712         ctxt->input = NULL;
   1713     ret = ctxt->inputTab[ctxt->inputNr];
   1714     ctxt->inputTab[ctxt->inputNr] = NULL;
   1715     return (ret);
   1716 }
   1717 /**
   1718  * nodePush:
   1719  * @ctxt:  an XML parser context
   1720  * @value:  the element node
   1721  *
   1722  * Pushes a new element node on top of the node stack
   1723  *
   1724  * Returns -1 in case of error, the index in the stack otherwise
   1725  */
   1726 int
   1727 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
   1728 {
   1729     if (ctxt == NULL) return(0);
   1730     if (ctxt->nodeNr >= ctxt->nodeMax) {
   1731         xmlNodePtr *tmp;
   1732 
   1733 	tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
   1734                                       ctxt->nodeMax * 2 *
   1735                                       sizeof(ctxt->nodeTab[0]));
   1736         if (tmp == NULL) {
   1737             xmlErrMemory(ctxt, NULL);
   1738             return (-1);
   1739         }
   1740         ctxt->nodeTab = tmp;
   1741 	ctxt->nodeMax *= 2;
   1742     }
   1743     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
   1744         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   1745 	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
   1746 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
   1747 			  xmlParserMaxDepth);
   1748 	ctxt->instate = XML_PARSER_EOF;
   1749 	return(-1);
   1750     }
   1751     ctxt->nodeTab[ctxt->nodeNr] = value;
   1752     ctxt->node = value;
   1753     return (ctxt->nodeNr++);
   1754 }
   1755 
   1756 /**
   1757  * nodePop:
   1758  * @ctxt: an XML parser context
   1759  *
   1760  * Pops the top element node from the node stack
   1761  *
   1762  * Returns the node just removed
   1763  */
   1764 xmlNodePtr
   1765 nodePop(xmlParserCtxtPtr ctxt)
   1766 {
   1767     xmlNodePtr ret;
   1768 
   1769     if (ctxt == NULL) return(NULL);
   1770     if (ctxt->nodeNr <= 0)
   1771         return (NULL);
   1772     ctxt->nodeNr--;
   1773     if (ctxt->nodeNr > 0)
   1774         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
   1775     else
   1776         ctxt->node = NULL;
   1777     ret = ctxt->nodeTab[ctxt->nodeNr];
   1778     ctxt->nodeTab[ctxt->nodeNr] = NULL;
   1779     return (ret);
   1780 }
   1781 
   1782 #ifdef LIBXML_PUSH_ENABLED
   1783 /**
   1784  * nameNsPush:
   1785  * @ctxt:  an XML parser context
   1786  * @value:  the element name
   1787  * @prefix:  the element prefix
   1788  * @URI:  the element namespace name
   1789  *
   1790  * Pushes a new element name/prefix/URL on top of the name stack
   1791  *
   1792  * Returns -1 in case of error, the index in the stack otherwise
   1793  */
   1794 static int
   1795 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
   1796            const xmlChar *prefix, const xmlChar *URI, int nsNr)
   1797 {
   1798     if (ctxt->nameNr >= ctxt->nameMax) {
   1799         const xmlChar * *tmp;
   1800         void **tmp2;
   1801         ctxt->nameMax *= 2;
   1802         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
   1803                                     ctxt->nameMax *
   1804                                     sizeof(ctxt->nameTab[0]));
   1805         if (tmp == NULL) {
   1806 	    ctxt->nameMax /= 2;
   1807 	    goto mem_error;
   1808         }
   1809 	ctxt->nameTab = tmp;
   1810         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
   1811                                     ctxt->nameMax * 3 *
   1812                                     sizeof(ctxt->pushTab[0]));
   1813         if (tmp2 == NULL) {
   1814 	    ctxt->nameMax /= 2;
   1815 	    goto mem_error;
   1816         }
   1817 	ctxt->pushTab = tmp2;
   1818     }
   1819     ctxt->nameTab[ctxt->nameNr] = value;
   1820     ctxt->name = value;
   1821     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
   1822     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
   1823     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
   1824     return (ctxt->nameNr++);
   1825 mem_error:
   1826     xmlErrMemory(ctxt, NULL);
   1827     return (-1);
   1828 }
   1829 /**
   1830  * nameNsPop:
   1831  * @ctxt: an XML parser context
   1832  *
   1833  * Pops the top element/prefix/URI name from the name stack
   1834  *
   1835  * Returns the name just removed
   1836  */
   1837 static const xmlChar *
   1838 nameNsPop(xmlParserCtxtPtr ctxt)
   1839 {
   1840     const xmlChar *ret;
   1841 
   1842     if (ctxt->nameNr <= 0)
   1843         return (NULL);
   1844     ctxt->nameNr--;
   1845     if (ctxt->nameNr > 0)
   1846         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
   1847     else
   1848         ctxt->name = NULL;
   1849     ret = ctxt->nameTab[ctxt->nameNr];
   1850     ctxt->nameTab[ctxt->nameNr] = NULL;
   1851     return (ret);
   1852 }
   1853 #endif /* LIBXML_PUSH_ENABLED */
   1854 
   1855 /**
   1856  * namePush:
   1857  * @ctxt:  an XML parser context
   1858  * @value:  the element name
   1859  *
   1860  * Pushes a new element name on top of the name stack
   1861  *
   1862  * Returns -1 in case of error, the index in the stack otherwise
   1863  */
   1864 int
   1865 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
   1866 {
   1867     if (ctxt == NULL) return (-1);
   1868 
   1869     if (ctxt->nameNr >= ctxt->nameMax) {
   1870         const xmlChar * *tmp;
   1871         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
   1872                                     ctxt->nameMax * 2 *
   1873                                     sizeof(ctxt->nameTab[0]));
   1874         if (tmp == NULL) {
   1875 	    goto mem_error;
   1876         }
   1877 	ctxt->nameTab = tmp;
   1878         ctxt->nameMax *= 2;
   1879     }
   1880     ctxt->nameTab[ctxt->nameNr] = value;
   1881     ctxt->name = value;
   1882     return (ctxt->nameNr++);
   1883 mem_error:
   1884     xmlErrMemory(ctxt, NULL);
   1885     return (-1);
   1886 }
   1887 /**
   1888  * namePop:
   1889  * @ctxt: an XML parser context
   1890  *
   1891  * Pops the top element name from the name stack
   1892  *
   1893  * Returns the name just removed
   1894  */
   1895 const xmlChar *
   1896 namePop(xmlParserCtxtPtr ctxt)
   1897 {
   1898     const xmlChar *ret;
   1899 
   1900     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
   1901         return (NULL);
   1902     ctxt->nameNr--;
   1903     if (ctxt->nameNr > 0)
   1904         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
   1905     else
   1906         ctxt->name = NULL;
   1907     ret = ctxt->nameTab[ctxt->nameNr];
   1908     ctxt->nameTab[ctxt->nameNr] = NULL;
   1909     return (ret);
   1910 }
   1911 
   1912 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
   1913     if (ctxt->spaceNr >= ctxt->spaceMax) {
   1914         int *tmp;
   1915 
   1916 	ctxt->spaceMax *= 2;
   1917         tmp = (int *) xmlRealloc(ctxt->spaceTab,
   1918 	                         ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
   1919         if (tmp == NULL) {
   1920 	    xmlErrMemory(ctxt, NULL);
   1921 	    ctxt->spaceMax /=2;
   1922 	    return(-1);
   1923 	}
   1924 	ctxt->spaceTab = tmp;
   1925     }
   1926     ctxt->spaceTab[ctxt->spaceNr] = val;
   1927     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
   1928     return(ctxt->spaceNr++);
   1929 }
   1930 
   1931 static int spacePop(xmlParserCtxtPtr ctxt) {
   1932     int ret;
   1933     if (ctxt->spaceNr <= 0) return(0);
   1934     ctxt->spaceNr--;
   1935     if (ctxt->spaceNr > 0)
   1936 	ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
   1937     else
   1938         ctxt->space = &ctxt->spaceTab[0];
   1939     ret = ctxt->spaceTab[ctxt->spaceNr];
   1940     ctxt->spaceTab[ctxt->spaceNr] = -1;
   1941     return(ret);
   1942 }
   1943 
   1944 /*
   1945  * Macros for accessing the content. Those should be used only by the parser,
   1946  * and not exported.
   1947  *
   1948  * Dirty macros, i.e. one often need to make assumption on the context to
   1949  * use them
   1950  *
   1951  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
   1952  *           To be used with extreme caution since operations consuming
   1953  *           characters may move the input buffer to a different location !
   1954  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
   1955  *           This should be used internally by the parser
   1956  *           only to compare to ASCII values otherwise it would break when
   1957  *           running with UTF-8 encoding.
   1958  *   RAW     same as CUR but in the input buffer, bypass any token
   1959  *           extraction that may have been done
   1960  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
   1961  *           to compare on ASCII based substring.
   1962  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
   1963  *           strings without newlines within the parser.
   1964  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
   1965  *           defined char within the parser.
   1966  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
   1967  *
   1968  *   NEXT    Skip to the next character, this does the proper decoding
   1969  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
   1970  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
   1971  *   CUR_CHAR(l) returns the current unicode character (int), set l
   1972  *           to the number of xmlChars used for the encoding [0-5].
   1973  *   CUR_SCHAR  same but operate on a string instead of the context
   1974  *   COPY_BUF  copy the current unicode char to the target buffer, increment
   1975  *            the index
   1976  *   GROW, SHRINK  handling of input buffers
   1977  */
   1978 
   1979 #define RAW (*ctxt->input->cur)
   1980 #define CUR (*ctxt->input->cur)
   1981 #define NXT(val) ctxt->input->cur[(val)]
   1982 #define CUR_PTR ctxt->input->cur
   1983 
   1984 #define CMP4( s, c1, c2, c3, c4 ) \
   1985   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
   1986     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
   1987 #define CMP5( s, c1, c2, c3, c4, c5 ) \
   1988   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
   1989 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
   1990   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
   1991 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
   1992   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
   1993 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
   1994   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
   1995 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
   1996   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
   1997     ((unsigned char *) s)[ 8 ] == c9 )
   1998 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
   1999   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
   2000     ((unsigned char *) s)[ 9 ] == c10 )
   2001 
   2002 #define SKIP(val) do {							\
   2003     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);			\
   2004     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
   2005     if ((*ctxt->input->cur == 0) &&					\
   2006         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
   2007 	    xmlPopInput(ctxt);						\
   2008   } while (0)
   2009 
   2010 #define SKIPL(val) do {							\
   2011     int skipl;								\
   2012     for(skipl=0; skipl<val; skipl++) {					\
   2013 	if (*(ctxt->input->cur) == '\n') {				\
   2014 	ctxt->input->line++; ctxt->input->col = 1;			\
   2015 	} else ctxt->input->col++;					\
   2016 	ctxt->nbChars++;						\
   2017 	ctxt->input->cur++;						\
   2018     }									\
   2019     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
   2020     if ((*ctxt->input->cur == 0) &&					\
   2021         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
   2022 	    xmlPopInput(ctxt);						\
   2023   } while (0)
   2024 
   2025 #define SHRINK if ((ctxt->progressive == 0) &&				\
   2026 		   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
   2027 		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
   2028 	xmlSHRINK (ctxt);
   2029 
   2030 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
   2031     xmlParserInputShrink(ctxt->input);
   2032     if ((*ctxt->input->cur == 0) &&
   2033         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
   2034 	    xmlPopInput(ctxt);
   2035   }
   2036 
   2037 #define GROW if ((ctxt->progressive == 0) &&				\
   2038 		 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))	\
   2039 	xmlGROW (ctxt);
   2040 
   2041 static void xmlGROW (xmlParserCtxtPtr ctxt) {
   2042     if ((((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
   2043          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
   2044          ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
   2045         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   2046         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
   2047         ctxt->instate = XML_PARSER_EOF;
   2048     }
   2049     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
   2050     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
   2051         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
   2052 	    xmlPopInput(ctxt);
   2053 }
   2054 
   2055 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
   2056 
   2057 #define NEXT xmlNextChar(ctxt)
   2058 
   2059 #define NEXT1 {								\
   2060 	ctxt->input->col++;						\
   2061 	ctxt->input->cur++;						\
   2062 	ctxt->nbChars++;						\
   2063 	if (*ctxt->input->cur == 0)					\
   2064 	    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);		\
   2065     }
   2066 
   2067 #define NEXTL(l) do {							\
   2068     if (*(ctxt->input->cur) == '\n') {					\
   2069 	ctxt->input->line++; ctxt->input->col = 1;			\
   2070     } else ctxt->input->col++;						\
   2071     ctxt->input->cur += l;				\
   2072     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
   2073   } while (0)
   2074 
   2075 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
   2076 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
   2077 
   2078 #define COPY_BUF(l,b,i,v)						\
   2079     if (l == 1) b[i++] = (xmlChar) v;					\
   2080     else i += xmlCopyCharMultiByte(&b[i],v)
   2081 
   2082 /**
   2083  * xmlSkipBlankChars:
   2084  * @ctxt:  the XML parser context
   2085  *
   2086  * skip all blanks character found at that point in the input streams.
   2087  * It pops up finished entities in the process if allowable at that point.
   2088  *
   2089  * Returns the number of space chars skipped
   2090  */
   2091 
   2092 int
   2093 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
   2094     int res = 0;
   2095 
   2096     /*
   2097      * It's Okay to use CUR/NEXT here since all the blanks are on
   2098      * the ASCII range.
   2099      */
   2100     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
   2101 	const xmlChar *cur;
   2102 	/*
   2103 	 * if we are in the document content, go really fast
   2104 	 */
   2105 	cur = ctxt->input->cur;
   2106 	while (IS_BLANK_CH(*cur)) {
   2107 	    if (*cur == '\n') {
   2108 		ctxt->input->line++; ctxt->input->col = 1;
   2109 	    }
   2110 	    cur++;
   2111 	    res++;
   2112 	    if (*cur == 0) {
   2113 		ctxt->input->cur = cur;
   2114 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
   2115 		cur = ctxt->input->cur;
   2116 	    }
   2117 	}
   2118 	ctxt->input->cur = cur;
   2119     } else {
   2120 	int cur;
   2121 	do {
   2122 	    cur = CUR;
   2123 	    while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
   2124 		NEXT;
   2125 		cur = CUR;
   2126 		res++;
   2127 	    }
   2128 	    while ((cur == 0) && (ctxt->inputNr > 1) &&
   2129 		   (ctxt->instate != XML_PARSER_COMMENT)) {
   2130 		xmlPopInput(ctxt);
   2131 		cur = CUR;
   2132 	    }
   2133 	    /*
   2134 	     * Need to handle support of entities branching here
   2135 	     */
   2136 	    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
   2137 	} while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
   2138     }
   2139     return(res);
   2140 }
   2141 
   2142 /************************************************************************
   2143  *									*
   2144  *		Commodity functions to handle entities			*
   2145  *									*
   2146  ************************************************************************/
   2147 
   2148 /**
   2149  * xmlPopInput:
   2150  * @ctxt:  an XML parser context
   2151  *
   2152  * xmlPopInput: the current input pointed by ctxt->input came to an end
   2153  *          pop it and return the next char.
   2154  *
   2155  * Returns the current xmlChar in the parser context
   2156  */
   2157 xmlChar
   2158 xmlPopInput(xmlParserCtxtPtr ctxt) {
   2159     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
   2160     if (xmlParserDebugEntities)
   2161 	xmlGenericError(xmlGenericErrorContext,
   2162 		"Popping input %d\n", ctxt->inputNr);
   2163     xmlFreeInputStream(inputPop(ctxt));
   2164     if ((*ctxt->input->cur == 0) &&
   2165         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
   2166 	    return(xmlPopInput(ctxt));
   2167     return(CUR);
   2168 }
   2169 
   2170 /**
   2171  * xmlPushInput:
   2172  * @ctxt:  an XML parser context
   2173  * @input:  an XML parser input fragment (entity, XML fragment ...).
   2174  *
   2175  * xmlPushInput: switch to a new input stream which is stacked on top
   2176  *               of the previous one(s).
   2177  * Returns -1 in case of error or the index in the input stack
   2178  */
   2179 int
   2180 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
   2181     int ret;
   2182     if (input == NULL) return(-1);
   2183 
   2184     if (xmlParserDebugEntities) {
   2185 	if ((ctxt->input != NULL) && (ctxt->input->filename))
   2186 	    xmlGenericError(xmlGenericErrorContext,
   2187 		    "%s(%d): ", ctxt->input->filename,
   2188 		    ctxt->input->line);
   2189 	xmlGenericError(xmlGenericErrorContext,
   2190 		"Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
   2191     }
   2192     ret = inputPush(ctxt, input);
   2193     if (ctxt->instate == XML_PARSER_EOF)
   2194         return(-1);
   2195     GROW;
   2196     return(ret);
   2197 }
   2198 
   2199 /**
   2200  * xmlParseCharRef:
   2201  * @ctxt:  an XML parser context
   2202  *
   2203  * parse Reference declarations
   2204  *
   2205  * [66] CharRef ::= '&#' [0-9]+ ';' |
   2206  *                  '&#x' [0-9a-fA-F]+ ';'
   2207  *
   2208  * [ WFC: Legal Character ]
   2209  * Characters referred to using character references must match the
   2210  * production for Char.
   2211  *
   2212  * Returns the value parsed (as an int), 0 in case of error
   2213  */
   2214 int
   2215 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
   2216     unsigned int val = 0;
   2217     int count = 0;
   2218     unsigned int outofrange = 0;
   2219 
   2220     /*
   2221      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
   2222      */
   2223     if ((RAW == '&') && (NXT(1) == '#') &&
   2224         (NXT(2) == 'x')) {
   2225 	SKIP(3);
   2226 	GROW;
   2227 	while (RAW != ';') { /* loop blocked by count */
   2228 	    if (count++ > 20) {
   2229 		count = 0;
   2230 		GROW;
   2231                 if (ctxt->instate == XML_PARSER_EOF)
   2232                     return(0);
   2233 	    }
   2234 	    if ((RAW >= '0') && (RAW <= '9'))
   2235 	        val = val * 16 + (CUR - '0');
   2236 	    else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
   2237 	        val = val * 16 + (CUR - 'a') + 10;
   2238 	    else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
   2239 	        val = val * 16 + (CUR - 'A') + 10;
   2240 	    else {
   2241 		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
   2242 		val = 0;
   2243 		break;
   2244 	    }
   2245 	    if (val > 0x10FFFF)
   2246 	        outofrange = val;
   2247 
   2248 	    NEXT;
   2249 	    count++;
   2250 	}
   2251 	if (RAW == ';') {
   2252 	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */
   2253 	    ctxt->input->col++;
   2254 	    ctxt->nbChars ++;
   2255 	    ctxt->input->cur++;
   2256 	}
   2257     } else if  ((RAW == '&') && (NXT(1) == '#')) {
   2258 	SKIP(2);
   2259 	GROW;
   2260 	while (RAW != ';') { /* loop blocked by count */
   2261 	    if (count++ > 20) {
   2262 		count = 0;
   2263 		GROW;
   2264                 if (ctxt->instate == XML_PARSER_EOF)
   2265                     return(0);
   2266 	    }
   2267 	    if ((RAW >= '0') && (RAW <= '9'))
   2268 	        val = val * 10 + (CUR - '0');
   2269 	    else {
   2270 		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
   2271 		val = 0;
   2272 		break;
   2273 	    }
   2274 	    if (val > 0x10FFFF)
   2275 	        outofrange = val;
   2276 
   2277 	    NEXT;
   2278 	    count++;
   2279 	}
   2280 	if (RAW == ';') {
   2281 	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */
   2282 	    ctxt->input->col++;
   2283 	    ctxt->nbChars ++;
   2284 	    ctxt->input->cur++;
   2285 	}
   2286     } else {
   2287         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
   2288     }
   2289 
   2290     /*
   2291      * [ WFC: Legal Character ]
   2292      * Characters referred to using character references must match the
   2293      * production for Char.
   2294      */
   2295     if ((IS_CHAR(val) && (outofrange == 0))) {
   2296         return(val);
   2297     } else {
   2298         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   2299                           "xmlParseCharRef: invalid xmlChar value %d\n",
   2300 	                  val);
   2301     }
   2302     return(0);
   2303 }
   2304 
   2305 /**
   2306  * xmlParseStringCharRef:
   2307  * @ctxt:  an XML parser context
   2308  * @str:  a pointer to an index in the string
   2309  *
   2310  * parse Reference declarations, variant parsing from a string rather
   2311  * than an an input flow.
   2312  *
   2313  * [66] CharRef ::= '&#' [0-9]+ ';' |
   2314  *                  '&#x' [0-9a-fA-F]+ ';'
   2315  *
   2316  * [ WFC: Legal Character ]
   2317  * Characters referred to using character references must match the
   2318  * production for Char.
   2319  *
   2320  * Returns the value parsed (as an int), 0 in case of error, str will be
   2321  *         updated to the current value of the index
   2322  */
   2323 static int
   2324 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
   2325     const xmlChar *ptr;
   2326     xmlChar cur;
   2327     unsigned int val = 0;
   2328     unsigned int outofrange = 0;
   2329 
   2330     if ((str == NULL) || (*str == NULL)) return(0);
   2331     ptr = *str;
   2332     cur = *ptr;
   2333     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
   2334 	ptr += 3;
   2335 	cur = *ptr;
   2336 	while (cur != ';') { /* Non input consuming loop */
   2337 	    if ((cur >= '0') && (cur <= '9'))
   2338 	        val = val * 16 + (cur - '0');
   2339 	    else if ((cur >= 'a') && (cur <= 'f'))
   2340 	        val = val * 16 + (cur - 'a') + 10;
   2341 	    else if ((cur >= 'A') && (cur <= 'F'))
   2342 	        val = val * 16 + (cur - 'A') + 10;
   2343 	    else {
   2344 		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
   2345 		val = 0;
   2346 		break;
   2347 	    }
   2348 	    if (val > 0x10FFFF)
   2349 	        outofrange = val;
   2350 
   2351 	    ptr++;
   2352 	    cur = *ptr;
   2353 	}
   2354 	if (cur == ';')
   2355 	    ptr++;
   2356     } else if  ((cur == '&') && (ptr[1] == '#')){
   2357 	ptr += 2;
   2358 	cur = *ptr;
   2359 	while (cur != ';') { /* Non input consuming loops */
   2360 	    if ((cur >= '0') && (cur <= '9'))
   2361 	        val = val * 10 + (cur - '0');
   2362 	    else {
   2363 		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
   2364 		val = 0;
   2365 		break;
   2366 	    }
   2367 	    if (val > 0x10FFFF)
   2368 	        outofrange = val;
   2369 
   2370 	    ptr++;
   2371 	    cur = *ptr;
   2372 	}
   2373 	if (cur == ';')
   2374 	    ptr++;
   2375     } else {
   2376 	xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
   2377 	return(0);
   2378     }
   2379     *str = ptr;
   2380 
   2381     /*
   2382      * [ WFC: Legal Character ]
   2383      * Characters referred to using character references must match the
   2384      * production for Char.
   2385      */
   2386     if ((IS_CHAR(val) && (outofrange == 0))) {
   2387         return(val);
   2388     } else {
   2389         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   2390 			  "xmlParseStringCharRef: invalid xmlChar value %d\n",
   2391 			  val);
   2392     }
   2393     return(0);
   2394 }
   2395 
   2396 /**
   2397  * xmlNewBlanksWrapperInputStream:
   2398  * @ctxt:  an XML parser context
   2399  * @entity:  an Entity pointer
   2400  *
   2401  * Create a new input stream for wrapping
   2402  * blanks around a PEReference
   2403  *
   2404  * Returns the new input stream or NULL
   2405  */
   2406 
   2407 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
   2408 
   2409 static xmlParserInputPtr
   2410 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
   2411     xmlParserInputPtr input;
   2412     xmlChar *buffer;
   2413     size_t length;
   2414     if (entity == NULL) {
   2415 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   2416 	            "xmlNewBlanksWrapperInputStream entity\n");
   2417 	return(NULL);
   2418     }
   2419     if (xmlParserDebugEntities)
   2420 	xmlGenericError(xmlGenericErrorContext,
   2421 		"new blanks wrapper for entity: %s\n", entity->name);
   2422     input = xmlNewInputStream(ctxt);
   2423     if (input == NULL) {
   2424 	return(NULL);
   2425     }
   2426     length = xmlStrlen(entity->name) + 5;
   2427     buffer = xmlMallocAtomic(length);
   2428     if (buffer == NULL) {
   2429 	xmlErrMemory(ctxt, NULL);
   2430         xmlFree(input);
   2431 	return(NULL);
   2432     }
   2433     buffer [0] = ' ';
   2434     buffer [1] = '%';
   2435     buffer [length-3] = ';';
   2436     buffer [length-2] = ' ';
   2437     buffer [length-1] = 0;
   2438     memcpy(buffer + 2, entity->name, length - 5);
   2439     input->free = deallocblankswrapper;
   2440     input->base = buffer;
   2441     input->cur = buffer;
   2442     input->length = length;
   2443     input->end = &buffer[length];
   2444     return(input);
   2445 }
   2446 
   2447 /**
   2448  * xmlParserHandlePEReference:
   2449  * @ctxt:  the parser context
   2450  *
   2451  * [69] PEReference ::= '%' Name ';'
   2452  *
   2453  * [ WFC: No Recursion ]
   2454  * A parsed entity must not contain a recursive
   2455  * reference to itself, either directly or indirectly.
   2456  *
   2457  * [ WFC: Entity Declared ]
   2458  * In a document without any DTD, a document with only an internal DTD
   2459  * subset which contains no parameter entity references, or a document
   2460  * with "standalone='yes'", ...  ... The declaration of a parameter
   2461  * entity must precede any reference to it...
   2462  *
   2463  * [ VC: Entity Declared ]
   2464  * In a document with an external subset or external parameter entities
   2465  * with "standalone='no'", ...  ... The declaration of a parameter entity
   2466  * must precede any reference to it...
   2467  *
   2468  * [ WFC: In DTD ]
   2469  * Parameter-entity references may only appear in the DTD.
   2470  * NOTE: misleading but this is handled.
   2471  *
   2472  * A PEReference may have been detected in the current input stream
   2473  * the handling is done accordingly to
   2474  *      http://www.w3.org/TR/REC-xml#entproc
   2475  * i.e.
   2476  *   - Included in literal in entity values
   2477  *   - Included as Parameter Entity reference within DTDs
   2478  */
   2479 void
   2480 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
   2481     const xmlChar *name;
   2482     xmlEntityPtr entity = NULL;
   2483     xmlParserInputPtr input;
   2484 
   2485     if (RAW != '%') return;
   2486     switch(ctxt->instate) {
   2487 	case XML_PARSER_CDATA_SECTION:
   2488 	    return;
   2489         case XML_PARSER_COMMENT:
   2490 	    return;
   2491 	case XML_PARSER_START_TAG:
   2492 	    return;
   2493 	case XML_PARSER_END_TAG:
   2494 	    return;
   2495         case XML_PARSER_EOF:
   2496 	    xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
   2497 	    return;
   2498         case XML_PARSER_PROLOG:
   2499 	case XML_PARSER_START:
   2500 	case XML_PARSER_MISC:
   2501 	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
   2502 	    return;
   2503 	case XML_PARSER_ENTITY_DECL:
   2504         case XML_PARSER_CONTENT:
   2505         case XML_PARSER_ATTRIBUTE_VALUE:
   2506         case XML_PARSER_PI:
   2507 	case XML_PARSER_SYSTEM_LITERAL:
   2508 	case XML_PARSER_PUBLIC_LITERAL:
   2509 	    /* we just ignore it there */
   2510 	    return;
   2511         case XML_PARSER_EPILOG:
   2512 	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
   2513 	    return;
   2514 	case XML_PARSER_ENTITY_VALUE:
   2515 	    /*
   2516 	     * NOTE: in the case of entity values, we don't do the
   2517 	     *       substitution here since we need the literal
   2518 	     *       entity value to be able to save the internal
   2519 	     *       subset of the document.
   2520 	     *       This will be handled by xmlStringDecodeEntities
   2521 	     */
   2522 	    return;
   2523         case XML_PARSER_DTD:
   2524 	    /*
   2525 	     * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
   2526 	     * In the internal DTD subset, parameter-entity references
   2527 	     * can occur only where markup declarations can occur, not
   2528 	     * within markup declarations.
   2529 	     * In that case this is handled in xmlParseMarkupDecl
   2530 	     */
   2531 	    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
   2532 		return;
   2533 	    if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
   2534 		return;
   2535             break;
   2536         case XML_PARSER_IGNORE:
   2537             return;
   2538     }
   2539 
   2540     NEXT;
   2541     name = xmlParseName(ctxt);
   2542     if (xmlParserDebugEntities)
   2543 	xmlGenericError(xmlGenericErrorContext,
   2544 		"PEReference: %s\n", name);
   2545     if (name == NULL) {
   2546 	xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
   2547     } else {
   2548 	if (RAW == ';') {
   2549 	    NEXT;
   2550 	    if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
   2551 		entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
   2552 	    if (ctxt->instate == XML_PARSER_EOF)
   2553 	        return;
   2554 	    if (entity == NULL) {
   2555 
   2556 		/*
   2557 		 * [ WFC: Entity Declared ]
   2558 		 * In a document without any DTD, a document with only an
   2559 		 * internal DTD subset which contains no parameter entity
   2560 		 * references, or a document with "standalone='yes'", ...
   2561 		 * ... The declaration of a parameter entity must precede
   2562 		 * any reference to it...
   2563 		 */
   2564 		if ((ctxt->standalone == 1) ||
   2565 		    ((ctxt->hasExternalSubset == 0) &&
   2566 		     (ctxt->hasPErefs == 0))) {
   2567 		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
   2568 			 "PEReference: %%%s; not found\n", name);
   2569 	        } else {
   2570 		    /*
   2571 		     * [ VC: Entity Declared ]
   2572 		     * In a document with an external subset or external
   2573 		     * parameter entities with "standalone='no'", ...
   2574 		     * ... The declaration of a parameter entity must precede
   2575 		     * any reference to it...
   2576 		     */
   2577 		    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
   2578 		        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
   2579 			                 "PEReference: %%%s; not found\n",
   2580 				         name, NULL);
   2581 		    } else
   2582 		        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
   2583 			              "PEReference: %%%s; not found\n",
   2584 				      name, NULL);
   2585 		    ctxt->valid = 0;
   2586 		}
   2587 	    } else if (ctxt->input->free != deallocblankswrapper) {
   2588 		    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
   2589 		    if (xmlPushInput(ctxt, input) < 0)
   2590 		        return;
   2591 	    } else {
   2592 	        if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
   2593 		    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
   2594 		    xmlChar start[4];
   2595 		    xmlCharEncoding enc;
   2596 
   2597 		    /*
   2598 		     * handle the extra spaces added before and after
   2599 		     * c.f. http://www.w3.org/TR/REC-xml#as-PE
   2600 		     * this is done independently.
   2601 		     */
   2602 		    input = xmlNewEntityInputStream(ctxt, entity);
   2603 		    if (xmlPushInput(ctxt, input) < 0)
   2604 		        return;
   2605 
   2606 		    /*
   2607 		     * Get the 4 first bytes and decode the charset
   2608 		     * if enc != XML_CHAR_ENCODING_NONE
   2609 		     * plug some encoding conversion routines.
   2610 		     * Note that, since we may have some non-UTF8
   2611 		     * encoding (like UTF16, bug 135229), the 'length'
   2612 		     * is not known, but we can calculate based upon
   2613 		     * the amount of data in the buffer.
   2614 		     */
   2615 		    GROW
   2616                     if (ctxt->instate == XML_PARSER_EOF)
   2617                         return;
   2618 		    if ((ctxt->input->end - ctxt->input->cur)>=4) {
   2619 			start[0] = RAW;
   2620 			start[1] = NXT(1);
   2621 			start[2] = NXT(2);
   2622 			start[3] = NXT(3);
   2623 			enc = xmlDetectCharEncoding(start, 4);
   2624 			if (enc != XML_CHAR_ENCODING_NONE) {
   2625 			    xmlSwitchEncoding(ctxt, enc);
   2626 			}
   2627 		    }
   2628 
   2629 		    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
   2630 			(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
   2631 			(IS_BLANK_CH(NXT(5)))) {
   2632 			xmlParseTextDecl(ctxt);
   2633 		    }
   2634 		} else {
   2635 		    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
   2636 			     "PEReference: %s is not a parameter entity\n",
   2637 				      name);
   2638 		}
   2639 	    }
   2640 	} else {
   2641 	    xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
   2642 	}
   2643     }
   2644 }
   2645 
   2646 /*
   2647  * Macro used to grow the current buffer.
   2648  * buffer##_size is expected to be a size_t
   2649  * mem_error: is expected to handle memory allocation failures
   2650  */
   2651 #define growBuffer(buffer, n) {						\
   2652     xmlChar *tmp;							\
   2653     size_t new_size = buffer##_size * 2 + n;                            \
   2654     if (new_size < buffer##_size) goto mem_error;                       \
   2655     tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
   2656     if (tmp == NULL) goto mem_error;					\
   2657     buffer = tmp;							\
   2658     buffer##_size = new_size;                                           \
   2659 }
   2660 
   2661 /**
   2662  * xmlStringLenDecodeEntities:
   2663  * @ctxt:  the parser context
   2664  * @str:  the input string
   2665  * @len: the string length
   2666  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
   2667  * @end:  an end marker xmlChar, 0 if none
   2668  * @end2:  an end marker xmlChar, 0 if none
   2669  * @end3:  an end marker xmlChar, 0 if none
   2670  *
   2671  * Takes a entity string content and process to do the adequate substitutions.
   2672  *
   2673  * [67] Reference ::= EntityRef | CharRef
   2674  *
   2675  * [69] PEReference ::= '%' Name ';'
   2676  *
   2677  * Returns A newly allocated string with the substitution done. The caller
   2678  *      must deallocate it !
   2679  */
   2680 xmlChar *
   2681 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
   2682 		      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
   2683     xmlChar *buffer = NULL;
   2684     size_t buffer_size = 0;
   2685     size_t nbchars = 0;
   2686 
   2687     xmlChar *current = NULL;
   2688     xmlChar *rep = NULL;
   2689     const xmlChar *last;
   2690     xmlEntityPtr ent;
   2691     int c,l;
   2692 
   2693     if ((ctxt == NULL) || (str == NULL) || (len < 0))
   2694 	return(NULL);
   2695     last = str + len;
   2696 
   2697     if (((ctxt->depth > 40) &&
   2698          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
   2699 	(ctxt->depth > 1024)) {
   2700 	xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
   2701 	return(NULL);
   2702     }
   2703 
   2704     /*
   2705      * allocate a translation buffer.
   2706      */
   2707     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
   2708     buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
   2709     if (buffer == NULL) goto mem_error;
   2710 
   2711     /*
   2712      * OK loop until we reach one of the ending char or a size limit.
   2713      * we are operating on already parsed values.
   2714      */
   2715     if (str < last)
   2716 	c = CUR_SCHAR(str, l);
   2717     else
   2718         c = 0;
   2719     while ((c != 0) && (c != end) && /* non input consuming loop */
   2720 	   (c != end2) && (c != end3)) {
   2721 
   2722 	if (c == 0) break;
   2723         if ((c == '&') && (str[1] == '#')) {
   2724 	    int val = xmlParseStringCharRef(ctxt, &str);
   2725 	    if (val != 0) {
   2726 		COPY_BUF(0,buffer,nbchars,val);
   2727 	    }
   2728 	    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
   2729 	        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
   2730 	    }
   2731 	} else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
   2732 	    if (xmlParserDebugEntities)
   2733 		xmlGenericError(xmlGenericErrorContext,
   2734 			"String decoding Entity Reference: %.30s\n",
   2735 			str);
   2736 	    ent = xmlParseStringEntityRef(ctxt, &str);
   2737 	    if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
   2738 	        (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
   2739 	        goto int_error;
   2740 	    if (ent != NULL)
   2741 	        ctxt->nbentities += ent->checked / 2;
   2742 	    if ((ent != NULL) &&
   2743 		(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
   2744 		if (ent->content != NULL) {
   2745 		    COPY_BUF(0,buffer,nbchars,ent->content[0]);
   2746 		    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
   2747 			growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
   2748 		    }
   2749 		} else {
   2750 		    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
   2751 			    "predefined entity has no content\n");
   2752 		}
   2753 	    } else if ((ent != NULL) && (ent->content != NULL)) {
   2754 		ctxt->depth++;
   2755 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
   2756 			                      0, 0, 0);
   2757 		ctxt->depth--;
   2758 
   2759 		if (rep != NULL) {
   2760 		    current = rep;
   2761 		    while (*current != 0) { /* non input consuming loop */
   2762 			buffer[nbchars++] = *current++;
   2763 			if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
   2764 			    if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
   2765 				goto int_error;
   2766 			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
   2767 			}
   2768 		    }
   2769 		    xmlFree(rep);
   2770 		    rep = NULL;
   2771 		}
   2772 	    } else if (ent != NULL) {
   2773 		int i = xmlStrlen(ent->name);
   2774 		const xmlChar *cur = ent->name;
   2775 
   2776 		buffer[nbchars++] = '&';
   2777 		if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
   2778 		    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
   2779 		}
   2780 		for (;i > 0;i--)
   2781 		    buffer[nbchars++] = *cur++;
   2782 		buffer[nbchars++] = ';';
   2783 	    }
   2784 	} else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
   2785 	    if (xmlParserDebugEntities)
   2786 		xmlGenericError(xmlGenericErrorContext,
   2787 			"String decoding PE Reference: %.30s\n", str);
   2788 	    ent = xmlParseStringPEReference(ctxt, &str);
   2789 	    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
   2790 	        goto int_error;
   2791 	    if (ent != NULL)
   2792 	        ctxt->nbentities += ent->checked / 2;
   2793 	    if (ent != NULL) {
   2794                 if (ent->content == NULL) {
   2795 		    xmlLoadEntityContent(ctxt, ent);
   2796 		}
   2797 		ctxt->depth++;
   2798 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
   2799 			                      0, 0, 0);
   2800 		ctxt->depth--;
   2801 		if (rep != NULL) {
   2802 		    current = rep;
   2803 		    while (*current != 0) { /* non input consuming loop */
   2804 			buffer[nbchars++] = *current++;
   2805 			if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
   2806 			    if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
   2807 			        goto int_error;
   2808 			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
   2809 			}
   2810 		    }
   2811 		    xmlFree(rep);
   2812 		    rep = NULL;
   2813 		}
   2814 	    }
   2815 	} else {
   2816 	    COPY_BUF(l,buffer,nbchars,c);
   2817 	    str += l;
   2818 	    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
   2819 	        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
   2820 	    }
   2821 	}
   2822 	if (str < last)
   2823 	    c = CUR_SCHAR(str, l);
   2824 	else
   2825 	    c = 0;
   2826     }
   2827     buffer[nbchars] = 0;
   2828     return(buffer);
   2829 
   2830 mem_error:
   2831     xmlErrMemory(ctxt, NULL);
   2832 int_error:
   2833     if (rep != NULL)
   2834         xmlFree(rep);
   2835     if (buffer != NULL)
   2836         xmlFree(buffer);
   2837     return(NULL);
   2838 }
   2839 
   2840 /**
   2841  * xmlStringDecodeEntities:
   2842  * @ctxt:  the parser context
   2843  * @str:  the input string
   2844  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
   2845  * @end:  an end marker xmlChar, 0 if none
   2846  * @end2:  an end marker xmlChar, 0 if none
   2847  * @end3:  an end marker xmlChar, 0 if none
   2848  *
   2849  * Takes a entity string content and process to do the adequate substitutions.
   2850  *
   2851  * [67] Reference ::= EntityRef | CharRef
   2852  *
   2853  * [69] PEReference ::= '%' Name ';'
   2854  *
   2855  * Returns A newly allocated string with the substitution done. The caller
   2856  *      must deallocate it !
   2857  */
   2858 xmlChar *
   2859 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
   2860 		        xmlChar end, xmlChar  end2, xmlChar end3) {
   2861     if ((ctxt == NULL) || (str == NULL)) return(NULL);
   2862     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
   2863            end, end2, end3));
   2864 }
   2865 
   2866 /************************************************************************
   2867  *									*
   2868  *		Commodity functions, cleanup needed ?			*
   2869  *									*
   2870  ************************************************************************/
   2871 
   2872 /**
   2873  * areBlanks:
   2874  * @ctxt:  an XML parser context
   2875  * @str:  a xmlChar *
   2876  * @len:  the size of @str
   2877  * @blank_chars: we know the chars are blanks
   2878  *
   2879  * Is this a sequence of blank chars that one can ignore ?
   2880  *
   2881  * Returns 1 if ignorable 0 otherwise.
   2882  */
   2883 
   2884 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
   2885                      int blank_chars) {
   2886     int i, ret;
   2887     xmlNodePtr lastChild;
   2888 
   2889     /*
   2890      * Don't spend time trying to differentiate them, the same callback is
   2891      * used !
   2892      */
   2893     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
   2894 	return(0);
   2895 
   2896     /*
   2897      * Check for xml:space value.
   2898      */
   2899     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
   2900         (*(ctxt->space) == -2))
   2901 	return(0);
   2902 
   2903     /*
   2904      * Check that the string is made of blanks
   2905      */
   2906     if (blank_chars == 0) {
   2907 	for (i = 0;i < len;i++)
   2908 	    if (!(IS_BLANK_CH(str[i]))) return(0);
   2909     }
   2910 
   2911     /*
   2912      * Look if the element is mixed content in the DTD if available
   2913      */
   2914     if (ctxt->node == NULL) return(0);
   2915     if (ctxt->myDoc != NULL) {
   2916 	ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
   2917         if (ret == 0) return(1);
   2918         if (ret == 1) return(0);
   2919     }
   2920 
   2921     /*
   2922      * Otherwise, heuristic :-\
   2923      */
   2924     if ((RAW != '<') && (RAW != 0xD)) return(0);
   2925     if ((ctxt->node->children == NULL) &&
   2926 	(RAW == '<') && (NXT(1) == '/')) return(0);
   2927 
   2928     lastChild = xmlGetLastChild(ctxt->node);
   2929     if (lastChild == NULL) {
   2930         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
   2931             (ctxt->node->content != NULL)) return(0);
   2932     } else if (xmlNodeIsText(lastChild))
   2933         return(0);
   2934     else if ((ctxt->node->children != NULL) &&
   2935              (xmlNodeIsText(ctxt->node->children)))
   2936         return(0);
   2937     return(1);
   2938 }
   2939 
   2940 /************************************************************************
   2941  *									*
   2942  *		Extra stuff for namespace support			*
   2943  *	Relates to http://www.w3.org/TR/WD-xml-names			*
   2944  *									*
   2945  ************************************************************************/
   2946 
   2947 /**
   2948  * xmlSplitQName:
   2949  * @ctxt:  an XML parser context
   2950  * @name:  an XML parser context
   2951  * @prefix:  a xmlChar **
   2952  *
   2953  * parse an UTF8 encoded XML qualified name string
   2954  *
   2955  * [NS 5] QName ::= (Prefix ':')? LocalPart
   2956  *
   2957  * [NS 6] Prefix ::= NCName
   2958  *
   2959  * [NS 7] LocalPart ::= NCName
   2960  *
   2961  * Returns the local part, and prefix is updated
   2962  *   to get the Prefix if any.
   2963  */
   2964 
   2965 xmlChar *
   2966 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
   2967     xmlChar buf[XML_MAX_NAMELEN + 5];
   2968     xmlChar *buffer = NULL;
   2969     int len = 0;
   2970     int max = XML_MAX_NAMELEN;
   2971     xmlChar *ret = NULL;
   2972     const xmlChar *cur = name;
   2973     int c;
   2974 
   2975     if (prefix == NULL) return(NULL);
   2976     *prefix = NULL;
   2977 
   2978     if (cur == NULL) return(NULL);
   2979 
   2980 #ifndef XML_XML_NAMESPACE
   2981     /* xml: prefix is not really a namespace */
   2982     if ((cur[0] == 'x') && (cur[1] == 'm') &&
   2983         (cur[2] == 'l') && (cur[3] == ':'))
   2984 	return(xmlStrdup(name));
   2985 #endif
   2986 
   2987     /* nasty but well=formed */
   2988     if (cur[0] == ':')
   2989 	return(xmlStrdup(name));
   2990 
   2991     c = *cur++;
   2992     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
   2993 	buf[len++] = c;
   2994 	c = *cur++;
   2995     }
   2996     if (len >= max) {
   2997 	/*
   2998 	 * Okay someone managed to make a huge name, so he's ready to pay
   2999 	 * for the processing speed.
   3000 	 */
   3001 	max = len * 2;
   3002 
   3003 	buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
   3004 	if (buffer == NULL) {
   3005 	    xmlErrMemory(ctxt, NULL);
   3006 	    return(NULL);
   3007 	}
   3008 	memcpy(buffer, buf, len);
   3009 	while ((c != 0) && (c != ':')) { /* tested bigname.xml */
   3010 	    if (len + 10 > max) {
   3011 	        xmlChar *tmp;
   3012 
   3013 		max *= 2;
   3014 		tmp = (xmlChar *) xmlRealloc(buffer,
   3015 						max * sizeof(xmlChar));
   3016 		if (tmp == NULL) {
   3017 		    xmlFree(buffer);
   3018 		    xmlErrMemory(ctxt, NULL);
   3019 		    return(NULL);
   3020 		}
   3021 		buffer = tmp;
   3022 	    }
   3023 	    buffer[len++] = c;
   3024 	    c = *cur++;
   3025 	}
   3026 	buffer[len] = 0;
   3027     }
   3028 
   3029     if ((c == ':') && (*cur == 0)) {
   3030         if (buffer != NULL)
   3031 	    xmlFree(buffer);
   3032 	*prefix = NULL;
   3033 	return(xmlStrdup(name));
   3034     }
   3035 
   3036     if (buffer == NULL)
   3037 	ret = xmlStrndup(buf, len);
   3038     else {
   3039 	ret = buffer;
   3040 	buffer = NULL;
   3041 	max = XML_MAX_NAMELEN;
   3042     }
   3043 
   3044 
   3045     if (c == ':') {
   3046 	c = *cur;
   3047         *prefix = ret;
   3048 	if (c == 0) {
   3049 	    return(xmlStrndup(BAD_CAST "", 0));
   3050 	}
   3051 	len = 0;
   3052 
   3053 	/*
   3054 	 * Check that the first character is proper to start
   3055 	 * a new name
   3056 	 */
   3057 	if (!(((c >= 0x61) && (c <= 0x7A)) ||
   3058 	      ((c >= 0x41) && (c <= 0x5A)) ||
   3059 	      (c == '_') || (c == ':'))) {
   3060 	    int l;
   3061 	    int first = CUR_SCHAR(cur, l);
   3062 
   3063 	    if (!IS_LETTER(first) && (first != '_')) {
   3064 		xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
   3065 			    "Name %s is not XML Namespace compliant\n",
   3066 				  name);
   3067 	    }
   3068 	}
   3069 	cur++;
   3070 
   3071 	while ((c != 0) && (len < max)) { /* tested bigname2.xml */
   3072 	    buf[len++] = c;
   3073 	    c = *cur++;
   3074 	}
   3075 	if (len >= max) {
   3076 	    /*
   3077 	     * Okay someone managed to make a huge name, so he's ready to pay
   3078 	     * for the processing speed.
   3079 	     */
   3080 	    max = len * 2;
   3081 
   3082 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
   3083 	    if (buffer == NULL) {
   3084 	        xmlErrMemory(ctxt, NULL);
   3085 		return(NULL);
   3086 	    }
   3087 	    memcpy(buffer, buf, len);
   3088 	    while (c != 0) { /* tested bigname2.xml */
   3089 		if (len + 10 > max) {
   3090 		    xmlChar *tmp;
   3091 
   3092 		    max *= 2;
   3093 		    tmp = (xmlChar *) xmlRealloc(buffer,
   3094 						    max * sizeof(xmlChar));
   3095 		    if (tmp == NULL) {
   3096 			xmlErrMemory(ctxt, NULL);
   3097 			xmlFree(buffer);
   3098 			return(NULL);
   3099 		    }
   3100 		    buffer = tmp;
   3101 		}
   3102 		buffer[len++] = c;
   3103 		c = *cur++;
   3104 	    }
   3105 	    buffer[len] = 0;
   3106 	}
   3107 
   3108 	if (buffer == NULL)
   3109 	    ret = xmlStrndup(buf, len);
   3110 	else {
   3111 	    ret = buffer;
   3112 	}
   3113     }
   3114 
   3115     return(ret);
   3116 }
   3117 
   3118 /************************************************************************
   3119  *									*
   3120  *			The parser itself				*
   3121  *	Relates to http://www.w3.org/TR/REC-xml				*
   3122  *									*
   3123  ************************************************************************/
   3124 
   3125 /************************************************************************
   3126  *									*
   3127  *	Routines to parse Name, NCName and NmToken			*
   3128  *									*
   3129  ************************************************************************/
   3130 #ifdef DEBUG
   3131 static unsigned long nbParseName = 0;
   3132 static unsigned long nbParseNmToken = 0;
   3133 static unsigned long nbParseNCName = 0;
   3134 static unsigned long nbParseNCNameComplex = 0;
   3135 static unsigned long nbParseNameComplex = 0;
   3136 static unsigned long nbParseStringName = 0;
   3137 #endif
   3138 
   3139 /*
   3140  * The two following functions are related to the change of accepted
   3141  * characters for Name and NmToken in the Revision 5 of XML-1.0
   3142  * They correspond to the modified production [4] and the new production [4a]
   3143  * changes in that revision. Also note that the macros used for the
   3144  * productions Letter, Digit, CombiningChar and Extender are not needed
   3145  * anymore.
   3146  * We still keep compatibility to pre-revision5 parsing semantic if the
   3147  * new XML_PARSE_OLD10 option is given to the parser.
   3148  */
   3149 static int
   3150 xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
   3151     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
   3152         /*
   3153 	 * Use the new checks of production [4] [4a] amd [5] of the
   3154 	 * Update 5 of XML-1.0
   3155 	 */
   3156 	if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
   3157 	    (((c >= 'a') && (c <= 'z')) ||
   3158 	     ((c >= 'A') && (c <= 'Z')) ||
   3159 	     (c == '_') || (c == ':') ||
   3160 	     ((c >= 0xC0) && (c <= 0xD6)) ||
   3161 	     ((c >= 0xD8) && (c <= 0xF6)) ||
   3162 	     ((c >= 0xF8) && (c <= 0x2FF)) ||
   3163 	     ((c >= 0x370) && (c <= 0x37D)) ||
   3164 	     ((c >= 0x37F) && (c <= 0x1FFF)) ||
   3165 	     ((c >= 0x200C) && (c <= 0x200D)) ||
   3166 	     ((c >= 0x2070) && (c <= 0x218F)) ||
   3167 	     ((c >= 0x2C00) && (c <= 0x2FEF)) ||
   3168 	     ((c >= 0x3001) && (c <= 0xD7FF)) ||
   3169 	     ((c >= 0xF900) && (c <= 0xFDCF)) ||
   3170 	     ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
   3171 	     ((c >= 0x10000) && (c <= 0xEFFFF))))
   3172 	    return(1);
   3173     } else {
   3174         if (IS_LETTER(c) || (c == '_') || (c == ':'))
   3175 	    return(1);
   3176     }
   3177     return(0);
   3178 }
   3179 
   3180 static int
   3181 xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
   3182     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
   3183         /*
   3184 	 * Use the new checks of production [4] [4a] amd [5] of the
   3185 	 * Update 5 of XML-1.0
   3186 	 */
   3187 	if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
   3188 	    (((c >= 'a') && (c <= 'z')) ||
   3189 	     ((c >= 'A') && (c <= 'Z')) ||
   3190 	     ((c >= '0') && (c <= '9')) || /* !start */
   3191 	     (c == '_') || (c == ':') ||
   3192 	     (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
   3193 	     ((c >= 0xC0) && (c <= 0xD6)) ||
   3194 	     ((c >= 0xD8) && (c <= 0xF6)) ||
   3195 	     ((c >= 0xF8) && (c <= 0x2FF)) ||
   3196 	     ((c >= 0x300) && (c <= 0x36F)) || /* !start */
   3197 	     ((c >= 0x370) && (c <= 0x37D)) ||
   3198 	     ((c >= 0x37F) && (c <= 0x1FFF)) ||
   3199 	     ((c >= 0x200C) && (c <= 0x200D)) ||
   3200 	     ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
   3201 	     ((c >= 0x2070) && (c <= 0x218F)) ||
   3202 	     ((c >= 0x2C00) && (c <= 0x2FEF)) ||
   3203 	     ((c >= 0x3001) && (c <= 0xD7FF)) ||
   3204 	     ((c >= 0xF900) && (c <= 0xFDCF)) ||
   3205 	     ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
   3206 	     ((c >= 0x10000) && (c <= 0xEFFFF))))
   3207 	     return(1);
   3208     } else {
   3209         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
   3210             (c == '.') || (c == '-') ||
   3211 	    (c == '_') || (c == ':') ||
   3212 	    (IS_COMBINING(c)) ||
   3213 	    (IS_EXTENDER(c)))
   3214 	    return(1);
   3215     }
   3216     return(0);
   3217 }
   3218 
   3219 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
   3220                                           int *len, int *alloc, int normalize);
   3221 
   3222 static const xmlChar *
   3223 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
   3224     int len = 0, l;
   3225     int c;
   3226     int count = 0;
   3227 
   3228 #ifdef DEBUG
   3229     nbParseNameComplex++;
   3230 #endif
   3231 
   3232     /*
   3233      * Handler for more complex cases
   3234      */
   3235     GROW;
   3236     if (ctxt->instate == XML_PARSER_EOF)
   3237         return(NULL);
   3238     c = CUR_CHAR(l);
   3239     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
   3240         /*
   3241 	 * Use the new checks of production [4] [4a] amd [5] of the
   3242 	 * Update 5 of XML-1.0
   3243 	 */
   3244 	if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
   3245 	    (!(((c >= 'a') && (c <= 'z')) ||
   3246 	       ((c >= 'A') && (c <= 'Z')) ||
   3247 	       (c == '_') || (c == ':') ||
   3248 	       ((c >= 0xC0) && (c <= 0xD6)) ||
   3249 	       ((c >= 0xD8) && (c <= 0xF6)) ||
   3250 	       ((c >= 0xF8) && (c <= 0x2FF)) ||
   3251 	       ((c >= 0x370) && (c <= 0x37D)) ||
   3252 	       ((c >= 0x37F) && (c <= 0x1FFF)) ||
   3253 	       ((c >= 0x200C) && (c <= 0x200D)) ||
   3254 	       ((c >= 0x2070) && (c <= 0x218F)) ||
   3255 	       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
   3256 	       ((c >= 0x3001) && (c <= 0xD7FF)) ||
   3257 	       ((c >= 0xF900) && (c <= 0xFDCF)) ||
   3258 	       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
   3259 	       ((c >= 0x10000) && (c <= 0xEFFFF))))) {
   3260 	    return(NULL);
   3261 	}
   3262 	len += l;
   3263 	NEXTL(l);
   3264 	c = CUR_CHAR(l);
   3265 	while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
   3266 	       (((c >= 'a') && (c <= 'z')) ||
   3267 	        ((c >= 'A') && (c <= 'Z')) ||
   3268 	        ((c >= '0') && (c <= '9')) || /* !start */
   3269 	        (c == '_') || (c == ':') ||
   3270 	        (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
   3271 	        ((c >= 0xC0) && (c <= 0xD6)) ||
   3272 	        ((c >= 0xD8) && (c <= 0xF6)) ||
   3273 	        ((c >= 0xF8) && (c <= 0x2FF)) ||
   3274 	        ((c >= 0x300) && (c <= 0x36F)) || /* !start */
   3275 	        ((c >= 0x370) && (c <= 0x37D)) ||
   3276 	        ((c >= 0x37F) && (c <= 0x1FFF)) ||
   3277 	        ((c >= 0x200C) && (c <= 0x200D)) ||
   3278 	        ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
   3279 	        ((c >= 0x2070) && (c <= 0x218F)) ||
   3280 	        ((c >= 0x2C00) && (c <= 0x2FEF)) ||
   3281 	        ((c >= 0x3001) && (c <= 0xD7FF)) ||
   3282 	        ((c >= 0xF900) && (c <= 0xFDCF)) ||
   3283 	        ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
   3284 	        ((c >= 0x10000) && (c <= 0xEFFFF))
   3285 		)) {
   3286 	    if (count++ > XML_PARSER_CHUNK_SIZE) {
   3287 		count = 0;
   3288 		GROW;
   3289                 if (ctxt->instate == XML_PARSER_EOF)
   3290                     return(NULL);
   3291 	    }
   3292 	    len += l;
   3293 	    NEXTL(l);
   3294 	    c = CUR_CHAR(l);
   3295 	}
   3296     } else {
   3297 	if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
   3298 	    (!IS_LETTER(c) && (c != '_') &&
   3299 	     (c != ':'))) {
   3300 	    return(NULL);
   3301 	}
   3302 	len += l;
   3303 	NEXTL(l);
   3304 	c = CUR_CHAR(l);
   3305 
   3306 	while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
   3307 	       ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
   3308 		(c == '.') || (c == '-') ||
   3309 		(c == '_') || (c == ':') ||
   3310 		(IS_COMBINING(c)) ||
   3311 		(IS_EXTENDER(c)))) {
   3312 	    if (count++ > XML_PARSER_CHUNK_SIZE) {
   3313 		count = 0;
   3314 		GROW;
   3315                 if (ctxt->instate == XML_PARSER_EOF)
   3316                     return(NULL);
   3317 	    }
   3318 	    len += l;
   3319 	    NEXTL(l);
   3320 	    c = CUR_CHAR(l);
   3321 	    if (c == 0) {
   3322 		count = 0;
   3323 		GROW;
   3324                 if (ctxt->instate == XML_PARSER_EOF)
   3325                     return(NULL);
   3326 		c = CUR_CHAR(l);
   3327 	    }
   3328 	}
   3329     }
   3330     if ((len > XML_MAX_NAME_LENGTH) &&
   3331         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3332         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
   3333         return(NULL);
   3334     }
   3335     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
   3336         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
   3337     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
   3338 }
   3339 
   3340 /**
   3341  * xmlParseName:
   3342  * @ctxt:  an XML parser context
   3343  *
   3344  * parse an XML name.
   3345  *
   3346  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
   3347  *                  CombiningChar | Extender
   3348  *
   3349  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
   3350  *
   3351  * [6] Names ::= Name (#x20 Name)*
   3352  *
   3353  * Returns the Name parsed or NULL
   3354  */
   3355 
   3356 const xmlChar *
   3357 xmlParseName(xmlParserCtxtPtr ctxt) {
   3358     const xmlChar *in;
   3359     const xmlChar *ret;
   3360     int count = 0;
   3361 
   3362     GROW;
   3363 
   3364 #ifdef DEBUG
   3365     nbParseName++;
   3366 #endif
   3367 
   3368     /*
   3369      * Accelerator for simple ASCII names
   3370      */
   3371     in = ctxt->input->cur;
   3372     if (((*in >= 0x61) && (*in <= 0x7A)) ||
   3373 	((*in >= 0x41) && (*in <= 0x5A)) ||
   3374 	(*in == '_') || (*in == ':')) {
   3375 	in++;
   3376 	while (((*in >= 0x61) && (*in <= 0x7A)) ||
   3377 	       ((*in >= 0x41) && (*in <= 0x5A)) ||
   3378 	       ((*in >= 0x30) && (*in <= 0x39)) ||
   3379 	       (*in == '_') || (*in == '-') ||
   3380 	       (*in == ':') || (*in == '.'))
   3381 	    in++;
   3382 	if ((*in > 0) && (*in < 0x80)) {
   3383 	    count = in - ctxt->input->cur;
   3384             if ((count > XML_MAX_NAME_LENGTH) &&
   3385                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3386                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
   3387                 return(NULL);
   3388             }
   3389 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
   3390 	    ctxt->input->cur = in;
   3391 	    ctxt->nbChars += count;
   3392 	    ctxt->input->col += count;
   3393 	    if (ret == NULL)
   3394 	        xmlErrMemory(ctxt, NULL);
   3395 	    return(ret);
   3396 	}
   3397     }
   3398     /* accelerator for special cases */
   3399     return(xmlParseNameComplex(ctxt));
   3400 }
   3401 
   3402 static const xmlChar *
   3403 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
   3404     int len = 0, l;
   3405     int c;
   3406     int count = 0;
   3407 
   3408 #ifdef DEBUG
   3409     nbParseNCNameComplex++;
   3410 #endif
   3411 
   3412     /*
   3413      * Handler for more complex cases
   3414      */
   3415     GROW;
   3416     c = CUR_CHAR(l);
   3417     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
   3418 	(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
   3419 	return(NULL);
   3420     }
   3421 
   3422     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
   3423 	   (xmlIsNameChar(ctxt, c) && (c != ':'))) {
   3424 	if (count++ > XML_PARSER_CHUNK_SIZE) {
   3425             if ((len > XML_MAX_NAME_LENGTH) &&
   3426                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3427                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
   3428                 return(NULL);
   3429             }
   3430 	    count = 0;
   3431 	    GROW;
   3432             if (ctxt->instate == XML_PARSER_EOF)
   3433                 return(NULL);
   3434 	}
   3435 	len += l;
   3436 	NEXTL(l);
   3437 	c = CUR_CHAR(l);
   3438 	if (c == 0) {
   3439 	    count = 0;
   3440 	    GROW;
   3441             if (ctxt->instate == XML_PARSER_EOF)
   3442                 return(NULL);
   3443 	    c = CUR_CHAR(l);
   3444 	}
   3445     }
   3446     if ((len > XML_MAX_NAME_LENGTH) &&
   3447         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3448         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
   3449         return(NULL);
   3450     }
   3451     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
   3452 }
   3453 
   3454 /**
   3455  * xmlParseNCName:
   3456  * @ctxt:  an XML parser context
   3457  * @len:  length of the string parsed
   3458  *
   3459  * parse an XML name.
   3460  *
   3461  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
   3462  *                      CombiningChar | Extender
   3463  *
   3464  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
   3465  *
   3466  * Returns the Name parsed or NULL
   3467  */
   3468 
   3469 static const xmlChar *
   3470 xmlParseNCName(xmlParserCtxtPtr ctxt) {
   3471     const xmlChar *in;
   3472     const xmlChar *ret;
   3473     int count = 0;
   3474 
   3475 #ifdef DEBUG
   3476     nbParseNCName++;
   3477 #endif
   3478 
   3479     /*
   3480      * Accelerator for simple ASCII names
   3481      */
   3482     in = ctxt->input->cur;
   3483     if (((*in >= 0x61) && (*in <= 0x7A)) ||
   3484 	((*in >= 0x41) && (*in <= 0x5A)) ||
   3485 	(*in == '_')) {
   3486 	in++;
   3487 	while (((*in >= 0x61) && (*in <= 0x7A)) ||
   3488 	       ((*in >= 0x41) && (*in <= 0x5A)) ||
   3489 	       ((*in >= 0x30) && (*in <= 0x39)) ||
   3490 	       (*in == '_') || (*in == '-') ||
   3491 	       (*in == '.'))
   3492 	    in++;
   3493 	if ((*in > 0) && (*in < 0x80)) {
   3494 	    count = in - ctxt->input->cur;
   3495             if ((count > XML_MAX_NAME_LENGTH) &&
   3496                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3497                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
   3498                 return(NULL);
   3499             }
   3500 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
   3501 	    ctxt->input->cur = in;
   3502 	    ctxt->nbChars += count;
   3503 	    ctxt->input->col += count;
   3504 	    if (ret == NULL) {
   3505 	        xmlErrMemory(ctxt, NULL);
   3506 	    }
   3507 	    return(ret);
   3508 	}
   3509     }
   3510     return(xmlParseNCNameComplex(ctxt));
   3511 }
   3512 
   3513 /**
   3514  * xmlParseNameAndCompare:
   3515  * @ctxt:  an XML parser context
   3516  *
   3517  * parse an XML name and compares for match
   3518  * (specialized for endtag parsing)
   3519  *
   3520  * Returns NULL for an illegal name, (xmlChar*) 1 for success
   3521  * and the name for mismatch
   3522  */
   3523 
   3524 static const xmlChar *
   3525 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
   3526     register const xmlChar *cmp = other;
   3527     register const xmlChar *in;
   3528     const xmlChar *ret;
   3529 
   3530     GROW;
   3531     if (ctxt->instate == XML_PARSER_EOF)
   3532         return(NULL);
   3533 
   3534     in = ctxt->input->cur;
   3535     while (*in != 0 && *in == *cmp) {
   3536 	++in;
   3537 	++cmp;
   3538 	ctxt->input->col++;
   3539     }
   3540     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
   3541 	/* success */
   3542 	ctxt->input->cur = in;
   3543 	return (const xmlChar*) 1;
   3544     }
   3545     /* failure (or end of input buffer), check with full function */
   3546     ret = xmlParseName (ctxt);
   3547     /* strings coming from the dictionnary direct compare possible */
   3548     if (ret == other) {
   3549 	return (const xmlChar*) 1;
   3550     }
   3551     return ret;
   3552 }
   3553 
   3554 /**
   3555  * xmlParseStringName:
   3556  * @ctxt:  an XML parser context
   3557  * @str:  a pointer to the string pointer (IN/OUT)
   3558  *
   3559  * parse an XML name.
   3560  *
   3561  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
   3562  *                  CombiningChar | Extender
   3563  *
   3564  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
   3565  *
   3566  * [6] Names ::= Name (#x20 Name)*
   3567  *
   3568  * Returns the Name parsed or NULL. The @str pointer
   3569  * is updated to the current location in the string.
   3570  */
   3571 
   3572 static xmlChar *
   3573 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
   3574     xmlChar buf[XML_MAX_NAMELEN + 5];
   3575     const xmlChar *cur = *str;
   3576     int len = 0, l;
   3577     int c;
   3578 
   3579 #ifdef DEBUG
   3580     nbParseStringName++;
   3581 #endif
   3582 
   3583     c = CUR_SCHAR(cur, l);
   3584     if (!xmlIsNameStartChar(ctxt, c)) {
   3585 	return(NULL);
   3586     }
   3587 
   3588     COPY_BUF(l,buf,len,c);
   3589     cur += l;
   3590     c = CUR_SCHAR(cur, l);
   3591     while (xmlIsNameChar(ctxt, c)) {
   3592 	COPY_BUF(l,buf,len,c);
   3593 	cur += l;
   3594 	c = CUR_SCHAR(cur, l);
   3595 	if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
   3596 	    /*
   3597 	     * Okay someone managed to make a huge name, so he's ready to pay
   3598 	     * for the processing speed.
   3599 	     */
   3600 	    xmlChar *buffer;
   3601 	    int max = len * 2;
   3602 
   3603 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
   3604 	    if (buffer == NULL) {
   3605 	        xmlErrMemory(ctxt, NULL);
   3606 		return(NULL);
   3607 	    }
   3608 	    memcpy(buffer, buf, len);
   3609 	    while (xmlIsNameChar(ctxt, c)) {
   3610 		if (len + 10 > max) {
   3611 		    xmlChar *tmp;
   3612 
   3613                     if ((len > XML_MAX_NAME_LENGTH) &&
   3614                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3615                         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
   3616 			xmlFree(buffer);
   3617                         return(NULL);
   3618                     }
   3619 		    max *= 2;
   3620 		    tmp = (xmlChar *) xmlRealloc(buffer,
   3621 			                            max * sizeof(xmlChar));
   3622 		    if (tmp == NULL) {
   3623 			xmlErrMemory(ctxt, NULL);
   3624 			xmlFree(buffer);
   3625 			return(NULL);
   3626 		    }
   3627 		    buffer = tmp;
   3628 		}
   3629 		COPY_BUF(l,buffer,len,c);
   3630 		cur += l;
   3631 		c = CUR_SCHAR(cur, l);
   3632 	    }
   3633 	    buffer[len] = 0;
   3634 	    *str = cur;
   3635 	    return(buffer);
   3636 	}
   3637     }
   3638     if ((len > XML_MAX_NAME_LENGTH) &&
   3639         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3640         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
   3641         return(NULL);
   3642     }
   3643     *str = cur;
   3644     return(xmlStrndup(buf, len));
   3645 }
   3646 
   3647 /**
   3648  * xmlParseNmtoken:
   3649  * @ctxt:  an XML parser context
   3650  *
   3651  * parse an XML Nmtoken.
   3652  *
   3653  * [7] Nmtoken ::= (NameChar)+
   3654  *
   3655  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
   3656  *
   3657  * Returns the Nmtoken parsed or NULL
   3658  */
   3659 
   3660 xmlChar *
   3661 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
   3662     xmlChar buf[XML_MAX_NAMELEN + 5];
   3663     int len = 0, l;
   3664     int c;
   3665     int count = 0;
   3666 
   3667 #ifdef DEBUG
   3668     nbParseNmToken++;
   3669 #endif
   3670 
   3671     GROW;
   3672     if (ctxt->instate == XML_PARSER_EOF)
   3673         return(NULL);
   3674     c = CUR_CHAR(l);
   3675 
   3676     while (xmlIsNameChar(ctxt, c)) {
   3677 	if (count++ > XML_PARSER_CHUNK_SIZE) {
   3678 	    count = 0;
   3679 	    GROW;
   3680 	}
   3681 	COPY_BUF(l,buf,len,c);
   3682 	NEXTL(l);
   3683 	c = CUR_CHAR(l);
   3684 	if (c == 0) {
   3685 	    count = 0;
   3686 	    GROW;
   3687 	    if (ctxt->instate == XML_PARSER_EOF)
   3688 		return(NULL);
   3689             c = CUR_CHAR(l);
   3690 	}
   3691 	if (len >= XML_MAX_NAMELEN) {
   3692 	    /*
   3693 	     * Okay someone managed to make a huge token, so he's ready to pay
   3694 	     * for the processing speed.
   3695 	     */
   3696 	    xmlChar *buffer;
   3697 	    int max = len * 2;
   3698 
   3699 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
   3700 	    if (buffer == NULL) {
   3701 	        xmlErrMemory(ctxt, NULL);
   3702 		return(NULL);
   3703 	    }
   3704 	    memcpy(buffer, buf, len);
   3705 	    while (xmlIsNameChar(ctxt, c)) {
   3706 		if (count++ > XML_PARSER_CHUNK_SIZE) {
   3707 		    count = 0;
   3708 		    GROW;
   3709                     if (ctxt->instate == XML_PARSER_EOF) {
   3710                         xmlFree(buffer);
   3711                         return(NULL);
   3712                     }
   3713 		}
   3714 		if (len + 10 > max) {
   3715 		    xmlChar *tmp;
   3716 
   3717                     if ((max > XML_MAX_NAME_LENGTH) &&
   3718                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3719                         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
   3720                         xmlFree(buffer);
   3721                         return(NULL);
   3722                     }
   3723 		    max *= 2;
   3724 		    tmp = (xmlChar *) xmlRealloc(buffer,
   3725 			                            max * sizeof(xmlChar));
   3726 		    if (tmp == NULL) {
   3727 			xmlErrMemory(ctxt, NULL);
   3728 			xmlFree(buffer);
   3729 			return(NULL);
   3730 		    }
   3731 		    buffer = tmp;
   3732 		}
   3733 		COPY_BUF(l,buffer,len,c);
   3734 		NEXTL(l);
   3735 		c = CUR_CHAR(l);
   3736 	    }
   3737 	    buffer[len] = 0;
   3738 	    return(buffer);
   3739 	}
   3740     }
   3741     if (len == 0)
   3742         return(NULL);
   3743     if ((len > XML_MAX_NAME_LENGTH) &&
   3744         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3745         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
   3746         return(NULL);
   3747     }
   3748     return(xmlStrndup(buf, len));
   3749 }
   3750 
   3751 /**
   3752  * xmlParseEntityValue:
   3753  * @ctxt:  an XML parser context
   3754  * @orig:  if non-NULL store a copy of the original entity value
   3755  *
   3756  * parse a value for ENTITY declarations
   3757  *
   3758  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
   3759  *	               "'" ([^%&'] | PEReference | Reference)* "'"
   3760  *
   3761  * Returns the EntityValue parsed with reference substituted or NULL
   3762  */
   3763 
   3764 xmlChar *
   3765 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
   3766     xmlChar *buf = NULL;
   3767     int len = 0;
   3768     int size = XML_PARSER_BUFFER_SIZE;
   3769     int c, l;
   3770     xmlChar stop;
   3771     xmlChar *ret = NULL;
   3772     const xmlChar *cur = NULL;
   3773     xmlParserInputPtr input;
   3774 
   3775     if (RAW == '"') stop = '"';
   3776     else if (RAW == '\'') stop = '\'';
   3777     else {
   3778 	xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
   3779 	return(NULL);
   3780     }
   3781     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   3782     if (buf == NULL) {
   3783 	xmlErrMemory(ctxt, NULL);
   3784 	return(NULL);
   3785     }
   3786 
   3787     /*
   3788      * The content of the entity definition is copied in a buffer.
   3789      */
   3790 
   3791     ctxt->instate = XML_PARSER_ENTITY_VALUE;
   3792     input = ctxt->input;
   3793     GROW;
   3794     if (ctxt->instate == XML_PARSER_EOF) {
   3795         xmlFree(buf);
   3796         return(NULL);
   3797     }
   3798     NEXT;
   3799     c = CUR_CHAR(l);
   3800     /*
   3801      * NOTE: 4.4.5 Included in Literal
   3802      * When a parameter entity reference appears in a literal entity
   3803      * value, ... a single or double quote character in the replacement
   3804      * text is always treated as a normal data character and will not
   3805      * terminate the literal.
   3806      * In practice it means we stop the loop only when back at parsing
   3807      * the initial entity and the quote is found
   3808      */
   3809     while (((IS_CHAR(c)) && ((c != stop) || /* checked */
   3810 	    (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
   3811 	if (len + 5 >= size) {
   3812 	    xmlChar *tmp;
   3813 
   3814 	    size *= 2;
   3815 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
   3816 	    if (tmp == NULL) {
   3817 		xmlErrMemory(ctxt, NULL);
   3818 		xmlFree(buf);
   3819 		return(NULL);
   3820 	    }
   3821 	    buf = tmp;
   3822 	}
   3823 	COPY_BUF(l,buf,len,c);
   3824 	NEXTL(l);
   3825 	/*
   3826 	 * Pop-up of finished entities.
   3827 	 */
   3828 	while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
   3829 	    xmlPopInput(ctxt);
   3830 
   3831 	GROW;
   3832 	c = CUR_CHAR(l);
   3833 	if (c == 0) {
   3834 	    GROW;
   3835 	    c = CUR_CHAR(l);
   3836 	}
   3837     }
   3838     buf[len] = 0;
   3839     if (ctxt->instate == XML_PARSER_EOF) {
   3840         xmlFree(buf);
   3841         return(NULL);
   3842     }
   3843 
   3844     /*
   3845      * Raise problem w.r.t. '&' and '%' being used in non-entities
   3846      * reference constructs. Note Charref will be handled in
   3847      * xmlStringDecodeEntities()
   3848      */
   3849     cur = buf;
   3850     while (*cur != 0) { /* non input consuming */
   3851 	if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
   3852 	    xmlChar *name;
   3853 	    xmlChar tmp = *cur;
   3854 
   3855 	    cur++;
   3856 	    name = xmlParseStringName(ctxt, &cur);
   3857             if ((name == NULL) || (*cur != ';')) {
   3858 		xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
   3859 	    "EntityValue: '%c' forbidden except for entities references\n",
   3860 	                          tmp);
   3861 	    }
   3862 	    if ((tmp == '%') && (ctxt->inSubset == 1) &&
   3863 		(ctxt->inputNr == 1)) {
   3864 		xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
   3865 	    }
   3866 	    if (name != NULL)
   3867 		xmlFree(name);
   3868 	    if (*cur == 0)
   3869 	        break;
   3870 	}
   3871 	cur++;
   3872     }
   3873 
   3874     /*
   3875      * Then PEReference entities are substituted.
   3876      */
   3877     if (c != stop) {
   3878 	xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
   3879 	xmlFree(buf);
   3880     } else {
   3881 	NEXT;
   3882 	/*
   3883 	 * NOTE: 4.4.7 Bypassed
   3884 	 * When a general entity reference appears in the EntityValue in
   3885 	 * an entity declaration, it is bypassed and left as is.
   3886 	 * so XML_SUBSTITUTE_REF is not set here.
   3887 	 */
   3888 	ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
   3889 				      0, 0, 0);
   3890 	if (orig != NULL)
   3891 	    *orig = buf;
   3892 	else
   3893 	    xmlFree(buf);
   3894     }
   3895 
   3896     return(ret);
   3897 }
   3898 
   3899 /**
   3900  * xmlParseAttValueComplex:
   3901  * @ctxt:  an XML parser context
   3902  * @len:   the resulting attribute len
   3903  * @normalize:  wether to apply the inner normalization
   3904  *
   3905  * parse a value for an attribute, this is the fallback function
   3906  * of xmlParseAttValue() when the attribute parsing requires handling
   3907  * of non-ASCII characters, or normalization compaction.
   3908  *
   3909  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
   3910  */
   3911 static xmlChar *
   3912 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
   3913     xmlChar limit = 0;
   3914     xmlChar *buf = NULL;
   3915     xmlChar *rep = NULL;
   3916     size_t len = 0;
   3917     size_t buf_size = 0;
   3918     int c, l, in_space = 0;
   3919     xmlChar *current = NULL;
   3920     xmlEntityPtr ent;
   3921 
   3922     if (NXT(0) == '"') {
   3923 	ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
   3924 	limit = '"';
   3925         NEXT;
   3926     } else if (NXT(0) == '\'') {
   3927 	limit = '\'';
   3928 	ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
   3929         NEXT;
   3930     } else {
   3931 	xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
   3932 	return(NULL);
   3933     }
   3934 
   3935     /*
   3936      * allocate a translation buffer.
   3937      */
   3938     buf_size = XML_PARSER_BUFFER_SIZE;
   3939     buf = (xmlChar *) xmlMallocAtomic(buf_size);
   3940     if (buf == NULL) goto mem_error;
   3941 
   3942     /*
   3943      * OK loop until we reach one of the ending char or a size limit.
   3944      */
   3945     c = CUR_CHAR(l);
   3946     while (((NXT(0) != limit) && /* checked */
   3947             (IS_CHAR(c)) && (c != '<')) &&
   3948             (ctxt->instate != XML_PARSER_EOF)) {
   3949         /*
   3950          * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
   3951          * special option is given
   3952          */
   3953         if ((len > XML_MAX_TEXT_LENGTH) &&
   3954             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   3955             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   3956                            "AttValue length too long\n");
   3957             goto mem_error;
   3958         }
   3959 	if (c == 0) break;
   3960 	if (c == '&') {
   3961 	    in_space = 0;
   3962 	    if (NXT(1) == '#') {
   3963 		int val = xmlParseCharRef(ctxt);
   3964 
   3965 		if (val == '&') {
   3966 		    if (ctxt->replaceEntities) {
   3967 			if (len + 10 > buf_size) {
   3968 			    growBuffer(buf, 10);
   3969 			}
   3970 			buf[len++] = '&';
   3971 		    } else {
   3972 			/*
   3973 			 * The reparsing will be done in xmlStringGetNodeList()
   3974 			 * called by the attribute() function in SAX.c
   3975 			 */
   3976 			if (len + 10 > buf_size) {
   3977 			    growBuffer(buf, 10);
   3978 			}
   3979 			buf[len++] = '&';
   3980 			buf[len++] = '#';
   3981 			buf[len++] = '3';
   3982 			buf[len++] = '8';
   3983 			buf[len++] = ';';
   3984 		    }
   3985 		} else if (val != 0) {
   3986 		    if (len + 10 > buf_size) {
   3987 			growBuffer(buf, 10);
   3988 		    }
   3989 		    len += xmlCopyChar(0, &buf[len], val);
   3990 		}
   3991 	    } else {
   3992 		ent = xmlParseEntityRef(ctxt);
   3993 		ctxt->nbentities++;
   3994 		if (ent != NULL)
   3995 		    ctxt->nbentities += ent->owner;
   3996 		if ((ent != NULL) &&
   3997 		    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
   3998 		    if (len + 10 > buf_size) {
   3999 			growBuffer(buf, 10);
   4000 		    }
   4001 		    if ((ctxt->replaceEntities == 0) &&
   4002 		        (ent->content[0] == '&')) {
   4003 			buf[len++] = '&';
   4004 			buf[len++] = '#';
   4005 			buf[len++] = '3';
   4006 			buf[len++] = '8';
   4007 			buf[len++] = ';';
   4008 		    } else {
   4009 			buf[len++] = ent->content[0];
   4010 		    }
   4011 		} else if ((ent != NULL) &&
   4012 		           (ctxt->replaceEntities != 0)) {
   4013 		    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
   4014 			rep = xmlStringDecodeEntities(ctxt, ent->content,
   4015 						      XML_SUBSTITUTE_REF,
   4016 						      0, 0, 0);
   4017 			if (rep != NULL) {
   4018 			    current = rep;
   4019 			    while (*current != 0) { /* non input consuming */
   4020                                 if ((*current == 0xD) || (*current == 0xA) ||
   4021                                     (*current == 0x9)) {
   4022                                     buf[len++] = 0x20;
   4023                                     current++;
   4024                                 } else
   4025                                     buf[len++] = *current++;
   4026 				if (len + 10 > buf_size) {
   4027 				    growBuffer(buf, 10);
   4028 				}
   4029 			    }
   4030 			    xmlFree(rep);
   4031 			    rep = NULL;
   4032 			}
   4033 		    } else {
   4034 			if (len + 10 > buf_size) {
   4035 			    growBuffer(buf, 10);
   4036 			}
   4037 			if (ent->content != NULL)
   4038 			    buf[len++] = ent->content[0];
   4039 		    }
   4040 		} else if (ent != NULL) {
   4041 		    int i = xmlStrlen(ent->name);
   4042 		    const xmlChar *cur = ent->name;
   4043 
   4044 		    /*
   4045 		     * This may look absurd but is needed to detect
   4046 		     * entities problems
   4047 		     */
   4048 		    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
   4049 			(ent->content != NULL) && (ent->checked == 0)) {
   4050 			unsigned long oldnbent = ctxt->nbentities;
   4051 
   4052 			rep = xmlStringDecodeEntities(ctxt, ent->content,
   4053 						  XML_SUBSTITUTE_REF, 0, 0, 0);
   4054 
   4055 			ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
   4056 			if (rep != NULL) {
   4057 			    if (xmlStrchr(rep, '<'))
   4058 			        ent->checked |= 1;
   4059 			    xmlFree(rep);
   4060 			    rep = NULL;
   4061 			}
   4062 		    }
   4063 
   4064 		    /*
   4065 		     * Just output the reference
   4066 		     */
   4067 		    buf[len++] = '&';
   4068 		    while (len + i + 10 > buf_size) {
   4069 			growBuffer(buf, i + 10);
   4070 		    }
   4071 		    for (;i > 0;i--)
   4072 			buf[len++] = *cur++;
   4073 		    buf[len++] = ';';
   4074 		}
   4075 	    }
   4076 	} else {
   4077 	    if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
   4078 	        if ((len != 0) || (!normalize)) {
   4079 		    if ((!normalize) || (!in_space)) {
   4080 			COPY_BUF(l,buf,len,0x20);
   4081 			while (len + 10 > buf_size) {
   4082 			    growBuffer(buf, 10);
   4083 			}
   4084 		    }
   4085 		    in_space = 1;
   4086 		}
   4087 	    } else {
   4088 	        in_space = 0;
   4089 		COPY_BUF(l,buf,len,c);
   4090 		if (len + 10 > buf_size) {
   4091 		    growBuffer(buf, 10);
   4092 		}
   4093 	    }
   4094 	    NEXTL(l);
   4095 	}
   4096 	GROW;
   4097 	c = CUR_CHAR(l);
   4098     }
   4099     if (ctxt->instate == XML_PARSER_EOF)
   4100         goto error;
   4101 
   4102     if ((in_space) && (normalize)) {
   4103         while ((len > 0) && (buf[len - 1] == 0x20)) len--;
   4104     }
   4105     buf[len] = 0;
   4106     if (RAW == '<') {
   4107 	xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
   4108     } else if (RAW != limit) {
   4109 	if ((c != 0) && (!IS_CHAR(c))) {
   4110 	    xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
   4111 			   "invalid character in attribute value\n");
   4112 	} else {
   4113 	    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   4114 			   "AttValue: ' expected\n");
   4115         }
   4116     } else
   4117 	NEXT;
   4118 
   4119     /*
   4120      * There we potentially risk an overflow, don't allow attribute value of
   4121      * length more than INT_MAX it is a very reasonnable assumption !
   4122      */
   4123     if (len >= INT_MAX) {
   4124         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   4125                        "AttValue length too long\n");
   4126         goto mem_error;
   4127     }
   4128 
   4129     if (attlen != NULL) *attlen = (int) len;
   4130     return(buf);
   4131 
   4132 mem_error:
   4133     xmlErrMemory(ctxt, NULL);
   4134 error:
   4135     if (buf != NULL)
   4136         xmlFree(buf);
   4137     if (rep != NULL)
   4138         xmlFree(rep);
   4139     return(NULL);
   4140 }
   4141 
   4142 /**
   4143  * xmlParseAttValue:
   4144  * @ctxt:  an XML parser context
   4145  *
   4146  * parse a value for an attribute
   4147  * Note: the parser won't do substitution of entities here, this
   4148  * will be handled later in xmlStringGetNodeList
   4149  *
   4150  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
   4151  *                   "'" ([^<&'] | Reference)* "'"
   4152  *
   4153  * 3.3.3 Attribute-Value Normalization:
   4154  * Before the value of an attribute is passed to the application or
   4155  * checked for validity, the XML processor must normalize it as follows:
   4156  * - a character reference is processed by appending the referenced
   4157  *   character to the attribute value
   4158  * - an entity reference is processed by recursively processing the
   4159  *   replacement text of the entity
   4160  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
   4161  *   appending #x20 to the normalized value, except that only a single
   4162  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
   4163  *   parsed entity or the literal entity value of an internal parsed entity
   4164  * - other characters are processed by appending them to the normalized value
   4165  * If the declared value is not CDATA, then the XML processor must further
   4166  * process the normalized attribute value by discarding any leading and
   4167  * trailing space (#x20) characters, and by replacing sequences of space
   4168  * (#x20) characters by a single space (#x20) character.
   4169  * All attributes for which no declaration has been read should be treated
   4170  * by a non-validating parser as if declared CDATA.
   4171  *
   4172  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
   4173  */
   4174 
   4175 
   4176 xmlChar *
   4177 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
   4178     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
   4179     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
   4180 }
   4181 
   4182 /**
   4183  * xmlParseSystemLiteral:
   4184  * @ctxt:  an XML parser context
   4185  *
   4186  * parse an XML Literal
   4187  *
   4188  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
   4189  *
   4190  * Returns the SystemLiteral parsed or NULL
   4191  */
   4192 
   4193 xmlChar *
   4194 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
   4195     xmlChar *buf = NULL;
   4196     int len = 0;
   4197     int size = XML_PARSER_BUFFER_SIZE;
   4198     int cur, l;
   4199     xmlChar stop;
   4200     int state = ctxt->instate;
   4201     int count = 0;
   4202 
   4203     SHRINK;
   4204     if (RAW == '"') {
   4205         NEXT;
   4206 	stop = '"';
   4207     } else if (RAW == '\'') {
   4208         NEXT;
   4209 	stop = '\'';
   4210     } else {
   4211 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
   4212 	return(NULL);
   4213     }
   4214 
   4215     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   4216     if (buf == NULL) {
   4217         xmlErrMemory(ctxt, NULL);
   4218 	return(NULL);
   4219     }
   4220     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
   4221     cur = CUR_CHAR(l);
   4222     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
   4223 	if (len + 5 >= size) {
   4224 	    xmlChar *tmp;
   4225 
   4226             if ((size > XML_MAX_NAME_LENGTH) &&
   4227                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   4228                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
   4229                 xmlFree(buf);
   4230 		ctxt->instate = (xmlParserInputState) state;
   4231                 return(NULL);
   4232             }
   4233 	    size *= 2;
   4234 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
   4235 	    if (tmp == NULL) {
   4236 	        xmlFree(buf);
   4237 		xmlErrMemory(ctxt, NULL);
   4238 		ctxt->instate = (xmlParserInputState) state;
   4239 		return(NULL);
   4240 	    }
   4241 	    buf = tmp;
   4242 	}
   4243 	count++;
   4244 	if (count > 50) {
   4245 	    GROW;
   4246 	    count = 0;
   4247             if (ctxt->instate == XML_PARSER_EOF) {
   4248 	        xmlFree(buf);
   4249 		return(NULL);
   4250             }
   4251 	}
   4252 	COPY_BUF(l,buf,len,cur);
   4253 	NEXTL(l);
   4254 	cur = CUR_CHAR(l);
   4255 	if (cur == 0) {
   4256 	    GROW;
   4257 	    SHRINK;
   4258 	    cur = CUR_CHAR(l);
   4259 	}
   4260     }
   4261     buf[len] = 0;
   4262     ctxt->instate = (xmlParserInputState) state;
   4263     if (!IS_CHAR(cur)) {
   4264 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
   4265     } else {
   4266 	NEXT;
   4267     }
   4268     return(buf);
   4269 }
   4270 
   4271 /**
   4272  * xmlParsePubidLiteral:
   4273  * @ctxt:  an XML parser context
   4274  *
   4275  * parse an XML public literal
   4276  *
   4277  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
   4278  *
   4279  * Returns the PubidLiteral parsed or NULL.
   4280  */
   4281 
   4282 xmlChar *
   4283 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
   4284     xmlChar *buf = NULL;
   4285     int len = 0;
   4286     int size = XML_PARSER_BUFFER_SIZE;
   4287     xmlChar cur;
   4288     xmlChar stop;
   4289     int count = 0;
   4290     xmlParserInputState oldstate = ctxt->instate;
   4291 
   4292     SHRINK;
   4293     if (RAW == '"') {
   4294         NEXT;
   4295 	stop = '"';
   4296     } else if (RAW == '\'') {
   4297         NEXT;
   4298 	stop = '\'';
   4299     } else {
   4300 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
   4301 	return(NULL);
   4302     }
   4303     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   4304     if (buf == NULL) {
   4305 	xmlErrMemory(ctxt, NULL);
   4306 	return(NULL);
   4307     }
   4308     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
   4309     cur = CUR;
   4310     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
   4311 	if (len + 1 >= size) {
   4312 	    xmlChar *tmp;
   4313 
   4314             if ((size > XML_MAX_NAME_LENGTH) &&
   4315                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   4316                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
   4317                 xmlFree(buf);
   4318                 return(NULL);
   4319             }
   4320 	    size *= 2;
   4321 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
   4322 	    if (tmp == NULL) {
   4323 		xmlErrMemory(ctxt, NULL);
   4324 		xmlFree(buf);
   4325 		return(NULL);
   4326 	    }
   4327 	    buf = tmp;
   4328 	}
   4329 	buf[len++] = cur;
   4330 	count++;
   4331 	if (count > 50) {
   4332 	    GROW;
   4333 	    count = 0;
   4334             if (ctxt->instate == XML_PARSER_EOF) {
   4335 		xmlFree(buf);
   4336 		return(NULL);
   4337             }
   4338 	}
   4339 	NEXT;
   4340 	cur = CUR;
   4341 	if (cur == 0) {
   4342 	    GROW;
   4343 	    SHRINK;
   4344 	    cur = CUR;
   4345 	}
   4346     }
   4347     buf[len] = 0;
   4348     if (cur != stop) {
   4349 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
   4350     } else {
   4351 	NEXT;
   4352     }
   4353     ctxt->instate = oldstate;
   4354     return(buf);
   4355 }
   4356 
   4357 static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
   4358 
   4359 /*
   4360  * used for the test in the inner loop of the char data testing
   4361  */
   4362 static const unsigned char test_char_data[256] = {
   4363     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4364     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
   4365     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4366     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4367     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
   4368     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
   4369     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
   4370     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
   4371     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
   4372     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
   4373     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
   4374     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
   4375     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   4376     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
   4377     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   4378     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
   4379     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
   4380     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4381     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4382     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4383     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4384     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4385     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4386     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4387     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4388     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4389     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4390     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4391     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4392     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4393     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   4394     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   4395 };
   4396 
   4397 /**
   4398  * xmlParseCharData:
   4399  * @ctxt:  an XML parser context
   4400  * @cdata:  int indicating whether we are within a CDATA section
   4401  *
   4402  * parse a CharData section.
   4403  * if we are within a CDATA section ']]>' marks an end of section.
   4404  *
   4405  * The right angle bracket (>) may be represented using the string "&gt;",
   4406  * and must, for compatibility, be escaped using "&gt;" or a character
   4407  * reference when it appears in the string "]]>" in content, when that
   4408  * string is not marking the end of a CDATA section.
   4409  *
   4410  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
   4411  */
   4412 
   4413 void
   4414 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
   4415     const xmlChar *in;
   4416     int nbchar = 0;
   4417     int line = ctxt->input->line;
   4418     int col = ctxt->input->col;
   4419     int ccol;
   4420 
   4421     SHRINK;
   4422     GROW;
   4423     /*
   4424      * Accelerated common case where input don't need to be
   4425      * modified before passing it to the handler.
   4426      */
   4427     if (!cdata) {
   4428 	in = ctxt->input->cur;
   4429 	do {
   4430 get_more_space:
   4431 	    while (*in == 0x20) { in++; ctxt->input->col++; }
   4432 	    if (*in == 0xA) {
   4433 		do {
   4434 		    ctxt->input->line++; ctxt->input->col = 1;
   4435 		    in++;
   4436 		} while (*in == 0xA);
   4437 		goto get_more_space;
   4438 	    }
   4439 	    if (*in == '<') {
   4440 		nbchar = in - ctxt->input->cur;
   4441 		if (nbchar > 0) {
   4442 		    const xmlChar *tmp = ctxt->input->cur;
   4443 		    ctxt->input->cur = in;
   4444 
   4445 		    if ((ctxt->sax != NULL) &&
   4446 		        (ctxt->sax->ignorableWhitespace !=
   4447 		         ctxt->sax->characters)) {
   4448 			if (areBlanks(ctxt, tmp, nbchar, 1)) {
   4449 			    if (ctxt->sax->ignorableWhitespace != NULL)
   4450 				ctxt->sax->ignorableWhitespace(ctxt->userData,
   4451 						       tmp, nbchar);
   4452 			} else {
   4453 			    if (ctxt->sax->characters != NULL)
   4454 				ctxt->sax->characters(ctxt->userData,
   4455 						      tmp, nbchar);
   4456 			    if (*ctxt->space == -1)
   4457 			        *ctxt->space = -2;
   4458 			}
   4459 		    } else if ((ctxt->sax != NULL) &&
   4460 		               (ctxt->sax->characters != NULL)) {
   4461 			ctxt->sax->characters(ctxt->userData,
   4462 					      tmp, nbchar);
   4463 		    }
   4464 		}
   4465 		return;
   4466 	    }
   4467 
   4468 get_more:
   4469             ccol = ctxt->input->col;
   4470 	    while (test_char_data[*in]) {
   4471 		in++;
   4472 		ccol++;
   4473 	    }
   4474 	    ctxt->input->col = ccol;
   4475 	    if (*in == 0xA) {
   4476 		do {
   4477 		    ctxt->input->line++; ctxt->input->col = 1;
   4478 		    in++;
   4479 		} while (*in == 0xA);
   4480 		goto get_more;
   4481 	    }
   4482 	    if (*in == ']') {
   4483 		if ((in[1] == ']') && (in[2] == '>')) {
   4484 		    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
   4485 		    ctxt->input->cur = in;
   4486 		    return;
   4487 		}
   4488 		in++;
   4489 		ctxt->input->col++;
   4490 		goto get_more;
   4491 	    }
   4492 	    nbchar = in - ctxt->input->cur;
   4493 	    if (nbchar > 0) {
   4494 		if ((ctxt->sax != NULL) &&
   4495 		    (ctxt->sax->ignorableWhitespace !=
   4496 		     ctxt->sax->characters) &&
   4497 		    (IS_BLANK_CH(*ctxt->input->cur))) {
   4498 		    const xmlChar *tmp = ctxt->input->cur;
   4499 		    ctxt->input->cur = in;
   4500 
   4501 		    if (areBlanks(ctxt, tmp, nbchar, 0)) {
   4502 		        if (ctxt->sax->ignorableWhitespace != NULL)
   4503 			    ctxt->sax->ignorableWhitespace(ctxt->userData,
   4504 							   tmp, nbchar);
   4505 		    } else {
   4506 		        if (ctxt->sax->characters != NULL)
   4507 			    ctxt->sax->characters(ctxt->userData,
   4508 						  tmp, nbchar);
   4509 			if (*ctxt->space == -1)
   4510 			    *ctxt->space = -2;
   4511 		    }
   4512                     line = ctxt->input->line;
   4513                     col = ctxt->input->col;
   4514 		} else if (ctxt->sax != NULL) {
   4515 		    if (ctxt->sax->characters != NULL)
   4516 			ctxt->sax->characters(ctxt->userData,
   4517 					      ctxt->input->cur, nbchar);
   4518                     line = ctxt->input->line;
   4519                     col = ctxt->input->col;
   4520 		}
   4521                 /* something really bad happened in the SAX callback */
   4522                 if (ctxt->instate != XML_PARSER_CONTENT)
   4523                     return;
   4524 	    }
   4525 	    ctxt->input->cur = in;
   4526 	    if (*in == 0xD) {
   4527 		in++;
   4528 		if (*in == 0xA) {
   4529 		    ctxt->input->cur = in;
   4530 		    in++;
   4531 		    ctxt->input->line++; ctxt->input->col = 1;
   4532 		    continue; /* while */
   4533 		}
   4534 		in--;
   4535 	    }
   4536 	    if (*in == '<') {
   4537 		return;
   4538 	    }
   4539 	    if (*in == '&') {
   4540 		return;
   4541 	    }
   4542 	    SHRINK;
   4543 	    GROW;
   4544             if (ctxt->instate == XML_PARSER_EOF)
   4545 		return;
   4546 	    in = ctxt->input->cur;
   4547 	} while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
   4548 	nbchar = 0;
   4549     }
   4550     ctxt->input->line = line;
   4551     ctxt->input->col = col;
   4552     xmlParseCharDataComplex(ctxt, cdata);
   4553 }
   4554 
   4555 /**
   4556  * xmlParseCharDataComplex:
   4557  * @ctxt:  an XML parser context
   4558  * @cdata:  int indicating whether we are within a CDATA section
   4559  *
   4560  * parse a CharData section.this is the fallback function
   4561  * of xmlParseCharData() when the parsing requires handling
   4562  * of non-ASCII characters.
   4563  */
   4564 static void
   4565 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
   4566     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
   4567     int nbchar = 0;
   4568     int cur, l;
   4569     int count = 0;
   4570 
   4571     SHRINK;
   4572     GROW;
   4573     cur = CUR_CHAR(l);
   4574     while ((cur != '<') && /* checked */
   4575            (cur != '&') &&
   4576 	   (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
   4577 	if ((cur == ']') && (NXT(1) == ']') &&
   4578 	    (NXT(2) == '>')) {
   4579 	    if (cdata) break;
   4580 	    else {
   4581 		xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
   4582 	    }
   4583 	}
   4584 	COPY_BUF(l,buf,nbchar,cur);
   4585 	if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
   4586 	    buf[nbchar] = 0;
   4587 
   4588 	    /*
   4589 	     * OK the segment is to be consumed as chars.
   4590 	     */
   4591 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
   4592 		if (areBlanks(ctxt, buf, nbchar, 0)) {
   4593 		    if (ctxt->sax->ignorableWhitespace != NULL)
   4594 			ctxt->sax->ignorableWhitespace(ctxt->userData,
   4595 			                               buf, nbchar);
   4596 		} else {
   4597 		    if (ctxt->sax->characters != NULL)
   4598 			ctxt->sax->characters(ctxt->userData, buf, nbchar);
   4599 		    if ((ctxt->sax->characters !=
   4600 		         ctxt->sax->ignorableWhitespace) &&
   4601 			(*ctxt->space == -1))
   4602 			*ctxt->space = -2;
   4603 		}
   4604 	    }
   4605 	    nbchar = 0;
   4606             /* something really bad happened in the SAX callback */
   4607             if (ctxt->instate != XML_PARSER_CONTENT)
   4608                 return;
   4609 	}
   4610 	count++;
   4611 	if (count > 50) {
   4612 	    GROW;
   4613 	    count = 0;
   4614             if (ctxt->instate == XML_PARSER_EOF)
   4615 		return;
   4616 	}
   4617 	NEXTL(l);
   4618 	cur = CUR_CHAR(l);
   4619     }
   4620     if (nbchar != 0) {
   4621         buf[nbchar] = 0;
   4622 	/*
   4623 	 * OK the segment is to be consumed as chars.
   4624 	 */
   4625 	if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
   4626 	    if (areBlanks(ctxt, buf, nbchar, 0)) {
   4627 		if (ctxt->sax->ignorableWhitespace != NULL)
   4628 		    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
   4629 	    } else {
   4630 		if (ctxt->sax->characters != NULL)
   4631 		    ctxt->sax->characters(ctxt->userData, buf, nbchar);
   4632 		if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
   4633 		    (*ctxt->space == -1))
   4634 		    *ctxt->space = -2;
   4635 	    }
   4636 	}
   4637     }
   4638     if ((cur != 0) && (!IS_CHAR(cur))) {
   4639 	/* Generate the error and skip the offending character */
   4640         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   4641                           "PCDATA invalid Char value %d\n",
   4642 	                  cur);
   4643 	NEXTL(l);
   4644     }
   4645 }
   4646 
   4647 /**
   4648  * xmlParseExternalID:
   4649  * @ctxt:  an XML parser context
   4650  * @publicID:  a xmlChar** receiving PubidLiteral
   4651  * @strict: indicate whether we should restrict parsing to only
   4652  *          production [75], see NOTE below
   4653  *
   4654  * Parse an External ID or a Public ID
   4655  *
   4656  * NOTE: Productions [75] and [83] interact badly since [75] can generate
   4657  *       'PUBLIC' S PubidLiteral S SystemLiteral
   4658  *
   4659  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
   4660  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
   4661  *
   4662  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
   4663  *
   4664  * Returns the function returns SystemLiteral and in the second
   4665  *                case publicID receives PubidLiteral, is strict is off
   4666  *                it is possible to return NULL and have publicID set.
   4667  */
   4668 
   4669 xmlChar *
   4670 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
   4671     xmlChar *URI = NULL;
   4672 
   4673     SHRINK;
   4674 
   4675     *publicID = NULL;
   4676     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
   4677         SKIP(6);
   4678 	if (!IS_BLANK_CH(CUR)) {
   4679 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   4680 	                   "Space required after 'SYSTEM'\n");
   4681 	}
   4682         SKIP_BLANKS;
   4683 	URI = xmlParseSystemLiteral(ctxt);
   4684 	if (URI == NULL) {
   4685 	    xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
   4686         }
   4687     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
   4688         SKIP(6);
   4689 	if (!IS_BLANK_CH(CUR)) {
   4690 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   4691 		    "Space required after 'PUBLIC'\n");
   4692 	}
   4693         SKIP_BLANKS;
   4694 	*publicID = xmlParsePubidLiteral(ctxt);
   4695 	if (*publicID == NULL) {
   4696 	    xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
   4697 	}
   4698 	if (strict) {
   4699 	    /*
   4700 	     * We don't handle [83] so "S SystemLiteral" is required.
   4701 	     */
   4702 	    if (!IS_BLANK_CH(CUR)) {
   4703 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   4704 			"Space required after the Public Identifier\n");
   4705 	    }
   4706 	} else {
   4707 	    /*
   4708 	     * We handle [83] so we return immediately, if
   4709 	     * "S SystemLiteral" is not detected. From a purely parsing
   4710 	     * point of view that's a nice mess.
   4711 	     */
   4712 	    const xmlChar *ptr;
   4713 	    GROW;
   4714 
   4715 	    ptr = CUR_PTR;
   4716 	    if (!IS_BLANK_CH(*ptr)) return(NULL);
   4717 
   4718 	    while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
   4719 	    if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
   4720 	}
   4721         SKIP_BLANKS;
   4722 	URI = xmlParseSystemLiteral(ctxt);
   4723 	if (URI == NULL) {
   4724 	    xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
   4725         }
   4726     }
   4727     return(URI);
   4728 }
   4729 
   4730 /**
   4731  * xmlParseCommentComplex:
   4732  * @ctxt:  an XML parser context
   4733  * @buf:  the already parsed part of the buffer
   4734  * @len:  number of bytes filles in the buffer
   4735  * @size:  allocated size of the buffer
   4736  *
   4737  * Skip an XML (SGML) comment <!-- .... -->
   4738  *  The spec says that "For compatibility, the string "--" (double-hyphen)
   4739  *  must not occur within comments. "
   4740  * This is the slow routine in case the accelerator for ascii didn't work
   4741  *
   4742  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
   4743  */
   4744 static void
   4745 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
   4746                        size_t len, size_t size) {
   4747     int q, ql;
   4748     int r, rl;
   4749     int cur, l;
   4750     size_t count = 0;
   4751     int inputid;
   4752 
   4753     inputid = ctxt->input->id;
   4754 
   4755     if (buf == NULL) {
   4756         len = 0;
   4757 	size = XML_PARSER_BUFFER_SIZE;
   4758 	buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   4759 	if (buf == NULL) {
   4760 	    xmlErrMemory(ctxt, NULL);
   4761 	    return;
   4762 	}
   4763     }
   4764     GROW;	/* Assure there's enough input data */
   4765     q = CUR_CHAR(ql);
   4766     if (q == 0)
   4767         goto not_terminated;
   4768     if (!IS_CHAR(q)) {
   4769         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   4770                           "xmlParseComment: invalid xmlChar value %d\n",
   4771 	                  q);
   4772 	xmlFree (buf);
   4773 	return;
   4774     }
   4775     NEXTL(ql);
   4776     r = CUR_CHAR(rl);
   4777     if (r == 0)
   4778         goto not_terminated;
   4779     if (!IS_CHAR(r)) {
   4780         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   4781                           "xmlParseComment: invalid xmlChar value %d\n",
   4782 	                  q);
   4783 	xmlFree (buf);
   4784 	return;
   4785     }
   4786     NEXTL(rl);
   4787     cur = CUR_CHAR(l);
   4788     if (cur == 0)
   4789         goto not_terminated;
   4790     while (IS_CHAR(cur) && /* checked */
   4791            ((cur != '>') ||
   4792 	    (r != '-') || (q != '-'))) {
   4793 	if ((r == '-') && (q == '-')) {
   4794 	    xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
   4795 	}
   4796         if ((len > XML_MAX_TEXT_LENGTH) &&
   4797             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   4798             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
   4799                          "Comment too big found", NULL);
   4800             xmlFree (buf);
   4801             return;
   4802         }
   4803 	if (len + 5 >= size) {
   4804 	    xmlChar *new_buf;
   4805             size_t new_size;
   4806 
   4807 	    new_size = size * 2;
   4808 	    new_buf = (xmlChar *) xmlRealloc(buf, new_size);
   4809 	    if (new_buf == NULL) {
   4810 		xmlFree (buf);
   4811 		xmlErrMemory(ctxt, NULL);
   4812 		return;
   4813 	    }
   4814 	    buf = new_buf;
   4815             size = new_size;
   4816 	}
   4817 	COPY_BUF(ql,buf,len,q);
   4818 	q = r;
   4819 	ql = rl;
   4820 	r = cur;
   4821 	rl = l;
   4822 
   4823 	count++;
   4824 	if (count > 50) {
   4825 	    GROW;
   4826 	    count = 0;
   4827             if (ctxt->instate == XML_PARSER_EOF) {
   4828 		xmlFree(buf);
   4829 		return;
   4830             }
   4831 	}
   4832 	NEXTL(l);
   4833 	cur = CUR_CHAR(l);
   4834 	if (cur == 0) {
   4835 	    SHRINK;
   4836 	    GROW;
   4837 	    cur = CUR_CHAR(l);
   4838 	}
   4839     }
   4840     buf[len] = 0;
   4841     if (cur == 0) {
   4842 	xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
   4843 	                     "Comment not terminated \n<!--%.50s\n", buf);
   4844     } else if (!IS_CHAR(cur)) {
   4845         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   4846                           "xmlParseComment: invalid xmlChar value %d\n",
   4847 	                  cur);
   4848     } else {
   4849 	if (inputid != ctxt->input->id) {
   4850 	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
   4851 		"Comment doesn't start and stop in the same entity\n");
   4852 	}
   4853         NEXT;
   4854 	if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
   4855 	    (!ctxt->disableSAX))
   4856 	    ctxt->sax->comment(ctxt->userData, buf);
   4857     }
   4858     xmlFree(buf);
   4859     return;
   4860 not_terminated:
   4861     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
   4862 			 "Comment not terminated\n", NULL);
   4863     xmlFree(buf);
   4864     return;
   4865 }
   4866 
   4867 /**
   4868  * xmlParseComment:
   4869  * @ctxt:  an XML parser context
   4870  *
   4871  * Skip an XML (SGML) comment <!-- .... -->
   4872  *  The spec says that "For compatibility, the string "--" (double-hyphen)
   4873  *  must not occur within comments. "
   4874  *
   4875  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
   4876  */
   4877 void
   4878 xmlParseComment(xmlParserCtxtPtr ctxt) {
   4879     xmlChar *buf = NULL;
   4880     size_t size = XML_PARSER_BUFFER_SIZE;
   4881     size_t len = 0;
   4882     xmlParserInputState state;
   4883     const xmlChar *in;
   4884     size_t nbchar = 0;
   4885     int ccol;
   4886     int inputid;
   4887 
   4888     /*
   4889      * Check that there is a comment right here.
   4890      */
   4891     if ((RAW != '<') || (NXT(1) != '!') ||
   4892         (NXT(2) != '-') || (NXT(3) != '-')) return;
   4893     state = ctxt->instate;
   4894     ctxt->instate = XML_PARSER_COMMENT;
   4895     inputid = ctxt->input->id;
   4896     SKIP(4);
   4897     SHRINK;
   4898     GROW;
   4899 
   4900     /*
   4901      * Accelerated common case where input don't need to be
   4902      * modified before passing it to the handler.
   4903      */
   4904     in = ctxt->input->cur;
   4905     do {
   4906 	if (*in == 0xA) {
   4907 	    do {
   4908 		ctxt->input->line++; ctxt->input->col = 1;
   4909 		in++;
   4910 	    } while (*in == 0xA);
   4911 	}
   4912 get_more:
   4913         ccol = ctxt->input->col;
   4914 	while (((*in > '-') && (*in <= 0x7F)) ||
   4915 	       ((*in >= 0x20) && (*in < '-')) ||
   4916 	       (*in == 0x09)) {
   4917 		    in++;
   4918 		    ccol++;
   4919 	}
   4920 	ctxt->input->col = ccol;
   4921 	if (*in == 0xA) {
   4922 	    do {
   4923 		ctxt->input->line++; ctxt->input->col = 1;
   4924 		in++;
   4925 	    } while (*in == 0xA);
   4926 	    goto get_more;
   4927 	}
   4928 	nbchar = in - ctxt->input->cur;
   4929 	/*
   4930 	 * save current set of data
   4931 	 */
   4932 	if (nbchar > 0) {
   4933 	    if ((ctxt->sax != NULL) &&
   4934 		(ctxt->sax->comment != NULL)) {
   4935 		if (buf == NULL) {
   4936 		    if ((*in == '-') && (in[1] == '-'))
   4937 		        size = nbchar + 1;
   4938 		    else
   4939 		        size = XML_PARSER_BUFFER_SIZE + nbchar;
   4940 		    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   4941 		    if (buf == NULL) {
   4942 		        xmlErrMemory(ctxt, NULL);
   4943 			ctxt->instate = state;
   4944 			return;
   4945 		    }
   4946 		    len = 0;
   4947 		} else if (len + nbchar + 1 >= size) {
   4948 		    xmlChar *new_buf;
   4949 		    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
   4950 		    new_buf = (xmlChar *) xmlRealloc(buf,
   4951 		                                     size * sizeof(xmlChar));
   4952 		    if (new_buf == NULL) {
   4953 		        xmlFree (buf);
   4954 			xmlErrMemory(ctxt, NULL);
   4955 			ctxt->instate = state;
   4956 			return;
   4957 		    }
   4958 		    buf = new_buf;
   4959 		}
   4960 		memcpy(&buf[len], ctxt->input->cur, nbchar);
   4961 		len += nbchar;
   4962 		buf[len] = 0;
   4963 	    }
   4964 	}
   4965         if ((len > XML_MAX_TEXT_LENGTH) &&
   4966             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   4967             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
   4968                          "Comment too big found", NULL);
   4969             xmlFree (buf);
   4970             return;
   4971         }
   4972 	ctxt->input->cur = in;
   4973 	if (*in == 0xA) {
   4974 	    in++;
   4975 	    ctxt->input->line++; ctxt->input->col = 1;
   4976 	}
   4977 	if (*in == 0xD) {
   4978 	    in++;
   4979 	    if (*in == 0xA) {
   4980 		ctxt->input->cur = in;
   4981 		in++;
   4982 		ctxt->input->line++; ctxt->input->col = 1;
   4983 		continue; /* while */
   4984 	    }
   4985 	    in--;
   4986 	}
   4987 	SHRINK;
   4988 	GROW;
   4989         if (ctxt->instate == XML_PARSER_EOF) {
   4990             xmlFree(buf);
   4991             return;
   4992         }
   4993 	in = ctxt->input->cur;
   4994 	if (*in == '-') {
   4995 	    if (in[1] == '-') {
   4996 	        if (in[2] == '>') {
   4997 		    if (ctxt->input->id != inputid) {
   4998 			xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
   4999 			"comment doesn't start and stop in the same entity\n");
   5000 		    }
   5001 		    SKIP(3);
   5002 		    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
   5003 		        (!ctxt->disableSAX)) {
   5004 			if (buf != NULL)
   5005 			    ctxt->sax->comment(ctxt->userData, buf);
   5006 			else
   5007 			    ctxt->sax->comment(ctxt->userData, BAD_CAST "");
   5008 		    }
   5009 		    if (buf != NULL)
   5010 		        xmlFree(buf);
   5011 		    if (ctxt->instate != XML_PARSER_EOF)
   5012 			ctxt->instate = state;
   5013 		    return;
   5014 		}
   5015 		if (buf != NULL) {
   5016 		    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
   5017 		                      "Double hyphen within comment: "
   5018                                       "<!--%.50s\n",
   5019 				      buf);
   5020 		} else
   5021 		    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
   5022 		                      "Double hyphen within comment\n", NULL);
   5023 		in++;
   5024 		ctxt->input->col++;
   5025 	    }
   5026 	    in++;
   5027 	    ctxt->input->col++;
   5028 	    goto get_more;
   5029 	}
   5030     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
   5031     xmlParseCommentComplex(ctxt, buf, len, size);
   5032     ctxt->instate = state;
   5033     return;
   5034 }
   5035 
   5036 
   5037 /**
   5038  * xmlParsePITarget:
   5039  * @ctxt:  an XML parser context
   5040  *
   5041  * parse the name of a PI
   5042  *
   5043  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
   5044  *
   5045  * Returns the PITarget name or NULL
   5046  */
   5047 
   5048 const xmlChar *
   5049 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
   5050     const xmlChar *name;
   5051 
   5052     name = xmlParseName(ctxt);
   5053     if ((name != NULL) &&
   5054         ((name[0] == 'x') || (name[0] == 'X')) &&
   5055         ((name[1] == 'm') || (name[1] == 'M')) &&
   5056         ((name[2] == 'l') || (name[2] == 'L'))) {
   5057 	int i;
   5058 	if ((name[0] == 'x') && (name[1] == 'm') &&
   5059 	    (name[2] == 'l') && (name[3] == 0)) {
   5060 	    xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
   5061 		 "XML declaration allowed only at the start of the document\n");
   5062 	    return(name);
   5063 	} else if (name[3] == 0) {
   5064 	    xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
   5065 	    return(name);
   5066 	}
   5067 	for (i = 0;;i++) {
   5068 	    if (xmlW3CPIs[i] == NULL) break;
   5069 	    if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
   5070 	        return(name);
   5071 	}
   5072 	xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
   5073 		      "xmlParsePITarget: invalid name prefix 'xml'\n",
   5074 		      NULL, NULL);
   5075     }
   5076     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
   5077 	xmlNsErr(ctxt, XML_NS_ERR_COLON,
   5078 		 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
   5079     }
   5080     return(name);
   5081 }
   5082 
   5083 #ifdef LIBXML_CATALOG_ENABLED
   5084 /**
   5085  * xmlParseCatalogPI:
   5086  * @ctxt:  an XML parser context
   5087  * @catalog:  the PI value string
   5088  *
   5089  * parse an XML Catalog Processing Instruction.
   5090  *
   5091  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
   5092  *
   5093  * Occurs only if allowed by the user and if happening in the Misc
   5094  * part of the document before any doctype informations
   5095  * This will add the given catalog to the parsing context in order
   5096  * to be used if there is a resolution need further down in the document
   5097  */
   5098 
   5099 static void
   5100 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
   5101     xmlChar *URL = NULL;
   5102     const xmlChar *tmp, *base;
   5103     xmlChar marker;
   5104 
   5105     tmp = catalog;
   5106     while (IS_BLANK_CH(*tmp)) tmp++;
   5107     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
   5108 	goto error;
   5109     tmp += 7;
   5110     while (IS_BLANK_CH(*tmp)) tmp++;
   5111     if (*tmp != '=') {
   5112 	return;
   5113     }
   5114     tmp++;
   5115     while (IS_BLANK_CH(*tmp)) tmp++;
   5116     marker = *tmp;
   5117     if ((marker != '\'') && (marker != '"'))
   5118 	goto error;
   5119     tmp++;
   5120     base = tmp;
   5121     while ((*tmp != 0) && (*tmp != marker)) tmp++;
   5122     if (*tmp == 0)
   5123 	goto error;
   5124     URL = xmlStrndup(base, tmp - base);
   5125     tmp++;
   5126     while (IS_BLANK_CH(*tmp)) tmp++;
   5127     if (*tmp != 0)
   5128 	goto error;
   5129 
   5130     if (URL != NULL) {
   5131 	ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
   5132 	xmlFree(URL);
   5133     }
   5134     return;
   5135 
   5136 error:
   5137     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
   5138 	          "Catalog PI syntax error: %s\n",
   5139 		  catalog, NULL);
   5140     if (URL != NULL)
   5141 	xmlFree(URL);
   5142 }
   5143 #endif
   5144 
   5145 /**
   5146  * xmlParsePI:
   5147  * @ctxt:  an XML parser context
   5148  *
   5149  * parse an XML Processing Instruction.
   5150  *
   5151  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
   5152  *
   5153  * The processing is transfered to SAX once parsed.
   5154  */
   5155 
   5156 void
   5157 xmlParsePI(xmlParserCtxtPtr ctxt) {
   5158     xmlChar *buf = NULL;
   5159     size_t len = 0;
   5160     size_t size = XML_PARSER_BUFFER_SIZE;
   5161     int cur, l;
   5162     const xmlChar *target;
   5163     xmlParserInputState state;
   5164     int count = 0;
   5165 
   5166     if ((RAW == '<') && (NXT(1) == '?')) {
   5167 	xmlParserInputPtr input = ctxt->input;
   5168 	state = ctxt->instate;
   5169         ctxt->instate = XML_PARSER_PI;
   5170 	/*
   5171 	 * this is a Processing Instruction.
   5172 	 */
   5173 	SKIP(2);
   5174 	SHRINK;
   5175 
   5176 	/*
   5177 	 * Parse the target name and check for special support like
   5178 	 * namespace.
   5179 	 */
   5180         target = xmlParsePITarget(ctxt);
   5181 	if (target != NULL) {
   5182 	    if ((RAW == '?') && (NXT(1) == '>')) {
   5183 		if (input != ctxt->input) {
   5184 		    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
   5185 	    "PI declaration doesn't start and stop in the same entity\n");
   5186 		}
   5187 		SKIP(2);
   5188 
   5189 		/*
   5190 		 * SAX: PI detected.
   5191 		 */
   5192 		if ((ctxt->sax) && (!ctxt->disableSAX) &&
   5193 		    (ctxt->sax->processingInstruction != NULL))
   5194 		    ctxt->sax->processingInstruction(ctxt->userData,
   5195 		                                     target, NULL);
   5196 		if (ctxt->instate != XML_PARSER_EOF)
   5197 		    ctxt->instate = state;
   5198 		return;
   5199 	    }
   5200 	    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   5201 	    if (buf == NULL) {
   5202 		xmlErrMemory(ctxt, NULL);
   5203 		ctxt->instate = state;
   5204 		return;
   5205 	    }
   5206 	    cur = CUR;
   5207 	    if (!IS_BLANK(cur)) {
   5208 		xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
   5209 			  "ParsePI: PI %s space expected\n", target);
   5210 	    }
   5211             SKIP_BLANKS;
   5212 	    cur = CUR_CHAR(l);
   5213 	    while (IS_CHAR(cur) && /* checked */
   5214 		   ((cur != '?') || (NXT(1) != '>'))) {
   5215 		if (len + 5 >= size) {
   5216 		    xmlChar *tmp;
   5217                     size_t new_size = size * 2;
   5218 		    tmp = (xmlChar *) xmlRealloc(buf, new_size);
   5219 		    if (tmp == NULL) {
   5220 			xmlErrMemory(ctxt, NULL);
   5221 			xmlFree(buf);
   5222 			ctxt->instate = state;
   5223 			return;
   5224 		    }
   5225 		    buf = tmp;
   5226                     size = new_size;
   5227 		}
   5228 		count++;
   5229 		if (count > 50) {
   5230 		    GROW;
   5231                     if (ctxt->instate == XML_PARSER_EOF) {
   5232                         xmlFree(buf);
   5233                         return;
   5234                     }
   5235 		    count = 0;
   5236                     if ((len > XML_MAX_TEXT_LENGTH) &&
   5237                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   5238                         xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
   5239                                           "PI %s too big found", target);
   5240                         xmlFree(buf);
   5241                         ctxt->instate = state;
   5242                         return;
   5243                     }
   5244 		}
   5245 		COPY_BUF(l,buf,len,cur);
   5246 		NEXTL(l);
   5247 		cur = CUR_CHAR(l);
   5248 		if (cur == 0) {
   5249 		    SHRINK;
   5250 		    GROW;
   5251 		    cur = CUR_CHAR(l);
   5252 		}
   5253 	    }
   5254             if ((len > XML_MAX_TEXT_LENGTH) &&
   5255                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   5256                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
   5257                                   "PI %s too big found", target);
   5258                 xmlFree(buf);
   5259                 ctxt->instate = state;
   5260                 return;
   5261             }
   5262 	    buf[len] = 0;
   5263 	    if (cur != '?') {
   5264 		xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
   5265 		      "ParsePI: PI %s never end ...\n", target);
   5266 	    } else {
   5267 		if (input != ctxt->input) {
   5268 		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5269 	    "PI declaration doesn't start and stop in the same entity\n");
   5270 		}
   5271 		SKIP(2);
   5272 
   5273 #ifdef LIBXML_CATALOG_ENABLED
   5274 		if (((state == XML_PARSER_MISC) ||
   5275 	             (state == XML_PARSER_START)) &&
   5276 		    (xmlStrEqual(target, XML_CATALOG_PI))) {
   5277 		    xmlCatalogAllow allow = xmlCatalogGetDefaults();
   5278 		    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
   5279 			(allow == XML_CATA_ALLOW_ALL))
   5280 			xmlParseCatalogPI(ctxt, buf);
   5281 		}
   5282 #endif
   5283 
   5284 
   5285 		/*
   5286 		 * SAX: PI detected.
   5287 		 */
   5288 		if ((ctxt->sax) && (!ctxt->disableSAX) &&
   5289 		    (ctxt->sax->processingInstruction != NULL))
   5290 		    ctxt->sax->processingInstruction(ctxt->userData,
   5291 		                                     target, buf);
   5292 	    }
   5293 	    xmlFree(buf);
   5294 	} else {
   5295 	    xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
   5296 	}
   5297 	if (ctxt->instate != XML_PARSER_EOF)
   5298 	    ctxt->instate = state;
   5299     }
   5300 }
   5301 
   5302 /**
   5303  * xmlParseNotationDecl:
   5304  * @ctxt:  an XML parser context
   5305  *
   5306  * parse a notation declaration
   5307  *
   5308  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
   5309  *
   5310  * Hence there is actually 3 choices:
   5311  *     'PUBLIC' S PubidLiteral
   5312  *     'PUBLIC' S PubidLiteral S SystemLiteral
   5313  * and 'SYSTEM' S SystemLiteral
   5314  *
   5315  * See the NOTE on xmlParseExternalID().
   5316  */
   5317 
   5318 void
   5319 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
   5320     const xmlChar *name;
   5321     xmlChar *Pubid;
   5322     xmlChar *Systemid;
   5323 
   5324     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
   5325 	xmlParserInputPtr input = ctxt->input;
   5326 	SHRINK;
   5327 	SKIP(10);
   5328 	if (!IS_BLANK_CH(CUR)) {
   5329 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5330 			   "Space required after '<!NOTATION'\n");
   5331 	    return;
   5332 	}
   5333 	SKIP_BLANKS;
   5334 
   5335         name = xmlParseName(ctxt);
   5336 	if (name == NULL) {
   5337 	    xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
   5338 	    return;
   5339 	}
   5340 	if (!IS_BLANK_CH(CUR)) {
   5341 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5342 		     "Space required after the NOTATION name'\n");
   5343 	    return;
   5344 	}
   5345 	if (xmlStrchr(name, ':') != NULL) {
   5346 	    xmlNsErr(ctxt, XML_NS_ERR_COLON,
   5347 		     "colon are forbidden from notation names '%s'\n",
   5348 		     name, NULL, NULL);
   5349 	}
   5350 	SKIP_BLANKS;
   5351 
   5352 	/*
   5353 	 * Parse the IDs.
   5354 	 */
   5355 	Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
   5356 	SKIP_BLANKS;
   5357 
   5358 	if (RAW == '>') {
   5359 	    if (input != ctxt->input) {
   5360 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5361 	"Notation declaration doesn't start and stop in the same entity\n");
   5362 	    }
   5363 	    NEXT;
   5364 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
   5365 		(ctxt->sax->notationDecl != NULL))
   5366 		ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
   5367 	} else {
   5368 	    xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
   5369 	}
   5370 	if (Systemid != NULL) xmlFree(Systemid);
   5371 	if (Pubid != NULL) xmlFree(Pubid);
   5372     }
   5373 }
   5374 
   5375 /**
   5376  * xmlParseEntityDecl:
   5377  * @ctxt:  an XML parser context
   5378  *
   5379  * parse <!ENTITY declarations
   5380  *
   5381  * [70] EntityDecl ::= GEDecl | PEDecl
   5382  *
   5383  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
   5384  *
   5385  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
   5386  *
   5387  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
   5388  *
   5389  * [74] PEDef ::= EntityValue | ExternalID
   5390  *
   5391  * [76] NDataDecl ::= S 'NDATA' S Name
   5392  *
   5393  * [ VC: Notation Declared ]
   5394  * The Name must match the declared name of a notation.
   5395  */
   5396 
   5397 void
   5398 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
   5399     const xmlChar *name = NULL;
   5400     xmlChar *value = NULL;
   5401     xmlChar *URI = NULL, *literal = NULL;
   5402     const xmlChar *ndata = NULL;
   5403     int isParameter = 0;
   5404     xmlChar *orig = NULL;
   5405     int skipped;
   5406 
   5407     /* GROW; done in the caller */
   5408     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
   5409 	xmlParserInputPtr input = ctxt->input;
   5410 	SHRINK;
   5411 	SKIP(8);
   5412 	skipped = SKIP_BLANKS;
   5413 	if (skipped == 0) {
   5414 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5415 			   "Space required after '<!ENTITY'\n");
   5416 	}
   5417 
   5418 	if (RAW == '%') {
   5419 	    NEXT;
   5420 	    skipped = SKIP_BLANKS;
   5421 	    if (skipped == 0) {
   5422 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5423 			       "Space required after '%'\n");
   5424 	    }
   5425 	    isParameter = 1;
   5426 	}
   5427 
   5428         name = xmlParseName(ctxt);
   5429 	if (name == NULL) {
   5430 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   5431 	                   "xmlParseEntityDecl: no name\n");
   5432             return;
   5433 	}
   5434 	if (xmlStrchr(name, ':') != NULL) {
   5435 	    xmlNsErr(ctxt, XML_NS_ERR_COLON,
   5436 		     "colon are forbidden from entities names '%s'\n",
   5437 		     name, NULL, NULL);
   5438 	}
   5439         skipped = SKIP_BLANKS;
   5440 	if (skipped == 0) {
   5441 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5442 			   "Space required after the entity name\n");
   5443 	}
   5444 
   5445 	ctxt->instate = XML_PARSER_ENTITY_DECL;
   5446 	/*
   5447 	 * handle the various case of definitions...
   5448 	 */
   5449 	if (isParameter) {
   5450 	    if ((RAW == '"') || (RAW == '\'')) {
   5451 	        value = xmlParseEntityValue(ctxt, &orig);
   5452 		if (value) {
   5453 		    if ((ctxt->sax != NULL) &&
   5454 			(!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
   5455 			ctxt->sax->entityDecl(ctxt->userData, name,
   5456 		                    XML_INTERNAL_PARAMETER_ENTITY,
   5457 				    NULL, NULL, value);
   5458 		}
   5459 	    } else {
   5460 	        URI = xmlParseExternalID(ctxt, &literal, 1);
   5461 		if ((URI == NULL) && (literal == NULL)) {
   5462 		    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
   5463 		}
   5464 		if (URI) {
   5465 		    xmlURIPtr uri;
   5466 
   5467 		    uri = xmlParseURI((const char *) URI);
   5468 		    if (uri == NULL) {
   5469 		        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
   5470 				     "Invalid URI: %s\n", URI);
   5471 			/*
   5472 			 * This really ought to be a well formedness error
   5473 			 * but the XML Core WG decided otherwise c.f. issue
   5474 			 * E26 of the XML erratas.
   5475 			 */
   5476 		    } else {
   5477 			if (uri->fragment != NULL) {
   5478 			    /*
   5479 			     * Okay this is foolish to block those but not
   5480 			     * invalid URIs.
   5481 			     */
   5482 			    xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
   5483 			} else {
   5484 			    if ((ctxt->sax != NULL) &&
   5485 				(!ctxt->disableSAX) &&
   5486 				(ctxt->sax->entityDecl != NULL))
   5487 				ctxt->sax->entityDecl(ctxt->userData, name,
   5488 					    XML_EXTERNAL_PARAMETER_ENTITY,
   5489 					    literal, URI, NULL);
   5490 			}
   5491 			xmlFreeURI(uri);
   5492 		    }
   5493 		}
   5494 	    }
   5495 	} else {
   5496 	    if ((RAW == '"') || (RAW == '\'')) {
   5497 	        value = xmlParseEntityValue(ctxt, &orig);
   5498 		if ((ctxt->sax != NULL) &&
   5499 		    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
   5500 		    ctxt->sax->entityDecl(ctxt->userData, name,
   5501 				XML_INTERNAL_GENERAL_ENTITY,
   5502 				NULL, NULL, value);
   5503 		/*
   5504 		 * For expat compatibility in SAX mode.
   5505 		 */
   5506 		if ((ctxt->myDoc == NULL) ||
   5507 		    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
   5508 		    if (ctxt->myDoc == NULL) {
   5509 			ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
   5510 			if (ctxt->myDoc == NULL) {
   5511 			    xmlErrMemory(ctxt, "New Doc failed");
   5512 			    return;
   5513 			}
   5514 			ctxt->myDoc->properties = XML_DOC_INTERNAL;
   5515 		    }
   5516 		    if (ctxt->myDoc->intSubset == NULL)
   5517 			ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
   5518 					    BAD_CAST "fake", NULL, NULL);
   5519 
   5520 		    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
   5521 			              NULL, NULL, value);
   5522 		}
   5523 	    } else {
   5524 	        URI = xmlParseExternalID(ctxt, &literal, 1);
   5525 		if ((URI == NULL) && (literal == NULL)) {
   5526 		    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
   5527 		}
   5528 		if (URI) {
   5529 		    xmlURIPtr uri;
   5530 
   5531 		    uri = xmlParseURI((const char *)URI);
   5532 		    if (uri == NULL) {
   5533 		        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
   5534 				     "Invalid URI: %s\n", URI);
   5535 			/*
   5536 			 * This really ought to be a well formedness error
   5537 			 * but the XML Core WG decided otherwise c.f. issue
   5538 			 * E26 of the XML erratas.
   5539 			 */
   5540 		    } else {
   5541 			if (uri->fragment != NULL) {
   5542 			    /*
   5543 			     * Okay this is foolish to block those but not
   5544 			     * invalid URIs.
   5545 			     */
   5546 			    xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
   5547 			}
   5548 			xmlFreeURI(uri);
   5549 		    }
   5550 		}
   5551 		if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
   5552 		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5553 				   "Space required before 'NDATA'\n");
   5554 		}
   5555 		SKIP_BLANKS;
   5556 		if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
   5557 		    SKIP(5);
   5558 		    if (!IS_BLANK_CH(CUR)) {
   5559 			xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5560 				       "Space required after 'NDATA'\n");
   5561 		    }
   5562 		    SKIP_BLANKS;
   5563 		    ndata = xmlParseName(ctxt);
   5564 		    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
   5565 		        (ctxt->sax->unparsedEntityDecl != NULL))
   5566 			ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
   5567 				    literal, URI, ndata);
   5568 		} else {
   5569 		    if ((ctxt->sax != NULL) &&
   5570 		        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
   5571 			ctxt->sax->entityDecl(ctxt->userData, name,
   5572 				    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
   5573 				    literal, URI, NULL);
   5574 		    /*
   5575 		     * For expat compatibility in SAX mode.
   5576 		     * assuming the entity repalcement was asked for
   5577 		     */
   5578 		    if ((ctxt->replaceEntities != 0) &&
   5579 			((ctxt->myDoc == NULL) ||
   5580 			(xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
   5581 			if (ctxt->myDoc == NULL) {
   5582 			    ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
   5583 			    if (ctxt->myDoc == NULL) {
   5584 			        xmlErrMemory(ctxt, "New Doc failed");
   5585 				return;
   5586 			    }
   5587 			    ctxt->myDoc->properties = XML_DOC_INTERNAL;
   5588 			}
   5589 
   5590 			if (ctxt->myDoc->intSubset == NULL)
   5591 			    ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
   5592 						BAD_CAST "fake", NULL, NULL);
   5593 			xmlSAX2EntityDecl(ctxt, name,
   5594 				          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
   5595 				          literal, URI, NULL);
   5596 		    }
   5597 		}
   5598 	    }
   5599 	}
   5600 	if (ctxt->instate == XML_PARSER_EOF)
   5601 	    return;
   5602 	SKIP_BLANKS;
   5603 	if (RAW != '>') {
   5604 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
   5605 	            "xmlParseEntityDecl: entity %s not terminated\n", name);
   5606 	} else {
   5607 	    if (input != ctxt->input) {
   5608 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
   5609 	"Entity declaration doesn't start and stop in the same entity\n");
   5610 	    }
   5611 	    NEXT;
   5612 	}
   5613 	if (orig != NULL) {
   5614 	    /*
   5615 	     * Ugly mechanism to save the raw entity value.
   5616 	     */
   5617 	    xmlEntityPtr cur = NULL;
   5618 
   5619 	    if (isParameter) {
   5620 	        if ((ctxt->sax != NULL) &&
   5621 		    (ctxt->sax->getParameterEntity != NULL))
   5622 		    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
   5623 	    } else {
   5624 	        if ((ctxt->sax != NULL) &&
   5625 		    (ctxt->sax->getEntity != NULL))
   5626 		    cur = ctxt->sax->getEntity(ctxt->userData, name);
   5627 		if ((cur == NULL) && (ctxt->userData==ctxt)) {
   5628 		    cur = xmlSAX2GetEntity(ctxt, name);
   5629 		}
   5630 	    }
   5631             if (cur != NULL) {
   5632 	        if (cur->orig != NULL)
   5633 		    xmlFree(orig);
   5634 		else
   5635 		    cur->orig = orig;
   5636 	    } else
   5637 		xmlFree(orig);
   5638 	}
   5639 	if (value != NULL) xmlFree(value);
   5640 	if (URI != NULL) xmlFree(URI);
   5641 	if (literal != NULL) xmlFree(literal);
   5642     }
   5643 }
   5644 
   5645 /**
   5646  * xmlParseDefaultDecl:
   5647  * @ctxt:  an XML parser context
   5648  * @value:  Receive a possible fixed default value for the attribute
   5649  *
   5650  * Parse an attribute default declaration
   5651  *
   5652  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
   5653  *
   5654  * [ VC: Required Attribute ]
   5655  * if the default declaration is the keyword #REQUIRED, then the
   5656  * attribute must be specified for all elements of the type in the
   5657  * attribute-list declaration.
   5658  *
   5659  * [ VC: Attribute Default Legal ]
   5660  * The declared default value must meet the lexical constraints of
   5661  * the declared attribute type c.f. xmlValidateAttributeDecl()
   5662  *
   5663  * [ VC: Fixed Attribute Default ]
   5664  * if an attribute has a default value declared with the #FIXED
   5665  * keyword, instances of that attribute must match the default value.
   5666  *
   5667  * [ WFC: No < in Attribute Values ]
   5668  * handled in xmlParseAttValue()
   5669  *
   5670  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
   5671  *          or XML_ATTRIBUTE_FIXED.
   5672  */
   5673 
   5674 int
   5675 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
   5676     int val;
   5677     xmlChar *ret;
   5678 
   5679     *value = NULL;
   5680     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
   5681 	SKIP(9);
   5682 	return(XML_ATTRIBUTE_REQUIRED);
   5683     }
   5684     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
   5685 	SKIP(8);
   5686 	return(XML_ATTRIBUTE_IMPLIED);
   5687     }
   5688     val = XML_ATTRIBUTE_NONE;
   5689     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
   5690 	SKIP(6);
   5691 	val = XML_ATTRIBUTE_FIXED;
   5692 	if (!IS_BLANK_CH(CUR)) {
   5693 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5694 			   "Space required after '#FIXED'\n");
   5695 	}
   5696 	SKIP_BLANKS;
   5697     }
   5698     ret = xmlParseAttValue(ctxt);
   5699     ctxt->instate = XML_PARSER_DTD;
   5700     if (ret == NULL) {
   5701 	xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
   5702 		       "Attribute default value declaration error\n");
   5703     } else
   5704         *value = ret;
   5705     return(val);
   5706 }
   5707 
   5708 /**
   5709  * xmlParseNotationType:
   5710  * @ctxt:  an XML parser context
   5711  *
   5712  * parse an Notation attribute type.
   5713  *
   5714  * Note: the leading 'NOTATION' S part has already being parsed...
   5715  *
   5716  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
   5717  *
   5718  * [ VC: Notation Attributes ]
   5719  * Values of this type must match one of the notation names included
   5720  * in the declaration; all notation names in the declaration must be declared.
   5721  *
   5722  * Returns: the notation attribute tree built while parsing
   5723  */
   5724 
   5725 xmlEnumerationPtr
   5726 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
   5727     const xmlChar *name;
   5728     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
   5729 
   5730     if (RAW != '(') {
   5731 	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
   5732 	return(NULL);
   5733     }
   5734     SHRINK;
   5735     do {
   5736         NEXT;
   5737 	SKIP_BLANKS;
   5738         name = xmlParseName(ctxt);
   5739 	if (name == NULL) {
   5740 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   5741 			   "Name expected in NOTATION declaration\n");
   5742             xmlFreeEnumeration(ret);
   5743 	    return(NULL);
   5744 	}
   5745 	tmp = ret;
   5746 	while (tmp != NULL) {
   5747 	    if (xmlStrEqual(name, tmp->name)) {
   5748 		xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
   5749 	  "standalone: attribute notation value token %s duplicated\n",
   5750 				 name, NULL);
   5751 		if (!xmlDictOwns(ctxt->dict, name))
   5752 		    xmlFree((xmlChar *) name);
   5753 		break;
   5754 	    }
   5755 	    tmp = tmp->next;
   5756 	}
   5757 	if (tmp == NULL) {
   5758 	    cur = xmlCreateEnumeration(name);
   5759 	    if (cur == NULL) {
   5760                 xmlFreeEnumeration(ret);
   5761                 return(NULL);
   5762             }
   5763 	    if (last == NULL) ret = last = cur;
   5764 	    else {
   5765 		last->next = cur;
   5766 		last = cur;
   5767 	    }
   5768 	}
   5769 	SKIP_BLANKS;
   5770     } while (RAW == '|');
   5771     if (RAW != ')') {
   5772 	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
   5773         xmlFreeEnumeration(ret);
   5774 	return(NULL);
   5775     }
   5776     NEXT;
   5777     return(ret);
   5778 }
   5779 
   5780 /**
   5781  * xmlParseEnumerationType:
   5782  * @ctxt:  an XML parser context
   5783  *
   5784  * parse an Enumeration attribute type.
   5785  *
   5786  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
   5787  *
   5788  * [ VC: Enumeration ]
   5789  * Values of this type must match one of the Nmtoken tokens in
   5790  * the declaration
   5791  *
   5792  * Returns: the enumeration attribute tree built while parsing
   5793  */
   5794 
   5795 xmlEnumerationPtr
   5796 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
   5797     xmlChar *name;
   5798     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
   5799 
   5800     if (RAW != '(') {
   5801 	xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
   5802 	return(NULL);
   5803     }
   5804     SHRINK;
   5805     do {
   5806         NEXT;
   5807 	SKIP_BLANKS;
   5808         name = xmlParseNmtoken(ctxt);
   5809 	if (name == NULL) {
   5810 	    xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
   5811 	    return(ret);
   5812 	}
   5813 	tmp = ret;
   5814 	while (tmp != NULL) {
   5815 	    if (xmlStrEqual(name, tmp->name)) {
   5816 		xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
   5817 	  "standalone: attribute enumeration value token %s duplicated\n",
   5818 				 name, NULL);
   5819 		if (!xmlDictOwns(ctxt->dict, name))
   5820 		    xmlFree(name);
   5821 		break;
   5822 	    }
   5823 	    tmp = tmp->next;
   5824 	}
   5825 	if (tmp == NULL) {
   5826 	    cur = xmlCreateEnumeration(name);
   5827 	    if (!xmlDictOwns(ctxt->dict, name))
   5828 		xmlFree(name);
   5829 	    if (cur == NULL) {
   5830                 xmlFreeEnumeration(ret);
   5831                 return(NULL);
   5832             }
   5833 	    if (last == NULL) ret = last = cur;
   5834 	    else {
   5835 		last->next = cur;
   5836 		last = cur;
   5837 	    }
   5838 	}
   5839 	SKIP_BLANKS;
   5840     } while (RAW == '|');
   5841     if (RAW != ')') {
   5842 	xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
   5843 	return(ret);
   5844     }
   5845     NEXT;
   5846     return(ret);
   5847 }
   5848 
   5849 /**
   5850  * xmlParseEnumeratedType:
   5851  * @ctxt:  an XML parser context
   5852  * @tree:  the enumeration tree built while parsing
   5853  *
   5854  * parse an Enumerated attribute type.
   5855  *
   5856  * [57] EnumeratedType ::= NotationType | Enumeration
   5857  *
   5858  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
   5859  *
   5860  *
   5861  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
   5862  */
   5863 
   5864 int
   5865 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
   5866     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
   5867 	SKIP(8);
   5868 	if (!IS_BLANK_CH(CUR)) {
   5869 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5870 			   "Space required after 'NOTATION'\n");
   5871 	    return(0);
   5872 	}
   5873         SKIP_BLANKS;
   5874 	*tree = xmlParseNotationType(ctxt);
   5875 	if (*tree == NULL) return(0);
   5876 	return(XML_ATTRIBUTE_NOTATION);
   5877     }
   5878     *tree = xmlParseEnumerationType(ctxt);
   5879     if (*tree == NULL) return(0);
   5880     return(XML_ATTRIBUTE_ENUMERATION);
   5881 }
   5882 
   5883 /**
   5884  * xmlParseAttributeType:
   5885  * @ctxt:  an XML parser context
   5886  * @tree:  the enumeration tree built while parsing
   5887  *
   5888  * parse the Attribute list def for an element
   5889  *
   5890  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
   5891  *
   5892  * [55] StringType ::= 'CDATA'
   5893  *
   5894  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
   5895  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
   5896  *
   5897  * Validity constraints for attribute values syntax are checked in
   5898  * xmlValidateAttributeValue()
   5899  *
   5900  * [ VC: ID ]
   5901  * Values of type ID must match the Name production. A name must not
   5902  * appear more than once in an XML document as a value of this type;
   5903  * i.e., ID values must uniquely identify the elements which bear them.
   5904  *
   5905  * [ VC: One ID per Element Type ]
   5906  * No element type may have more than one ID attribute specified.
   5907  *
   5908  * [ VC: ID Attribute Default ]
   5909  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
   5910  *
   5911  * [ VC: IDREF ]
   5912  * Values of type IDREF must match the Name production, and values
   5913  * of type IDREFS must match Names; each IDREF Name must match the value
   5914  * of an ID attribute on some element in the XML document; i.e. IDREF
   5915  * values must match the value of some ID attribute.
   5916  *
   5917  * [ VC: Entity Name ]
   5918  * Values of type ENTITY must match the Name production, values
   5919  * of type ENTITIES must match Names; each Entity Name must match the
   5920  * name of an unparsed entity declared in the DTD.
   5921  *
   5922  * [ VC: Name Token ]
   5923  * Values of type NMTOKEN must match the Nmtoken production; values
   5924  * of type NMTOKENS must match Nmtokens.
   5925  *
   5926  * Returns the attribute type
   5927  */
   5928 int
   5929 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
   5930     SHRINK;
   5931     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
   5932 	SKIP(5);
   5933 	return(XML_ATTRIBUTE_CDATA);
   5934      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
   5935 	SKIP(6);
   5936 	return(XML_ATTRIBUTE_IDREFS);
   5937      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
   5938 	SKIP(5);
   5939 	return(XML_ATTRIBUTE_IDREF);
   5940      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
   5941         SKIP(2);
   5942 	return(XML_ATTRIBUTE_ID);
   5943      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
   5944 	SKIP(6);
   5945 	return(XML_ATTRIBUTE_ENTITY);
   5946      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
   5947 	SKIP(8);
   5948 	return(XML_ATTRIBUTE_ENTITIES);
   5949      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
   5950 	SKIP(8);
   5951 	return(XML_ATTRIBUTE_NMTOKENS);
   5952      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
   5953 	SKIP(7);
   5954 	return(XML_ATTRIBUTE_NMTOKEN);
   5955      }
   5956      return(xmlParseEnumeratedType(ctxt, tree));
   5957 }
   5958 
   5959 /**
   5960  * xmlParseAttributeListDecl:
   5961  * @ctxt:  an XML parser context
   5962  *
   5963  * : parse the Attribute list def for an element
   5964  *
   5965  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
   5966  *
   5967  * [53] AttDef ::= S Name S AttType S DefaultDecl
   5968  *
   5969  */
   5970 void
   5971 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
   5972     const xmlChar *elemName;
   5973     const xmlChar *attrName;
   5974     xmlEnumerationPtr tree;
   5975 
   5976     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
   5977 	xmlParserInputPtr input = ctxt->input;
   5978 
   5979 	SKIP(9);
   5980 	if (!IS_BLANK_CH(CUR)) {
   5981 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   5982 		                 "Space required after '<!ATTLIST'\n");
   5983 	}
   5984         SKIP_BLANKS;
   5985         elemName = xmlParseName(ctxt);
   5986 	if (elemName == NULL) {
   5987 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   5988 			   "ATTLIST: no name for Element\n");
   5989 	    return;
   5990 	}
   5991 	SKIP_BLANKS;
   5992 	GROW;
   5993 	while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
   5994 	    const xmlChar *check = CUR_PTR;
   5995 	    int type;
   5996 	    int def;
   5997 	    xmlChar *defaultValue = NULL;
   5998 
   5999 	    GROW;
   6000             tree = NULL;
   6001 	    attrName = xmlParseName(ctxt);
   6002 	    if (attrName == NULL) {
   6003 		xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   6004 			       "ATTLIST: no name for Attribute\n");
   6005 		break;
   6006 	    }
   6007 	    GROW;
   6008 	    if (!IS_BLANK_CH(CUR)) {
   6009 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6010 		        "Space required after the attribute name\n");
   6011 		break;
   6012 	    }
   6013 	    SKIP_BLANKS;
   6014 
   6015 	    type = xmlParseAttributeType(ctxt, &tree);
   6016 	    if (type <= 0) {
   6017 	        break;
   6018 	    }
   6019 
   6020 	    GROW;
   6021 	    if (!IS_BLANK_CH(CUR)) {
   6022 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6023 			       "Space required after the attribute type\n");
   6024 	        if (tree != NULL)
   6025 		    xmlFreeEnumeration(tree);
   6026 		break;
   6027 	    }
   6028 	    SKIP_BLANKS;
   6029 
   6030 	    def = xmlParseDefaultDecl(ctxt, &defaultValue);
   6031 	    if (def <= 0) {
   6032                 if (defaultValue != NULL)
   6033 		    xmlFree(defaultValue);
   6034 	        if (tree != NULL)
   6035 		    xmlFreeEnumeration(tree);
   6036 	        break;
   6037 	    }
   6038 	    if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
   6039 	        xmlAttrNormalizeSpace(defaultValue, defaultValue);
   6040 
   6041 	    GROW;
   6042             if (RAW != '>') {
   6043 		if (!IS_BLANK_CH(CUR)) {
   6044 		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6045 			"Space required after the attribute default value\n");
   6046 		    if (defaultValue != NULL)
   6047 			xmlFree(defaultValue);
   6048 		    if (tree != NULL)
   6049 			xmlFreeEnumeration(tree);
   6050 		    break;
   6051 		}
   6052 		SKIP_BLANKS;
   6053 	    }
   6054 	    if (check == CUR_PTR) {
   6055 		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   6056 		            "in xmlParseAttributeListDecl\n");
   6057 		if (defaultValue != NULL)
   6058 		    xmlFree(defaultValue);
   6059 	        if (tree != NULL)
   6060 		    xmlFreeEnumeration(tree);
   6061 		break;
   6062 	    }
   6063 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
   6064 		(ctxt->sax->attributeDecl != NULL))
   6065 		ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
   6066 	                        type, def, defaultValue, tree);
   6067 	    else if (tree != NULL)
   6068 		xmlFreeEnumeration(tree);
   6069 
   6070 	    if ((ctxt->sax2) && (defaultValue != NULL) &&
   6071 	        (def != XML_ATTRIBUTE_IMPLIED) &&
   6072 		(def != XML_ATTRIBUTE_REQUIRED)) {
   6073 		xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
   6074 	    }
   6075 	    if (ctxt->sax2) {
   6076 		xmlAddSpecialAttr(ctxt, elemName, attrName, type);
   6077 	    }
   6078 	    if (defaultValue != NULL)
   6079 	        xmlFree(defaultValue);
   6080 	    GROW;
   6081 	}
   6082 	if (RAW == '>') {
   6083 	    if (input != ctxt->input) {
   6084 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6085     "Attribute list declaration doesn't start and stop in the same entity\n",
   6086                                  NULL, NULL);
   6087 	    }
   6088 	    NEXT;
   6089 	}
   6090     }
   6091 }
   6092 
   6093 /**
   6094  * xmlParseElementMixedContentDecl:
   6095  * @ctxt:  an XML parser context
   6096  * @inputchk:  the input used for the current entity, needed for boundary checks
   6097  *
   6098  * parse the declaration for a Mixed Element content
   6099  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
   6100  *
   6101  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
   6102  *                '(' S? '#PCDATA' S? ')'
   6103  *
   6104  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
   6105  *
   6106  * [ VC: No Duplicate Types ]
   6107  * The same name must not appear more than once in a single
   6108  * mixed-content declaration.
   6109  *
   6110  * returns: the list of the xmlElementContentPtr describing the element choices
   6111  */
   6112 xmlElementContentPtr
   6113 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
   6114     xmlElementContentPtr ret = NULL, cur = NULL, n;
   6115     const xmlChar *elem = NULL;
   6116 
   6117     GROW;
   6118     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
   6119 	SKIP(7);
   6120 	SKIP_BLANKS;
   6121 	SHRINK;
   6122 	if (RAW == ')') {
   6123 	    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
   6124 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6125 "Element content declaration doesn't start and stop in the same entity\n",
   6126                                  NULL, NULL);
   6127 	    }
   6128 	    NEXT;
   6129 	    ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
   6130 	    if (ret == NULL)
   6131 	        return(NULL);
   6132 	    if (RAW == '*') {
   6133 		ret->ocur = XML_ELEMENT_CONTENT_MULT;
   6134 		NEXT;
   6135 	    }
   6136 	    return(ret);
   6137 	}
   6138 	if ((RAW == '(') || (RAW == '|')) {
   6139 	    ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
   6140 	    if (ret == NULL) return(NULL);
   6141 	}
   6142 	while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
   6143 	    NEXT;
   6144 	    if (elem == NULL) {
   6145 	        ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
   6146 		if (ret == NULL) return(NULL);
   6147 		ret->c1 = cur;
   6148 		if (cur != NULL)
   6149 		    cur->parent = ret;
   6150 		cur = ret;
   6151 	    } else {
   6152 	        n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
   6153 		if (n == NULL) return(NULL);
   6154 		n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
   6155 		if (n->c1 != NULL)
   6156 		    n->c1->parent = n;
   6157 	        cur->c2 = n;
   6158 		if (n != NULL)
   6159 		    n->parent = cur;
   6160 		cur = n;
   6161 	    }
   6162 	    SKIP_BLANKS;
   6163 	    elem = xmlParseName(ctxt);
   6164 	    if (elem == NULL) {
   6165 		xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   6166 			"xmlParseElementMixedContentDecl : Name expected\n");
   6167 		xmlFreeDocElementContent(ctxt->myDoc, cur);
   6168 		return(NULL);
   6169 	    }
   6170 	    SKIP_BLANKS;
   6171 	    GROW;
   6172 	}
   6173 	if ((RAW == ')') && (NXT(1) == '*')) {
   6174 	    if (elem != NULL) {
   6175 		cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
   6176 		                               XML_ELEMENT_CONTENT_ELEMENT);
   6177 		if (cur->c2 != NULL)
   6178 		    cur->c2->parent = cur;
   6179             }
   6180             if (ret != NULL)
   6181                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
   6182 	    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
   6183 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6184 "Element content declaration doesn't start and stop in the same entity\n",
   6185 				 NULL, NULL);
   6186 	    }
   6187 	    SKIP(2);
   6188 	} else {
   6189 	    xmlFreeDocElementContent(ctxt->myDoc, ret);
   6190 	    xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
   6191 	    return(NULL);
   6192 	}
   6193 
   6194     } else {
   6195 	xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
   6196     }
   6197     return(ret);
   6198 }
   6199 
   6200 /**
   6201  * xmlParseElementChildrenContentDeclPriv:
   6202  * @ctxt:  an XML parser context
   6203  * @inputchk:  the input used for the current entity, needed for boundary checks
   6204  * @depth: the level of recursion
   6205  *
   6206  * parse the declaration for a Mixed Element content
   6207  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
   6208  *
   6209  *
   6210  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
   6211  *
   6212  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
   6213  *
   6214  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
   6215  *
   6216  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
   6217  *
   6218  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
   6219  * TODO Parameter-entity replacement text must be properly nested
   6220  *	with parenthesized groups. That is to say, if either of the
   6221  *	opening or closing parentheses in a choice, seq, or Mixed
   6222  *	construct is contained in the replacement text for a parameter
   6223  *	entity, both must be contained in the same replacement text. For
   6224  *	interoperability, if a parameter-entity reference appears in a
   6225  *	choice, seq, or Mixed construct, its replacement text should not
   6226  *	be empty, and neither the first nor last non-blank character of
   6227  *	the replacement text should be a connector (| or ,).
   6228  *
   6229  * Returns the tree of xmlElementContentPtr describing the element
   6230  *          hierarchy.
   6231  */
   6232 static xmlElementContentPtr
   6233 xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
   6234                                        int depth) {
   6235     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
   6236     const xmlChar *elem;
   6237     xmlChar type = 0;
   6238 
   6239     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
   6240         (depth >  2048)) {
   6241         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
   6242 "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
   6243                           depth);
   6244 	return(NULL);
   6245     }
   6246     SKIP_BLANKS;
   6247     GROW;
   6248     if (RAW == '(') {
   6249 	int inputid = ctxt->input->id;
   6250 
   6251         /* Recurse on first child */
   6252 	NEXT;
   6253 	SKIP_BLANKS;
   6254         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
   6255                                                            depth + 1);
   6256 	SKIP_BLANKS;
   6257 	GROW;
   6258     } else {
   6259 	elem = xmlParseName(ctxt);
   6260 	if (elem == NULL) {
   6261 	    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
   6262 	    return(NULL);
   6263 	}
   6264         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
   6265 	if (cur == NULL) {
   6266 	    xmlErrMemory(ctxt, NULL);
   6267 	    return(NULL);
   6268 	}
   6269 	GROW;
   6270 	if (RAW == '?') {
   6271 	    cur->ocur = XML_ELEMENT_CONTENT_OPT;
   6272 	    NEXT;
   6273 	} else if (RAW == '*') {
   6274 	    cur->ocur = XML_ELEMENT_CONTENT_MULT;
   6275 	    NEXT;
   6276 	} else if (RAW == '+') {
   6277 	    cur->ocur = XML_ELEMENT_CONTENT_PLUS;
   6278 	    NEXT;
   6279 	} else {
   6280 	    cur->ocur = XML_ELEMENT_CONTENT_ONCE;
   6281 	}
   6282 	GROW;
   6283     }
   6284     SKIP_BLANKS;
   6285     SHRINK;
   6286     while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
   6287         /*
   6288 	 * Each loop we parse one separator and one element.
   6289 	 */
   6290         if (RAW == ',') {
   6291 	    if (type == 0) type = CUR;
   6292 
   6293 	    /*
   6294 	     * Detect "Name | Name , Name" error
   6295 	     */
   6296 	    else if (type != CUR) {
   6297 		xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
   6298 		    "xmlParseElementChildrenContentDecl : '%c' expected\n",
   6299 		                  type);
   6300 		if ((last != NULL) && (last != ret))
   6301 		    xmlFreeDocElementContent(ctxt->myDoc, last);
   6302 		if (ret != NULL)
   6303 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
   6304 		return(NULL);
   6305 	    }
   6306 	    NEXT;
   6307 
   6308 	    op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
   6309 	    if (op == NULL) {
   6310 		if ((last != NULL) && (last != ret))
   6311 		    xmlFreeDocElementContent(ctxt->myDoc, last);
   6312 	        xmlFreeDocElementContent(ctxt->myDoc, ret);
   6313 		return(NULL);
   6314 	    }
   6315 	    if (last == NULL) {
   6316 		op->c1 = ret;
   6317 		if (ret != NULL)
   6318 		    ret->parent = op;
   6319 		ret = cur = op;
   6320 	    } else {
   6321 	        cur->c2 = op;
   6322 		if (op != NULL)
   6323 		    op->parent = cur;
   6324 		op->c1 = last;
   6325 		if (last != NULL)
   6326 		    last->parent = op;
   6327 		cur =op;
   6328 		last = NULL;
   6329 	    }
   6330 	} else if (RAW == '|') {
   6331 	    if (type == 0) type = CUR;
   6332 
   6333 	    /*
   6334 	     * Detect "Name , Name | Name" error
   6335 	     */
   6336 	    else if (type != CUR) {
   6337 		xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
   6338 		    "xmlParseElementChildrenContentDecl : '%c' expected\n",
   6339 				  type);
   6340 		if ((last != NULL) && (last != ret))
   6341 		    xmlFreeDocElementContent(ctxt->myDoc, last);
   6342 		if (ret != NULL)
   6343 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
   6344 		return(NULL);
   6345 	    }
   6346 	    NEXT;
   6347 
   6348 	    op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
   6349 	    if (op == NULL) {
   6350 		if ((last != NULL) && (last != ret))
   6351 		    xmlFreeDocElementContent(ctxt->myDoc, last);
   6352 		if (ret != NULL)
   6353 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
   6354 		return(NULL);
   6355 	    }
   6356 	    if (last == NULL) {
   6357 		op->c1 = ret;
   6358 		if (ret != NULL)
   6359 		    ret->parent = op;
   6360 		ret = cur = op;
   6361 	    } else {
   6362 	        cur->c2 = op;
   6363 		if (op != NULL)
   6364 		    op->parent = cur;
   6365 		op->c1 = last;
   6366 		if (last != NULL)
   6367 		    last->parent = op;
   6368 		cur =op;
   6369 		last = NULL;
   6370 	    }
   6371 	} else {
   6372 	    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
   6373 	    if ((last != NULL) && (last != ret))
   6374 	        xmlFreeDocElementContent(ctxt->myDoc, last);
   6375 	    if (ret != NULL)
   6376 		xmlFreeDocElementContent(ctxt->myDoc, ret);
   6377 	    return(NULL);
   6378 	}
   6379 	GROW;
   6380 	SKIP_BLANKS;
   6381 	GROW;
   6382 	if (RAW == '(') {
   6383 	    int inputid = ctxt->input->id;
   6384 	    /* Recurse on second child */
   6385 	    NEXT;
   6386 	    SKIP_BLANKS;
   6387 	    last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
   6388                                                           depth + 1);
   6389 	    SKIP_BLANKS;
   6390 	} else {
   6391 	    elem = xmlParseName(ctxt);
   6392 	    if (elem == NULL) {
   6393 		xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
   6394 		if (ret != NULL)
   6395 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
   6396 		return(NULL);
   6397 	    }
   6398 	    last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
   6399 	    if (last == NULL) {
   6400 		if (ret != NULL)
   6401 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
   6402 		return(NULL);
   6403 	    }
   6404 	    if (RAW == '?') {
   6405 		last->ocur = XML_ELEMENT_CONTENT_OPT;
   6406 		NEXT;
   6407 	    } else if (RAW == '*') {
   6408 		last->ocur = XML_ELEMENT_CONTENT_MULT;
   6409 		NEXT;
   6410 	    } else if (RAW == '+') {
   6411 		last->ocur = XML_ELEMENT_CONTENT_PLUS;
   6412 		NEXT;
   6413 	    } else {
   6414 		last->ocur = XML_ELEMENT_CONTENT_ONCE;
   6415 	    }
   6416 	}
   6417 	SKIP_BLANKS;
   6418 	GROW;
   6419     }
   6420     if ((cur != NULL) && (last != NULL)) {
   6421         cur->c2 = last;
   6422 	if (last != NULL)
   6423 	    last->parent = cur;
   6424     }
   6425     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
   6426 	xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6427 "Element content declaration doesn't start and stop in the same entity\n",
   6428 			 NULL, NULL);
   6429     }
   6430     NEXT;
   6431     if (RAW == '?') {
   6432 	if (ret != NULL) {
   6433 	    if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
   6434 	        (ret->ocur == XML_ELEMENT_CONTENT_MULT))
   6435 	        ret->ocur = XML_ELEMENT_CONTENT_MULT;
   6436 	    else
   6437 	        ret->ocur = XML_ELEMENT_CONTENT_OPT;
   6438 	}
   6439 	NEXT;
   6440     } else if (RAW == '*') {
   6441 	if (ret != NULL) {
   6442 	    ret->ocur = XML_ELEMENT_CONTENT_MULT;
   6443 	    cur = ret;
   6444 	    /*
   6445 	     * Some normalization:
   6446 	     * (a | b* | c?)* == (a | b | c)*
   6447 	     */
   6448 	    while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
   6449 		if ((cur->c1 != NULL) &&
   6450 	            ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
   6451 		     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
   6452 		    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
   6453 		if ((cur->c2 != NULL) &&
   6454 	            ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
   6455 		     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
   6456 		    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
   6457 		cur = cur->c2;
   6458 	    }
   6459 	}
   6460 	NEXT;
   6461     } else if (RAW == '+') {
   6462 	if (ret != NULL) {
   6463 	    int found = 0;
   6464 
   6465 	    if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
   6466 	        (ret->ocur == XML_ELEMENT_CONTENT_MULT))
   6467 	        ret->ocur = XML_ELEMENT_CONTENT_MULT;
   6468 	    else
   6469 	        ret->ocur = XML_ELEMENT_CONTENT_PLUS;
   6470 	    /*
   6471 	     * Some normalization:
   6472 	     * (a | b*)+ == (a | b)*
   6473 	     * (a | b?)+ == (a | b)*
   6474 	     */
   6475 	    while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
   6476 		if ((cur->c1 != NULL) &&
   6477 	            ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
   6478 		     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
   6479 		    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
   6480 		    found = 1;
   6481 		}
   6482 		if ((cur->c2 != NULL) &&
   6483 	            ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
   6484 		     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
   6485 		    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
   6486 		    found = 1;
   6487 		}
   6488 		cur = cur->c2;
   6489 	    }
   6490 	    if (found)
   6491 		ret->ocur = XML_ELEMENT_CONTENT_MULT;
   6492 	}
   6493 	NEXT;
   6494     }
   6495     return(ret);
   6496 }
   6497 
   6498 /**
   6499  * xmlParseElementChildrenContentDecl:
   6500  * @ctxt:  an XML parser context
   6501  * @inputchk:  the input used for the current entity, needed for boundary checks
   6502  *
   6503  * parse the declaration for a Mixed Element content
   6504  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
   6505  *
   6506  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
   6507  *
   6508  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
   6509  *
   6510  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
   6511  *
   6512  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
   6513  *
   6514  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
   6515  * TODO Parameter-entity replacement text must be properly nested
   6516  *	with parenthesized groups. That is to say, if either of the
   6517  *	opening or closing parentheses in a choice, seq, or Mixed
   6518  *	construct is contained in the replacement text for a parameter
   6519  *	entity, both must be contained in the same replacement text. For
   6520  *	interoperability, if a parameter-entity reference appears in a
   6521  *	choice, seq, or Mixed construct, its replacement text should not
   6522  *	be empty, and neither the first nor last non-blank character of
   6523  *	the replacement text should be a connector (| or ,).
   6524  *
   6525  * Returns the tree of xmlElementContentPtr describing the element
   6526  *          hierarchy.
   6527  */
   6528 xmlElementContentPtr
   6529 xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
   6530     /* stub left for API/ABI compat */
   6531     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
   6532 }
   6533 
   6534 /**
   6535  * xmlParseElementContentDecl:
   6536  * @ctxt:  an XML parser context
   6537  * @name:  the name of the element being defined.
   6538  * @result:  the Element Content pointer will be stored here if any
   6539  *
   6540  * parse the declaration for an Element content either Mixed or Children,
   6541  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
   6542  *
   6543  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
   6544  *
   6545  * returns: the type of element content XML_ELEMENT_TYPE_xxx
   6546  */
   6547 
   6548 int
   6549 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
   6550                            xmlElementContentPtr *result) {
   6551 
   6552     xmlElementContentPtr tree = NULL;
   6553     int inputid = ctxt->input->id;
   6554     int res;
   6555 
   6556     *result = NULL;
   6557 
   6558     if (RAW != '(') {
   6559 	xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
   6560 		"xmlParseElementContentDecl : %s '(' expected\n", name);
   6561 	return(-1);
   6562     }
   6563     NEXT;
   6564     GROW;
   6565     if (ctxt->instate == XML_PARSER_EOF)
   6566         return(-1);
   6567     SKIP_BLANKS;
   6568     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
   6569         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
   6570 	res = XML_ELEMENT_TYPE_MIXED;
   6571     } else {
   6572         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
   6573 	res = XML_ELEMENT_TYPE_ELEMENT;
   6574     }
   6575     SKIP_BLANKS;
   6576     *result = tree;
   6577     return(res);
   6578 }
   6579 
   6580 /**
   6581  * xmlParseElementDecl:
   6582  * @ctxt:  an XML parser context
   6583  *
   6584  * parse an Element declaration.
   6585  *
   6586  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
   6587  *
   6588  * [ VC: Unique Element Type Declaration ]
   6589  * No element type may be declared more than once
   6590  *
   6591  * Returns the type of the element, or -1 in case of error
   6592  */
   6593 int
   6594 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
   6595     const xmlChar *name;
   6596     int ret = -1;
   6597     xmlElementContentPtr content  = NULL;
   6598 
   6599     /* GROW; done in the caller */
   6600     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
   6601 	xmlParserInputPtr input = ctxt->input;
   6602 
   6603 	SKIP(9);
   6604 	if (!IS_BLANK_CH(CUR)) {
   6605 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6606 		           "Space required after 'ELEMENT'\n");
   6607 	}
   6608         SKIP_BLANKS;
   6609         name = xmlParseName(ctxt);
   6610 	if (name == NULL) {
   6611 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   6612 			   "xmlParseElementDecl: no name for Element\n");
   6613 	    return(-1);
   6614 	}
   6615 	while ((RAW == 0) && (ctxt->inputNr > 1))
   6616 	    xmlPopInput(ctxt);
   6617 	if (!IS_BLANK_CH(CUR)) {
   6618 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6619 			   "Space required after the element name\n");
   6620 	}
   6621         SKIP_BLANKS;
   6622 	if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
   6623 	    SKIP(5);
   6624 	    /*
   6625 	     * Element must always be empty.
   6626 	     */
   6627 	    ret = XML_ELEMENT_TYPE_EMPTY;
   6628 	} else if ((RAW == 'A') && (NXT(1) == 'N') &&
   6629 	           (NXT(2) == 'Y')) {
   6630 	    SKIP(3);
   6631 	    /*
   6632 	     * Element is a generic container.
   6633 	     */
   6634 	    ret = XML_ELEMENT_TYPE_ANY;
   6635 	} else if (RAW == '(') {
   6636 	    ret = xmlParseElementContentDecl(ctxt, name, &content);
   6637 	} else {
   6638 	    /*
   6639 	     * [ WFC: PEs in Internal Subset ] error handling.
   6640 	     */
   6641 	    if ((RAW == '%') && (ctxt->external == 0) &&
   6642 	        (ctxt->inputNr == 1)) {
   6643 		xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
   6644 	  "PEReference: forbidden within markup decl in internal subset\n");
   6645 	    } else {
   6646 		xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
   6647 		      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
   6648             }
   6649 	    return(-1);
   6650 	}
   6651 
   6652 	SKIP_BLANKS;
   6653 	/*
   6654 	 * Pop-up of finished entities.
   6655 	 */
   6656 	while ((RAW == 0) && (ctxt->inputNr > 1))
   6657 	    xmlPopInput(ctxt);
   6658 	SKIP_BLANKS;
   6659 
   6660 	if (RAW != '>') {
   6661 	    xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
   6662 	    if (content != NULL) {
   6663 		xmlFreeDocElementContent(ctxt->myDoc, content);
   6664 	    }
   6665 	} else {
   6666 	    if (input != ctxt->input) {
   6667 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6668     "Element declaration doesn't start and stop in the same entity\n");
   6669 	    }
   6670 
   6671 	    NEXT;
   6672 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
   6673 		(ctxt->sax->elementDecl != NULL)) {
   6674 		if (content != NULL)
   6675 		    content->parent = NULL;
   6676 	        ctxt->sax->elementDecl(ctxt->userData, name, ret,
   6677 		                       content);
   6678 		if ((content != NULL) && (content->parent == NULL)) {
   6679 		    /*
   6680 		     * this is a trick: if xmlAddElementDecl is called,
   6681 		     * instead of copying the full tree it is plugged directly
   6682 		     * if called from the parser. Avoid duplicating the
   6683 		     * interfaces or change the API/ABI
   6684 		     */
   6685 		    xmlFreeDocElementContent(ctxt->myDoc, content);
   6686 		}
   6687 	    } else if (content != NULL) {
   6688 		xmlFreeDocElementContent(ctxt->myDoc, content);
   6689 	    }
   6690 	}
   6691     }
   6692     return(ret);
   6693 }
   6694 
   6695 /**
   6696  * xmlParseConditionalSections
   6697  * @ctxt:  an XML parser context
   6698  *
   6699  * [61] conditionalSect ::= includeSect | ignoreSect
   6700  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
   6701  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
   6702  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
   6703  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
   6704  */
   6705 
   6706 static void
   6707 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
   6708     int id = ctxt->input->id;
   6709 
   6710     SKIP(3);
   6711     SKIP_BLANKS;
   6712     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
   6713 	SKIP(7);
   6714 	SKIP_BLANKS;
   6715 	if (RAW != '[') {
   6716 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
   6717 	} else {
   6718 	    if (ctxt->input->id != id) {
   6719 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6720 	    "All markup of the conditional section is not in the same entity\n",
   6721 				     NULL, NULL);
   6722 	    }
   6723 	    NEXT;
   6724 	}
   6725 	if (xmlParserDebugEntities) {
   6726 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
   6727 		xmlGenericError(xmlGenericErrorContext,
   6728 			"%s(%d): ", ctxt->input->filename,
   6729 			ctxt->input->line);
   6730 	    xmlGenericError(xmlGenericErrorContext,
   6731 		    "Entering INCLUDE Conditional Section\n");
   6732 	}
   6733 
   6734 	while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
   6735 	        (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
   6736 	    const xmlChar *check = CUR_PTR;
   6737 	    unsigned int cons = ctxt->input->consumed;
   6738 
   6739 	    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
   6740 		xmlParseConditionalSections(ctxt);
   6741 	    } else if (IS_BLANK_CH(CUR)) {
   6742 		NEXT;
   6743 	    } else if (RAW == '%') {
   6744 		xmlParsePEReference(ctxt);
   6745 	    } else
   6746 		xmlParseMarkupDecl(ctxt);
   6747 
   6748 	    /*
   6749 	     * Pop-up of finished entities.
   6750 	     */
   6751 	    while ((RAW == 0) && (ctxt->inputNr > 1))
   6752 		xmlPopInput(ctxt);
   6753 
   6754 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
   6755 		xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
   6756 		break;
   6757 	    }
   6758 	}
   6759 	if (xmlParserDebugEntities) {
   6760 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
   6761 		xmlGenericError(xmlGenericErrorContext,
   6762 			"%s(%d): ", ctxt->input->filename,
   6763 			ctxt->input->line);
   6764 	    xmlGenericError(xmlGenericErrorContext,
   6765 		    "Leaving INCLUDE Conditional Section\n");
   6766 	}
   6767 
   6768     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
   6769 	int state;
   6770 	xmlParserInputState instate;
   6771 	int depth = 0;
   6772 
   6773 	SKIP(6);
   6774 	SKIP_BLANKS;
   6775 	if (RAW != '[') {
   6776 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
   6777 	} else {
   6778 	    if (ctxt->input->id != id) {
   6779 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6780 	    "All markup of the conditional section is not in the same entity\n",
   6781 				     NULL, NULL);
   6782 	    }
   6783 	    NEXT;
   6784 	}
   6785 	if (xmlParserDebugEntities) {
   6786 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
   6787 		xmlGenericError(xmlGenericErrorContext,
   6788 			"%s(%d): ", ctxt->input->filename,
   6789 			ctxt->input->line);
   6790 	    xmlGenericError(xmlGenericErrorContext,
   6791 		    "Entering IGNORE Conditional Section\n");
   6792 	}
   6793 
   6794 	/*
   6795 	 * Parse up to the end of the conditional section
   6796 	 * But disable SAX event generating DTD building in the meantime
   6797 	 */
   6798 	state = ctxt->disableSAX;
   6799 	instate = ctxt->instate;
   6800 	if (ctxt->recovery == 0) ctxt->disableSAX = 1;
   6801 	ctxt->instate = XML_PARSER_IGNORE;
   6802 
   6803 	while (((depth >= 0) && (RAW != 0)) &&
   6804                (ctxt->instate != XML_PARSER_EOF)) {
   6805 	  if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
   6806 	    depth++;
   6807 	    SKIP(3);
   6808 	    continue;
   6809 	  }
   6810 	  if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
   6811 	    if (--depth >= 0) SKIP(3);
   6812 	    continue;
   6813 	  }
   6814 	  NEXT;
   6815 	  continue;
   6816 	}
   6817 
   6818 	ctxt->disableSAX = state;
   6819 	ctxt->instate = instate;
   6820 
   6821 	if (xmlParserDebugEntities) {
   6822 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
   6823 		xmlGenericError(xmlGenericErrorContext,
   6824 			"%s(%d): ", ctxt->input->filename,
   6825 			ctxt->input->line);
   6826 	    xmlGenericError(xmlGenericErrorContext,
   6827 		    "Leaving IGNORE Conditional Section\n");
   6828 	}
   6829 
   6830     } else {
   6831 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
   6832     }
   6833 
   6834     if (RAW == 0)
   6835         SHRINK;
   6836 
   6837     if (RAW == 0) {
   6838 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
   6839     } else {
   6840 	if (ctxt->input->id != id) {
   6841 	    xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
   6842 	"All markup of the conditional section is not in the same entity\n",
   6843 				 NULL, NULL);
   6844 	}
   6845         SKIP(3);
   6846     }
   6847 }
   6848 
   6849 /**
   6850  * xmlParseMarkupDecl:
   6851  * @ctxt:  an XML parser context
   6852  *
   6853  * parse Markup declarations
   6854  *
   6855  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
   6856  *                     NotationDecl | PI | Comment
   6857  *
   6858  * [ VC: Proper Declaration/PE Nesting ]
   6859  * Parameter-entity replacement text must be properly nested with
   6860  * markup declarations. That is to say, if either the first character
   6861  * or the last character of a markup declaration (markupdecl above) is
   6862  * contained in the replacement text for a parameter-entity reference,
   6863  * both must be contained in the same replacement text.
   6864  *
   6865  * [ WFC: PEs in Internal Subset ]
   6866  * In the internal DTD subset, parameter-entity references can occur
   6867  * only where markup declarations can occur, not within markup declarations.
   6868  * (This does not apply to references that occur in external parameter
   6869  * entities or to the external subset.)
   6870  */
   6871 void
   6872 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
   6873     GROW;
   6874     if (CUR == '<') {
   6875         if (NXT(1) == '!') {
   6876 	    switch (NXT(2)) {
   6877 	        case 'E':
   6878 		    if (NXT(3) == 'L')
   6879 			xmlParseElementDecl(ctxt);
   6880 		    else if (NXT(3) == 'N')
   6881 			xmlParseEntityDecl(ctxt);
   6882 		    break;
   6883 	        case 'A':
   6884 		    xmlParseAttributeListDecl(ctxt);
   6885 		    break;
   6886 	        case 'N':
   6887 		    xmlParseNotationDecl(ctxt);
   6888 		    break;
   6889 	        case '-':
   6890 		    xmlParseComment(ctxt);
   6891 		    break;
   6892 		default:
   6893 		    /* there is an error but it will be detected later */
   6894 		    break;
   6895 	    }
   6896 	} else if (NXT(1) == '?') {
   6897 	    xmlParsePI(ctxt);
   6898 	}
   6899     }
   6900     /*
   6901      * This is only for internal subset. On external entities,
   6902      * the replacement is done before parsing stage
   6903      */
   6904     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
   6905 	xmlParsePEReference(ctxt);
   6906 
   6907     /*
   6908      * Conditional sections are allowed from entities included
   6909      * by PE References in the internal subset.
   6910      */
   6911     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
   6912         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
   6913 	    xmlParseConditionalSections(ctxt);
   6914 	}
   6915     }
   6916 
   6917     ctxt->instate = XML_PARSER_DTD;
   6918 }
   6919 
   6920 /**
   6921  * xmlParseTextDecl:
   6922  * @ctxt:  an XML parser context
   6923  *
   6924  * parse an XML declaration header for external entities
   6925  *
   6926  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
   6927  */
   6928 
   6929 void
   6930 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
   6931     xmlChar *version;
   6932     const xmlChar *encoding;
   6933 
   6934     /*
   6935      * We know that '<?xml' is here.
   6936      */
   6937     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
   6938 	SKIP(5);
   6939     } else {
   6940 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
   6941 	return;
   6942     }
   6943 
   6944     if (!IS_BLANK_CH(CUR)) {
   6945 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6946 		       "Space needed after '<?xml'\n");
   6947     }
   6948     SKIP_BLANKS;
   6949 
   6950     /*
   6951      * We may have the VersionInfo here.
   6952      */
   6953     version = xmlParseVersionInfo(ctxt);
   6954     if (version == NULL)
   6955 	version = xmlCharStrdup(XML_DEFAULT_VERSION);
   6956     else {
   6957 	if (!IS_BLANK_CH(CUR)) {
   6958 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   6959 		           "Space needed here\n");
   6960 	}
   6961     }
   6962     ctxt->input->version = version;
   6963 
   6964     /*
   6965      * We must have the encoding declaration
   6966      */
   6967     encoding = xmlParseEncodingDecl(ctxt);
   6968     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
   6969 	/*
   6970 	 * The XML REC instructs us to stop parsing right here
   6971 	 */
   6972         return;
   6973     }
   6974     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
   6975 	xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
   6976 		       "Missing encoding in text declaration\n");
   6977     }
   6978 
   6979     SKIP_BLANKS;
   6980     if ((RAW == '?') && (NXT(1) == '>')) {
   6981         SKIP(2);
   6982     } else if (RAW == '>') {
   6983         /* Deprecated old WD ... */
   6984 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
   6985 	NEXT;
   6986     } else {
   6987 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
   6988 	MOVETO_ENDTAG(CUR_PTR);
   6989 	NEXT;
   6990     }
   6991 }
   6992 
   6993 /**
   6994  * xmlParseExternalSubset:
   6995  * @ctxt:  an XML parser context
   6996  * @ExternalID: the external identifier
   6997  * @SystemID: the system identifier (or URL)
   6998  *
   6999  * parse Markup declarations from an external subset
   7000  *
   7001  * [30] extSubset ::= textDecl? extSubsetDecl
   7002  *
   7003  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
   7004  */
   7005 void
   7006 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
   7007                        const xmlChar *SystemID) {
   7008     xmlDetectSAX2(ctxt);
   7009     GROW;
   7010 
   7011     if ((ctxt->encoding == NULL) &&
   7012         (ctxt->input->end - ctxt->input->cur >= 4)) {
   7013         xmlChar start[4];
   7014 	xmlCharEncoding enc;
   7015 
   7016 	start[0] = RAW;
   7017 	start[1] = NXT(1);
   7018 	start[2] = NXT(2);
   7019 	start[3] = NXT(3);
   7020 	enc = xmlDetectCharEncoding(start, 4);
   7021 	if (enc != XML_CHAR_ENCODING_NONE)
   7022 	    xmlSwitchEncoding(ctxt, enc);
   7023     }
   7024 
   7025     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
   7026 	xmlParseTextDecl(ctxt);
   7027 	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
   7028 	    /*
   7029 	     * The XML REC instructs us to stop parsing right here
   7030 	     */
   7031 	    ctxt->instate = XML_PARSER_EOF;
   7032 	    return;
   7033 	}
   7034     }
   7035     if (ctxt->myDoc == NULL) {
   7036         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
   7037 	if (ctxt->myDoc == NULL) {
   7038 	    xmlErrMemory(ctxt, "New Doc failed");
   7039 	    return;
   7040 	}
   7041 	ctxt->myDoc->properties = XML_DOC_INTERNAL;
   7042     }
   7043     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
   7044         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
   7045 
   7046     ctxt->instate = XML_PARSER_DTD;
   7047     ctxt->external = 1;
   7048     while (((RAW == '<') && (NXT(1) == '?')) ||
   7049            ((RAW == '<') && (NXT(1) == '!')) ||
   7050 	   (RAW == '%') || IS_BLANK_CH(CUR)) {
   7051 	const xmlChar *check = CUR_PTR;
   7052 	unsigned int cons = ctxt->input->consumed;
   7053 
   7054 	GROW;
   7055         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
   7056 	    xmlParseConditionalSections(ctxt);
   7057 	} else if (IS_BLANK_CH(CUR)) {
   7058 	    NEXT;
   7059 	} else if (RAW == '%') {
   7060             xmlParsePEReference(ctxt);
   7061 	} else
   7062 	    xmlParseMarkupDecl(ctxt);
   7063 
   7064 	/*
   7065 	 * Pop-up of finished entities.
   7066 	 */
   7067 	while ((RAW == 0) && (ctxt->inputNr > 1))
   7068 	    xmlPopInput(ctxt);
   7069 
   7070 	if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
   7071 	    xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
   7072 	    break;
   7073 	}
   7074     }
   7075 
   7076     if (RAW != 0) {
   7077 	xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
   7078     }
   7079 
   7080 }
   7081 
   7082 /**
   7083  * xmlParseReference:
   7084  * @ctxt:  an XML parser context
   7085  *
   7086  * parse and handle entity references in content, depending on the SAX
   7087  * interface, this may end-up in a call to character() if this is a
   7088  * CharRef, a predefined entity, if there is no reference() callback.
   7089  * or if the parser was asked to switch to that mode.
   7090  *
   7091  * [67] Reference ::= EntityRef | CharRef
   7092  */
   7093 void
   7094 xmlParseReference(xmlParserCtxtPtr ctxt) {
   7095     xmlEntityPtr ent;
   7096     xmlChar *val;
   7097     int was_checked;
   7098     xmlNodePtr list = NULL;
   7099     xmlParserErrors ret = XML_ERR_OK;
   7100 
   7101 
   7102     if (RAW != '&')
   7103         return;
   7104 
   7105     /*
   7106      * Simple case of a CharRef
   7107      */
   7108     if (NXT(1) == '#') {
   7109 	int i = 0;
   7110 	xmlChar out[10];
   7111 	int hex = NXT(2);
   7112 	int value = xmlParseCharRef(ctxt);
   7113 
   7114 	if (value == 0)
   7115 	    return;
   7116 	if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
   7117 	    /*
   7118 	     * So we are using non-UTF-8 buffers
   7119 	     * Check that the char fit on 8bits, if not
   7120 	     * generate a CharRef.
   7121 	     */
   7122 	    if (value <= 0xFF) {
   7123 		out[0] = value;
   7124 		out[1] = 0;
   7125 		if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
   7126 		    (!ctxt->disableSAX))
   7127 		    ctxt->sax->characters(ctxt->userData, out, 1);
   7128 	    } else {
   7129 		if ((hex == 'x') || (hex == 'X'))
   7130 		    snprintf((char *)out, sizeof(out), "#x%X", value);
   7131 		else
   7132 		    snprintf((char *)out, sizeof(out), "#%d", value);
   7133 		if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
   7134 		    (!ctxt->disableSAX))
   7135 		    ctxt->sax->reference(ctxt->userData, out);
   7136 	    }
   7137 	} else {
   7138 	    /*
   7139 	     * Just encode the value in UTF-8
   7140 	     */
   7141 	    COPY_BUF(0 ,out, i, value);
   7142 	    out[i] = 0;
   7143 	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
   7144 		(!ctxt->disableSAX))
   7145 		ctxt->sax->characters(ctxt->userData, out, i);
   7146 	}
   7147 	return;
   7148     }
   7149 
   7150     /*
   7151      * We are seeing an entity reference
   7152      */
   7153     ent = xmlParseEntityRef(ctxt);
   7154     if (ent == NULL) return;
   7155     if (!ctxt->wellFormed)
   7156 	return;
   7157     was_checked = ent->checked;
   7158 
   7159     /* special case of predefined entities */
   7160     if ((ent->name == NULL) ||
   7161         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
   7162 	val = ent->content;
   7163 	if (val == NULL) return;
   7164 	/*
   7165 	 * inline the entity.
   7166 	 */
   7167 	if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
   7168 	    (!ctxt->disableSAX))
   7169 	    ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
   7170 	return;
   7171     }
   7172 
   7173     /*
   7174      * The first reference to the entity trigger a parsing phase
   7175      * where the ent->children is filled with the result from
   7176      * the parsing.
   7177      * Note: external parsed entities will not be loaded, it is not
   7178      * required for a non-validating parser, unless the parsing option
   7179      * of validating, or substituting entities were given. Doing so is
   7180      * far more secure as the parser will only process data coming from
   7181      * the document entity by default.
   7182      */
   7183     if ((ent->checked == 0) &&
   7184         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
   7185          (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
   7186 	unsigned long oldnbent = ctxt->nbentities;
   7187 
   7188 	/*
   7189 	 * This is a bit hackish but this seems the best
   7190 	 * way to make sure both SAX and DOM entity support
   7191 	 * behaves okay.
   7192 	 */
   7193 	void *user_data;
   7194 	if (ctxt->userData == ctxt)
   7195 	    user_data = NULL;
   7196 	else
   7197 	    user_data = ctxt->userData;
   7198 
   7199 	/*
   7200 	 * Check that this entity is well formed
   7201 	 * 4.3.2: An internal general parsed entity is well-formed
   7202 	 * if its replacement text matches the production labeled
   7203 	 * content.
   7204 	 */
   7205 	if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
   7206 	    ctxt->depth++;
   7207 	    ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
   7208 	                                              user_data, &list);
   7209 	    ctxt->depth--;
   7210 
   7211 	} else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
   7212 	    ctxt->depth++;
   7213 	    ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
   7214 	                                   user_data, ctxt->depth, ent->URI,
   7215 					   ent->ExternalID, &list);
   7216 	    ctxt->depth--;
   7217 	} else {
   7218 	    ret = XML_ERR_ENTITY_PE_INTERNAL;
   7219 	    xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
   7220 			 "invalid entity type found\n", NULL);
   7221 	}
   7222 
   7223 	/*
   7224 	 * Store the number of entities needing parsing for this entity
   7225 	 * content and do checkings
   7226 	 */
   7227 	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
   7228 	if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
   7229 	    ent->checked |= 1;
   7230 	if (ret == XML_ERR_ENTITY_LOOP) {
   7231 	    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
   7232 	    xmlFreeNodeList(list);
   7233 	    return;
   7234 	}
   7235 	if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
   7236 	    xmlFreeNodeList(list);
   7237 	    return;
   7238 	}
   7239 
   7240 	if ((ret == XML_ERR_OK) && (list != NULL)) {
   7241 	    if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
   7242 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
   7243 		(ent->children == NULL)) {
   7244 		ent->children = list;
   7245 		if (ctxt->replaceEntities) {
   7246 		    /*
   7247 		     * Prune it directly in the generated document
   7248 		     * except for single text nodes.
   7249 		     */
   7250 		    if (((list->type == XML_TEXT_NODE) &&
   7251 			 (list->next == NULL)) ||
   7252 			(ctxt->parseMode == XML_PARSE_READER)) {
   7253 			list->parent = (xmlNodePtr) ent;
   7254 			list = NULL;
   7255 			ent->owner = 1;
   7256 		    } else {
   7257 			ent->owner = 0;
   7258 			while (list != NULL) {
   7259 			    list->parent = (xmlNodePtr) ctxt->node;
   7260 			    list->doc = ctxt->myDoc;
   7261 			    if (list->next == NULL)
   7262 				ent->last = list;
   7263 			    list = list->next;
   7264 			}
   7265 			list = ent->children;
   7266 #ifdef LIBXML_LEGACY_ENABLED
   7267 			if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
   7268 			  xmlAddEntityReference(ent, list, NULL);
   7269 #endif /* LIBXML_LEGACY_ENABLED */
   7270 		    }
   7271 		} else {
   7272 		    ent->owner = 1;
   7273 		    while (list != NULL) {
   7274 			list->parent = (xmlNodePtr) ent;
   7275 			xmlSetTreeDoc(list, ent->doc);
   7276 			if (list->next == NULL)
   7277 			    ent->last = list;
   7278 			list = list->next;
   7279 		    }
   7280 		}
   7281 	    } else {
   7282 		xmlFreeNodeList(list);
   7283 		list = NULL;
   7284 	    }
   7285 	} else if ((ret != XML_ERR_OK) &&
   7286 		   (ret != XML_WAR_UNDECLARED_ENTITY)) {
   7287 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
   7288 		     "Entity '%s' failed to parse\n", ent->name);
   7289 	} else if (list != NULL) {
   7290 	    xmlFreeNodeList(list);
   7291 	    list = NULL;
   7292 	}
   7293 	if (ent->checked == 0)
   7294 	    ent->checked = 2;
   7295     } else if (ent->checked != 1) {
   7296 	ctxt->nbentities += ent->checked / 2;
   7297     }
   7298 
   7299     /*
   7300      * Now that the entity content has been gathered
   7301      * provide it to the application, this can take different forms based
   7302      * on the parsing modes.
   7303      */
   7304     if (ent->children == NULL) {
   7305 	/*
   7306 	 * Probably running in SAX mode and the callbacks don't
   7307 	 * build the entity content. So unless we already went
   7308 	 * though parsing for first checking go though the entity
   7309 	 * content to generate callbacks associated to the entity
   7310 	 */
   7311 	if (was_checked != 0) {
   7312 	    void *user_data;
   7313 	    /*
   7314 	     * This is a bit hackish but this seems the best
   7315 	     * way to make sure both SAX and DOM entity support
   7316 	     * behaves okay.
   7317 	     */
   7318 	    if (ctxt->userData == ctxt)
   7319 		user_data = NULL;
   7320 	    else
   7321 		user_data = ctxt->userData;
   7322 
   7323 	    if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
   7324 		ctxt->depth++;
   7325 		ret = xmlParseBalancedChunkMemoryInternal(ctxt,
   7326 				   ent->content, user_data, NULL);
   7327 		ctxt->depth--;
   7328 	    } else if (ent->etype ==
   7329 		       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
   7330 		ctxt->depth++;
   7331 		ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
   7332 			   ctxt->sax, user_data, ctxt->depth,
   7333 			   ent->URI, ent->ExternalID, NULL);
   7334 		ctxt->depth--;
   7335 	    } else {
   7336 		ret = XML_ERR_ENTITY_PE_INTERNAL;
   7337 		xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
   7338 			     "invalid entity type found\n", NULL);
   7339 	    }
   7340 	    if (ret == XML_ERR_ENTITY_LOOP) {
   7341 		xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
   7342 		return;
   7343 	    }
   7344 	}
   7345 	if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
   7346 	    (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
   7347 	    /*
   7348 	     * Entity reference callback comes second, it's somewhat
   7349 	     * superfluous but a compatibility to historical behaviour
   7350 	     */
   7351 	    ctxt->sax->reference(ctxt->userData, ent->name);
   7352 	}
   7353 	return;
   7354     }
   7355 
   7356     /*
   7357      * If we didn't get any children for the entity being built
   7358      */
   7359     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
   7360 	(ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
   7361 	/*
   7362 	 * Create a node.
   7363 	 */
   7364 	ctxt->sax->reference(ctxt->userData, ent->name);
   7365 	return;
   7366     }
   7367 
   7368     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
   7369 	/*
   7370 	 * There is a problem on the handling of _private for entities
   7371 	 * (bug 155816): Should we copy the content of the field from
   7372 	 * the entity (possibly overwriting some value set by the user
   7373 	 * when a copy is created), should we leave it alone, or should
   7374 	 * we try to take care of different situations?  The problem
   7375 	 * is exacerbated by the usage of this field by the xmlReader.
   7376 	 * To fix this bug, we look at _private on the created node
   7377 	 * and, if it's NULL, we copy in whatever was in the entity.
   7378 	 * If it's not NULL we leave it alone.  This is somewhat of a
   7379 	 * hack - maybe we should have further tests to determine
   7380 	 * what to do.
   7381 	 */
   7382 	if ((ctxt->node != NULL) && (ent->children != NULL)) {
   7383 	    /*
   7384 	     * Seems we are generating the DOM content, do
   7385 	     * a simple tree copy for all references except the first
   7386 	     * In the first occurrence list contains the replacement.
   7387 	     */
   7388 	    if (((list == NULL) && (ent->owner == 0)) ||
   7389 		(ctxt->parseMode == XML_PARSE_READER)) {
   7390 		xmlNodePtr nw = NULL, cur, firstChild = NULL;
   7391 
   7392 		/*
   7393 		 * We are copying here, make sure there is no abuse
   7394 		 */
   7395 		ctxt->sizeentcopy += ent->length;
   7396 		if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
   7397 		    return;
   7398 
   7399 		/*
   7400 		 * when operating on a reader, the entities definitions
   7401 		 * are always owning the entities subtree.
   7402 		if (ctxt->parseMode == XML_PARSE_READER)
   7403 		    ent->owner = 1;
   7404 		 */
   7405 
   7406 		cur = ent->children;
   7407 		while (cur != NULL) {
   7408 		    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
   7409 		    if (nw != NULL) {
   7410 			if (nw->_private == NULL)
   7411 			    nw->_private = cur->_private;
   7412 			if (firstChild == NULL){
   7413 			    firstChild = nw;
   7414 			}
   7415 			nw = xmlAddChild(ctxt->node, nw);
   7416 		    }
   7417 		    if (cur == ent->last) {
   7418 			/*
   7419 			 * needed to detect some strange empty
   7420 			 * node cases in the reader tests
   7421 			 */
   7422 			if ((ctxt->parseMode == XML_PARSE_READER) &&
   7423 			    (nw != NULL) &&
   7424 			    (nw->type == XML_ELEMENT_NODE) &&
   7425 			    (nw->children == NULL))
   7426 			    nw->extra = 1;
   7427 
   7428 			break;
   7429 		    }
   7430 		    cur = cur->next;
   7431 		}
   7432 #ifdef LIBXML_LEGACY_ENABLED
   7433 		if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
   7434 		  xmlAddEntityReference(ent, firstChild, nw);
   7435 #endif /* LIBXML_LEGACY_ENABLED */
   7436 	    } else if ((list == NULL) || (ctxt->inputNr > 0)) {
   7437 		xmlNodePtr nw = NULL, cur, next, last,
   7438 			   firstChild = NULL;
   7439 
   7440 		/*
   7441 		 * We are copying here, make sure there is no abuse
   7442 		 */
   7443 		ctxt->sizeentcopy += ent->length;
   7444 		if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
   7445 		    return;
   7446 
   7447 		/*
   7448 		 * Copy the entity child list and make it the new
   7449 		 * entity child list. The goal is to make sure any
   7450 		 * ID or REF referenced will be the one from the
   7451 		 * document content and not the entity copy.
   7452 		 */
   7453 		cur = ent->children;
   7454 		ent->children = NULL;
   7455 		last = ent->last;
   7456 		ent->last = NULL;
   7457 		while (cur != NULL) {
   7458 		    next = cur->next;
   7459 		    cur->next = NULL;
   7460 		    cur->parent = NULL;
   7461 		    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
   7462 		    if (nw != NULL) {
   7463 			if (nw->_private == NULL)
   7464 			    nw->_private = cur->_private;
   7465 			if (firstChild == NULL){
   7466 			    firstChild = cur;
   7467 			}
   7468 			xmlAddChild((xmlNodePtr) ent, nw);
   7469 			xmlAddChild(ctxt->node, cur);
   7470 		    }
   7471 		    if (cur == last)
   7472 			break;
   7473 		    cur = next;
   7474 		}
   7475 		if (ent->owner == 0)
   7476 		    ent->owner = 1;
   7477 #ifdef LIBXML_LEGACY_ENABLED
   7478 		if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
   7479 		  xmlAddEntityReference(ent, firstChild, nw);
   7480 #endif /* LIBXML_LEGACY_ENABLED */
   7481 	    } else {
   7482 		const xmlChar *nbktext;
   7483 
   7484 		/*
   7485 		 * the name change is to avoid coalescing of the
   7486 		 * node with a possible previous text one which
   7487 		 * would make ent->children a dangling pointer
   7488 		 */
   7489 		nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
   7490 					-1);
   7491 		if (ent->children->type == XML_TEXT_NODE)
   7492 		    ent->children->name = nbktext;
   7493 		if ((ent->last != ent->children) &&
   7494 		    (ent->last->type == XML_TEXT_NODE))
   7495 		    ent->last->name = nbktext;
   7496 		xmlAddChildList(ctxt->node, ent->children);
   7497 	    }
   7498 
   7499 	    /*
   7500 	     * This is to avoid a nasty side effect, see
   7501 	     * characters() in SAX.c
   7502 	     */
   7503 	    ctxt->nodemem = 0;
   7504 	    ctxt->nodelen = 0;
   7505 	    return;
   7506 	}
   7507     }
   7508 }
   7509 
   7510 /**
   7511  * xmlParseEntityRef:
   7512  * @ctxt:  an XML parser context
   7513  *
   7514  * parse ENTITY references declarations
   7515  *
   7516  * [68] EntityRef ::= '&' Name ';'
   7517  *
   7518  * [ WFC: Entity Declared ]
   7519  * In a document without any DTD, a document with only an internal DTD
   7520  * subset which contains no parameter entity references, or a document
   7521  * with "standalone='yes'", the Name given in the entity reference
   7522  * must match that in an entity declaration, except that well-formed
   7523  * documents need not declare any of the following entities: amp, lt,
   7524  * gt, apos, quot.  The declaration of a parameter entity must precede
   7525  * any reference to it.  Similarly, the declaration of a general entity
   7526  * must precede any reference to it which appears in a default value in an
   7527  * attribute-list declaration. Note that if entities are declared in the
   7528  * external subset or in external parameter entities, a non-validating
   7529  * processor is not obligated to read and process their declarations;
   7530  * for such documents, the rule that an entity must be declared is a
   7531  * well-formedness constraint only if standalone='yes'.
   7532  *
   7533  * [ WFC: Parsed Entity ]
   7534  * An entity reference must not contain the name of an unparsed entity
   7535  *
   7536  * Returns the xmlEntityPtr if found, or NULL otherwise.
   7537  */
   7538 xmlEntityPtr
   7539 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
   7540     const xmlChar *name;
   7541     xmlEntityPtr ent = NULL;
   7542 
   7543     GROW;
   7544     if (ctxt->instate == XML_PARSER_EOF)
   7545         return(NULL);
   7546 
   7547     if (RAW != '&')
   7548         return(NULL);
   7549     NEXT;
   7550     name = xmlParseName(ctxt);
   7551     if (name == NULL) {
   7552 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   7553 		       "xmlParseEntityRef: no name\n");
   7554         return(NULL);
   7555     }
   7556     if (RAW != ';') {
   7557 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
   7558 	return(NULL);
   7559     }
   7560     NEXT;
   7561 
   7562     /*
   7563      * Predefined entities override any extra definition
   7564      */
   7565     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
   7566         ent = xmlGetPredefinedEntity(name);
   7567         if (ent != NULL)
   7568             return(ent);
   7569     }
   7570 
   7571     /*
   7572      * Increase the number of entity references parsed
   7573      */
   7574     ctxt->nbentities++;
   7575 
   7576     /*
   7577      * Ask first SAX for entity resolution, otherwise try the
   7578      * entities which may have stored in the parser context.
   7579      */
   7580     if (ctxt->sax != NULL) {
   7581 	if (ctxt->sax->getEntity != NULL)
   7582 	    ent = ctxt->sax->getEntity(ctxt->userData, name);
   7583 	if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
   7584 	    (ctxt->options & XML_PARSE_OLDSAX))
   7585 	    ent = xmlGetPredefinedEntity(name);
   7586 	if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
   7587 	    (ctxt->userData==ctxt)) {
   7588 	    ent = xmlSAX2GetEntity(ctxt, name);
   7589 	}
   7590     }
   7591     if (ctxt->instate == XML_PARSER_EOF)
   7592 	return(NULL);
   7593     /*
   7594      * [ WFC: Entity Declared ]
   7595      * In a document without any DTD, a document with only an
   7596      * internal DTD subset which contains no parameter entity
   7597      * references, or a document with "standalone='yes'", the
   7598      * Name given in the entity reference must match that in an
   7599      * entity declaration, except that well-formed documents
   7600      * need not declare any of the following entities: amp, lt,
   7601      * gt, apos, quot.
   7602      * The declaration of a parameter entity must precede any
   7603      * reference to it.
   7604      * Similarly, the declaration of a general entity must
   7605      * precede any reference to it which appears in a default
   7606      * value in an attribute-list declaration. Note that if
   7607      * entities are declared in the external subset or in
   7608      * external parameter entities, a non-validating processor
   7609      * is not obligated to read and process their declarations;
   7610      * for such documents, the rule that an entity must be
   7611      * declared is a well-formedness constraint only if
   7612      * standalone='yes'.
   7613      */
   7614     if (ent == NULL) {
   7615 	if ((ctxt->standalone == 1) ||
   7616 	    ((ctxt->hasExternalSubset == 0) &&
   7617 	     (ctxt->hasPErefs == 0))) {
   7618 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
   7619 		     "Entity '%s' not defined\n", name);
   7620 	} else {
   7621 	    xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
   7622 		     "Entity '%s' not defined\n", name);
   7623 	    if ((ctxt->inSubset == 0) &&
   7624 		(ctxt->sax != NULL) &&
   7625 		(ctxt->sax->reference != NULL)) {
   7626 		ctxt->sax->reference(ctxt->userData, name);
   7627 	    }
   7628 	}
   7629 	ctxt->valid = 0;
   7630     }
   7631 
   7632     /*
   7633      * [ WFC: Parsed Entity ]
   7634      * An entity reference must not contain the name of an
   7635      * unparsed entity
   7636      */
   7637     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
   7638 	xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
   7639 		 "Entity reference to unparsed entity %s\n", name);
   7640     }
   7641 
   7642     /*
   7643      * [ WFC: No External Entity References ]
   7644      * Attribute values cannot contain direct or indirect
   7645      * entity references to external entities.
   7646      */
   7647     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
   7648 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
   7649 	xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
   7650 	     "Attribute references external entity '%s'\n", name);
   7651     }
   7652     /*
   7653      * [ WFC: No < in Attribute Values ]
   7654      * The replacement text of any entity referred to directly or
   7655      * indirectly in an attribute value (other than "&lt;") must
   7656      * not contain a <.
   7657      */
   7658     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
   7659 	     (ent != NULL) &&
   7660 	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
   7661 	if ((ent->checked & 1) || ((ent->checked == 0) &&
   7662 	     (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
   7663 	    xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
   7664 	"'<' in entity '%s' is not allowed in attributes values\n", name);
   7665         }
   7666     }
   7667 
   7668     /*
   7669      * Internal check, no parameter entities here ...
   7670      */
   7671     else {
   7672 	switch (ent->etype) {
   7673 	    case XML_INTERNAL_PARAMETER_ENTITY:
   7674 	    case XML_EXTERNAL_PARAMETER_ENTITY:
   7675 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
   7676 	     "Attempt to reference the parameter entity '%s'\n",
   7677 			      name);
   7678 	    break;
   7679 	    default:
   7680 	    break;
   7681 	}
   7682     }
   7683 
   7684     /*
   7685      * [ WFC: No Recursion ]
   7686      * A parsed entity must not contain a recursive reference
   7687      * to itself, either directly or indirectly.
   7688      * Done somewhere else
   7689      */
   7690     return(ent);
   7691 }
   7692 
   7693 /**
   7694  * xmlParseStringEntityRef:
   7695  * @ctxt:  an XML parser context
   7696  * @str:  a pointer to an index in the string
   7697  *
   7698  * parse ENTITY references declarations, but this version parses it from
   7699  * a string value.
   7700  *
   7701  * [68] EntityRef ::= '&' Name ';'
   7702  *
   7703  * [ WFC: Entity Declared ]
   7704  * In a document without any DTD, a document with only an internal DTD
   7705  * subset which contains no parameter entity references, or a document
   7706  * with "standalone='yes'", the Name given in the entity reference
   7707  * must match that in an entity declaration, except that well-formed
   7708  * documents need not declare any of the following entities: amp, lt,
   7709  * gt, apos, quot.  The declaration of a parameter entity must precede
   7710  * any reference to it.  Similarly, the declaration of a general entity
   7711  * must precede any reference to it which appears in a default value in an
   7712  * attribute-list declaration. Note that if entities are declared in the
   7713  * external subset or in external parameter entities, a non-validating
   7714  * processor is not obligated to read and process their declarations;
   7715  * for such documents, the rule that an entity must be declared is a
   7716  * well-formedness constraint only if standalone='yes'.
   7717  *
   7718  * [ WFC: Parsed Entity ]
   7719  * An entity reference must not contain the name of an unparsed entity
   7720  *
   7721  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
   7722  * is updated to the current location in the string.
   7723  */
   7724 static xmlEntityPtr
   7725 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
   7726     xmlChar *name;
   7727     const xmlChar *ptr;
   7728     xmlChar cur;
   7729     xmlEntityPtr ent = NULL;
   7730 
   7731     if ((str == NULL) || (*str == NULL))
   7732         return(NULL);
   7733     ptr = *str;
   7734     cur = *ptr;
   7735     if (cur != '&')
   7736 	return(NULL);
   7737 
   7738     ptr++;
   7739     name = xmlParseStringName(ctxt, &ptr);
   7740     if (name == NULL) {
   7741 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   7742 		       "xmlParseStringEntityRef: no name\n");
   7743 	*str = ptr;
   7744 	return(NULL);
   7745     }
   7746     if (*ptr != ';') {
   7747 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
   7748         xmlFree(name);
   7749 	*str = ptr;
   7750 	return(NULL);
   7751     }
   7752     ptr++;
   7753 
   7754 
   7755     /*
   7756      * Predefined entites override any extra definition
   7757      */
   7758     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
   7759         ent = xmlGetPredefinedEntity(name);
   7760         if (ent != NULL) {
   7761             xmlFree(name);
   7762             *str = ptr;
   7763             return(ent);
   7764         }
   7765     }
   7766 
   7767     /*
   7768      * Increate the number of entity references parsed
   7769      */
   7770     ctxt->nbentities++;
   7771 
   7772     /*
   7773      * Ask first SAX for entity resolution, otherwise try the
   7774      * entities which may have stored in the parser context.
   7775      */
   7776     if (ctxt->sax != NULL) {
   7777 	if (ctxt->sax->getEntity != NULL)
   7778 	    ent = ctxt->sax->getEntity(ctxt->userData, name);
   7779 	if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
   7780 	    ent = xmlGetPredefinedEntity(name);
   7781 	if ((ent == NULL) && (ctxt->userData==ctxt)) {
   7782 	    ent = xmlSAX2GetEntity(ctxt, name);
   7783 	}
   7784     }
   7785     if (ctxt->instate == XML_PARSER_EOF) {
   7786 	xmlFree(name);
   7787 	return(NULL);
   7788     }
   7789 
   7790     /*
   7791      * [ WFC: Entity Declared ]
   7792      * In a document without any DTD, a document with only an
   7793      * internal DTD subset which contains no parameter entity
   7794      * references, or a document with "standalone='yes'", the
   7795      * Name given in the entity reference must match that in an
   7796      * entity declaration, except that well-formed documents
   7797      * need not declare any of the following entities: amp, lt,
   7798      * gt, apos, quot.
   7799      * The declaration of a parameter entity must precede any
   7800      * reference to it.
   7801      * Similarly, the declaration of a general entity must
   7802      * precede any reference to it which appears in a default
   7803      * value in an attribute-list declaration. Note that if
   7804      * entities are declared in the external subset or in
   7805      * external parameter entities, a non-validating processor
   7806      * is not obligated to read and process their declarations;
   7807      * for such documents, the rule that an entity must be
   7808      * declared is a well-formedness constraint only if
   7809      * standalone='yes'.
   7810      */
   7811     if (ent == NULL) {
   7812 	if ((ctxt->standalone == 1) ||
   7813 	    ((ctxt->hasExternalSubset == 0) &&
   7814 	     (ctxt->hasPErefs == 0))) {
   7815 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
   7816 		     "Entity '%s' not defined\n", name);
   7817 	} else {
   7818 	    xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
   7819 			  "Entity '%s' not defined\n",
   7820 			  name);
   7821 	}
   7822 	/* TODO ? check regressions ctxt->valid = 0; */
   7823     }
   7824 
   7825     /*
   7826      * [ WFC: Parsed Entity ]
   7827      * An entity reference must not contain the name of an
   7828      * unparsed entity
   7829      */
   7830     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
   7831 	xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
   7832 		 "Entity reference to unparsed entity %s\n", name);
   7833     }
   7834 
   7835     /*
   7836      * [ WFC: No External Entity References ]
   7837      * Attribute values cannot contain direct or indirect
   7838      * entity references to external entities.
   7839      */
   7840     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
   7841 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
   7842 	xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
   7843 	 "Attribute references external entity '%s'\n", name);
   7844     }
   7845     /*
   7846      * [ WFC: No < in Attribute Values ]
   7847      * The replacement text of any entity referred to directly or
   7848      * indirectly in an attribute value (other than "&lt;") must
   7849      * not contain a <.
   7850      */
   7851     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
   7852 	     (ent != NULL) && (ent->content != NULL) &&
   7853 	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
   7854 	     (xmlStrchr(ent->content, '<'))) {
   7855 	xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
   7856      "'<' in entity '%s' is not allowed in attributes values\n",
   7857 			  name);
   7858     }
   7859 
   7860     /*
   7861      * Internal check, no parameter entities here ...
   7862      */
   7863     else {
   7864 	switch (ent->etype) {
   7865 	    case XML_INTERNAL_PARAMETER_ENTITY:
   7866 	    case XML_EXTERNAL_PARAMETER_ENTITY:
   7867 		xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
   7868 	     "Attempt to reference the parameter entity '%s'\n",
   7869 				  name);
   7870 	    break;
   7871 	    default:
   7872 	    break;
   7873 	}
   7874     }
   7875 
   7876     /*
   7877      * [ WFC: No Recursion ]
   7878      * A parsed entity must not contain a recursive reference
   7879      * to itself, either directly or indirectly.
   7880      * Done somewhere else
   7881      */
   7882 
   7883     xmlFree(name);
   7884     *str = ptr;
   7885     return(ent);
   7886 }
   7887 
   7888 /**
   7889  * xmlParsePEReference:
   7890  * @ctxt:  an XML parser context
   7891  *
   7892  * parse PEReference declarations
   7893  * The entity content is handled directly by pushing it's content as
   7894  * a new input stream.
   7895  *
   7896  * [69] PEReference ::= '%' Name ';'
   7897  *
   7898  * [ WFC: No Recursion ]
   7899  * A parsed entity must not contain a recursive
   7900  * reference to itself, either directly or indirectly.
   7901  *
   7902  * [ WFC: Entity Declared ]
   7903  * In a document without any DTD, a document with only an internal DTD
   7904  * subset which contains no parameter entity references, or a document
   7905  * with "standalone='yes'", ...  ... The declaration of a parameter
   7906  * entity must precede any reference to it...
   7907  *
   7908  * [ VC: Entity Declared ]
   7909  * In a document with an external subset or external parameter entities
   7910  * with "standalone='no'", ...  ... The declaration of a parameter entity
   7911  * must precede any reference to it...
   7912  *
   7913  * [ WFC: In DTD ]
   7914  * Parameter-entity references may only appear in the DTD.
   7915  * NOTE: misleading but this is handled.
   7916  */
   7917 void
   7918 xmlParsePEReference(xmlParserCtxtPtr ctxt)
   7919 {
   7920     const xmlChar *name;
   7921     xmlEntityPtr entity = NULL;
   7922     xmlParserInputPtr input;
   7923 
   7924     if (RAW != '%')
   7925         return;
   7926     NEXT;
   7927     name = xmlParseName(ctxt);
   7928     if (name == NULL) {
   7929 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   7930 		       "xmlParsePEReference: no name\n");
   7931 	return;
   7932     }
   7933     if (RAW != ';') {
   7934 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
   7935         return;
   7936     }
   7937 
   7938     NEXT;
   7939 
   7940     /*
   7941      * Increate the number of entity references parsed
   7942      */
   7943     ctxt->nbentities++;
   7944 
   7945     /*
   7946      * Request the entity from SAX
   7947      */
   7948     if ((ctxt->sax != NULL) &&
   7949 	(ctxt->sax->getParameterEntity != NULL))
   7950 	entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
   7951     if (ctxt->instate == XML_PARSER_EOF)
   7952 	return;
   7953     if (entity == NULL) {
   7954 	/*
   7955 	 * [ WFC: Entity Declared ]
   7956 	 * In a document without any DTD, a document with only an
   7957 	 * internal DTD subset which contains no parameter entity
   7958 	 * references, or a document with "standalone='yes'", ...
   7959 	 * ... The declaration of a parameter entity must precede
   7960 	 * any reference to it...
   7961 	 */
   7962 	if ((ctxt->standalone == 1) ||
   7963 	    ((ctxt->hasExternalSubset == 0) &&
   7964 	     (ctxt->hasPErefs == 0))) {
   7965 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
   7966 			      "PEReference: %%%s; not found\n",
   7967 			      name);
   7968 	} else {
   7969 	    /*
   7970 	     * [ VC: Entity Declared ]
   7971 	     * In a document with an external subset or external
   7972 	     * parameter entities with "standalone='no'", ...
   7973 	     * ... The declaration of a parameter entity must
   7974 	     * precede any reference to it...
   7975 	     */
   7976 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
   7977 			  "PEReference: %%%s; not found\n",
   7978 			  name, NULL);
   7979 	    ctxt->valid = 0;
   7980 	}
   7981     } else {
   7982 	/*
   7983 	 * Internal checking in case the entity quest barfed
   7984 	 */
   7985 	if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
   7986 	    (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
   7987 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
   7988 		  "Internal: %%%s; is not a parameter entity\n",
   7989 			  name, NULL);
   7990 	} else if (ctxt->input->free != deallocblankswrapper) {
   7991 	    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
   7992 	    if (xmlPushInput(ctxt, input) < 0)
   7993 		return;
   7994 	} else {
   7995 	    /*
   7996 	     * TODO !!!
   7997 	     * handle the extra spaces added before and after
   7998 	     * c.f. http://www.w3.org/TR/REC-xml#as-PE
   7999 	     */
   8000 	    input = xmlNewEntityInputStream(ctxt, entity);
   8001 	    if (xmlPushInput(ctxt, input) < 0)
   8002 		return;
   8003 	    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
   8004 		(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
   8005 		(IS_BLANK_CH(NXT(5)))) {
   8006 		xmlParseTextDecl(ctxt);
   8007 		if (ctxt->errNo ==
   8008 		    XML_ERR_UNSUPPORTED_ENCODING) {
   8009 		    /*
   8010 		     * The XML REC instructs us to stop parsing
   8011 		     * right here
   8012 		     */
   8013 		    ctxt->instate = XML_PARSER_EOF;
   8014 		    return;
   8015 		}
   8016 	    }
   8017 	}
   8018     }
   8019     ctxt->hasPErefs = 1;
   8020 }
   8021 
   8022 /**
   8023  * xmlLoadEntityContent:
   8024  * @ctxt:  an XML parser context
   8025  * @entity: an unloaded system entity
   8026  *
   8027  * Load the original content of the given system entity from the
   8028  * ExternalID/SystemID given. This is to be used for Included in Literal
   8029  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
   8030  *
   8031  * Returns 0 in case of success and -1 in case of failure
   8032  */
   8033 static int
   8034 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
   8035     xmlParserInputPtr input;
   8036     xmlBufferPtr buf;
   8037     int l, c;
   8038     int count = 0;
   8039 
   8040     if ((ctxt == NULL) || (entity == NULL) ||
   8041         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
   8042 	 (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
   8043 	(entity->content != NULL)) {
   8044 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   8045 	            "xmlLoadEntityContent parameter error");
   8046         return(-1);
   8047     }
   8048 
   8049     if (xmlParserDebugEntities)
   8050 	xmlGenericError(xmlGenericErrorContext,
   8051 		"Reading %s entity content input\n", entity->name);
   8052 
   8053     buf = xmlBufferCreate();
   8054     if (buf == NULL) {
   8055 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   8056 	            "xmlLoadEntityContent parameter error");
   8057         return(-1);
   8058     }
   8059 
   8060     input = xmlNewEntityInputStream(ctxt, entity);
   8061     if (input == NULL) {
   8062 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   8063 	            "xmlLoadEntityContent input error");
   8064 	xmlBufferFree(buf);
   8065         return(-1);
   8066     }
   8067 
   8068     /*
   8069      * Push the entity as the current input, read char by char
   8070      * saving to the buffer until the end of the entity or an error
   8071      */
   8072     if (xmlPushInput(ctxt, input) < 0) {
   8073         xmlBufferFree(buf);
   8074 	return(-1);
   8075     }
   8076 
   8077     GROW;
   8078     c = CUR_CHAR(l);
   8079     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
   8080            (IS_CHAR(c))) {
   8081         xmlBufferAdd(buf, ctxt->input->cur, l);
   8082 	if (count++ > XML_PARSER_CHUNK_SIZE) {
   8083 	    count = 0;
   8084 	    GROW;
   8085             if (ctxt->instate == XML_PARSER_EOF) {
   8086                 xmlBufferFree(buf);
   8087                 return(-1);
   8088             }
   8089 	}
   8090 	NEXTL(l);
   8091 	c = CUR_CHAR(l);
   8092 	if (c == 0) {
   8093 	    count = 0;
   8094 	    GROW;
   8095             if (ctxt->instate == XML_PARSER_EOF) {
   8096                 xmlBufferFree(buf);
   8097                 return(-1);
   8098             }
   8099 	    c = CUR_CHAR(l);
   8100 	}
   8101     }
   8102 
   8103     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
   8104         xmlPopInput(ctxt);
   8105     } else if (!IS_CHAR(c)) {
   8106         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
   8107                           "xmlLoadEntityContent: invalid char value %d\n",
   8108 	                  c);
   8109 	xmlBufferFree(buf);
   8110 	return(-1);
   8111     }
   8112     entity->content = buf->content;
   8113     buf->content = NULL;
   8114     xmlBufferFree(buf);
   8115 
   8116     return(0);
   8117 }
   8118 
   8119 /**
   8120  * xmlParseStringPEReference:
   8121  * @ctxt:  an XML parser context
   8122  * @str:  a pointer to an index in the string
   8123  *
   8124  * parse PEReference declarations
   8125  *
   8126  * [69] PEReference ::= '%' Name ';'
   8127  *
   8128  * [ WFC: No Recursion ]
   8129  * A parsed entity must not contain a recursive
   8130  * reference to itself, either directly or indirectly.
   8131  *
   8132  * [ WFC: Entity Declared ]
   8133  * In a document without any DTD, a document with only an internal DTD
   8134  * subset which contains no parameter entity references, or a document
   8135  * with "standalone='yes'", ...  ... The declaration of a parameter
   8136  * entity must precede any reference to it...
   8137  *
   8138  * [ VC: Entity Declared ]
   8139  * In a document with an external subset or external parameter entities
   8140  * with "standalone='no'", ...  ... The declaration of a parameter entity
   8141  * must precede any reference to it...
   8142  *
   8143  * [ WFC: In DTD ]
   8144  * Parameter-entity references may only appear in the DTD.
   8145  * NOTE: misleading but this is handled.
   8146  *
   8147  * Returns the string of the entity content.
   8148  *         str is updated to the current value of the index
   8149  */
   8150 static xmlEntityPtr
   8151 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
   8152     const xmlChar *ptr;
   8153     xmlChar cur;
   8154     xmlChar *name;
   8155     xmlEntityPtr entity = NULL;
   8156 
   8157     if ((str == NULL) || (*str == NULL)) return(NULL);
   8158     ptr = *str;
   8159     cur = *ptr;
   8160     if (cur != '%')
   8161         return(NULL);
   8162     ptr++;
   8163     name = xmlParseStringName(ctxt, &ptr);
   8164     if (name == NULL) {
   8165 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   8166 		       "xmlParseStringPEReference: no name\n");
   8167 	*str = ptr;
   8168 	return(NULL);
   8169     }
   8170     cur = *ptr;
   8171     if (cur != ';') {
   8172 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
   8173 	xmlFree(name);
   8174 	*str = ptr;
   8175 	return(NULL);
   8176     }
   8177     ptr++;
   8178 
   8179     /*
   8180      * Increate the number of entity references parsed
   8181      */
   8182     ctxt->nbentities++;
   8183 
   8184     /*
   8185      * Request the entity from SAX
   8186      */
   8187     if ((ctxt->sax != NULL) &&
   8188 	(ctxt->sax->getParameterEntity != NULL))
   8189 	entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
   8190     if (ctxt->instate == XML_PARSER_EOF) {
   8191 	xmlFree(name);
   8192 	return(NULL);
   8193     }
   8194     if (entity == NULL) {
   8195 	/*
   8196 	 * [ WFC: Entity Declared ]
   8197 	 * In a document without any DTD, a document with only an
   8198 	 * internal DTD subset which contains no parameter entity
   8199 	 * references, or a document with "standalone='yes'", ...
   8200 	 * ... The declaration of a parameter entity must precede
   8201 	 * any reference to it...
   8202 	 */
   8203 	if ((ctxt->standalone == 1) ||
   8204 	    ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
   8205 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
   8206 		 "PEReference: %%%s; not found\n", name);
   8207 	} else {
   8208 	    /*
   8209 	     * [ VC: Entity Declared ]
   8210 	     * In a document with an external subset or external
   8211 	     * parameter entities with "standalone='no'", ...
   8212 	     * ... The declaration of a parameter entity must
   8213 	     * precede any reference to it...
   8214 	     */
   8215 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
   8216 			  "PEReference: %%%s; not found\n",
   8217 			  name, NULL);
   8218 	    ctxt->valid = 0;
   8219 	}
   8220     } else {
   8221 	/*
   8222 	 * Internal checking in case the entity quest barfed
   8223 	 */
   8224 	if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
   8225 	    (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
   8226 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
   8227 			  "%%%s; is not a parameter entity\n",
   8228 			  name, NULL);
   8229 	}
   8230     }
   8231     ctxt->hasPErefs = 1;
   8232     xmlFree(name);
   8233     *str = ptr;
   8234     return(entity);
   8235 }
   8236 
   8237 /**
   8238  * xmlParseDocTypeDecl:
   8239  * @ctxt:  an XML parser context
   8240  *
   8241  * parse a DOCTYPE declaration
   8242  *
   8243  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
   8244  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
   8245  *
   8246  * [ VC: Root Element Type ]
   8247  * The Name in the document type declaration must match the element
   8248  * type of the root element.
   8249  */
   8250 
   8251 void
   8252 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
   8253     const xmlChar *name = NULL;
   8254     xmlChar *ExternalID = NULL;
   8255     xmlChar *URI = NULL;
   8256 
   8257     /*
   8258      * We know that '<!DOCTYPE' has been detected.
   8259      */
   8260     SKIP(9);
   8261 
   8262     SKIP_BLANKS;
   8263 
   8264     /*
   8265      * Parse the DOCTYPE name.
   8266      */
   8267     name = xmlParseName(ctxt);
   8268     if (name == NULL) {
   8269 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   8270 		       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
   8271     }
   8272     ctxt->intSubName = name;
   8273 
   8274     SKIP_BLANKS;
   8275 
   8276     /*
   8277      * Check for SystemID and ExternalID
   8278      */
   8279     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
   8280 
   8281     if ((URI != NULL) || (ExternalID != NULL)) {
   8282         ctxt->hasExternalSubset = 1;
   8283     }
   8284     ctxt->extSubURI = URI;
   8285     ctxt->extSubSystem = ExternalID;
   8286 
   8287     SKIP_BLANKS;
   8288 
   8289     /*
   8290      * Create and update the internal subset.
   8291      */
   8292     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
   8293 	(!ctxt->disableSAX))
   8294 	ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
   8295     if (ctxt->instate == XML_PARSER_EOF)
   8296 	return;
   8297 
   8298     /*
   8299      * Is there any internal subset declarations ?
   8300      * they are handled separately in xmlParseInternalSubset()
   8301      */
   8302     if (RAW == '[')
   8303 	return;
   8304 
   8305     /*
   8306      * We should be at the end of the DOCTYPE declaration.
   8307      */
   8308     if (RAW != '>') {
   8309 	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
   8310     }
   8311     NEXT;
   8312 }
   8313 
   8314 /**
   8315  * xmlParseInternalSubset:
   8316  * @ctxt:  an XML parser context
   8317  *
   8318  * parse the internal subset declaration
   8319  *
   8320  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
   8321  */
   8322 
   8323 static void
   8324 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
   8325     /*
   8326      * Is there any DTD definition ?
   8327      */
   8328     if (RAW == '[') {
   8329         ctxt->instate = XML_PARSER_DTD;
   8330         NEXT;
   8331 	/*
   8332 	 * Parse the succession of Markup declarations and
   8333 	 * PEReferences.
   8334 	 * Subsequence (markupdecl | PEReference | S)*
   8335 	 */
   8336 	while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
   8337 	    const xmlChar *check = CUR_PTR;
   8338 	    unsigned int cons = ctxt->input->consumed;
   8339 
   8340 	    SKIP_BLANKS;
   8341 	    xmlParseMarkupDecl(ctxt);
   8342 	    xmlParsePEReference(ctxt);
   8343 
   8344 	    /*
   8345 	     * Pop-up of finished entities.
   8346 	     */
   8347 	    while ((RAW == 0) && (ctxt->inputNr > 1))
   8348 		xmlPopInput(ctxt);
   8349 
   8350 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
   8351 		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   8352 	     "xmlParseInternalSubset: error detected in Markup declaration\n");
   8353 		break;
   8354 	    }
   8355 	}
   8356 	if (RAW == ']') {
   8357 	    NEXT;
   8358 	    SKIP_BLANKS;
   8359 	}
   8360     }
   8361 
   8362     /*
   8363      * We should be at the end of the DOCTYPE declaration.
   8364      */
   8365     if (RAW != '>') {
   8366 	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
   8367     }
   8368     NEXT;
   8369 }
   8370 
   8371 #ifdef LIBXML_SAX1_ENABLED
   8372 /**
   8373  * xmlParseAttribute:
   8374  * @ctxt:  an XML parser context
   8375  * @value:  a xmlChar ** used to store the value of the attribute
   8376  *
   8377  * parse an attribute
   8378  *
   8379  * [41] Attribute ::= Name Eq AttValue
   8380  *
   8381  * [ WFC: No External Entity References ]
   8382  * Attribute values cannot contain direct or indirect entity references
   8383  * to external entities.
   8384  *
   8385  * [ WFC: No < in Attribute Values ]
   8386  * The replacement text of any entity referred to directly or indirectly in
   8387  * an attribute value (other than "&lt;") must not contain a <.
   8388  *
   8389  * [ VC: Attribute Value Type ]
   8390  * The attribute must have been declared; the value must be of the type
   8391  * declared for it.
   8392  *
   8393  * [25] Eq ::= S? '=' S?
   8394  *
   8395  * With namespace:
   8396  *
   8397  * [NS 11] Attribute ::= QName Eq AttValue
   8398  *
   8399  * Also the case QName == xmlns:??? is handled independently as a namespace
   8400  * definition.
   8401  *
   8402  * Returns the attribute name, and the value in *value.
   8403  */
   8404 
   8405 const xmlChar *
   8406 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
   8407     const xmlChar *name;
   8408     xmlChar *val;
   8409 
   8410     *value = NULL;
   8411     GROW;
   8412     name = xmlParseName(ctxt);
   8413     if (name == NULL) {
   8414 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   8415 	               "error parsing attribute name\n");
   8416         return(NULL);
   8417     }
   8418 
   8419     /*
   8420      * read the value
   8421      */
   8422     SKIP_BLANKS;
   8423     if (RAW == '=') {
   8424         NEXT;
   8425 	SKIP_BLANKS;
   8426 	val = xmlParseAttValue(ctxt);
   8427 	ctxt->instate = XML_PARSER_CONTENT;
   8428     } else {
   8429 	xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
   8430 	       "Specification mandate value for attribute %s\n", name);
   8431 	return(NULL);
   8432     }
   8433 
   8434     /*
   8435      * Check that xml:lang conforms to the specification
   8436      * No more registered as an error, just generate a warning now
   8437      * since this was deprecated in XML second edition
   8438      */
   8439     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
   8440 	if (!xmlCheckLanguageID(val)) {
   8441 	    xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
   8442 		          "Malformed value for xml:lang : %s\n",
   8443 			  val, NULL);
   8444 	}
   8445     }
   8446 
   8447     /*
   8448      * Check that xml:space conforms to the specification
   8449      */
   8450     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
   8451 	if (xmlStrEqual(val, BAD_CAST "default"))
   8452 	    *(ctxt->space) = 0;
   8453 	else if (xmlStrEqual(val, BAD_CAST "preserve"))
   8454 	    *(ctxt->space) = 1;
   8455 	else {
   8456 		xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
   8457 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
   8458                                  val, NULL);
   8459 	}
   8460     }
   8461 
   8462     *value = val;
   8463     return(name);
   8464 }
   8465 
   8466 /**
   8467  * xmlParseStartTag:
   8468  * @ctxt:  an XML parser context
   8469  *
   8470  * parse a start of tag either for rule element or
   8471  * EmptyElement. In both case we don't parse the tag closing chars.
   8472  *
   8473  * [40] STag ::= '<' Name (S Attribute)* S? '>'
   8474  *
   8475  * [ WFC: Unique Att Spec ]
   8476  * No attribute name may appear more than once in the same start-tag or
   8477  * empty-element tag.
   8478  *
   8479  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
   8480  *
   8481  * [ WFC: Unique Att Spec ]
   8482  * No attribute name may appear more than once in the same start-tag or
   8483  * empty-element tag.
   8484  *
   8485  * With namespace:
   8486  *
   8487  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
   8488  *
   8489  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
   8490  *
   8491  * Returns the element name parsed
   8492  */
   8493 
   8494 const xmlChar *
   8495 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
   8496     const xmlChar *name;
   8497     const xmlChar *attname;
   8498     xmlChar *attvalue;
   8499     const xmlChar **atts = ctxt->atts;
   8500     int nbatts = 0;
   8501     int maxatts = ctxt->maxatts;
   8502     int i;
   8503 
   8504     if (RAW != '<') return(NULL);
   8505     NEXT1;
   8506 
   8507     name = xmlParseName(ctxt);
   8508     if (name == NULL) {
   8509 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   8510 	     "xmlParseStartTag: invalid element name\n");
   8511         return(NULL);
   8512     }
   8513 
   8514     /*
   8515      * Now parse the attributes, it ends up with the ending
   8516      *
   8517      * (S Attribute)* S?
   8518      */
   8519     SKIP_BLANKS;
   8520     GROW;
   8521 
   8522     while (((RAW != '>') &&
   8523 	   ((RAW != '/') || (NXT(1) != '>')) &&
   8524 	   (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
   8525 	const xmlChar *q = CUR_PTR;
   8526 	unsigned int cons = ctxt->input->consumed;
   8527 
   8528 	attname = xmlParseAttribute(ctxt, &attvalue);
   8529         if ((attname != NULL) && (attvalue != NULL)) {
   8530 	    /*
   8531 	     * [ WFC: Unique Att Spec ]
   8532 	     * No attribute name may appear more than once in the same
   8533 	     * start-tag or empty-element tag.
   8534 	     */
   8535 	    for (i = 0; i < nbatts;i += 2) {
   8536 	        if (xmlStrEqual(atts[i], attname)) {
   8537 		    xmlErrAttributeDup(ctxt, NULL, attname);
   8538 		    xmlFree(attvalue);
   8539 		    goto failed;
   8540 		}
   8541 	    }
   8542 	    /*
   8543 	     * Add the pair to atts
   8544 	     */
   8545 	    if (atts == NULL) {
   8546 	        maxatts = 22; /* allow for 10 attrs by default */
   8547 	        atts = (const xmlChar **)
   8548 		       xmlMalloc(maxatts * sizeof(xmlChar *));
   8549 		if (atts == NULL) {
   8550 		    xmlErrMemory(ctxt, NULL);
   8551 		    if (attvalue != NULL)
   8552 			xmlFree(attvalue);
   8553 		    goto failed;
   8554 		}
   8555 		ctxt->atts = atts;
   8556 		ctxt->maxatts = maxatts;
   8557 	    } else if (nbatts + 4 > maxatts) {
   8558 	        const xmlChar **n;
   8559 
   8560 	        maxatts *= 2;
   8561 	        n = (const xmlChar **) xmlRealloc((void *) atts,
   8562 					     maxatts * sizeof(const xmlChar *));
   8563 		if (n == NULL) {
   8564 		    xmlErrMemory(ctxt, NULL);
   8565 		    if (attvalue != NULL)
   8566 			xmlFree(attvalue);
   8567 		    goto failed;
   8568 		}
   8569 		atts = n;
   8570 		ctxt->atts = atts;
   8571 		ctxt->maxatts = maxatts;
   8572 	    }
   8573 	    atts[nbatts++] = attname;
   8574 	    atts[nbatts++] = attvalue;
   8575 	    atts[nbatts] = NULL;
   8576 	    atts[nbatts + 1] = NULL;
   8577 	} else {
   8578 	    if (attvalue != NULL)
   8579 		xmlFree(attvalue);
   8580 	}
   8581 
   8582 failed:
   8583 
   8584 	GROW
   8585 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
   8586 	    break;
   8587 	if (!IS_BLANK_CH(RAW)) {
   8588 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   8589 			   "attributes construct error\n");
   8590 	}
   8591 	SKIP_BLANKS;
   8592         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
   8593             (attname == NULL) && (attvalue == NULL)) {
   8594 	    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
   8595 			   "xmlParseStartTag: problem parsing attributes\n");
   8596 	    break;
   8597 	}
   8598 	SHRINK;
   8599         GROW;
   8600     }
   8601 
   8602     /*
   8603      * SAX: Start of Element !
   8604      */
   8605     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
   8606 	(!ctxt->disableSAX)) {
   8607 	if (nbatts > 0)
   8608 	    ctxt->sax->startElement(ctxt->userData, name, atts);
   8609 	else
   8610 	    ctxt->sax->startElement(ctxt->userData, name, NULL);
   8611     }
   8612 
   8613     if (atts != NULL) {
   8614         /* Free only the content strings */
   8615         for (i = 1;i < nbatts;i+=2)
   8616 	    if (atts[i] != NULL)
   8617 	       xmlFree((xmlChar *) atts[i]);
   8618     }
   8619     return(name);
   8620 }
   8621 
   8622 /**
   8623  * xmlParseEndTag1:
   8624  * @ctxt:  an XML parser context
   8625  * @line:  line of the start tag
   8626  * @nsNr:  number of namespaces on the start tag
   8627  *
   8628  * parse an end of tag
   8629  *
   8630  * [42] ETag ::= '</' Name S? '>'
   8631  *
   8632  * With namespace
   8633  *
   8634  * [NS 9] ETag ::= '</' QName S? '>'
   8635  */
   8636 
   8637 static void
   8638 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
   8639     const xmlChar *name;
   8640 
   8641     GROW;
   8642     if ((RAW != '<') || (NXT(1) != '/')) {
   8643 	xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
   8644 		       "xmlParseEndTag: '</' not found\n");
   8645 	return;
   8646     }
   8647     SKIP(2);
   8648 
   8649     name = xmlParseNameAndCompare(ctxt,ctxt->name);
   8650 
   8651     /*
   8652      * We should definitely be at the ending "S? '>'" part
   8653      */
   8654     GROW;
   8655     SKIP_BLANKS;
   8656     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
   8657 	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
   8658     } else
   8659 	NEXT1;
   8660 
   8661     /*
   8662      * [ WFC: Element Type Match ]
   8663      * The Name in an element's end-tag must match the element type in the
   8664      * start-tag.
   8665      *
   8666      */
   8667     if (name != (xmlChar*)1) {
   8668         if (name == NULL) name = BAD_CAST "unparseable";
   8669         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
   8670 		     "Opening and ending tag mismatch: %s line %d and %s\n",
   8671 		                ctxt->name, line, name);
   8672     }
   8673 
   8674     /*
   8675      * SAX: End of Tag
   8676      */
   8677     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
   8678 	(!ctxt->disableSAX))
   8679         ctxt->sax->endElement(ctxt->userData, ctxt->name);
   8680 
   8681     namePop(ctxt);
   8682     spacePop(ctxt);
   8683     return;
   8684 }
   8685 
   8686 /**
   8687  * xmlParseEndTag:
   8688  * @ctxt:  an XML parser context
   8689  *
   8690  * parse an end of tag
   8691  *
   8692  * [42] ETag ::= '</' Name S? '>'
   8693  *
   8694  * With namespace
   8695  *
   8696  * [NS 9] ETag ::= '</' QName S? '>'
   8697  */
   8698 
   8699 void
   8700 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
   8701     xmlParseEndTag1(ctxt, 0);
   8702 }
   8703 #endif /* LIBXML_SAX1_ENABLED */
   8704 
   8705 /************************************************************************
   8706  *									*
   8707  *		      SAX 2 specific operations				*
   8708  *									*
   8709  ************************************************************************/
   8710 
   8711 /*
   8712  * xmlGetNamespace:
   8713  * @ctxt:  an XML parser context
   8714  * @prefix:  the prefix to lookup
   8715  *
   8716  * Lookup the namespace name for the @prefix (which ca be NULL)
   8717  * The prefix must come from the @ctxt->dict dictionnary
   8718  *
   8719  * Returns the namespace name or NULL if not bound
   8720  */
   8721 static const xmlChar *
   8722 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
   8723     int i;
   8724 
   8725     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
   8726     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
   8727         if (ctxt->nsTab[i] == prefix) {
   8728 	    if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
   8729 	        return(NULL);
   8730 	    return(ctxt->nsTab[i + 1]);
   8731 	}
   8732     return(NULL);
   8733 }
   8734 
   8735 /**
   8736  * xmlParseQName:
   8737  * @ctxt:  an XML parser context
   8738  * @prefix:  pointer to store the prefix part
   8739  *
   8740  * parse an XML Namespace QName
   8741  *
   8742  * [6]  QName  ::= (Prefix ':')? LocalPart
   8743  * [7]  Prefix  ::= NCName
   8744  * [8]  LocalPart  ::= NCName
   8745  *
   8746  * Returns the Name parsed or NULL
   8747  */
   8748 
   8749 static const xmlChar *
   8750 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
   8751     const xmlChar *l, *p;
   8752 
   8753     GROW;
   8754 
   8755     l = xmlParseNCName(ctxt);
   8756     if (l == NULL) {
   8757         if (CUR == ':') {
   8758 	    l = xmlParseName(ctxt);
   8759 	    if (l != NULL) {
   8760 	        xmlNsErr(ctxt, XML_NS_ERR_QNAME,
   8761 		         "Failed to parse QName '%s'\n", l, NULL, NULL);
   8762 		*prefix = NULL;
   8763 		return(l);
   8764 	    }
   8765 	}
   8766         return(NULL);
   8767     }
   8768     if (CUR == ':') {
   8769         NEXT;
   8770 	p = l;
   8771 	l = xmlParseNCName(ctxt);
   8772 	if (l == NULL) {
   8773 	    xmlChar *tmp;
   8774 
   8775             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
   8776 	             "Failed to parse QName '%s:'\n", p, NULL, NULL);
   8777 	    l = xmlParseNmtoken(ctxt);
   8778 	    if (l == NULL)
   8779 		tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
   8780 	    else {
   8781 		tmp = xmlBuildQName(l, p, NULL, 0);
   8782 		xmlFree((char *)l);
   8783 	    }
   8784 	    p = xmlDictLookup(ctxt->dict, tmp, -1);
   8785 	    if (tmp != NULL) xmlFree(tmp);
   8786 	    *prefix = NULL;
   8787 	    return(p);
   8788 	}
   8789 	if (CUR == ':') {
   8790 	    xmlChar *tmp;
   8791 
   8792             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
   8793 	             "Failed to parse QName '%s:%s:'\n", p, l, NULL);
   8794 	    NEXT;
   8795 	    tmp = (xmlChar *) xmlParseName(ctxt);
   8796 	    if (tmp != NULL) {
   8797 	        tmp = xmlBuildQName(tmp, l, NULL, 0);
   8798 		l = xmlDictLookup(ctxt->dict, tmp, -1);
   8799 		if (tmp != NULL) xmlFree(tmp);
   8800 		*prefix = p;
   8801 		return(l);
   8802 	    }
   8803 	    tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
   8804 	    l = xmlDictLookup(ctxt->dict, tmp, -1);
   8805 	    if (tmp != NULL) xmlFree(tmp);
   8806 	    *prefix = p;
   8807 	    return(l);
   8808 	}
   8809 	*prefix = p;
   8810     } else
   8811         *prefix = NULL;
   8812     return(l);
   8813 }
   8814 
   8815 /**
   8816  * xmlParseQNameAndCompare:
   8817  * @ctxt:  an XML parser context
   8818  * @name:  the localname
   8819  * @prefix:  the prefix, if any.
   8820  *
   8821  * parse an XML name and compares for match
   8822  * (specialized for endtag parsing)
   8823  *
   8824  * Returns NULL for an illegal name, (xmlChar*) 1 for success
   8825  * and the name for mismatch
   8826  */
   8827 
   8828 static const xmlChar *
   8829 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
   8830                         xmlChar const *prefix) {
   8831     const xmlChar *cmp;
   8832     const xmlChar *in;
   8833     const xmlChar *ret;
   8834     const xmlChar *prefix2;
   8835 
   8836     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
   8837 
   8838     GROW;
   8839     in = ctxt->input->cur;
   8840 
   8841     cmp = prefix;
   8842     while (*in != 0 && *in == *cmp) {
   8843 	++in;
   8844 	++cmp;
   8845     }
   8846     if ((*cmp == 0) && (*in == ':')) {
   8847         in++;
   8848 	cmp = name;
   8849 	while (*in != 0 && *in == *cmp) {
   8850 	    ++in;
   8851 	    ++cmp;
   8852 	}
   8853 	if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
   8854 	    /* success */
   8855 	    ctxt->input->cur = in;
   8856 	    return((const xmlChar*) 1);
   8857 	}
   8858     }
   8859     /*
   8860      * all strings coms from the dictionary, equality can be done directly
   8861      */
   8862     ret = xmlParseQName (ctxt, &prefix2);
   8863     if ((ret == name) && (prefix == prefix2))
   8864 	return((const xmlChar*) 1);
   8865     return ret;
   8866 }
   8867 
   8868 /**
   8869  * xmlParseAttValueInternal:
   8870  * @ctxt:  an XML parser context
   8871  * @len:  attribute len result
   8872  * @alloc:  whether the attribute was reallocated as a new string
   8873  * @normalize:  if 1 then further non-CDATA normalization must be done
   8874  *
   8875  * parse a value for an attribute.
   8876  * NOTE: if no normalization is needed, the routine will return pointers
   8877  *       directly from the data buffer.
   8878  *
   8879  * 3.3.3 Attribute-Value Normalization:
   8880  * Before the value of an attribute is passed to the application or
   8881  * checked for validity, the XML processor must normalize it as follows:
   8882  * - a character reference is processed by appending the referenced
   8883  *   character to the attribute value
   8884  * - an entity reference is processed by recursively processing the
   8885  *   replacement text of the entity
   8886  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
   8887  *   appending #x20 to the normalized value, except that only a single
   8888  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
   8889  *   parsed entity or the literal entity value of an internal parsed entity
   8890  * - other characters are processed by appending them to the normalized value
   8891  * If the declared value is not CDATA, then the XML processor must further
   8892  * process the normalized attribute value by discarding any leading and
   8893  * trailing space (#x20) characters, and by replacing sequences of space
   8894  * (#x20) characters by a single space (#x20) character.
   8895  * All attributes for which no declaration has been read should be treated
   8896  * by a non-validating parser as if declared CDATA.
   8897  *
   8898  * Returns the AttValue parsed or NULL. The value has to be freed by the
   8899  *     caller if it was copied, this can be detected by val[*len] == 0.
   8900  */
   8901 
   8902 static xmlChar *
   8903 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
   8904                          int normalize)
   8905 {
   8906     xmlChar limit = 0;
   8907     const xmlChar *in = NULL, *start, *end, *last;
   8908     xmlChar *ret = NULL;
   8909 
   8910     GROW;
   8911     in = (xmlChar *) CUR_PTR;
   8912     if (*in != '"' && *in != '\'') {
   8913         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
   8914         return (NULL);
   8915     }
   8916     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
   8917 
   8918     /*
   8919      * try to handle in this routine the most common case where no
   8920      * allocation of a new string is required and where content is
   8921      * pure ASCII.
   8922      */
   8923     limit = *in++;
   8924     end = ctxt->input->end;
   8925     start = in;
   8926     if (in >= end) {
   8927         const xmlChar *oldbase = ctxt->input->base;
   8928 	GROW;
   8929 	if (oldbase != ctxt->input->base) {
   8930 	    long delta = ctxt->input->base - oldbase;
   8931 	    start = start + delta;
   8932 	    in = in + delta;
   8933 	}
   8934 	end = ctxt->input->end;
   8935     }
   8936     if (normalize) {
   8937         /*
   8938 	 * Skip any leading spaces
   8939 	 */
   8940 	while ((in < end) && (*in != limit) &&
   8941 	       ((*in == 0x20) || (*in == 0x9) ||
   8942 	        (*in == 0xA) || (*in == 0xD))) {
   8943 	    in++;
   8944 	    start = in;
   8945 	    if (in >= end) {
   8946 		const xmlChar *oldbase = ctxt->input->base;
   8947 		GROW;
   8948                 if (ctxt->instate == XML_PARSER_EOF)
   8949                     return(NULL);
   8950 		if (oldbase != ctxt->input->base) {
   8951 		    long delta = ctxt->input->base - oldbase;
   8952 		    start = start + delta;
   8953 		    in = in + delta;
   8954 		}
   8955 		end = ctxt->input->end;
   8956                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
   8957                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   8958                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   8959                                    "AttValue length too long\n");
   8960                     return(NULL);
   8961                 }
   8962 	    }
   8963 	}
   8964 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
   8965 	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
   8966 	    if ((*in++ == 0x20) && (*in == 0x20)) break;
   8967 	    if (in >= end) {
   8968 		const xmlChar *oldbase = ctxt->input->base;
   8969 		GROW;
   8970                 if (ctxt->instate == XML_PARSER_EOF)
   8971                     return(NULL);
   8972 		if (oldbase != ctxt->input->base) {
   8973 		    long delta = ctxt->input->base - oldbase;
   8974 		    start = start + delta;
   8975 		    in = in + delta;
   8976 		}
   8977 		end = ctxt->input->end;
   8978                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
   8979                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   8980                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   8981                                    "AttValue length too long\n");
   8982                     return(NULL);
   8983                 }
   8984 	    }
   8985 	}
   8986 	last = in;
   8987 	/*
   8988 	 * skip the trailing blanks
   8989 	 */
   8990 	while ((last[-1] == 0x20) && (last > start)) last--;
   8991 	while ((in < end) && (*in != limit) &&
   8992 	       ((*in == 0x20) || (*in == 0x9) ||
   8993 	        (*in == 0xA) || (*in == 0xD))) {
   8994 	    in++;
   8995 	    if (in >= end) {
   8996 		const xmlChar *oldbase = ctxt->input->base;
   8997 		GROW;
   8998                 if (ctxt->instate == XML_PARSER_EOF)
   8999                     return(NULL);
   9000 		if (oldbase != ctxt->input->base) {
   9001 		    long delta = ctxt->input->base - oldbase;
   9002 		    start = start + delta;
   9003 		    in = in + delta;
   9004 		    last = last + delta;
   9005 		}
   9006 		end = ctxt->input->end;
   9007                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
   9008                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   9009                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   9010                                    "AttValue length too long\n");
   9011                     return(NULL);
   9012                 }
   9013 	    }
   9014 	}
   9015         if (((in - start) > XML_MAX_TEXT_LENGTH) &&
   9016             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   9017             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   9018                            "AttValue length too long\n");
   9019             return(NULL);
   9020         }
   9021 	if (*in != limit) goto need_complex;
   9022     } else {
   9023 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
   9024 	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
   9025 	    in++;
   9026 	    if (in >= end) {
   9027 		const xmlChar *oldbase = ctxt->input->base;
   9028 		GROW;
   9029                 if (ctxt->instate == XML_PARSER_EOF)
   9030                     return(NULL);
   9031 		if (oldbase != ctxt->input->base) {
   9032 		    long delta = ctxt->input->base - oldbase;
   9033 		    start = start + delta;
   9034 		    in = in + delta;
   9035 		}
   9036 		end = ctxt->input->end;
   9037                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
   9038                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   9039                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   9040                                    "AttValue length too long\n");
   9041                     return(NULL);
   9042                 }
   9043 	    }
   9044 	}
   9045 	last = in;
   9046         if (((in - start) > XML_MAX_TEXT_LENGTH) &&
   9047             ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   9048             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
   9049                            "AttValue length too long\n");
   9050             return(NULL);
   9051         }
   9052 	if (*in != limit) goto need_complex;
   9053     }
   9054     in++;
   9055     if (len != NULL) {
   9056         *len = last - start;
   9057         ret = (xmlChar *) start;
   9058     } else {
   9059         if (alloc) *alloc = 1;
   9060         ret = xmlStrndup(start, last - start);
   9061     }
   9062     CUR_PTR = in;
   9063     if (alloc) *alloc = 0;
   9064     return ret;
   9065 need_complex:
   9066     if (alloc) *alloc = 1;
   9067     return xmlParseAttValueComplex(ctxt, len, normalize);
   9068 }
   9069 
   9070 /**
   9071  * xmlParseAttribute2:
   9072  * @ctxt:  an XML parser context
   9073  * @pref:  the element prefix
   9074  * @elem:  the element name
   9075  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
   9076  * @value:  a xmlChar ** used to store the value of the attribute
   9077  * @len:  an int * to save the length of the attribute
   9078  * @alloc:  an int * to indicate if the attribute was allocated
   9079  *
   9080  * parse an attribute in the new SAX2 framework.
   9081  *
   9082  * Returns the attribute name, and the value in *value, .
   9083  */
   9084 
   9085 static const xmlChar *
   9086 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
   9087                    const xmlChar * pref, const xmlChar * elem,
   9088                    const xmlChar ** prefix, xmlChar ** value,
   9089                    int *len, int *alloc)
   9090 {
   9091     const xmlChar *name;
   9092     xmlChar *val, *internal_val = NULL;
   9093     int normalize = 0;
   9094 
   9095     *value = NULL;
   9096     GROW;
   9097     name = xmlParseQName(ctxt, prefix);
   9098     if (name == NULL) {
   9099         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   9100                        "error parsing attribute name\n");
   9101         return (NULL);
   9102     }
   9103 
   9104     /*
   9105      * get the type if needed
   9106      */
   9107     if (ctxt->attsSpecial != NULL) {
   9108         int type;
   9109 
   9110         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
   9111                                             pref, elem, *prefix, name);
   9112         if (type != 0)
   9113             normalize = 1;
   9114     }
   9115 
   9116     /*
   9117      * read the value
   9118      */
   9119     SKIP_BLANKS;
   9120     if (RAW == '=') {
   9121         NEXT;
   9122         SKIP_BLANKS;
   9123         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
   9124 	if (normalize) {
   9125 	    /*
   9126 	     * Sometimes a second normalisation pass for spaces is needed
   9127 	     * but that only happens if charrefs or entities refernces
   9128 	     * have been used in the attribute value, i.e. the attribute
   9129 	     * value have been extracted in an allocated string already.
   9130 	     */
   9131 	    if (*alloc) {
   9132 	        const xmlChar *val2;
   9133 
   9134 	        val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
   9135 		if ((val2 != NULL) && (val2 != val)) {
   9136 		    xmlFree(val);
   9137 		    val = (xmlChar *) val2;
   9138 		}
   9139 	    }
   9140 	}
   9141         ctxt->instate = XML_PARSER_CONTENT;
   9142     } else {
   9143         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
   9144                           "Specification mandate value for attribute %s\n",
   9145                           name);
   9146         return (NULL);
   9147     }
   9148 
   9149     if (*prefix == ctxt->str_xml) {
   9150         /*
   9151          * Check that xml:lang conforms to the specification
   9152          * No more registered as an error, just generate a warning now
   9153          * since this was deprecated in XML second edition
   9154          */
   9155         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
   9156             internal_val = xmlStrndup(val, *len);
   9157             if (!xmlCheckLanguageID(internal_val)) {
   9158                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
   9159                               "Malformed value for xml:lang : %s\n",
   9160                               internal_val, NULL);
   9161             }
   9162         }
   9163 
   9164         /*
   9165          * Check that xml:space conforms to the specification
   9166          */
   9167         if (xmlStrEqual(name, BAD_CAST "space")) {
   9168             internal_val = xmlStrndup(val, *len);
   9169             if (xmlStrEqual(internal_val, BAD_CAST "default"))
   9170                 *(ctxt->space) = 0;
   9171             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
   9172                 *(ctxt->space) = 1;
   9173             else {
   9174                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
   9175                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
   9176                               internal_val, NULL);
   9177             }
   9178         }
   9179         if (internal_val) {
   9180             xmlFree(internal_val);
   9181         }
   9182     }
   9183 
   9184     *value = val;
   9185     return (name);
   9186 }
   9187 /**
   9188  * xmlParseStartTag2:
   9189  * @ctxt:  an XML parser context
   9190  *
   9191  * parse a start of tag either for rule element or
   9192  * EmptyElement. In both case we don't parse the tag closing chars.
   9193  * This routine is called when running SAX2 parsing
   9194  *
   9195  * [40] STag ::= '<' Name (S Attribute)* S? '>'
   9196  *
   9197  * [ WFC: Unique Att Spec ]
   9198  * No attribute name may appear more than once in the same start-tag or
   9199  * empty-element tag.
   9200  *
   9201  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
   9202  *
   9203  * [ WFC: Unique Att Spec ]
   9204  * No attribute name may appear more than once in the same start-tag or
   9205  * empty-element tag.
   9206  *
   9207  * With namespace:
   9208  *
   9209  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
   9210  *
   9211  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
   9212  *
   9213  * Returns the element name parsed
   9214  */
   9215 
   9216 static const xmlChar *
   9217 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
   9218                   const xmlChar **URI, int *tlen) {
   9219     const xmlChar *localname;
   9220     const xmlChar *prefix;
   9221     const xmlChar *attname;
   9222     const xmlChar *aprefix;
   9223     const xmlChar *nsname;
   9224     xmlChar *attvalue;
   9225     const xmlChar **atts = ctxt->atts;
   9226     int maxatts = ctxt->maxatts;
   9227     int nratts, nbatts, nbdef;
   9228     int i, j, nbNs, attval, oldline, oldcol;
   9229     const xmlChar *base;
   9230     unsigned long cur;
   9231     int nsNr = ctxt->nsNr;
   9232 
   9233     if (RAW != '<') return(NULL);
   9234     NEXT1;
   9235 
   9236     /*
   9237      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
   9238      *       point since the attribute values may be stored as pointers to
   9239      *       the buffer and calling SHRINK would destroy them !
   9240      *       The Shrinking is only possible once the full set of attribute
   9241      *       callbacks have been done.
   9242      */
   9243 reparse:
   9244     SHRINK;
   9245     base = ctxt->input->base;
   9246     cur = ctxt->input->cur - ctxt->input->base;
   9247     oldline = ctxt->input->line;
   9248     oldcol = ctxt->input->col;
   9249     nbatts = 0;
   9250     nratts = 0;
   9251     nbdef = 0;
   9252     nbNs = 0;
   9253     attval = 0;
   9254     /* Forget any namespaces added during an earlier parse of this element. */
   9255     ctxt->nsNr = nsNr;
   9256 
   9257     localname = xmlParseQName(ctxt, &prefix);
   9258     if (localname == NULL) {
   9259 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
   9260 		       "StartTag: invalid element name\n");
   9261         return(NULL);
   9262     }
   9263     *tlen = ctxt->input->cur - ctxt->input->base - cur;
   9264 
   9265     /*
   9266      * Now parse the attributes, it ends up with the ending
   9267      *
   9268      * (S Attribute)* S?
   9269      */
   9270     SKIP_BLANKS;
   9271     GROW;
   9272     if (ctxt->input->base != base) goto base_changed;
   9273 
   9274     while (((RAW != '>') &&
   9275 	   ((RAW != '/') || (NXT(1) != '>')) &&
   9276 	   (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
   9277 	const xmlChar *q = CUR_PTR;
   9278 	unsigned int cons = ctxt->input->consumed;
   9279 	int len = -1, alloc = 0;
   9280 
   9281 	attname = xmlParseAttribute2(ctxt, prefix, localname,
   9282 	                             &aprefix, &attvalue, &len, &alloc);
   9283 	if (ctxt->input->base != base) {
   9284 	    if ((attvalue != NULL) && (alloc != 0))
   9285 	        xmlFree(attvalue);
   9286 	    attvalue = NULL;
   9287 	    goto base_changed;
   9288 	}
   9289         if ((attname != NULL) && (attvalue != NULL)) {
   9290 	    if (len < 0) len = xmlStrlen(attvalue);
   9291             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
   9292 	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
   9293 		xmlURIPtr uri;
   9294 
   9295                 if (*URL != 0) {
   9296 		    uri = xmlParseURI((const char *) URL);
   9297 		    if (uri == NULL) {
   9298 			xmlNsErr(ctxt, XML_WAR_NS_URI,
   9299 			         "xmlns: '%s' is not a valid URI\n",
   9300 					   URL, NULL, NULL);
   9301 		    } else {
   9302 			if (uri->scheme == NULL) {
   9303 			    xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
   9304 				      "xmlns: URI %s is not absolute\n",
   9305 				      URL, NULL, NULL);
   9306 			}
   9307 			xmlFreeURI(uri);
   9308 		    }
   9309 		    if (URL == ctxt->str_xml_ns) {
   9310 			if (attname != ctxt->str_xml) {
   9311 			    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9312 			 "xml namespace URI cannot be the default namespace\n",
   9313 				     NULL, NULL, NULL);
   9314 			}
   9315 			goto skip_default_ns;
   9316 		    }
   9317 		    if ((len == 29) &&
   9318 			(xmlStrEqual(URL,
   9319 				 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
   9320 			xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9321 			     "reuse of the xmlns namespace name is forbidden\n",
   9322 				 NULL, NULL, NULL);
   9323 			goto skip_default_ns;
   9324 		    }
   9325 		}
   9326 		/*
   9327 		 * check that it's not a defined namespace
   9328 		 */
   9329 		for (j = 1;j <= nbNs;j++)
   9330 		    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
   9331 			break;
   9332 		if (j <= nbNs)
   9333 		    xmlErrAttributeDup(ctxt, NULL, attname);
   9334 		else
   9335 		    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
   9336 skip_default_ns:
   9337 		if (alloc != 0) xmlFree(attvalue);
   9338 		SKIP_BLANKS;
   9339 		continue;
   9340 	    }
   9341             if (aprefix == ctxt->str_xmlns) {
   9342 	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
   9343 		xmlURIPtr uri;
   9344 
   9345                 if (attname == ctxt->str_xml) {
   9346 		    if (URL != ctxt->str_xml_ns) {
   9347 		        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9348 			         "xml namespace prefix mapped to wrong URI\n",
   9349 			         NULL, NULL, NULL);
   9350 		    }
   9351 		    /*
   9352 		     * Do not keep a namespace definition node
   9353 		     */
   9354 		    goto skip_ns;
   9355 		}
   9356                 if (URL == ctxt->str_xml_ns) {
   9357 		    if (attname != ctxt->str_xml) {
   9358 		        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9359 			         "xml namespace URI mapped to wrong prefix\n",
   9360 			         NULL, NULL, NULL);
   9361 		    }
   9362 		    goto skip_ns;
   9363 		}
   9364                 if (attname == ctxt->str_xmlns) {
   9365 		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9366 			     "redefinition of the xmlns prefix is forbidden\n",
   9367 			     NULL, NULL, NULL);
   9368 		    goto skip_ns;
   9369 		}
   9370 		if ((len == 29) &&
   9371 		    (xmlStrEqual(URL,
   9372 		                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
   9373 		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9374 			     "reuse of the xmlns namespace name is forbidden\n",
   9375 			     NULL, NULL, NULL);
   9376 		    goto skip_ns;
   9377 		}
   9378 		if ((URL == NULL) || (URL[0] == 0)) {
   9379 		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
   9380 		             "xmlns:%s: Empty XML namespace is not allowed\n",
   9381 			          attname, NULL, NULL);
   9382 		    goto skip_ns;
   9383 		} else {
   9384 		    uri = xmlParseURI((const char *) URL);
   9385 		    if (uri == NULL) {
   9386 			xmlNsErr(ctxt, XML_WAR_NS_URI,
   9387 			     "xmlns:%s: '%s' is not a valid URI\n",
   9388 					   attname, URL, NULL);
   9389 		    } else {
   9390 			if ((ctxt->pedantic) && (uri->scheme == NULL)) {
   9391 			    xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
   9392 				      "xmlns:%s: URI %s is not absolute\n",
   9393 				      attname, URL, NULL);
   9394 			}
   9395 			xmlFreeURI(uri);
   9396 		    }
   9397 		}
   9398 
   9399 		/*
   9400 		 * check that it's not a defined namespace
   9401 		 */
   9402 		for (j = 1;j <= nbNs;j++)
   9403 		    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
   9404 			break;
   9405 		if (j <= nbNs)
   9406 		    xmlErrAttributeDup(ctxt, aprefix, attname);
   9407 		else
   9408 		    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
   9409 skip_ns:
   9410 		if (alloc != 0) xmlFree(attvalue);
   9411 		SKIP_BLANKS;
   9412 		if (ctxt->input->base != base) goto base_changed;
   9413 		continue;
   9414 	    }
   9415 
   9416 	    /*
   9417 	     * Add the pair to atts
   9418 	     */
   9419 	    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
   9420 	        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
   9421 		    if (attvalue[len] == 0)
   9422 			xmlFree(attvalue);
   9423 		    goto failed;
   9424 		}
   9425 	        maxatts = ctxt->maxatts;
   9426 		atts = ctxt->atts;
   9427 	    }
   9428 	    ctxt->attallocs[nratts++] = alloc;
   9429 	    atts[nbatts++] = attname;
   9430 	    atts[nbatts++] = aprefix;
   9431 	    atts[nbatts++] = NULL; /* the URI will be fetched later */
   9432 	    atts[nbatts++] = attvalue;
   9433 	    attvalue += len;
   9434 	    atts[nbatts++] = attvalue;
   9435 	    /*
   9436 	     * tag if some deallocation is needed
   9437 	     */
   9438 	    if (alloc != 0) attval = 1;
   9439 	} else {
   9440 	    if ((attvalue != NULL) && (attvalue[len] == 0))
   9441 		xmlFree(attvalue);
   9442 	}
   9443 
   9444 failed:
   9445 
   9446 	GROW
   9447         if (ctxt->instate == XML_PARSER_EOF)
   9448             break;
   9449 	if (ctxt->input->base != base) goto base_changed;
   9450 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
   9451 	    break;
   9452 	if (!IS_BLANK_CH(RAW)) {
   9453 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   9454 			   "attributes construct error\n");
   9455 	    break;
   9456 	}
   9457 	SKIP_BLANKS;
   9458         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
   9459             (attname == NULL) && (attvalue == NULL)) {
   9460 	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   9461 	         "xmlParseStartTag: problem parsing attributes\n");
   9462 	    break;
   9463 	}
   9464         GROW;
   9465 	if (ctxt->input->base != base) goto base_changed;
   9466     }
   9467 
   9468     /*
   9469      * The attributes defaulting
   9470      */
   9471     if (ctxt->attsDefault != NULL) {
   9472         xmlDefAttrsPtr defaults;
   9473 
   9474 	defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
   9475 	if (defaults != NULL) {
   9476 	    for (i = 0;i < defaults->nbAttrs;i++) {
   9477 	        attname = defaults->values[5 * i];
   9478 		aprefix = defaults->values[5 * i + 1];
   9479 
   9480                 /*
   9481 		 * special work for namespaces defaulted defs
   9482 		 */
   9483 		if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
   9484 		    /*
   9485 		     * check that it's not a defined namespace
   9486 		     */
   9487 		    for (j = 1;j <= nbNs;j++)
   9488 		        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
   9489 			    break;
   9490 	            if (j <= nbNs) continue;
   9491 
   9492 		    nsname = xmlGetNamespace(ctxt, NULL);
   9493 		    if (nsname != defaults->values[5 * i + 2]) {
   9494 			if (nsPush(ctxt, NULL,
   9495 			           defaults->values[5 * i + 2]) > 0)
   9496 			    nbNs++;
   9497 		    }
   9498 		} else if (aprefix == ctxt->str_xmlns) {
   9499 		    /*
   9500 		     * check that it's not a defined namespace
   9501 		     */
   9502 		    for (j = 1;j <= nbNs;j++)
   9503 		        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
   9504 			    break;
   9505 	            if (j <= nbNs) continue;
   9506 
   9507 		    nsname = xmlGetNamespace(ctxt, attname);
   9508 		    if (nsname != defaults->values[2]) {
   9509 			if (nsPush(ctxt, attname,
   9510 			           defaults->values[5 * i + 2]) > 0)
   9511 			    nbNs++;
   9512 		    }
   9513 		} else {
   9514 		    /*
   9515 		     * check that it's not a defined attribute
   9516 		     */
   9517 		    for (j = 0;j < nbatts;j+=5) {
   9518 			if ((attname == atts[j]) && (aprefix == atts[j+1]))
   9519 			    break;
   9520 		    }
   9521 		    if (j < nbatts) continue;
   9522 
   9523 		    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
   9524 			if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
   9525 			    return(NULL);
   9526 			}
   9527 			maxatts = ctxt->maxatts;
   9528 			atts = ctxt->atts;
   9529 		    }
   9530 		    atts[nbatts++] = attname;
   9531 		    atts[nbatts++] = aprefix;
   9532 		    if (aprefix == NULL)
   9533 			atts[nbatts++] = NULL;
   9534 		    else
   9535 		        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
   9536 		    atts[nbatts++] = defaults->values[5 * i + 2];
   9537 		    atts[nbatts++] = defaults->values[5 * i + 3];
   9538 		    if ((ctxt->standalone == 1) &&
   9539 		        (defaults->values[5 * i + 4] != NULL)) {
   9540 			xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
   9541 	  "standalone: attribute %s on %s defaulted from external subset\n",
   9542 	                                 attname, localname);
   9543 		    }
   9544 		    nbdef++;
   9545 		}
   9546 	    }
   9547 	}
   9548     }
   9549 
   9550     /*
   9551      * The attributes checkings
   9552      */
   9553     for (i = 0; i < nbatts;i += 5) {
   9554         /*
   9555 	* The default namespace does not apply to attribute names.
   9556 	*/
   9557 	if (atts[i + 1] != NULL) {
   9558 	    nsname = xmlGetNamespace(ctxt, atts[i + 1]);
   9559 	    if (nsname == NULL) {
   9560 		xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
   9561 		    "Namespace prefix %s for %s on %s is not defined\n",
   9562 		    atts[i + 1], atts[i], localname);
   9563 	    }
   9564 	    atts[i + 2] = nsname;
   9565 	} else
   9566 	    nsname = NULL;
   9567 	/*
   9568 	 * [ WFC: Unique Att Spec ]
   9569 	 * No attribute name may appear more than once in the same
   9570 	 * start-tag or empty-element tag.
   9571 	 * As extended by the Namespace in XML REC.
   9572 	 */
   9573         for (j = 0; j < i;j += 5) {
   9574 	    if (atts[i] == atts[j]) {
   9575 	        if (atts[i+1] == atts[j+1]) {
   9576 		    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
   9577 		    break;
   9578 		}
   9579 		if ((nsname != NULL) && (atts[j + 2] == nsname)) {
   9580 		    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
   9581 			     "Namespaced Attribute %s in '%s' redefined\n",
   9582 			     atts[i], nsname, NULL);
   9583 		    break;
   9584 		}
   9585 	    }
   9586 	}
   9587     }
   9588 
   9589     nsname = xmlGetNamespace(ctxt, prefix);
   9590     if ((prefix != NULL) && (nsname == NULL)) {
   9591 	xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
   9592 	         "Namespace prefix %s on %s is not defined\n",
   9593 		 prefix, localname, NULL);
   9594     }
   9595     *pref = prefix;
   9596     *URI = nsname;
   9597 
   9598     /*
   9599      * SAX: Start of Element !
   9600      */
   9601     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
   9602 	(!ctxt->disableSAX)) {
   9603 	if (nbNs > 0)
   9604 	    ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
   9605 			  nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
   9606 			  nbatts / 5, nbdef, atts);
   9607 	else
   9608 	    ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
   9609 	                  nsname, 0, NULL, nbatts / 5, nbdef, atts);
   9610     }
   9611 
   9612     /*
   9613      * Free up attribute allocated strings if needed
   9614      */
   9615     if (attval != 0) {
   9616 	for (i = 3,j = 0; j < nratts;i += 5,j++)
   9617 	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
   9618 	        xmlFree((xmlChar *) atts[i]);
   9619     }
   9620 
   9621     return(localname);
   9622 
   9623 base_changed:
   9624     /*
   9625      * the attribute strings are valid iif the base didn't changed
   9626      */
   9627     if (attval != 0) {
   9628 	for (i = 3,j = 0; j < nratts;i += 5,j++)
   9629 	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
   9630 	        xmlFree((xmlChar *) atts[i]);
   9631     }
   9632     ctxt->input->cur = ctxt->input->base + cur;
   9633     ctxt->input->line = oldline;
   9634     ctxt->input->col = oldcol;
   9635     if (ctxt->wellFormed == 1) {
   9636 	goto reparse;
   9637     }
   9638     return(NULL);
   9639 }
   9640 
   9641 /**
   9642  * xmlParseEndTag2:
   9643  * @ctxt:  an XML parser context
   9644  * @line:  line of the start tag
   9645  * @nsNr:  number of namespaces on the start tag
   9646  *
   9647  * parse an end of tag
   9648  *
   9649  * [42] ETag ::= '</' Name S? '>'
   9650  *
   9651  * With namespace
   9652  *
   9653  * [NS 9] ETag ::= '</' QName S? '>'
   9654  */
   9655 
   9656 static void
   9657 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
   9658                 const xmlChar *URI, int line, int nsNr, int tlen) {
   9659     const xmlChar *name;
   9660 
   9661     GROW;
   9662     if ((RAW != '<') || (NXT(1) != '/')) {
   9663 	xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
   9664 	return;
   9665     }
   9666     SKIP(2);
   9667 
   9668     if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
   9669         if (ctxt->input->cur[tlen] == '>') {
   9670 	    ctxt->input->cur += tlen + 1;
   9671 	    goto done;
   9672 	}
   9673 	ctxt->input->cur += tlen;
   9674 	name = (xmlChar*)1;
   9675     } else {
   9676 	if (prefix == NULL)
   9677 	    name = xmlParseNameAndCompare(ctxt, ctxt->name);
   9678 	else
   9679 	    name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
   9680     }
   9681 
   9682     /*
   9683      * We should definitely be at the ending "S? '>'" part
   9684      */
   9685     GROW;
   9686     if (ctxt->instate == XML_PARSER_EOF)
   9687         return;
   9688     SKIP_BLANKS;
   9689     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
   9690 	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
   9691     } else
   9692 	NEXT1;
   9693 
   9694     /*
   9695      * [ WFC: Element Type Match ]
   9696      * The Name in an element's end-tag must match the element type in the
   9697      * start-tag.
   9698      *
   9699      */
   9700     if (name != (xmlChar*)1) {
   9701         if (name == NULL) name = BAD_CAST "unparseable";
   9702         if ((line == 0) && (ctxt->node != NULL))
   9703             line = ctxt->node->line;
   9704         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
   9705 		     "Opening and ending tag mismatch: %s line %d and %s\n",
   9706 		                ctxt->name, line, name);
   9707     }
   9708 
   9709     /*
   9710      * SAX: End of Tag
   9711      */
   9712 done:
   9713     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
   9714 	(!ctxt->disableSAX))
   9715 	ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
   9716 
   9717     spacePop(ctxt);
   9718     if (nsNr != 0)
   9719 	nsPop(ctxt, nsNr);
   9720     return;
   9721 }
   9722 
   9723 /**
   9724  * xmlParseCDSect:
   9725  * @ctxt:  an XML parser context
   9726  *
   9727  * Parse escaped pure raw content.
   9728  *
   9729  * [18] CDSect ::= CDStart CData CDEnd
   9730  *
   9731  * [19] CDStart ::= '<![CDATA['
   9732  *
   9733  * [20] Data ::= (Char* - (Char* ']]>' Char*))
   9734  *
   9735  * [21] CDEnd ::= ']]>'
   9736  */
   9737 void
   9738 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
   9739     xmlChar *buf = NULL;
   9740     int len = 0;
   9741     int size = XML_PARSER_BUFFER_SIZE;
   9742     int r, rl;
   9743     int	s, sl;
   9744     int cur, l;
   9745     int count = 0;
   9746 
   9747     /* Check 2.6.0 was NXT(0) not RAW */
   9748     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
   9749 	SKIP(9);
   9750     } else
   9751         return;
   9752 
   9753     ctxt->instate = XML_PARSER_CDATA_SECTION;
   9754     r = CUR_CHAR(rl);
   9755     if (!IS_CHAR(r)) {
   9756 	xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
   9757 	ctxt->instate = XML_PARSER_CONTENT;
   9758         return;
   9759     }
   9760     NEXTL(rl);
   9761     s = CUR_CHAR(sl);
   9762     if (!IS_CHAR(s)) {
   9763 	xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
   9764 	ctxt->instate = XML_PARSER_CONTENT;
   9765         return;
   9766     }
   9767     NEXTL(sl);
   9768     cur = CUR_CHAR(l);
   9769     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   9770     if (buf == NULL) {
   9771 	xmlErrMemory(ctxt, NULL);
   9772 	return;
   9773     }
   9774     while (IS_CHAR(cur) &&
   9775            ((r != ']') || (s != ']') || (cur != '>'))) {
   9776 	if (len + 5 >= size) {
   9777 	    xmlChar *tmp;
   9778 
   9779             if ((size > XML_MAX_TEXT_LENGTH) &&
   9780                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   9781                 xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
   9782                              "CData section too big found", NULL);
   9783                 xmlFree (buf);
   9784                 return;
   9785             }
   9786 	    tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
   9787 	    if (tmp == NULL) {
   9788 	        xmlFree(buf);
   9789 		xmlErrMemory(ctxt, NULL);
   9790 		return;
   9791 	    }
   9792 	    buf = tmp;
   9793 	    size *= 2;
   9794 	}
   9795 	COPY_BUF(rl,buf,len,r);
   9796 	r = s;
   9797 	rl = sl;
   9798 	s = cur;
   9799 	sl = l;
   9800 	count++;
   9801 	if (count > 50) {
   9802 	    GROW;
   9803             if (ctxt->instate == XML_PARSER_EOF) {
   9804 		xmlFree(buf);
   9805 		return;
   9806             }
   9807 	    count = 0;
   9808 	}
   9809 	NEXTL(l);
   9810 	cur = CUR_CHAR(l);
   9811     }
   9812     buf[len] = 0;
   9813     ctxt->instate = XML_PARSER_CONTENT;
   9814     if (cur != '>') {
   9815 	xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
   9816 	                     "CData section not finished\n%.50s\n", buf);
   9817 	xmlFree(buf);
   9818         return;
   9819     }
   9820     NEXTL(l);
   9821 
   9822     /*
   9823      * OK the buffer is to be consumed as cdata.
   9824      */
   9825     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
   9826 	if (ctxt->sax->cdataBlock != NULL)
   9827 	    ctxt->sax->cdataBlock(ctxt->userData, buf, len);
   9828 	else if (ctxt->sax->characters != NULL)
   9829 	    ctxt->sax->characters(ctxt->userData, buf, len);
   9830     }
   9831     xmlFree(buf);
   9832 }
   9833 
   9834 /**
   9835  * xmlParseContent:
   9836  * @ctxt:  an XML parser context
   9837  *
   9838  * Parse a content:
   9839  *
   9840  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
   9841  */
   9842 
   9843 void
   9844 xmlParseContent(xmlParserCtxtPtr ctxt) {
   9845     GROW;
   9846     while ((RAW != 0) &&
   9847 	   ((RAW != '<') || (NXT(1) != '/')) &&
   9848 	   (ctxt->instate != XML_PARSER_EOF)) {
   9849 	const xmlChar *test = CUR_PTR;
   9850 	unsigned int cons = ctxt->input->consumed;
   9851 	const xmlChar *cur = ctxt->input->cur;
   9852 
   9853 	/*
   9854 	 * First case : a Processing Instruction.
   9855 	 */
   9856 	if ((*cur == '<') && (cur[1] == '?')) {
   9857 	    xmlParsePI(ctxt);
   9858 	}
   9859 
   9860 	/*
   9861 	 * Second case : a CDSection
   9862 	 */
   9863 	/* 2.6.0 test was *cur not RAW */
   9864 	else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
   9865 	    xmlParseCDSect(ctxt);
   9866 	}
   9867 
   9868 	/*
   9869 	 * Third case :  a comment
   9870 	 */
   9871 	else if ((*cur == '<') && (NXT(1) == '!') &&
   9872 		 (NXT(2) == '-') && (NXT(3) == '-')) {
   9873 	    xmlParseComment(ctxt);
   9874 	    ctxt->instate = XML_PARSER_CONTENT;
   9875 	}
   9876 
   9877 	/*
   9878 	 * Fourth case :  a sub-element.
   9879 	 */
   9880 	else if (*cur == '<') {
   9881 	    xmlParseElement(ctxt);
   9882 	}
   9883 
   9884 	/*
   9885 	 * Fifth case : a reference. If if has not been resolved,
   9886 	 *    parsing returns it's Name, create the node
   9887 	 */
   9888 
   9889 	else if (*cur == '&') {
   9890 	    xmlParseReference(ctxt);
   9891 	}
   9892 
   9893 	/*
   9894 	 * Last case, text. Note that References are handled directly.
   9895 	 */
   9896 	else {
   9897 	    xmlParseCharData(ctxt, 0);
   9898 	}
   9899 
   9900 	GROW;
   9901 	/*
   9902 	 * Pop-up of finished entities.
   9903 	 */
   9904 	while ((RAW == 0) && (ctxt->inputNr > 1))
   9905 	    xmlPopInput(ctxt);
   9906 	SHRINK;
   9907 
   9908 	if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
   9909 	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   9910 	                "detected an error in element content\n");
   9911 	    ctxt->instate = XML_PARSER_EOF;
   9912             break;
   9913 	}
   9914     }
   9915 }
   9916 
   9917 /**
   9918  * xmlParseElement:
   9919  * @ctxt:  an XML parser context
   9920  *
   9921  * parse an XML element, this is highly recursive
   9922  *
   9923  * [39] element ::= EmptyElemTag | STag content ETag
   9924  *
   9925  * [ WFC: Element Type Match ]
   9926  * The Name in an element's end-tag must match the element type in the
   9927  * start-tag.
   9928  *
   9929  */
   9930 
   9931 void
   9932 xmlParseElement(xmlParserCtxtPtr ctxt) {
   9933     const xmlChar *name;
   9934     const xmlChar *prefix = NULL;
   9935     const xmlChar *URI = NULL;
   9936     xmlParserNodeInfo node_info;
   9937     int line, tlen = 0;
   9938     xmlNodePtr ret;
   9939     int nsNr = ctxt->nsNr;
   9940 
   9941     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
   9942         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   9943 	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
   9944 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
   9945 			  xmlParserMaxDepth);
   9946 	ctxt->instate = XML_PARSER_EOF;
   9947 	return;
   9948     }
   9949 
   9950     /* Capture start position */
   9951     if (ctxt->record_info) {
   9952         node_info.begin_pos = ctxt->input->consumed +
   9953                           (CUR_PTR - ctxt->input->base);
   9954 	node_info.begin_line = ctxt->input->line;
   9955     }
   9956 
   9957     if (ctxt->spaceNr == 0)
   9958 	spacePush(ctxt, -1);
   9959     else if (*ctxt->space == -2)
   9960 	spacePush(ctxt, -1);
   9961     else
   9962 	spacePush(ctxt, *ctxt->space);
   9963 
   9964     line = ctxt->input->line;
   9965 #ifdef LIBXML_SAX1_ENABLED
   9966     if (ctxt->sax2)
   9967 #endif /* LIBXML_SAX1_ENABLED */
   9968         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
   9969 #ifdef LIBXML_SAX1_ENABLED
   9970     else
   9971 	name = xmlParseStartTag(ctxt);
   9972 #endif /* LIBXML_SAX1_ENABLED */
   9973     if (ctxt->instate == XML_PARSER_EOF)
   9974 	return;
   9975     if (name == NULL) {
   9976 	spacePop(ctxt);
   9977         return;
   9978     }
   9979     namePush(ctxt, name);
   9980     ret = ctxt->node;
   9981 
   9982 #ifdef LIBXML_VALID_ENABLED
   9983     /*
   9984      * [ VC: Root Element Type ]
   9985      * The Name in the document type declaration must match the element
   9986      * type of the root element.
   9987      */
   9988     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
   9989         ctxt->node && (ctxt->node == ctxt->myDoc->children))
   9990         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
   9991 #endif /* LIBXML_VALID_ENABLED */
   9992 
   9993     /*
   9994      * Check for an Empty Element.
   9995      */
   9996     if ((RAW == '/') && (NXT(1) == '>')) {
   9997         SKIP(2);
   9998 	if (ctxt->sax2) {
   9999 	    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
   10000 		(!ctxt->disableSAX))
   10001 		ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
   10002 #ifdef LIBXML_SAX1_ENABLED
   10003 	} else {
   10004 	    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
   10005 		(!ctxt->disableSAX))
   10006 		ctxt->sax->endElement(ctxt->userData, name);
   10007 #endif /* LIBXML_SAX1_ENABLED */
   10008 	}
   10009 	namePop(ctxt);
   10010 	spacePop(ctxt);
   10011 	if (nsNr != ctxt->nsNr)
   10012 	    nsPop(ctxt, ctxt->nsNr - nsNr);
   10013 	if ( ret != NULL && ctxt->record_info ) {
   10014 	   node_info.end_pos = ctxt->input->consumed +
   10015 			      (CUR_PTR - ctxt->input->base);
   10016 	   node_info.end_line = ctxt->input->line;
   10017 	   node_info.node = ret;
   10018 	   xmlParserAddNodeInfo(ctxt, &node_info);
   10019 	}
   10020 	return;
   10021     }
   10022     if (RAW == '>') {
   10023         NEXT1;
   10024     } else {
   10025         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
   10026 		     "Couldn't find end of Start Tag %s line %d\n",
   10027 		                name, line, NULL);
   10028 
   10029 	/*
   10030 	 * end of parsing of this node.
   10031 	 */
   10032 	nodePop(ctxt);
   10033 	namePop(ctxt);
   10034 	spacePop(ctxt);
   10035 	if (nsNr != ctxt->nsNr)
   10036 	    nsPop(ctxt, ctxt->nsNr - nsNr);
   10037 
   10038 	/*
   10039 	 * Capture end position and add node
   10040 	 */
   10041 	if ( ret != NULL && ctxt->record_info ) {
   10042 	   node_info.end_pos = ctxt->input->consumed +
   10043 			      (CUR_PTR - ctxt->input->base);
   10044 	   node_info.end_line = ctxt->input->line;
   10045 	   node_info.node = ret;
   10046 	   xmlParserAddNodeInfo(ctxt, &node_info);
   10047 	}
   10048 	return;
   10049     }
   10050 
   10051     /*
   10052      * Parse the content of the element:
   10053      */
   10054     xmlParseContent(ctxt);
   10055     if (ctxt->instate == XML_PARSER_EOF)
   10056 	return;
   10057     if (!IS_BYTE_CHAR(RAW)) {
   10058         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
   10059 	 "Premature end of data in tag %s line %d\n",
   10060 		                name, line, NULL);
   10061 
   10062 	/*
   10063 	 * end of parsing of this node.
   10064 	 */
   10065 	nodePop(ctxt);
   10066 	namePop(ctxt);
   10067 	spacePop(ctxt);
   10068 	if (nsNr != ctxt->nsNr)
   10069 	    nsPop(ctxt, ctxt->nsNr - nsNr);
   10070 	return;
   10071     }
   10072 
   10073     /*
   10074      * parse the end of tag: '</' should be here.
   10075      */
   10076     if (ctxt->sax2) {
   10077 	xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
   10078 	namePop(ctxt);
   10079     }
   10080 #ifdef LIBXML_SAX1_ENABLED
   10081       else
   10082 	xmlParseEndTag1(ctxt, line);
   10083 #endif /* LIBXML_SAX1_ENABLED */
   10084 
   10085     /*
   10086      * Capture end position and add node
   10087      */
   10088     if ( ret != NULL && ctxt->record_info ) {
   10089        node_info.end_pos = ctxt->input->consumed +
   10090                           (CUR_PTR - ctxt->input->base);
   10091        node_info.end_line = ctxt->input->line;
   10092        node_info.node = ret;
   10093        xmlParserAddNodeInfo(ctxt, &node_info);
   10094     }
   10095 }
   10096 
   10097 /**
   10098  * xmlParseVersionNum:
   10099  * @ctxt:  an XML parser context
   10100  *
   10101  * parse the XML version value.
   10102  *
   10103  * [26] VersionNum ::= '1.' [0-9]+
   10104  *
   10105  * In practice allow [0-9].[0-9]+ at that level
   10106  *
   10107  * Returns the string giving the XML version number, or NULL
   10108  */
   10109 xmlChar *
   10110 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
   10111     xmlChar *buf = NULL;
   10112     int len = 0;
   10113     int size = 10;
   10114     xmlChar cur;
   10115 
   10116     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   10117     if (buf == NULL) {
   10118 	xmlErrMemory(ctxt, NULL);
   10119 	return(NULL);
   10120     }
   10121     cur = CUR;
   10122     if (!((cur >= '0') && (cur <= '9'))) {
   10123 	xmlFree(buf);
   10124 	return(NULL);
   10125     }
   10126     buf[len++] = cur;
   10127     NEXT;
   10128     cur=CUR;
   10129     if (cur != '.') {
   10130 	xmlFree(buf);
   10131 	return(NULL);
   10132     }
   10133     buf[len++] = cur;
   10134     NEXT;
   10135     cur=CUR;
   10136     while ((cur >= '0') && (cur <= '9')) {
   10137 	if (len + 1 >= size) {
   10138 	    xmlChar *tmp;
   10139 
   10140 	    size *= 2;
   10141 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
   10142 	    if (tmp == NULL) {
   10143 	        xmlFree(buf);
   10144 		xmlErrMemory(ctxt, NULL);
   10145 		return(NULL);
   10146 	    }
   10147 	    buf = tmp;
   10148 	}
   10149 	buf[len++] = cur;
   10150 	NEXT;
   10151 	cur=CUR;
   10152     }
   10153     buf[len] = 0;
   10154     return(buf);
   10155 }
   10156 
   10157 /**
   10158  * xmlParseVersionInfo:
   10159  * @ctxt:  an XML parser context
   10160  *
   10161  * parse the XML version.
   10162  *
   10163  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
   10164  *
   10165  * [25] Eq ::= S? '=' S?
   10166  *
   10167  * Returns the version string, e.g. "1.0"
   10168  */
   10169 
   10170 xmlChar *
   10171 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
   10172     xmlChar *version = NULL;
   10173 
   10174     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
   10175 	SKIP(7);
   10176 	SKIP_BLANKS;
   10177 	if (RAW != '=') {
   10178 	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
   10179 	    return(NULL);
   10180         }
   10181 	NEXT;
   10182 	SKIP_BLANKS;
   10183 	if (RAW == '"') {
   10184 	    NEXT;
   10185 	    version = xmlParseVersionNum(ctxt);
   10186 	    if (RAW != '"') {
   10187 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
   10188 	    } else
   10189 	        NEXT;
   10190 	} else if (RAW == '\''){
   10191 	    NEXT;
   10192 	    version = xmlParseVersionNum(ctxt);
   10193 	    if (RAW != '\'') {
   10194 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
   10195 	    } else
   10196 	        NEXT;
   10197 	} else {
   10198 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
   10199 	}
   10200     }
   10201     return(version);
   10202 }
   10203 
   10204 /**
   10205  * xmlParseEncName:
   10206  * @ctxt:  an XML parser context
   10207  *
   10208  * parse the XML encoding name
   10209  *
   10210  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
   10211  *
   10212  * Returns the encoding name value or NULL
   10213  */
   10214 xmlChar *
   10215 xmlParseEncName(xmlParserCtxtPtr ctxt) {
   10216     xmlChar *buf = NULL;
   10217     int len = 0;
   10218     int size = 10;
   10219     xmlChar cur;
   10220 
   10221     cur = CUR;
   10222     if (((cur >= 'a') && (cur <= 'z')) ||
   10223         ((cur >= 'A') && (cur <= 'Z'))) {
   10224 	buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
   10225 	if (buf == NULL) {
   10226 	    xmlErrMemory(ctxt, NULL);
   10227 	    return(NULL);
   10228 	}
   10229 
   10230 	buf[len++] = cur;
   10231 	NEXT;
   10232 	cur = CUR;
   10233 	while (((cur >= 'a') && (cur <= 'z')) ||
   10234 	       ((cur >= 'A') && (cur <= 'Z')) ||
   10235 	       ((cur >= '0') && (cur <= '9')) ||
   10236 	       (cur == '.') || (cur == '_') ||
   10237 	       (cur == '-')) {
   10238 	    if (len + 1 >= size) {
   10239 	        xmlChar *tmp;
   10240 
   10241 		size *= 2;
   10242 		tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
   10243 		if (tmp == NULL) {
   10244 		    xmlErrMemory(ctxt, NULL);
   10245 		    xmlFree(buf);
   10246 		    return(NULL);
   10247 		}
   10248 		buf = tmp;
   10249 	    }
   10250 	    buf[len++] = cur;
   10251 	    NEXT;
   10252 	    cur = CUR;
   10253 	    if (cur == 0) {
   10254 	        SHRINK;
   10255 		GROW;
   10256 		cur = CUR;
   10257 	    }
   10258         }
   10259 	buf[len] = 0;
   10260     } else {
   10261 	xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
   10262     }
   10263     return(buf);
   10264 }
   10265 
   10266 /**
   10267  * xmlParseEncodingDecl:
   10268  * @ctxt:  an XML parser context
   10269  *
   10270  * parse the XML encoding declaration
   10271  *
   10272  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
   10273  *
   10274  * this setups the conversion filters.
   10275  *
   10276  * Returns the encoding value or NULL
   10277  */
   10278 
   10279 const xmlChar *
   10280 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
   10281     xmlChar *encoding = NULL;
   10282 
   10283     SKIP_BLANKS;
   10284     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
   10285 	SKIP(8);
   10286 	SKIP_BLANKS;
   10287 	if (RAW != '=') {
   10288 	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
   10289 	    return(NULL);
   10290         }
   10291 	NEXT;
   10292 	SKIP_BLANKS;
   10293 	if (RAW == '"') {
   10294 	    NEXT;
   10295 	    encoding = xmlParseEncName(ctxt);
   10296 	    if (RAW != '"') {
   10297 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
   10298 	    } else
   10299 	        NEXT;
   10300 	} else if (RAW == '\''){
   10301 	    NEXT;
   10302 	    encoding = xmlParseEncName(ctxt);
   10303 	    if (RAW != '\'') {
   10304 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
   10305 	    } else
   10306 	        NEXT;
   10307 	} else {
   10308 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
   10309 	}
   10310 
   10311         /*
   10312          * Non standard parsing, allowing the user to ignore encoding
   10313          */
   10314         if (ctxt->options & XML_PARSE_IGNORE_ENC)
   10315             return(encoding);
   10316 
   10317 	/*
   10318 	 * UTF-16 encoding stwich has already taken place at this stage,
   10319 	 * more over the little-endian/big-endian selection is already done
   10320 	 */
   10321         if ((encoding != NULL) &&
   10322 	    ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
   10323 	     (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
   10324 	    /*
   10325 	     * If no encoding was passed to the parser, that we are
   10326 	     * using UTF-16 and no decoder is present i.e. the
   10327 	     * document is apparently UTF-8 compatible, then raise an
   10328 	     * encoding mismatch fatal error
   10329 	     */
   10330 	    if ((ctxt->encoding == NULL) &&
   10331 	        (ctxt->input->buf != NULL) &&
   10332 	        (ctxt->input->buf->encoder == NULL)) {
   10333 		xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
   10334 		  "Document labelled UTF-16 but has UTF-8 content\n");
   10335 	    }
   10336 	    if (ctxt->encoding != NULL)
   10337 		xmlFree((xmlChar *) ctxt->encoding);
   10338 	    ctxt->encoding = encoding;
   10339 	}
   10340 	/*
   10341 	 * UTF-8 encoding is handled natively
   10342 	 */
   10343         else if ((encoding != NULL) &&
   10344 	    ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
   10345 	     (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
   10346 	    if (ctxt->encoding != NULL)
   10347 		xmlFree((xmlChar *) ctxt->encoding);
   10348 	    ctxt->encoding = encoding;
   10349 	}
   10350 	else if (encoding != NULL) {
   10351 	    xmlCharEncodingHandlerPtr handler;
   10352 
   10353 	    if (ctxt->input->encoding != NULL)
   10354 		xmlFree((xmlChar *) ctxt->input->encoding);
   10355 	    ctxt->input->encoding = encoding;
   10356 
   10357             handler = xmlFindCharEncodingHandler((const char *) encoding);
   10358 	    if (handler != NULL) {
   10359 		xmlSwitchToEncoding(ctxt, handler);
   10360 	    } else {
   10361 		xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
   10362 			"Unsupported encoding %s\n", encoding);
   10363 		return(NULL);
   10364 	    }
   10365 	}
   10366     }
   10367     return(encoding);
   10368 }
   10369 
   10370 /**
   10371  * xmlParseSDDecl:
   10372  * @ctxt:  an XML parser context
   10373  *
   10374  * parse the XML standalone declaration
   10375  *
   10376  * [32] SDDecl ::= S 'standalone' Eq
   10377  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
   10378  *
   10379  * [ VC: Standalone Document Declaration ]
   10380  * TODO The standalone document declaration must have the value "no"
   10381  * if any external markup declarations contain declarations of:
   10382  *  - attributes with default values, if elements to which these
   10383  *    attributes apply appear in the document without specifications
   10384  *    of values for these attributes, or
   10385  *  - entities (other than amp, lt, gt, apos, quot), if references
   10386  *    to those entities appear in the document, or
   10387  *  - attributes with values subject to normalization, where the
   10388  *    attribute appears in the document with a value which will change
   10389  *    as a result of normalization, or
   10390  *  - element types with element content, if white space occurs directly
   10391  *    within any instance of those types.
   10392  *
   10393  * Returns:
   10394  *   1 if standalone="yes"
   10395  *   0 if standalone="no"
   10396  *  -2 if standalone attribute is missing or invalid
   10397  *	  (A standalone value of -2 means that the XML declaration was found,
   10398  *	   but no value was specified for the standalone attribute).
   10399  */
   10400 
   10401 int
   10402 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
   10403     int standalone = -2;
   10404 
   10405     SKIP_BLANKS;
   10406     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
   10407 	SKIP(10);
   10408         SKIP_BLANKS;
   10409 	if (RAW != '=') {
   10410 	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
   10411 	    return(standalone);
   10412         }
   10413 	NEXT;
   10414 	SKIP_BLANKS;
   10415         if (RAW == '\''){
   10416 	    NEXT;
   10417 	    if ((RAW == 'n') && (NXT(1) == 'o')) {
   10418 	        standalone = 0;
   10419                 SKIP(2);
   10420 	    } else if ((RAW == 'y') && (NXT(1) == 'e') &&
   10421 	               (NXT(2) == 's')) {
   10422 	        standalone = 1;
   10423 		SKIP(3);
   10424             } else {
   10425 		xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
   10426 	    }
   10427 	    if (RAW != '\'') {
   10428 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
   10429 	    } else
   10430 	        NEXT;
   10431 	} else if (RAW == '"'){
   10432 	    NEXT;
   10433 	    if ((RAW == 'n') && (NXT(1) == 'o')) {
   10434 	        standalone = 0;
   10435 		SKIP(2);
   10436 	    } else if ((RAW == 'y') && (NXT(1) == 'e') &&
   10437 	               (NXT(2) == 's')) {
   10438 	        standalone = 1;
   10439                 SKIP(3);
   10440             } else {
   10441 		xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
   10442 	    }
   10443 	    if (RAW != '"') {
   10444 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
   10445 	    } else
   10446 	        NEXT;
   10447 	} else {
   10448 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
   10449         }
   10450     }
   10451     return(standalone);
   10452 }
   10453 
   10454 /**
   10455  * xmlParseXMLDecl:
   10456  * @ctxt:  an XML parser context
   10457  *
   10458  * parse an XML declaration header
   10459  *
   10460  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
   10461  */
   10462 
   10463 void
   10464 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
   10465     xmlChar *version;
   10466 
   10467     /*
   10468      * This value for standalone indicates that the document has an
   10469      * XML declaration but it does not have a standalone attribute.
   10470      * It will be overwritten later if a standalone attribute is found.
   10471      */
   10472     ctxt->input->standalone = -2;
   10473 
   10474     /*
   10475      * We know that '<?xml' is here.
   10476      */
   10477     SKIP(5);
   10478 
   10479     if (!IS_BLANK_CH(RAW)) {
   10480 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
   10481 	               "Blank needed after '<?xml'\n");
   10482     }
   10483     SKIP_BLANKS;
   10484 
   10485     /*
   10486      * We must have the VersionInfo here.
   10487      */
   10488     version = xmlParseVersionInfo(ctxt);
   10489     if (version == NULL) {
   10490 	xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
   10491     } else {
   10492 	if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
   10493 	    /*
   10494 	     * Changed here for XML-1.0 5th edition
   10495 	     */
   10496 	    if (ctxt->options & XML_PARSE_OLD10) {
   10497 		xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
   10498 			          "Unsupported version '%s'\n",
   10499 			          version);
   10500 	    } else {
   10501 	        if ((version[0] == '1') && ((version[1] == '.'))) {
   10502 		    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
   10503 		                  "Unsupported version '%s'\n",
   10504 				  version, NULL);
   10505 		} else {
   10506 		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
   10507 				      "Unsupported version '%s'\n",
   10508 				      version);
   10509 		}
   10510 	    }
   10511 	}
   10512 	if (ctxt->version != NULL)
   10513 	    xmlFree((void *) ctxt->version);
   10514 	ctxt->version = version;
   10515     }
   10516 
   10517     /*
   10518      * We may have the encoding declaration
   10519      */
   10520     if (!IS_BLANK_CH(RAW)) {
   10521         if ((RAW == '?') && (NXT(1) == '>')) {
   10522 	    SKIP(2);
   10523 	    return;
   10524 	}
   10525 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
   10526     }
   10527     xmlParseEncodingDecl(ctxt);
   10528     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
   10529 	/*
   10530 	 * The XML REC instructs us to stop parsing right here
   10531 	 */
   10532         return;
   10533     }
   10534 
   10535     /*
   10536      * We may have the standalone status.
   10537      */
   10538     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
   10539         if ((RAW == '?') && (NXT(1) == '>')) {
   10540 	    SKIP(2);
   10541 	    return;
   10542 	}
   10543 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
   10544     }
   10545 
   10546     /*
   10547      * We can grow the input buffer freely at that point
   10548      */
   10549     GROW;
   10550 
   10551     SKIP_BLANKS;
   10552     ctxt->input->standalone = xmlParseSDDecl(ctxt);
   10553 
   10554     SKIP_BLANKS;
   10555     if ((RAW == '?') && (NXT(1) == '>')) {
   10556         SKIP(2);
   10557     } else if (RAW == '>') {
   10558         /* Deprecated old WD ... */
   10559 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
   10560 	NEXT;
   10561     } else {
   10562 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
   10563 	MOVETO_ENDTAG(CUR_PTR);
   10564 	NEXT;
   10565     }
   10566 }
   10567 
   10568 /**
   10569  * xmlParseMisc:
   10570  * @ctxt:  an XML parser context
   10571  *
   10572  * parse an XML Misc* optional field.
   10573  *
   10574  * [27] Misc ::= Comment | PI |  S
   10575  */
   10576 
   10577 void
   10578 xmlParseMisc(xmlParserCtxtPtr ctxt) {
   10579     while ((ctxt->instate != XML_PARSER_EOF) &&
   10580            (((RAW == '<') && (NXT(1) == '?')) ||
   10581             (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
   10582             IS_BLANK_CH(CUR))) {
   10583         if ((RAW == '<') && (NXT(1) == '?')) {
   10584 	    xmlParsePI(ctxt);
   10585 	} else if (IS_BLANK_CH(CUR)) {
   10586 	    NEXT;
   10587 	} else
   10588 	    xmlParseComment(ctxt);
   10589     }
   10590 }
   10591 
   10592 /**
   10593  * xmlParseDocument:
   10594  * @ctxt:  an XML parser context
   10595  *
   10596  * parse an XML document (and build a tree if using the standard SAX
   10597  * interface).
   10598  *
   10599  * [1] document ::= prolog element Misc*
   10600  *
   10601  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
   10602  *
   10603  * Returns 0, -1 in case of error. the parser context is augmented
   10604  *                as a result of the parsing.
   10605  */
   10606 
   10607 int
   10608 xmlParseDocument(xmlParserCtxtPtr ctxt) {
   10609     xmlChar start[4];
   10610     xmlCharEncoding enc;
   10611 
   10612     xmlInitParser();
   10613 
   10614     if ((ctxt == NULL) || (ctxt->input == NULL))
   10615         return(-1);
   10616 
   10617     GROW;
   10618 
   10619     /*
   10620      * SAX: detecting the level.
   10621      */
   10622     xmlDetectSAX2(ctxt);
   10623 
   10624     /*
   10625      * SAX: beginning of the document processing.
   10626      */
   10627     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
   10628         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
   10629     if (ctxt->instate == XML_PARSER_EOF)
   10630 	return(-1);
   10631 
   10632     if ((ctxt->encoding == NULL) &&
   10633         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
   10634 	/*
   10635 	 * Get the 4 first bytes and decode the charset
   10636 	 * if enc != XML_CHAR_ENCODING_NONE
   10637 	 * plug some encoding conversion routines.
   10638 	 */
   10639 	start[0] = RAW;
   10640 	start[1] = NXT(1);
   10641 	start[2] = NXT(2);
   10642 	start[3] = NXT(3);
   10643 	enc = xmlDetectCharEncoding(&start[0], 4);
   10644 	if (enc != XML_CHAR_ENCODING_NONE) {
   10645 	    xmlSwitchEncoding(ctxt, enc);
   10646 	}
   10647     }
   10648 
   10649 
   10650     if (CUR == 0) {
   10651 	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
   10652     }
   10653 
   10654     /*
   10655      * Check for the XMLDecl in the Prolog.
   10656      * do not GROW here to avoid the detected encoder to decode more
   10657      * than just the first line, unless the amount of data is really
   10658      * too small to hold "<?xml version="1.0" encoding="foo"
   10659      */
   10660     if ((ctxt->input->end - ctxt->input->cur) < 35) {
   10661        GROW;
   10662     }
   10663     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
   10664 
   10665 	/*
   10666 	 * Note that we will switch encoding on the fly.
   10667 	 */
   10668 	xmlParseXMLDecl(ctxt);
   10669 	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
   10670 	    /*
   10671 	     * The XML REC instructs us to stop parsing right here
   10672 	     */
   10673 	    return(-1);
   10674 	}
   10675 	ctxt->standalone = ctxt->input->standalone;
   10676 	SKIP_BLANKS;
   10677     } else {
   10678 	ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
   10679     }
   10680     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
   10681         ctxt->sax->startDocument(ctxt->userData);
   10682     if (ctxt->instate == XML_PARSER_EOF)
   10683 	return(-1);
   10684 
   10685     /*
   10686      * The Misc part of the Prolog
   10687      */
   10688     GROW;
   10689     xmlParseMisc(ctxt);
   10690 
   10691     /*
   10692      * Then possibly doc type declaration(s) and more Misc
   10693      * (doctypedecl Misc*)?
   10694      */
   10695     GROW;
   10696     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
   10697 
   10698 	ctxt->inSubset = 1;
   10699 	xmlParseDocTypeDecl(ctxt);
   10700 	if (RAW == '[') {
   10701 	    ctxt->instate = XML_PARSER_DTD;
   10702 	    xmlParseInternalSubset(ctxt);
   10703 	    if (ctxt->instate == XML_PARSER_EOF)
   10704 		return(-1);
   10705 	}
   10706 
   10707 	/*
   10708 	 * Create and update the external subset.
   10709 	 */
   10710 	ctxt->inSubset = 2;
   10711 	if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
   10712 	    (!ctxt->disableSAX))
   10713 	    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
   10714 	                              ctxt->extSubSystem, ctxt->extSubURI);
   10715 	if (ctxt->instate == XML_PARSER_EOF)
   10716 	    return(-1);
   10717 	ctxt->inSubset = 0;
   10718 
   10719         xmlCleanSpecialAttr(ctxt);
   10720 
   10721 	ctxt->instate = XML_PARSER_PROLOG;
   10722 	xmlParseMisc(ctxt);
   10723     }
   10724 
   10725     /*
   10726      * Time to start parsing the tree itself
   10727      */
   10728     GROW;
   10729     if (RAW != '<') {
   10730 	xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
   10731 		       "Start tag expected, '<' not found\n");
   10732     } else {
   10733 	ctxt->instate = XML_PARSER_CONTENT;
   10734 	xmlParseElement(ctxt);
   10735 	ctxt->instate = XML_PARSER_EPILOG;
   10736 
   10737 
   10738 	/*
   10739 	 * The Misc part at the end
   10740 	 */
   10741 	xmlParseMisc(ctxt);
   10742 
   10743 	if (RAW != 0) {
   10744 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
   10745 	}
   10746 	ctxt->instate = XML_PARSER_EOF;
   10747     }
   10748 
   10749     /*
   10750      * SAX: end of the document processing.
   10751      */
   10752     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   10753         ctxt->sax->endDocument(ctxt->userData);
   10754 
   10755     /*
   10756      * Remove locally kept entity definitions if the tree was not built
   10757      */
   10758     if ((ctxt->myDoc != NULL) &&
   10759 	(xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
   10760 	xmlFreeDoc(ctxt->myDoc);
   10761 	ctxt->myDoc = NULL;
   10762     }
   10763 
   10764     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
   10765         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
   10766 	if (ctxt->valid)
   10767 	    ctxt->myDoc->properties |= XML_DOC_DTDVALID;
   10768 	if (ctxt->nsWellFormed)
   10769 	    ctxt->myDoc->properties |= XML_DOC_NSVALID;
   10770 	if (ctxt->options & XML_PARSE_OLD10)
   10771 	    ctxt->myDoc->properties |= XML_DOC_OLD10;
   10772     }
   10773     if (! ctxt->wellFormed) {
   10774 	ctxt->valid = 0;
   10775 	return(-1);
   10776     }
   10777     return(0);
   10778 }
   10779 
   10780 /**
   10781  * xmlParseExtParsedEnt:
   10782  * @ctxt:  an XML parser context
   10783  *
   10784  * parse a general parsed entity
   10785  * An external general parsed entity is well-formed if it matches the
   10786  * production labeled extParsedEnt.
   10787  *
   10788  * [78] extParsedEnt ::= TextDecl? content
   10789  *
   10790  * Returns 0, -1 in case of error. the parser context is augmented
   10791  *                as a result of the parsing.
   10792  */
   10793 
   10794 int
   10795 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
   10796     xmlChar start[4];
   10797     xmlCharEncoding enc;
   10798 
   10799     if ((ctxt == NULL) || (ctxt->input == NULL))
   10800         return(-1);
   10801 
   10802     xmlDefaultSAXHandlerInit();
   10803 
   10804     xmlDetectSAX2(ctxt);
   10805 
   10806     GROW;
   10807 
   10808     /*
   10809      * SAX: beginning of the document processing.
   10810      */
   10811     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
   10812         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
   10813 
   10814     /*
   10815      * Get the 4 first bytes and decode the charset
   10816      * if enc != XML_CHAR_ENCODING_NONE
   10817      * plug some encoding conversion routines.
   10818      */
   10819     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
   10820 	start[0] = RAW;
   10821 	start[1] = NXT(1);
   10822 	start[2] = NXT(2);
   10823 	start[3] = NXT(3);
   10824 	enc = xmlDetectCharEncoding(start, 4);
   10825 	if (enc != XML_CHAR_ENCODING_NONE) {
   10826 	    xmlSwitchEncoding(ctxt, enc);
   10827 	}
   10828     }
   10829 
   10830 
   10831     if (CUR == 0) {
   10832 	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
   10833     }
   10834 
   10835     /*
   10836      * Check for the XMLDecl in the Prolog.
   10837      */
   10838     GROW;
   10839     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
   10840 
   10841 	/*
   10842 	 * Note that we will switch encoding on the fly.
   10843 	 */
   10844 	xmlParseXMLDecl(ctxt);
   10845 	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
   10846 	    /*
   10847 	     * The XML REC instructs us to stop parsing right here
   10848 	     */
   10849 	    return(-1);
   10850 	}
   10851 	SKIP_BLANKS;
   10852     } else {
   10853 	ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
   10854     }
   10855     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
   10856         ctxt->sax->startDocument(ctxt->userData);
   10857     if (ctxt->instate == XML_PARSER_EOF)
   10858 	return(-1);
   10859 
   10860     /*
   10861      * Doing validity checking on chunk doesn't make sense
   10862      */
   10863     ctxt->instate = XML_PARSER_CONTENT;
   10864     ctxt->validate = 0;
   10865     ctxt->loadsubset = 0;
   10866     ctxt->depth = 0;
   10867 
   10868     xmlParseContent(ctxt);
   10869     if (ctxt->instate == XML_PARSER_EOF)
   10870 	return(-1);
   10871 
   10872     if ((RAW == '<') && (NXT(1) == '/')) {
   10873 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   10874     } else if (RAW != 0) {
   10875 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
   10876     }
   10877 
   10878     /*
   10879      * SAX: end of the document processing.
   10880      */
   10881     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   10882         ctxt->sax->endDocument(ctxt->userData);
   10883 
   10884     if (! ctxt->wellFormed) return(-1);
   10885     return(0);
   10886 }
   10887 
   10888 #ifdef LIBXML_PUSH_ENABLED
   10889 /************************************************************************
   10890  *									*
   10891  *		Progressive parsing interfaces				*
   10892  *									*
   10893  ************************************************************************/
   10894 
   10895 /**
   10896  * xmlParseLookupSequence:
   10897  * @ctxt:  an XML parser context
   10898  * @first:  the first char to lookup
   10899  * @next:  the next char to lookup or zero
   10900  * @third:  the next char to lookup or zero
   10901  *
   10902  * Try to find if a sequence (first, next, third) or  just (first next) or
   10903  * (first) is available in the input stream.
   10904  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
   10905  * to avoid rescanning sequences of bytes, it DOES change the state of the
   10906  * parser, do not use liberally.
   10907  *
   10908  * Returns the index to the current parsing point if the full sequence
   10909  *      is available, -1 otherwise.
   10910  */
   10911 static int
   10912 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
   10913                        xmlChar next, xmlChar third) {
   10914     int base, len;
   10915     xmlParserInputPtr in;
   10916     const xmlChar *buf;
   10917 
   10918     in = ctxt->input;
   10919     if (in == NULL) return(-1);
   10920     base = in->cur - in->base;
   10921     if (base < 0) return(-1);
   10922     if (ctxt->checkIndex > base)
   10923         base = ctxt->checkIndex;
   10924     if (in->buf == NULL) {
   10925 	buf = in->base;
   10926 	len = in->length;
   10927     } else {
   10928 	buf = xmlBufContent(in->buf->buffer);
   10929 	len = xmlBufUse(in->buf->buffer);
   10930     }
   10931     /* take into account the sequence length */
   10932     if (third) len -= 2;
   10933     else if (next) len --;
   10934     for (;base < len;base++) {
   10935         if (buf[base] == first) {
   10936 	    if (third != 0) {
   10937 		if ((buf[base + 1] != next) ||
   10938 		    (buf[base + 2] != third)) continue;
   10939 	    } else if (next != 0) {
   10940 		if (buf[base + 1] != next) continue;
   10941 	    }
   10942 	    ctxt->checkIndex = 0;
   10943 #ifdef DEBUG_PUSH
   10944 	    if (next == 0)
   10945 		xmlGenericError(xmlGenericErrorContext,
   10946 			"PP: lookup '%c' found at %d\n",
   10947 			first, base);
   10948 	    else if (third == 0)
   10949 		xmlGenericError(xmlGenericErrorContext,
   10950 			"PP: lookup '%c%c' found at %d\n",
   10951 			first, next, base);
   10952 	    else
   10953 		xmlGenericError(xmlGenericErrorContext,
   10954 			"PP: lookup '%c%c%c' found at %d\n",
   10955 			first, next, third, base);
   10956 #endif
   10957 	    return(base - (in->cur - in->base));
   10958 	}
   10959     }
   10960     ctxt->checkIndex = base;
   10961 #ifdef DEBUG_PUSH
   10962     if (next == 0)
   10963 	xmlGenericError(xmlGenericErrorContext,
   10964 		"PP: lookup '%c' failed\n", first);
   10965     else if (third == 0)
   10966 	xmlGenericError(xmlGenericErrorContext,
   10967 		"PP: lookup '%c%c' failed\n", first, next);
   10968     else
   10969 	xmlGenericError(xmlGenericErrorContext,
   10970 		"PP: lookup '%c%c%c' failed\n", first, next, third);
   10971 #endif
   10972     return(-1);
   10973 }
   10974 
   10975 /**
   10976  * xmlParseGetLasts:
   10977  * @ctxt:  an XML parser context
   10978  * @lastlt:  pointer to store the last '<' from the input
   10979  * @lastgt:  pointer to store the last '>' from the input
   10980  *
   10981  * Lookup the last < and > in the current chunk
   10982  */
   10983 static void
   10984 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
   10985                  const xmlChar **lastgt) {
   10986     const xmlChar *tmp;
   10987 
   10988     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
   10989 	xmlGenericError(xmlGenericErrorContext,
   10990 		    "Internal error: xmlParseGetLasts\n");
   10991 	return;
   10992     }
   10993     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
   10994         tmp = ctxt->input->end;
   10995 	tmp--;
   10996 	while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
   10997 	if (tmp < ctxt->input->base) {
   10998 	    *lastlt = NULL;
   10999 	    *lastgt = NULL;
   11000 	} else {
   11001 	    *lastlt = tmp;
   11002 	    tmp++;
   11003 	    while ((tmp < ctxt->input->end) && (*tmp != '>')) {
   11004 	        if (*tmp == '\'') {
   11005 		    tmp++;
   11006 		    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
   11007 		    if (tmp < ctxt->input->end) tmp++;
   11008 		} else if (*tmp == '"') {
   11009 		    tmp++;
   11010 		    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
   11011 		    if (tmp < ctxt->input->end) tmp++;
   11012 		} else
   11013 		    tmp++;
   11014 	    }
   11015 	    if (tmp < ctxt->input->end)
   11016 	        *lastgt = tmp;
   11017 	    else {
   11018 	        tmp = *lastlt;
   11019 		tmp--;
   11020 		while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
   11021 		if (tmp >= ctxt->input->base)
   11022 		    *lastgt = tmp;
   11023 		else
   11024 		    *lastgt = NULL;
   11025 	    }
   11026 	}
   11027     } else {
   11028         *lastlt = NULL;
   11029 	*lastgt = NULL;
   11030     }
   11031 }
   11032 /**
   11033  * xmlCheckCdataPush:
   11034  * @cur: pointer to the bock of characters
   11035  * @len: length of the block in bytes
   11036  *
   11037  * Check that the block of characters is okay as SCdata content [20]
   11038  *
   11039  * Returns the number of bytes to pass if okay, a negative index where an
   11040  *         UTF-8 error occured otherwise
   11041  */
   11042 static int
   11043 xmlCheckCdataPush(const xmlChar *utf, int len) {
   11044     int ix;
   11045     unsigned char c;
   11046     int codepoint;
   11047 
   11048     if ((utf == NULL) || (len <= 0))
   11049         return(0);
   11050 
   11051     for (ix = 0; ix < len;) {      /* string is 0-terminated */
   11052         c = utf[ix];
   11053         if ((c & 0x80) == 0x00) {	/* 1-byte code, starts with 10 */
   11054 	    if (c >= 0x20)
   11055 		ix++;
   11056 	    else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
   11057 	        ix++;
   11058 	    else
   11059 	        return(-ix);
   11060 	} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
   11061 	    if (ix + 2 > len) return(ix);
   11062 	    if ((utf[ix+1] & 0xc0 ) != 0x80)
   11063 	        return(-ix);
   11064 	    codepoint = (utf[ix] & 0x1f) << 6;
   11065 	    codepoint |= utf[ix+1] & 0x3f;
   11066 	    if (!xmlIsCharQ(codepoint))
   11067 	        return(-ix);
   11068 	    ix += 2;
   11069 	} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
   11070 	    if (ix + 3 > len) return(ix);
   11071 	    if (((utf[ix+1] & 0xc0) != 0x80) ||
   11072 	        ((utf[ix+2] & 0xc0) != 0x80))
   11073 		    return(-ix);
   11074 	    codepoint = (utf[ix] & 0xf) << 12;
   11075 	    codepoint |= (utf[ix+1] & 0x3f) << 6;
   11076 	    codepoint |= utf[ix+2] & 0x3f;
   11077 	    if (!xmlIsCharQ(codepoint))
   11078 	        return(-ix);
   11079 	    ix += 3;
   11080 	} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
   11081 	    if (ix + 4 > len) return(ix);
   11082 	    if (((utf[ix+1] & 0xc0) != 0x80) ||
   11083 	        ((utf[ix+2] & 0xc0) != 0x80) ||
   11084 		((utf[ix+3] & 0xc0) != 0x80))
   11085 		    return(-ix);
   11086 	    codepoint = (utf[ix] & 0x7) << 18;
   11087 	    codepoint |= (utf[ix+1] & 0x3f) << 12;
   11088 	    codepoint |= (utf[ix+2] & 0x3f) << 6;
   11089 	    codepoint |= utf[ix+3] & 0x3f;
   11090 	    if (!xmlIsCharQ(codepoint))
   11091 	        return(-ix);
   11092 	    ix += 4;
   11093 	} else				/* unknown encoding */
   11094 	    return(-ix);
   11095       }
   11096       return(ix);
   11097 }
   11098 
   11099 /**
   11100  * xmlParseTryOrFinish:
   11101  * @ctxt:  an XML parser context
   11102  * @terminate:  last chunk indicator
   11103  *
   11104  * Try to progress on parsing
   11105  *
   11106  * Returns zero if no parsing was possible
   11107  */
   11108 static int
   11109 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
   11110     int ret = 0;
   11111     int avail, tlen;
   11112     xmlChar cur, next;
   11113     const xmlChar *lastlt, *lastgt;
   11114 
   11115     if (ctxt->input == NULL)
   11116         return(0);
   11117 
   11118 #ifdef DEBUG_PUSH
   11119     switch (ctxt->instate) {
   11120 	case XML_PARSER_EOF:
   11121 	    xmlGenericError(xmlGenericErrorContext,
   11122 		    "PP: try EOF\n"); break;
   11123 	case XML_PARSER_START:
   11124 	    xmlGenericError(xmlGenericErrorContext,
   11125 		    "PP: try START\n"); break;
   11126 	case XML_PARSER_MISC:
   11127 	    xmlGenericError(xmlGenericErrorContext,
   11128 		    "PP: try MISC\n");break;
   11129 	case XML_PARSER_COMMENT:
   11130 	    xmlGenericError(xmlGenericErrorContext,
   11131 		    "PP: try COMMENT\n");break;
   11132 	case XML_PARSER_PROLOG:
   11133 	    xmlGenericError(xmlGenericErrorContext,
   11134 		    "PP: try PROLOG\n");break;
   11135 	case XML_PARSER_START_TAG:
   11136 	    xmlGenericError(xmlGenericErrorContext,
   11137 		    "PP: try START_TAG\n");break;
   11138 	case XML_PARSER_CONTENT:
   11139 	    xmlGenericError(xmlGenericErrorContext,
   11140 		    "PP: try CONTENT\n");break;
   11141 	case XML_PARSER_CDATA_SECTION:
   11142 	    xmlGenericError(xmlGenericErrorContext,
   11143 		    "PP: try CDATA_SECTION\n");break;
   11144 	case XML_PARSER_END_TAG:
   11145 	    xmlGenericError(xmlGenericErrorContext,
   11146 		    "PP: try END_TAG\n");break;
   11147 	case XML_PARSER_ENTITY_DECL:
   11148 	    xmlGenericError(xmlGenericErrorContext,
   11149 		    "PP: try ENTITY_DECL\n");break;
   11150 	case XML_PARSER_ENTITY_VALUE:
   11151 	    xmlGenericError(xmlGenericErrorContext,
   11152 		    "PP: try ENTITY_VALUE\n");break;
   11153 	case XML_PARSER_ATTRIBUTE_VALUE:
   11154 	    xmlGenericError(xmlGenericErrorContext,
   11155 		    "PP: try ATTRIBUTE_VALUE\n");break;
   11156 	case XML_PARSER_DTD:
   11157 	    xmlGenericError(xmlGenericErrorContext,
   11158 		    "PP: try DTD\n");break;
   11159 	case XML_PARSER_EPILOG:
   11160 	    xmlGenericError(xmlGenericErrorContext,
   11161 		    "PP: try EPILOG\n");break;
   11162 	case XML_PARSER_PI:
   11163 	    xmlGenericError(xmlGenericErrorContext,
   11164 		    "PP: try PI\n");break;
   11165         case XML_PARSER_IGNORE:
   11166             xmlGenericError(xmlGenericErrorContext,
   11167 		    "PP: try IGNORE\n");break;
   11168     }
   11169 #endif
   11170 
   11171     if ((ctxt->input != NULL) &&
   11172         (ctxt->input->cur - ctxt->input->base > 4096)) {
   11173 	xmlSHRINK(ctxt);
   11174 	ctxt->checkIndex = 0;
   11175     }
   11176     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
   11177 
   11178     while (ctxt->instate != XML_PARSER_EOF) {
   11179 	if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
   11180 	    return(0);
   11181 
   11182 
   11183 	/*
   11184 	 * Pop-up of finished entities.
   11185 	 */
   11186 	while ((RAW == 0) && (ctxt->inputNr > 1))
   11187 	    xmlPopInput(ctxt);
   11188 
   11189 	if (ctxt->input == NULL) break;
   11190 	if (ctxt->input->buf == NULL)
   11191 	    avail = ctxt->input->length -
   11192 	            (ctxt->input->cur - ctxt->input->base);
   11193 	else {
   11194 	    /*
   11195 	     * If we are operating on converted input, try to flush
   11196 	     * remainng chars to avoid them stalling in the non-converted
   11197 	     * buffer. But do not do this in document start where
   11198 	     * encoding="..." may not have been read and we work on a
   11199 	     * guessed encoding.
   11200 	     */
   11201 	    if ((ctxt->instate != XML_PARSER_START) &&
   11202 	        (ctxt->input->buf->raw != NULL) &&
   11203 		(xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
   11204                 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
   11205                                                  ctxt->input);
   11206 		size_t current = ctxt->input->cur - ctxt->input->base;
   11207 
   11208 		xmlParserInputBufferPush(ctxt->input->buf, 0, "");
   11209                 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
   11210                                       base, current);
   11211 	    }
   11212 	    avail = xmlBufUse(ctxt->input->buf->buffer) -
   11213 		    (ctxt->input->cur - ctxt->input->base);
   11214 	}
   11215         if (avail < 1)
   11216 	    goto done;
   11217         switch (ctxt->instate) {
   11218             case XML_PARSER_EOF:
   11219 	        /*
   11220 		 * Document parsing is done !
   11221 		 */
   11222 	        goto done;
   11223             case XML_PARSER_START:
   11224 		if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
   11225 		    xmlChar start[4];
   11226 		    xmlCharEncoding enc;
   11227 
   11228 		    /*
   11229 		     * Very first chars read from the document flow.
   11230 		     */
   11231 		    if (avail < 4)
   11232 			goto done;
   11233 
   11234 		    /*
   11235 		     * Get the 4 first bytes and decode the charset
   11236 		     * if enc != XML_CHAR_ENCODING_NONE
   11237 		     * plug some encoding conversion routines,
   11238 		     * else xmlSwitchEncoding will set to (default)
   11239 		     * UTF8.
   11240 		     */
   11241 		    start[0] = RAW;
   11242 		    start[1] = NXT(1);
   11243 		    start[2] = NXT(2);
   11244 		    start[3] = NXT(3);
   11245 		    enc = xmlDetectCharEncoding(start, 4);
   11246 		    xmlSwitchEncoding(ctxt, enc);
   11247 		    break;
   11248 		}
   11249 
   11250 		if (avail < 2)
   11251 		    goto done;
   11252 		cur = ctxt->input->cur[0];
   11253 		next = ctxt->input->cur[1];
   11254 		if (cur == 0) {
   11255 		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
   11256 			ctxt->sax->setDocumentLocator(ctxt->userData,
   11257 						      &xmlDefaultSAXLocator);
   11258 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
   11259 		    ctxt->instate = XML_PARSER_EOF;
   11260 #ifdef DEBUG_PUSH
   11261 		    xmlGenericError(xmlGenericErrorContext,
   11262 			    "PP: entering EOF\n");
   11263 #endif
   11264 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   11265 			ctxt->sax->endDocument(ctxt->userData);
   11266 		    goto done;
   11267 		}
   11268 	        if ((cur == '<') && (next == '?')) {
   11269 		    /* PI or XML decl */
   11270 		    if (avail < 5) return(ret);
   11271 		    if ((!terminate) &&
   11272 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
   11273 			return(ret);
   11274 		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
   11275 			ctxt->sax->setDocumentLocator(ctxt->userData,
   11276 						      &xmlDefaultSAXLocator);
   11277 		    if ((ctxt->input->cur[2] == 'x') &&
   11278 			(ctxt->input->cur[3] == 'm') &&
   11279 			(ctxt->input->cur[4] == 'l') &&
   11280 			(IS_BLANK_CH(ctxt->input->cur[5]))) {
   11281 			ret += 5;
   11282 #ifdef DEBUG_PUSH
   11283 			xmlGenericError(xmlGenericErrorContext,
   11284 				"PP: Parsing XML Decl\n");
   11285 #endif
   11286 			xmlParseXMLDecl(ctxt);
   11287 			if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
   11288 			    /*
   11289 			     * The XML REC instructs us to stop parsing right
   11290 			     * here
   11291 			     */
   11292 			    ctxt->instate = XML_PARSER_EOF;
   11293 			    return(0);
   11294 			}
   11295 			ctxt->standalone = ctxt->input->standalone;
   11296 			if ((ctxt->encoding == NULL) &&
   11297 			    (ctxt->input->encoding != NULL))
   11298 			    ctxt->encoding = xmlStrdup(ctxt->input->encoding);
   11299 			if ((ctxt->sax) && (ctxt->sax->startDocument) &&
   11300 			    (!ctxt->disableSAX))
   11301 			    ctxt->sax->startDocument(ctxt->userData);
   11302 			ctxt->instate = XML_PARSER_MISC;
   11303 #ifdef DEBUG_PUSH
   11304 			xmlGenericError(xmlGenericErrorContext,
   11305 				"PP: entering MISC\n");
   11306 #endif
   11307 		    } else {
   11308 			ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
   11309 			if ((ctxt->sax) && (ctxt->sax->startDocument) &&
   11310 			    (!ctxt->disableSAX))
   11311 			    ctxt->sax->startDocument(ctxt->userData);
   11312 			ctxt->instate = XML_PARSER_MISC;
   11313 #ifdef DEBUG_PUSH
   11314 			xmlGenericError(xmlGenericErrorContext,
   11315 				"PP: entering MISC\n");
   11316 #endif
   11317 		    }
   11318 		} else {
   11319 		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
   11320 			ctxt->sax->setDocumentLocator(ctxt->userData,
   11321 						      &xmlDefaultSAXLocator);
   11322 		    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
   11323 		    if (ctxt->version == NULL) {
   11324 		        xmlErrMemory(ctxt, NULL);
   11325 			break;
   11326 		    }
   11327 		    if ((ctxt->sax) && (ctxt->sax->startDocument) &&
   11328 		        (!ctxt->disableSAX))
   11329 			ctxt->sax->startDocument(ctxt->userData);
   11330 		    ctxt->instate = XML_PARSER_MISC;
   11331 #ifdef DEBUG_PUSH
   11332 		    xmlGenericError(xmlGenericErrorContext,
   11333 			    "PP: entering MISC\n");
   11334 #endif
   11335 		}
   11336 		break;
   11337             case XML_PARSER_START_TAG: {
   11338 	        const xmlChar *name;
   11339 		const xmlChar *prefix = NULL;
   11340 		const xmlChar *URI = NULL;
   11341 		int nsNr = ctxt->nsNr;
   11342 
   11343 		if ((avail < 2) && (ctxt->inputNr == 1))
   11344 		    goto done;
   11345 		cur = ctxt->input->cur[0];
   11346 	        if (cur != '<') {
   11347 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
   11348 		    ctxt->instate = XML_PARSER_EOF;
   11349 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   11350 			ctxt->sax->endDocument(ctxt->userData);
   11351 		    goto done;
   11352 		}
   11353 		if (!terminate) {
   11354 		    if (ctxt->progressive) {
   11355 		        /* > can be found unescaped in attribute values */
   11356 		        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
   11357 			    goto done;
   11358 		    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
   11359 			goto done;
   11360 		    }
   11361 		}
   11362 		if (ctxt->spaceNr == 0)
   11363 		    spacePush(ctxt, -1);
   11364 		else if (*ctxt->space == -2)
   11365 		    spacePush(ctxt, -1);
   11366 		else
   11367 		    spacePush(ctxt, *ctxt->space);
   11368 #ifdef LIBXML_SAX1_ENABLED
   11369 		if (ctxt->sax2)
   11370 #endif /* LIBXML_SAX1_ENABLED */
   11371 		    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
   11372 #ifdef LIBXML_SAX1_ENABLED
   11373 		else
   11374 		    name = xmlParseStartTag(ctxt);
   11375 #endif /* LIBXML_SAX1_ENABLED */
   11376 		if (ctxt->instate == XML_PARSER_EOF)
   11377 		    goto done;
   11378 		if (name == NULL) {
   11379 		    spacePop(ctxt);
   11380 		    ctxt->instate = XML_PARSER_EOF;
   11381 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   11382 			ctxt->sax->endDocument(ctxt->userData);
   11383 		    goto done;
   11384 		}
   11385 #ifdef LIBXML_VALID_ENABLED
   11386 		/*
   11387 		 * [ VC: Root Element Type ]
   11388 		 * The Name in the document type declaration must match
   11389 		 * the element type of the root element.
   11390 		 */
   11391 		if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
   11392 		    ctxt->node && (ctxt->node == ctxt->myDoc->children))
   11393 		    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
   11394 #endif /* LIBXML_VALID_ENABLED */
   11395 
   11396 		/*
   11397 		 * Check for an Empty Element.
   11398 		 */
   11399 		if ((RAW == '/') && (NXT(1) == '>')) {
   11400 		    SKIP(2);
   11401 
   11402 		    if (ctxt->sax2) {
   11403 			if ((ctxt->sax != NULL) &&
   11404 			    (ctxt->sax->endElementNs != NULL) &&
   11405 			    (!ctxt->disableSAX))
   11406 			    ctxt->sax->endElementNs(ctxt->userData, name,
   11407 			                            prefix, URI);
   11408 			if (ctxt->nsNr - nsNr > 0)
   11409 			    nsPop(ctxt, ctxt->nsNr - nsNr);
   11410 #ifdef LIBXML_SAX1_ENABLED
   11411 		    } else {
   11412 			if ((ctxt->sax != NULL) &&
   11413 			    (ctxt->sax->endElement != NULL) &&
   11414 			    (!ctxt->disableSAX))
   11415 			    ctxt->sax->endElement(ctxt->userData, name);
   11416 #endif /* LIBXML_SAX1_ENABLED */
   11417 		    }
   11418 		    if (ctxt->instate == XML_PARSER_EOF)
   11419 			goto done;
   11420 		    spacePop(ctxt);
   11421 		    if (ctxt->nameNr == 0) {
   11422 			ctxt->instate = XML_PARSER_EPILOG;
   11423 		    } else {
   11424 			ctxt->instate = XML_PARSER_CONTENT;
   11425 		    }
   11426                     ctxt->progressive = 1;
   11427 		    break;
   11428 		}
   11429 		if (RAW == '>') {
   11430 		    NEXT;
   11431 		} else {
   11432 		    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
   11433 					 "Couldn't find end of Start Tag %s\n",
   11434 					 name);
   11435 		    nodePop(ctxt);
   11436 		    spacePop(ctxt);
   11437 		}
   11438 		if (ctxt->sax2)
   11439 		    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
   11440 #ifdef LIBXML_SAX1_ENABLED
   11441 		else
   11442 		    namePush(ctxt, name);
   11443 #endif /* LIBXML_SAX1_ENABLED */
   11444 
   11445 		ctxt->instate = XML_PARSER_CONTENT;
   11446                 ctxt->progressive = 1;
   11447                 break;
   11448 	    }
   11449             case XML_PARSER_CONTENT: {
   11450 		const xmlChar *test;
   11451 		unsigned int cons;
   11452 		if ((avail < 2) && (ctxt->inputNr == 1))
   11453 		    goto done;
   11454 		cur = ctxt->input->cur[0];
   11455 		next = ctxt->input->cur[1];
   11456 
   11457 		test = CUR_PTR;
   11458 	        cons = ctxt->input->consumed;
   11459 		if ((cur == '<') && (next == '/')) {
   11460 		    ctxt->instate = XML_PARSER_END_TAG;
   11461 		    break;
   11462 	        } else if ((cur == '<') && (next == '?')) {
   11463 		    if ((!terminate) &&
   11464 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
   11465                         ctxt->progressive = XML_PARSER_PI;
   11466 			goto done;
   11467                     }
   11468 		    xmlParsePI(ctxt);
   11469 		    ctxt->instate = XML_PARSER_CONTENT;
   11470                     ctxt->progressive = 1;
   11471 		} else if ((cur == '<') && (next != '!')) {
   11472 		    ctxt->instate = XML_PARSER_START_TAG;
   11473 		    break;
   11474 		} else if ((cur == '<') && (next == '!') &&
   11475 		           (ctxt->input->cur[2] == '-') &&
   11476 			   (ctxt->input->cur[3] == '-')) {
   11477 		    int term;
   11478 
   11479 	            if (avail < 4)
   11480 		        goto done;
   11481 		    ctxt->input->cur += 4;
   11482 		    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
   11483 		    ctxt->input->cur -= 4;
   11484 		    if ((!terminate) && (term < 0)) {
   11485                         ctxt->progressive = XML_PARSER_COMMENT;
   11486 			goto done;
   11487                     }
   11488 		    xmlParseComment(ctxt);
   11489 		    ctxt->instate = XML_PARSER_CONTENT;
   11490                     ctxt->progressive = 1;
   11491 		} else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
   11492 		    (ctxt->input->cur[2] == '[') &&
   11493 		    (ctxt->input->cur[3] == 'C') &&
   11494 		    (ctxt->input->cur[4] == 'D') &&
   11495 		    (ctxt->input->cur[5] == 'A') &&
   11496 		    (ctxt->input->cur[6] == 'T') &&
   11497 		    (ctxt->input->cur[7] == 'A') &&
   11498 		    (ctxt->input->cur[8] == '[')) {
   11499 		    SKIP(9);
   11500 		    ctxt->instate = XML_PARSER_CDATA_SECTION;
   11501 		    break;
   11502 		} else if ((cur == '<') && (next == '!') &&
   11503 		           (avail < 9)) {
   11504 		    goto done;
   11505 		} else if (cur == '&') {
   11506 		    if ((!terminate) &&
   11507 		        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
   11508 			goto done;
   11509 		    xmlParseReference(ctxt);
   11510 		} else {
   11511 		    /* TODO Avoid the extra copy, handle directly !!! */
   11512 		    /*
   11513 		     * Goal of the following test is:
   11514 		     *  - minimize calls to the SAX 'character' callback
   11515 		     *    when they are mergeable
   11516 		     *  - handle an problem for isBlank when we only parse
   11517 		     *    a sequence of blank chars and the next one is
   11518 		     *    not available to check against '<' presence.
   11519 		     *  - tries to homogenize the differences in SAX
   11520 		     *    callbacks between the push and pull versions
   11521 		     *    of the parser.
   11522 		     */
   11523 		    if ((ctxt->inputNr == 1) &&
   11524 		        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
   11525 			if (!terminate) {
   11526 			    if (ctxt->progressive) {
   11527 				if ((lastlt == NULL) ||
   11528 				    (ctxt->input->cur > lastlt))
   11529 				    goto done;
   11530 			    } else if (xmlParseLookupSequence(ctxt,
   11531 			                                      '<', 0, 0) < 0) {
   11532 				goto done;
   11533 			    }
   11534 			}
   11535                     }
   11536 		    ctxt->checkIndex = 0;
   11537 		    xmlParseCharData(ctxt, 0);
   11538 		}
   11539 		/*
   11540 		 * Pop-up of finished entities.
   11541 		 */
   11542 		while ((RAW == 0) && (ctxt->inputNr > 1))
   11543 		    xmlPopInput(ctxt);
   11544 		if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
   11545 		    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
   11546 		                "detected an error in element content\n");
   11547 		    ctxt->instate = XML_PARSER_EOF;
   11548 		    break;
   11549 		}
   11550 		break;
   11551 	    }
   11552             case XML_PARSER_END_TAG:
   11553 		if (avail < 2)
   11554 		    goto done;
   11555 		if (!terminate) {
   11556 		    if (ctxt->progressive) {
   11557 		        /* > can be found unescaped in attribute values */
   11558 		        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
   11559 			    goto done;
   11560 		    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
   11561 			goto done;
   11562 		    }
   11563 		}
   11564 		if (ctxt->sax2) {
   11565 		    xmlParseEndTag2(ctxt,
   11566 		           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
   11567 		           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
   11568 		       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
   11569 		    nameNsPop(ctxt);
   11570 		}
   11571 #ifdef LIBXML_SAX1_ENABLED
   11572 		  else
   11573 		    xmlParseEndTag1(ctxt, 0);
   11574 #endif /* LIBXML_SAX1_ENABLED */
   11575 		if (ctxt->instate == XML_PARSER_EOF) {
   11576 		    /* Nothing */
   11577 		} else if (ctxt->nameNr == 0) {
   11578 		    ctxt->instate = XML_PARSER_EPILOG;
   11579 		} else {
   11580 		    ctxt->instate = XML_PARSER_CONTENT;
   11581 		}
   11582 		break;
   11583             case XML_PARSER_CDATA_SECTION: {
   11584 	        /*
   11585 		 * The Push mode need to have the SAX callback for
   11586 		 * cdataBlock merge back contiguous callbacks.
   11587 		 */
   11588 		int base;
   11589 
   11590 		base = xmlParseLookupSequence(ctxt, ']', ']', '>');
   11591 		if (base < 0) {
   11592 		    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
   11593 		        int tmp;
   11594 
   11595 			tmp = xmlCheckCdataPush(ctxt->input->cur,
   11596 			                        XML_PARSER_BIG_BUFFER_SIZE);
   11597 			if (tmp < 0) {
   11598 			    tmp = -tmp;
   11599 			    ctxt->input->cur += tmp;
   11600 			    goto encoding_error;
   11601 			}
   11602 			if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
   11603 			    if (ctxt->sax->cdataBlock != NULL)
   11604 				ctxt->sax->cdataBlock(ctxt->userData,
   11605 				                      ctxt->input->cur, tmp);
   11606 			    else if (ctxt->sax->characters != NULL)
   11607 				ctxt->sax->characters(ctxt->userData,
   11608 				                      ctxt->input->cur, tmp);
   11609 			}
   11610 			if (ctxt->instate == XML_PARSER_EOF)
   11611 			    goto done;
   11612 			SKIPL(tmp);
   11613 			ctxt->checkIndex = 0;
   11614 		    }
   11615 		    goto done;
   11616 		} else {
   11617 		    int tmp;
   11618 
   11619 		    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
   11620 		    if ((tmp < 0) || (tmp != base)) {
   11621 			tmp = -tmp;
   11622 			ctxt->input->cur += tmp;
   11623 			goto encoding_error;
   11624 		    }
   11625 		    if ((ctxt->sax != NULL) && (base == 0) &&
   11626 		        (ctxt->sax->cdataBlock != NULL) &&
   11627 		        (!ctxt->disableSAX)) {
   11628 			/*
   11629 			 * Special case to provide identical behaviour
   11630 			 * between pull and push parsers on enpty CDATA
   11631 			 * sections
   11632 			 */
   11633 			 if ((ctxt->input->cur - ctxt->input->base >= 9) &&
   11634 			     (!strncmp((const char *)&ctxt->input->cur[-9],
   11635 			               "<![CDATA[", 9)))
   11636 			     ctxt->sax->cdataBlock(ctxt->userData,
   11637 			                           BAD_CAST "", 0);
   11638 		    } else if ((ctxt->sax != NULL) && (base > 0) &&
   11639 			(!ctxt->disableSAX)) {
   11640 			if (ctxt->sax->cdataBlock != NULL)
   11641 			    ctxt->sax->cdataBlock(ctxt->userData,
   11642 						  ctxt->input->cur, base);
   11643 			else if (ctxt->sax->characters != NULL)
   11644 			    ctxt->sax->characters(ctxt->userData,
   11645 						  ctxt->input->cur, base);
   11646 		    }
   11647 		    if (ctxt->instate == XML_PARSER_EOF)
   11648 			goto done;
   11649 		    SKIPL(base + 3);
   11650 		    ctxt->checkIndex = 0;
   11651 		    ctxt->instate = XML_PARSER_CONTENT;
   11652 #ifdef DEBUG_PUSH
   11653 		    xmlGenericError(xmlGenericErrorContext,
   11654 			    "PP: entering CONTENT\n");
   11655 #endif
   11656 		}
   11657 		break;
   11658 	    }
   11659             case XML_PARSER_MISC:
   11660 		SKIP_BLANKS;
   11661 		if (ctxt->input->buf == NULL)
   11662 		    avail = ctxt->input->length -
   11663 		            (ctxt->input->cur - ctxt->input->base);
   11664 		else
   11665 		    avail = xmlBufUse(ctxt->input->buf->buffer) -
   11666 		            (ctxt->input->cur - ctxt->input->base);
   11667 		if (avail < 2)
   11668 		    goto done;
   11669 		cur = ctxt->input->cur[0];
   11670 		next = ctxt->input->cur[1];
   11671 	        if ((cur == '<') && (next == '?')) {
   11672 		    if ((!terminate) &&
   11673 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
   11674                         ctxt->progressive = XML_PARSER_PI;
   11675 			goto done;
   11676                     }
   11677 #ifdef DEBUG_PUSH
   11678 		    xmlGenericError(xmlGenericErrorContext,
   11679 			    "PP: Parsing PI\n");
   11680 #endif
   11681 		    xmlParsePI(ctxt);
   11682 		    if (ctxt->instate == XML_PARSER_EOF)
   11683 			goto done;
   11684 		    ctxt->instate = XML_PARSER_MISC;
   11685                     ctxt->progressive = 1;
   11686 		    ctxt->checkIndex = 0;
   11687 		} else if ((cur == '<') && (next == '!') &&
   11688 		    (ctxt->input->cur[2] == '-') &&
   11689 		    (ctxt->input->cur[3] == '-')) {
   11690 		    if ((!terminate) &&
   11691 		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
   11692                         ctxt->progressive = XML_PARSER_COMMENT;
   11693 			goto done;
   11694                     }
   11695 #ifdef DEBUG_PUSH
   11696 		    xmlGenericError(xmlGenericErrorContext,
   11697 			    "PP: Parsing Comment\n");
   11698 #endif
   11699 		    xmlParseComment(ctxt);
   11700 		    if (ctxt->instate == XML_PARSER_EOF)
   11701 			goto done;
   11702 		    ctxt->instate = XML_PARSER_MISC;
   11703                     ctxt->progressive = 1;
   11704 		    ctxt->checkIndex = 0;
   11705 		} else if ((cur == '<') && (next == '!') &&
   11706 		    (ctxt->input->cur[2] == 'D') &&
   11707 		    (ctxt->input->cur[3] == 'O') &&
   11708 		    (ctxt->input->cur[4] == 'C') &&
   11709 		    (ctxt->input->cur[5] == 'T') &&
   11710 		    (ctxt->input->cur[6] == 'Y') &&
   11711 		    (ctxt->input->cur[7] == 'P') &&
   11712 		    (ctxt->input->cur[8] == 'E')) {
   11713 		    if ((!terminate) &&
   11714 		        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
   11715                         ctxt->progressive = XML_PARSER_DTD;
   11716 			goto done;
   11717                     }
   11718 #ifdef DEBUG_PUSH
   11719 		    xmlGenericError(xmlGenericErrorContext,
   11720 			    "PP: Parsing internal subset\n");
   11721 #endif
   11722 		    ctxt->inSubset = 1;
   11723                     ctxt->progressive = 0;
   11724 		    ctxt->checkIndex = 0;
   11725 		    xmlParseDocTypeDecl(ctxt);
   11726 		    if (ctxt->instate == XML_PARSER_EOF)
   11727 			goto done;
   11728 		    if (RAW == '[') {
   11729 			ctxt->instate = XML_PARSER_DTD;
   11730 #ifdef DEBUG_PUSH
   11731 			xmlGenericError(xmlGenericErrorContext,
   11732 				"PP: entering DTD\n");
   11733 #endif
   11734 		    } else {
   11735 			/*
   11736 			 * Create and update the external subset.
   11737 			 */
   11738 			ctxt->inSubset = 2;
   11739 			if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
   11740 			    (ctxt->sax->externalSubset != NULL))
   11741 			    ctxt->sax->externalSubset(ctxt->userData,
   11742 				    ctxt->intSubName, ctxt->extSubSystem,
   11743 				    ctxt->extSubURI);
   11744 			ctxt->inSubset = 0;
   11745 			xmlCleanSpecialAttr(ctxt);
   11746 			ctxt->instate = XML_PARSER_PROLOG;
   11747 #ifdef DEBUG_PUSH
   11748 			xmlGenericError(xmlGenericErrorContext,
   11749 				"PP: entering PROLOG\n");
   11750 #endif
   11751 		    }
   11752 		} else if ((cur == '<') && (next == '!') &&
   11753 		           (avail < 9)) {
   11754 		    goto done;
   11755 		} else {
   11756 		    ctxt->instate = XML_PARSER_START_TAG;
   11757 		    ctxt->progressive = XML_PARSER_START_TAG;
   11758 		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
   11759 #ifdef DEBUG_PUSH
   11760 		    xmlGenericError(xmlGenericErrorContext,
   11761 			    "PP: entering START_TAG\n");
   11762 #endif
   11763 		}
   11764 		break;
   11765             case XML_PARSER_PROLOG:
   11766 		SKIP_BLANKS;
   11767 		if (ctxt->input->buf == NULL)
   11768 		    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
   11769 		else
   11770 		    avail = xmlBufUse(ctxt->input->buf->buffer) -
   11771                             (ctxt->input->cur - ctxt->input->base);
   11772 		if (avail < 2)
   11773 		    goto done;
   11774 		cur = ctxt->input->cur[0];
   11775 		next = ctxt->input->cur[1];
   11776 	        if ((cur == '<') && (next == '?')) {
   11777 		    if ((!terminate) &&
   11778 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
   11779                         ctxt->progressive = XML_PARSER_PI;
   11780 			goto done;
   11781                     }
   11782 #ifdef DEBUG_PUSH
   11783 		    xmlGenericError(xmlGenericErrorContext,
   11784 			    "PP: Parsing PI\n");
   11785 #endif
   11786 		    xmlParsePI(ctxt);
   11787 		    if (ctxt->instate == XML_PARSER_EOF)
   11788 			goto done;
   11789 		    ctxt->instate = XML_PARSER_PROLOG;
   11790                     ctxt->progressive = 1;
   11791 		} else if ((cur == '<') && (next == '!') &&
   11792 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
   11793 		    if ((!terminate) &&
   11794 		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
   11795                         ctxt->progressive = XML_PARSER_COMMENT;
   11796 			goto done;
   11797                     }
   11798 #ifdef DEBUG_PUSH
   11799 		    xmlGenericError(xmlGenericErrorContext,
   11800 			    "PP: Parsing Comment\n");
   11801 #endif
   11802 		    xmlParseComment(ctxt);
   11803 		    if (ctxt->instate == XML_PARSER_EOF)
   11804 			goto done;
   11805 		    ctxt->instate = XML_PARSER_PROLOG;
   11806                     ctxt->progressive = 1;
   11807 		} else if ((cur == '<') && (next == '!') &&
   11808 		           (avail < 4)) {
   11809 		    goto done;
   11810 		} else {
   11811 		    ctxt->instate = XML_PARSER_START_TAG;
   11812 		    if (ctxt->progressive == 0)
   11813 			ctxt->progressive = XML_PARSER_START_TAG;
   11814 		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
   11815 #ifdef DEBUG_PUSH
   11816 		    xmlGenericError(xmlGenericErrorContext,
   11817 			    "PP: entering START_TAG\n");
   11818 #endif
   11819 		}
   11820 		break;
   11821             case XML_PARSER_EPILOG:
   11822 		SKIP_BLANKS;
   11823 		if (ctxt->input->buf == NULL)
   11824 		    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
   11825 		else
   11826 		    avail = xmlBufUse(ctxt->input->buf->buffer) -
   11827                             (ctxt->input->cur - ctxt->input->base);
   11828 		if (avail < 2)
   11829 		    goto done;
   11830 		cur = ctxt->input->cur[0];
   11831 		next = ctxt->input->cur[1];
   11832 	        if ((cur == '<') && (next == '?')) {
   11833 		    if ((!terminate) &&
   11834 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
   11835                         ctxt->progressive = XML_PARSER_PI;
   11836 			goto done;
   11837                     }
   11838 #ifdef DEBUG_PUSH
   11839 		    xmlGenericError(xmlGenericErrorContext,
   11840 			    "PP: Parsing PI\n");
   11841 #endif
   11842 		    xmlParsePI(ctxt);
   11843 		    if (ctxt->instate == XML_PARSER_EOF)
   11844 			goto done;
   11845 		    ctxt->instate = XML_PARSER_EPILOG;
   11846                     ctxt->progressive = 1;
   11847 		} else if ((cur == '<') && (next == '!') &&
   11848 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
   11849 		    if ((!terminate) &&
   11850 		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
   11851                         ctxt->progressive = XML_PARSER_COMMENT;
   11852 			goto done;
   11853                     }
   11854 #ifdef DEBUG_PUSH
   11855 		    xmlGenericError(xmlGenericErrorContext,
   11856 			    "PP: Parsing Comment\n");
   11857 #endif
   11858 		    xmlParseComment(ctxt);
   11859 		    if (ctxt->instate == XML_PARSER_EOF)
   11860 			goto done;
   11861 		    ctxt->instate = XML_PARSER_EPILOG;
   11862                     ctxt->progressive = 1;
   11863 		} else if ((cur == '<') && (next == '!') &&
   11864 		           (avail < 4)) {
   11865 		    goto done;
   11866 		} else {
   11867 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
   11868 		    ctxt->instate = XML_PARSER_EOF;
   11869 #ifdef DEBUG_PUSH
   11870 		    xmlGenericError(xmlGenericErrorContext,
   11871 			    "PP: entering EOF\n");
   11872 #endif
   11873 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   11874 			ctxt->sax->endDocument(ctxt->userData);
   11875 		    goto done;
   11876 		}
   11877 		break;
   11878             case XML_PARSER_DTD: {
   11879 	        /*
   11880 		 * Sorry but progressive parsing of the internal subset
   11881 		 * is not expected to be supported. We first check that
   11882 		 * the full content of the internal subset is available and
   11883 		 * the parsing is launched only at that point.
   11884 		 * Internal subset ends up with "']' S? '>'" in an unescaped
   11885 		 * section and not in a ']]>' sequence which are conditional
   11886 		 * sections (whoever argued to keep that crap in XML deserve
   11887 		 * a place in hell !).
   11888 		 */
   11889 		int base, i;
   11890 		xmlChar *buf;
   11891 	        xmlChar quote = 0;
   11892                 size_t use;
   11893 
   11894 		base = ctxt->input->cur - ctxt->input->base;
   11895 		if (base < 0) return(0);
   11896 		if (ctxt->checkIndex > base)
   11897 		    base = ctxt->checkIndex;
   11898 		buf = xmlBufContent(ctxt->input->buf->buffer);
   11899                 use = xmlBufUse(ctxt->input->buf->buffer);
   11900 		for (;(unsigned int) base < use; base++) {
   11901 		    if (quote != 0) {
   11902 		        if (buf[base] == quote)
   11903 			    quote = 0;
   11904 			continue;
   11905 		    }
   11906 		    if ((quote == 0) && (buf[base] == '<')) {
   11907 		        int found  = 0;
   11908 			/* special handling of comments */
   11909 		        if (((unsigned int) base + 4 < use) &&
   11910 			    (buf[base + 1] == '!') &&
   11911 			    (buf[base + 2] == '-') &&
   11912 			    (buf[base + 3] == '-')) {
   11913 			    for (;(unsigned int) base + 3 < use; base++) {
   11914 				if ((buf[base] == '-') &&
   11915 				    (buf[base + 1] == '-') &&
   11916 				    (buf[base + 2] == '>')) {
   11917 				    found = 1;
   11918 				    base += 2;
   11919 				    break;
   11920 				}
   11921 		            }
   11922 			    if (!found) {
   11923 #if 0
   11924 			        fprintf(stderr, "unfinished comment\n");
   11925 #endif
   11926 			        break; /* for */
   11927 		            }
   11928 		            continue;
   11929 			}
   11930 		    }
   11931 		    if (buf[base] == '"') {
   11932 		        quote = '"';
   11933 			continue;
   11934 		    }
   11935 		    if (buf[base] == '\'') {
   11936 		        quote = '\'';
   11937 			continue;
   11938 		    }
   11939 		    if (buf[base] == ']') {
   11940 #if 0
   11941 		        fprintf(stderr, "%c%c%c%c: ", buf[base],
   11942 			        buf[base + 1], buf[base + 2], buf[base + 3]);
   11943 #endif
   11944 		        if ((unsigned int) base +1 >= use)
   11945 			    break;
   11946 			if (buf[base + 1] == ']') {
   11947 			    /* conditional crap, skip both ']' ! */
   11948 			    base++;
   11949 			    continue;
   11950 			}
   11951 		        for (i = 1; (unsigned int) base + i < use; i++) {
   11952 			    if (buf[base + i] == '>') {
   11953 #if 0
   11954 			        fprintf(stderr, "found\n");
   11955 #endif
   11956 			        goto found_end_int_subset;
   11957 			    }
   11958 			    if (!IS_BLANK_CH(buf[base + i])) {
   11959 #if 0
   11960 			        fprintf(stderr, "not found\n");
   11961 #endif
   11962 			        goto not_end_of_int_subset;
   11963 			    }
   11964 			}
   11965 #if 0
   11966 			fprintf(stderr, "end of stream\n");
   11967 #endif
   11968 		        break;
   11969 
   11970 		    }
   11971 not_end_of_int_subset:
   11972                     continue; /* for */
   11973 		}
   11974 		/*
   11975 		 * We didn't found the end of the Internal subset
   11976 		 */
   11977                 if (quote == 0)
   11978                     ctxt->checkIndex = base;
   11979                 else
   11980                     ctxt->checkIndex = 0;
   11981 #ifdef DEBUG_PUSH
   11982 		if (next == 0)
   11983 		    xmlGenericError(xmlGenericErrorContext,
   11984 			    "PP: lookup of int subset end filed\n");
   11985 #endif
   11986 	        goto done;
   11987 
   11988 found_end_int_subset:
   11989                 ctxt->checkIndex = 0;
   11990 		xmlParseInternalSubset(ctxt);
   11991 		if (ctxt->instate == XML_PARSER_EOF)
   11992 		    goto done;
   11993 		ctxt->inSubset = 2;
   11994 		if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
   11995 		    (ctxt->sax->externalSubset != NULL))
   11996 		    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
   11997 			    ctxt->extSubSystem, ctxt->extSubURI);
   11998 		ctxt->inSubset = 0;
   11999 		xmlCleanSpecialAttr(ctxt);
   12000 		if (ctxt->instate == XML_PARSER_EOF)
   12001 		    goto done;
   12002 		ctxt->instate = XML_PARSER_PROLOG;
   12003 		ctxt->checkIndex = 0;
   12004 #ifdef DEBUG_PUSH
   12005 		xmlGenericError(xmlGenericErrorContext,
   12006 			"PP: entering PROLOG\n");
   12007 #endif
   12008                 break;
   12009 	    }
   12010             case XML_PARSER_COMMENT:
   12011 		xmlGenericError(xmlGenericErrorContext,
   12012 			"PP: internal error, state == COMMENT\n");
   12013 		ctxt->instate = XML_PARSER_CONTENT;
   12014 #ifdef DEBUG_PUSH
   12015 		xmlGenericError(xmlGenericErrorContext,
   12016 			"PP: entering CONTENT\n");
   12017 #endif
   12018 		break;
   12019             case XML_PARSER_IGNORE:
   12020 		xmlGenericError(xmlGenericErrorContext,
   12021 			"PP: internal error, state == IGNORE");
   12022 	        ctxt->instate = XML_PARSER_DTD;
   12023 #ifdef DEBUG_PUSH
   12024 		xmlGenericError(xmlGenericErrorContext,
   12025 			"PP: entering DTD\n");
   12026 #endif
   12027 	        break;
   12028             case XML_PARSER_PI:
   12029 		xmlGenericError(xmlGenericErrorContext,
   12030 			"PP: internal error, state == PI\n");
   12031 		ctxt->instate = XML_PARSER_CONTENT;
   12032 #ifdef DEBUG_PUSH
   12033 		xmlGenericError(xmlGenericErrorContext,
   12034 			"PP: entering CONTENT\n");
   12035 #endif
   12036 		break;
   12037             case XML_PARSER_ENTITY_DECL:
   12038 		xmlGenericError(xmlGenericErrorContext,
   12039 			"PP: internal error, state == ENTITY_DECL\n");
   12040 		ctxt->instate = XML_PARSER_DTD;
   12041 #ifdef DEBUG_PUSH
   12042 		xmlGenericError(xmlGenericErrorContext,
   12043 			"PP: entering DTD\n");
   12044 #endif
   12045 		break;
   12046             case XML_PARSER_ENTITY_VALUE:
   12047 		xmlGenericError(xmlGenericErrorContext,
   12048 			"PP: internal error, state == ENTITY_VALUE\n");
   12049 		ctxt->instate = XML_PARSER_CONTENT;
   12050 #ifdef DEBUG_PUSH
   12051 		xmlGenericError(xmlGenericErrorContext,
   12052 			"PP: entering DTD\n");
   12053 #endif
   12054 		break;
   12055             case XML_PARSER_ATTRIBUTE_VALUE:
   12056 		xmlGenericError(xmlGenericErrorContext,
   12057 			"PP: internal error, state == ATTRIBUTE_VALUE\n");
   12058 		ctxt->instate = XML_PARSER_START_TAG;
   12059 #ifdef DEBUG_PUSH
   12060 		xmlGenericError(xmlGenericErrorContext,
   12061 			"PP: entering START_TAG\n");
   12062 #endif
   12063 		break;
   12064             case XML_PARSER_SYSTEM_LITERAL:
   12065 		xmlGenericError(xmlGenericErrorContext,
   12066 			"PP: internal error, state == SYSTEM_LITERAL\n");
   12067 		ctxt->instate = XML_PARSER_START_TAG;
   12068 #ifdef DEBUG_PUSH
   12069 		xmlGenericError(xmlGenericErrorContext,
   12070 			"PP: entering START_TAG\n");
   12071 #endif
   12072 		break;
   12073             case XML_PARSER_PUBLIC_LITERAL:
   12074 		xmlGenericError(xmlGenericErrorContext,
   12075 			"PP: internal error, state == PUBLIC_LITERAL\n");
   12076 		ctxt->instate = XML_PARSER_START_TAG;
   12077 #ifdef DEBUG_PUSH
   12078 		xmlGenericError(xmlGenericErrorContext,
   12079 			"PP: entering START_TAG\n");
   12080 #endif
   12081 		break;
   12082 	}
   12083     }
   12084 done:
   12085 #ifdef DEBUG_PUSH
   12086     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
   12087 #endif
   12088     return(ret);
   12089 encoding_error:
   12090     {
   12091         char buffer[150];
   12092 
   12093 	snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
   12094 			ctxt->input->cur[0], ctxt->input->cur[1],
   12095 			ctxt->input->cur[2], ctxt->input->cur[3]);
   12096 	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
   12097 		     "Input is not proper UTF-8, indicate encoding !\n%s",
   12098 		     BAD_CAST buffer, NULL);
   12099     }
   12100     return(0);
   12101 }
   12102 
   12103 /**
   12104  * xmlParseCheckTransition:
   12105  * @ctxt:  an XML parser context
   12106  * @chunk:  a char array
   12107  * @size:  the size in byte of the chunk
   12108  *
   12109  * Check depending on the current parser state if the chunk given must be
   12110  * processed immediately or one need more data to advance on parsing.
   12111  *
   12112  * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
   12113  */
   12114 static int
   12115 xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
   12116     if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
   12117         return(-1);
   12118     if (ctxt->instate == XML_PARSER_START_TAG) {
   12119         if (memchr(chunk, '>', size) != NULL)
   12120             return(1);
   12121         return(0);
   12122     }
   12123     if (ctxt->progressive == XML_PARSER_COMMENT) {
   12124         if (memchr(chunk, '>', size) != NULL)
   12125             return(1);
   12126         return(0);
   12127     }
   12128     if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
   12129         if (memchr(chunk, '>', size) != NULL)
   12130             return(1);
   12131         return(0);
   12132     }
   12133     if (ctxt->progressive == XML_PARSER_PI) {
   12134         if (memchr(chunk, '>', size) != NULL)
   12135             return(1);
   12136         return(0);
   12137     }
   12138     if (ctxt->instate == XML_PARSER_END_TAG) {
   12139         if (memchr(chunk, '>', size) != NULL)
   12140             return(1);
   12141         return(0);
   12142     }
   12143     if ((ctxt->progressive == XML_PARSER_DTD) ||
   12144         (ctxt->instate == XML_PARSER_DTD)) {
   12145         if (memchr(chunk, '>', size) != NULL)
   12146             return(1);
   12147         return(0);
   12148     }
   12149     return(1);
   12150 }
   12151 
   12152 /**
   12153  * xmlParseChunk:
   12154  * @ctxt:  an XML parser context
   12155  * @chunk:  an char array
   12156  * @size:  the size in byte of the chunk
   12157  * @terminate:  last chunk indicator
   12158  *
   12159  * Parse a Chunk of memory
   12160  *
   12161  * Returns zero if no error, the xmlParserErrors otherwise.
   12162  */
   12163 int
   12164 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
   12165               int terminate) {
   12166     int end_in_lf = 0;
   12167     int remain = 0;
   12168     size_t old_avail = 0;
   12169     size_t avail = 0;
   12170 
   12171     if (ctxt == NULL)
   12172         return(XML_ERR_INTERNAL_ERROR);
   12173     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
   12174         return(ctxt->errNo);
   12175     if (ctxt->instate == XML_PARSER_EOF)
   12176         return(-1);
   12177     if (ctxt->instate == XML_PARSER_START)
   12178         xmlDetectSAX2(ctxt);
   12179     if ((size > 0) && (chunk != NULL) && (!terminate) &&
   12180         (chunk[size - 1] == '\r')) {
   12181 	end_in_lf = 1;
   12182 	size--;
   12183     }
   12184 
   12185 xmldecl_done:
   12186 
   12187     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
   12188         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
   12189 	size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
   12190 	size_t cur = ctxt->input->cur - ctxt->input->base;
   12191 	int res;
   12192 
   12193         old_avail = xmlBufUse(ctxt->input->buf->buffer);
   12194         /*
   12195          * Specific handling if we autodetected an encoding, we should not
   12196          * push more than the first line ... which depend on the encoding
   12197          * And only push the rest once the final encoding was detected
   12198          */
   12199         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
   12200             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
   12201             unsigned int len = 45;
   12202 
   12203             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
   12204                                BAD_CAST "UTF-16")) ||
   12205                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
   12206                                BAD_CAST "UTF16")))
   12207                 len = 90;
   12208             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
   12209                                     BAD_CAST "UCS-4")) ||
   12210                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
   12211                                     BAD_CAST "UCS4")))
   12212                 len = 180;
   12213 
   12214             if (ctxt->input->buf->rawconsumed < len)
   12215                 len -= ctxt->input->buf->rawconsumed;
   12216 
   12217             /*
   12218              * Change size for reading the initial declaration only
   12219              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
   12220              * will blindly copy extra bytes from memory.
   12221              */
   12222             if ((unsigned int) size > len) {
   12223                 remain = size - len;
   12224                 size = len;
   12225             } else {
   12226                 remain = 0;
   12227             }
   12228         }
   12229 	res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
   12230 	if (res < 0) {
   12231 	    ctxt->errNo = XML_PARSER_EOF;
   12232 	    ctxt->disableSAX = 1;
   12233 	    return (XML_PARSER_EOF);
   12234 	}
   12235         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
   12236 #ifdef DEBUG_PUSH
   12237 	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
   12238 #endif
   12239 
   12240     } else if (ctxt->instate != XML_PARSER_EOF) {
   12241 	if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
   12242 	    xmlParserInputBufferPtr in = ctxt->input->buf;
   12243 	    if ((in->encoder != NULL) && (in->buffer != NULL) &&
   12244 		    (in->raw != NULL)) {
   12245 		int nbchars;
   12246 		size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
   12247 		size_t current = ctxt->input->cur - ctxt->input->base;
   12248 
   12249 		nbchars = xmlCharEncInput(in, terminate);
   12250 		if (nbchars < 0) {
   12251 		    /* TODO 2.6.0 */
   12252 		    xmlGenericError(xmlGenericErrorContext,
   12253 				    "xmlParseChunk: encoder error\n");
   12254 		    return(XML_ERR_INVALID_ENCODING);
   12255 		}
   12256 		xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
   12257 	    }
   12258 	}
   12259     }
   12260     if (remain != 0) {
   12261         xmlParseTryOrFinish(ctxt, 0);
   12262     } else {
   12263         if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
   12264             avail = xmlBufUse(ctxt->input->buf->buffer);
   12265         /*
   12266          * Depending on the current state it may not be such
   12267          * a good idea to try parsing if there is nothing in the chunk
   12268          * which would be worth doing a parser state transition and we
   12269          * need to wait for more data
   12270          */
   12271         if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
   12272             (old_avail == 0) || (avail == 0) ||
   12273             (xmlParseCheckTransition(ctxt,
   12274                        (const char *)&ctxt->input->base[old_avail],
   12275                                      avail - old_avail)))
   12276             xmlParseTryOrFinish(ctxt, terminate);
   12277     }
   12278     if (ctxt->instate == XML_PARSER_EOF)
   12279         return(ctxt->errNo);
   12280 
   12281     if ((ctxt->input != NULL) &&
   12282          (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
   12283          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
   12284         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
   12285         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
   12286         ctxt->instate = XML_PARSER_EOF;
   12287     }
   12288     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
   12289         return(ctxt->errNo);
   12290 
   12291     if (remain != 0) {
   12292         chunk += size;
   12293         size = remain;
   12294         remain = 0;
   12295         goto xmldecl_done;
   12296     }
   12297     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
   12298         (ctxt->input->buf != NULL)) {
   12299 	size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
   12300 					 ctxt->input);
   12301 	size_t current = ctxt->input->cur - ctxt->input->base;
   12302 
   12303 	xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
   12304 
   12305 	xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
   12306 			      base, current);
   12307     }
   12308     if (terminate) {
   12309 	/*
   12310 	 * Check for termination
   12311 	 */
   12312 	int cur_avail = 0;
   12313 
   12314 	if (ctxt->input != NULL) {
   12315 	    if (ctxt->input->buf == NULL)
   12316 		cur_avail = ctxt->input->length -
   12317 			    (ctxt->input->cur - ctxt->input->base);
   12318 	    else
   12319 		cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
   12320 			              (ctxt->input->cur - ctxt->input->base);
   12321 	}
   12322 
   12323 	if ((ctxt->instate != XML_PARSER_EOF) &&
   12324 	    (ctxt->instate != XML_PARSER_EPILOG)) {
   12325 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
   12326 	}
   12327 	if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
   12328 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
   12329 	}
   12330 	if (ctxt->instate != XML_PARSER_EOF) {
   12331 	    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
   12332 		ctxt->sax->endDocument(ctxt->userData);
   12333 	}
   12334 	ctxt->instate = XML_PARSER_EOF;
   12335     }
   12336     if (ctxt->wellFormed == 0)
   12337 	return((xmlParserErrors) ctxt->errNo);
   12338     else
   12339         return(0);
   12340 }
   12341 
   12342 /************************************************************************
   12343  *									*
   12344  *		I/O front end functions to the parser			*
   12345  *									*
   12346  ************************************************************************/
   12347 
   12348 /**
   12349  * xmlCreatePushParserCtxt:
   12350  * @sax:  a SAX handler
   12351  * @user_data:  The user data returned on SAX callbacks
   12352  * @chunk:  a pointer to an array of chars
   12353  * @size:  number of chars in the array
   12354  * @filename:  an optional file name or URI
   12355  *
   12356  * Create a parser context for using the XML parser in push mode.
   12357  * If @buffer and @size are non-NULL, the data is used to detect
   12358  * the encoding.  The remaining characters will be parsed so they
   12359  * don't need to be fed in again through xmlParseChunk.
   12360  * To allow content encoding detection, @size should be >= 4
   12361  * The value of @filename is used for fetching external entities
   12362  * and error/warning reports.
   12363  *
   12364  * Returns the new parser context or NULL
   12365  */
   12366 
   12367 xmlParserCtxtPtr
   12368 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
   12369                         const char *chunk, int size, const char *filename) {
   12370     xmlParserCtxtPtr ctxt;
   12371     xmlParserInputPtr inputStream;
   12372     xmlParserInputBufferPtr buf;
   12373     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
   12374 
   12375     /*
   12376      * plug some encoding conversion routines
   12377      */
   12378     if ((chunk != NULL) && (size >= 4))
   12379 	enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
   12380 
   12381     buf = xmlAllocParserInputBuffer(enc);
   12382     if (buf == NULL) return(NULL);
   12383 
   12384     ctxt = xmlNewParserCtxt();
   12385     if (ctxt == NULL) {
   12386         xmlErrMemory(NULL, "creating parser: out of memory\n");
   12387 	xmlFreeParserInputBuffer(buf);
   12388 	return(NULL);
   12389     }
   12390     ctxt->dictNames = 1;
   12391     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
   12392     if (ctxt->pushTab == NULL) {
   12393         xmlErrMemory(ctxt, NULL);
   12394 	xmlFreeParserInputBuffer(buf);
   12395 	xmlFreeParserCtxt(ctxt);
   12396 	return(NULL);
   12397     }
   12398     if (sax != NULL) {
   12399 #ifdef LIBXML_SAX1_ENABLED
   12400 	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
   12401 #endif /* LIBXML_SAX1_ENABLED */
   12402 	    xmlFree(ctxt->sax);
   12403 	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
   12404 	if (ctxt->sax == NULL) {
   12405 	    xmlErrMemory(ctxt, NULL);
   12406 	    xmlFreeParserInputBuffer(buf);
   12407 	    xmlFreeParserCtxt(ctxt);
   12408 	    return(NULL);
   12409 	}
   12410 	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
   12411 	if (sax->initialized == XML_SAX2_MAGIC)
   12412 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
   12413 	else
   12414 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
   12415 	if (user_data != NULL)
   12416 	    ctxt->userData = user_data;
   12417     }
   12418     if (filename == NULL) {
   12419 	ctxt->directory = NULL;
   12420     } else {
   12421         ctxt->directory = xmlParserGetDirectory(filename);
   12422     }
   12423 
   12424     inputStream = xmlNewInputStream(ctxt);
   12425     if (inputStream == NULL) {
   12426 	xmlFreeParserCtxt(ctxt);
   12427 	xmlFreeParserInputBuffer(buf);
   12428 	return(NULL);
   12429     }
   12430 
   12431     if (filename == NULL)
   12432 	inputStream->filename = NULL;
   12433     else {
   12434 	inputStream->filename = (char *)
   12435 	    xmlCanonicPath((const xmlChar *) filename);
   12436 	if (inputStream->filename == NULL) {
   12437 	    xmlFreeParserCtxt(ctxt);
   12438 	    xmlFreeParserInputBuffer(buf);
   12439 	    return(NULL);
   12440 	}
   12441     }
   12442     inputStream->buf = buf;
   12443     xmlBufResetInput(inputStream->buf->buffer, inputStream);
   12444     inputPush(ctxt, inputStream);
   12445 
   12446     /*
   12447      * If the caller didn't provide an initial 'chunk' for determining
   12448      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
   12449      * that it can be automatically determined later
   12450      */
   12451     if ((size == 0) || (chunk == NULL)) {
   12452 	ctxt->charset = XML_CHAR_ENCODING_NONE;
   12453     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
   12454 	size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
   12455 	size_t cur = ctxt->input->cur - ctxt->input->base;
   12456 
   12457 	xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
   12458 
   12459         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
   12460 #ifdef DEBUG_PUSH
   12461 	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
   12462 #endif
   12463     }
   12464 
   12465     if (enc != XML_CHAR_ENCODING_NONE) {
   12466         xmlSwitchEncoding(ctxt, enc);
   12467     }
   12468 
   12469     return(ctxt);
   12470 }
   12471 #endif /* LIBXML_PUSH_ENABLED */
   12472 
   12473 /**
   12474  * xmlStopParser:
   12475  * @ctxt:  an XML parser context
   12476  *
   12477  * Blocks further parser processing
   12478  */
   12479 void
   12480 xmlStopParser(xmlParserCtxtPtr ctxt) {
   12481     if (ctxt == NULL)
   12482         return;
   12483     ctxt->instate = XML_PARSER_EOF;
   12484     ctxt->errNo = XML_ERR_USER_STOP;
   12485     ctxt->disableSAX = 1;
   12486     if (ctxt->input != NULL) {
   12487 	ctxt->input->cur = BAD_CAST"";
   12488 	ctxt->input->base = ctxt->input->cur;
   12489     }
   12490 }
   12491 
   12492 /**
   12493  * xmlCreateIOParserCtxt:
   12494  * @sax:  a SAX handler
   12495  * @user_data:  The user data returned on SAX callbacks
   12496  * @ioread:  an I/O read function
   12497  * @ioclose:  an I/O close function
   12498  * @ioctx:  an I/O handler
   12499  * @enc:  the charset encoding if known
   12500  *
   12501  * Create a parser context for using the XML parser with an existing
   12502  * I/O stream
   12503  *
   12504  * Returns the new parser context or NULL
   12505  */
   12506 xmlParserCtxtPtr
   12507 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
   12508 	xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
   12509 	void *ioctx, xmlCharEncoding enc) {
   12510     xmlParserCtxtPtr ctxt;
   12511     xmlParserInputPtr inputStream;
   12512     xmlParserInputBufferPtr buf;
   12513 
   12514     if (ioread == NULL) return(NULL);
   12515 
   12516     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
   12517     if (buf == NULL) {
   12518         if (ioclose != NULL)
   12519             ioclose(ioctx);
   12520         return (NULL);
   12521     }
   12522 
   12523     ctxt = xmlNewParserCtxt();
   12524     if (ctxt == NULL) {
   12525 	xmlFreeParserInputBuffer(buf);
   12526 	return(NULL);
   12527     }
   12528     if (sax != NULL) {
   12529 #ifdef LIBXML_SAX1_ENABLED
   12530 	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
   12531 #endif /* LIBXML_SAX1_ENABLED */
   12532 	    xmlFree(ctxt->sax);
   12533 	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
   12534 	if (ctxt->sax == NULL) {
   12535 	    xmlErrMemory(ctxt, NULL);
   12536 	    xmlFreeParserCtxt(ctxt);
   12537 	    return(NULL);
   12538 	}
   12539 	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
   12540 	if (sax->initialized == XML_SAX2_MAGIC)
   12541 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
   12542 	else
   12543 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
   12544 	if (user_data != NULL)
   12545 	    ctxt->userData = user_data;
   12546     }
   12547 
   12548     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
   12549     if (inputStream == NULL) {
   12550 	xmlFreeParserCtxt(ctxt);
   12551 	return(NULL);
   12552     }
   12553     inputPush(ctxt, inputStream);
   12554 
   12555     return(ctxt);
   12556 }
   12557 
   12558 #ifdef LIBXML_VALID_ENABLED
   12559 /************************************************************************
   12560  *									*
   12561  *		Front ends when parsing a DTD				*
   12562  *									*
   12563  ************************************************************************/
   12564 
   12565 /**
   12566  * xmlIOParseDTD:
   12567  * @sax:  the SAX handler block or NULL
   12568  * @input:  an Input Buffer
   12569  * @enc:  the charset encoding if known
   12570  *
   12571  * Load and parse a DTD
   12572  *
   12573  * Returns the resulting xmlDtdPtr or NULL in case of error.
   12574  * @input will be freed by the function in any case.
   12575  */
   12576 
   12577 xmlDtdPtr
   12578 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
   12579 	      xmlCharEncoding enc) {
   12580     xmlDtdPtr ret = NULL;
   12581     xmlParserCtxtPtr ctxt;
   12582     xmlParserInputPtr pinput = NULL;
   12583     xmlChar start[4];
   12584 
   12585     if (input == NULL)
   12586 	return(NULL);
   12587 
   12588     ctxt = xmlNewParserCtxt();
   12589     if (ctxt == NULL) {
   12590         xmlFreeParserInputBuffer(input);
   12591 	return(NULL);
   12592     }
   12593 
   12594     /*
   12595      * Set-up the SAX context
   12596      */
   12597     if (sax != NULL) {
   12598 	if (ctxt->sax != NULL)
   12599 	    xmlFree(ctxt->sax);
   12600         ctxt->sax = sax;
   12601         ctxt->userData = ctxt;
   12602     }
   12603     xmlDetectSAX2(ctxt);
   12604 
   12605     /*
   12606      * generate a parser input from the I/O handler
   12607      */
   12608 
   12609     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
   12610     if (pinput == NULL) {
   12611         if (sax != NULL) ctxt->sax = NULL;
   12612         xmlFreeParserInputBuffer(input);
   12613 	xmlFreeParserCtxt(ctxt);
   12614 	return(NULL);
   12615     }
   12616 
   12617     /*
   12618      * plug some encoding conversion routines here.
   12619      */
   12620     if (xmlPushInput(ctxt, pinput) < 0) {
   12621         if (sax != NULL) ctxt->sax = NULL;
   12622 	xmlFreeParserCtxt(ctxt);
   12623 	return(NULL);
   12624     }
   12625     if (enc != XML_CHAR_ENCODING_NONE) {
   12626         xmlSwitchEncoding(ctxt, enc);
   12627     }
   12628 
   12629     pinput->filename = NULL;
   12630     pinput->line = 1;
   12631     pinput->col = 1;
   12632     pinput->base = ctxt->input->cur;
   12633     pinput->cur = ctxt->input->cur;
   12634     pinput->free = NULL;
   12635 
   12636     /*
   12637      * let's parse that entity knowing it's an external subset.
   12638      */
   12639     ctxt->inSubset = 2;
   12640     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
   12641     if (ctxt->myDoc == NULL) {
   12642 	xmlErrMemory(ctxt, "New Doc failed");
   12643 	return(NULL);
   12644     }
   12645     ctxt->myDoc->properties = XML_DOC_INTERNAL;
   12646     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
   12647 	                               BAD_CAST "none", BAD_CAST "none");
   12648 
   12649     if ((enc == XML_CHAR_ENCODING_NONE) &&
   12650         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
   12651 	/*
   12652 	 * Get the 4 first bytes and decode the charset
   12653 	 * if enc != XML_CHAR_ENCODING_NONE
   12654 	 * plug some encoding conversion routines.
   12655 	 */
   12656 	start[0] = RAW;
   12657 	start[1] = NXT(1);
   12658 	start[2] = NXT(2);
   12659 	start[3] = NXT(3);
   12660 	enc = xmlDetectCharEncoding(start, 4);
   12661 	if (enc != XML_CHAR_ENCODING_NONE) {
   12662 	    xmlSwitchEncoding(ctxt, enc);
   12663 	}
   12664     }
   12665 
   12666     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
   12667 
   12668     if (ctxt->myDoc != NULL) {
   12669 	if (ctxt->wellFormed) {
   12670 	    ret = ctxt->myDoc->extSubset;
   12671 	    ctxt->myDoc->extSubset = NULL;
   12672 	    if (ret != NULL) {
   12673 		xmlNodePtr tmp;
   12674 
   12675 		ret->doc = NULL;
   12676 		tmp = ret->children;
   12677 		while (tmp != NULL) {
   12678 		    tmp->doc = NULL;
   12679 		    tmp = tmp->next;
   12680 		}
   12681 	    }
   12682 	} else {
   12683 	    ret = NULL;
   12684 	}
   12685         xmlFreeDoc(ctxt->myDoc);
   12686         ctxt->myDoc = NULL;
   12687     }
   12688     if (sax != NULL) ctxt->sax = NULL;
   12689     xmlFreeParserCtxt(ctxt);
   12690 
   12691     return(ret);
   12692 }
   12693 
   12694 /**
   12695  * xmlSAXParseDTD:
   12696  * @sax:  the SAX handler block
   12697  * @ExternalID:  a NAME* containing the External ID of the DTD
   12698  * @SystemID:  a NAME* containing the URL to the DTD
   12699  *
   12700  * Load and parse an external subset.
   12701  *
   12702  * Returns the resulting xmlDtdPtr or NULL in case of error.
   12703  */
   12704 
   12705 xmlDtdPtr
   12706 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
   12707                           const xmlChar *SystemID) {
   12708     xmlDtdPtr ret = NULL;
   12709     xmlParserCtxtPtr ctxt;
   12710     xmlParserInputPtr input = NULL;
   12711     xmlCharEncoding enc;
   12712     xmlChar* systemIdCanonic;
   12713 
   12714     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
   12715 
   12716     ctxt = xmlNewParserCtxt();
   12717     if (ctxt == NULL) {
   12718 	return(NULL);
   12719     }
   12720 
   12721     /*
   12722      * Set-up the SAX context
   12723      */
   12724     if (sax != NULL) {
   12725 	if (ctxt->sax != NULL)
   12726 	    xmlFree(ctxt->sax);
   12727         ctxt->sax = sax;
   12728         ctxt->userData = ctxt;
   12729     }
   12730 
   12731     /*
   12732      * Canonicalise the system ID
   12733      */
   12734     systemIdCanonic = xmlCanonicPath(SystemID);
   12735     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
   12736 	xmlFreeParserCtxt(ctxt);
   12737 	return(NULL);
   12738     }
   12739 
   12740     /*
   12741      * Ask the Entity resolver to load the damn thing
   12742      */
   12743 
   12744     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
   12745 	input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
   12746 	                                 systemIdCanonic);
   12747     if (input == NULL) {
   12748         if (sax != NULL) ctxt->sax = NULL;
   12749 	xmlFreeParserCtxt(ctxt);
   12750 	if (systemIdCanonic != NULL)
   12751 	    xmlFree(systemIdCanonic);
   12752 	return(NULL);
   12753     }
   12754 
   12755     /*
   12756      * plug some encoding conversion routines here.
   12757      */
   12758     if (xmlPushInput(ctxt, input) < 0) {
   12759         if (sax != NULL) ctxt->sax = NULL;
   12760 	xmlFreeParserCtxt(ctxt);
   12761 	if (systemIdCanonic != NULL)
   12762 	    xmlFree(systemIdCanonic);
   12763 	return(NULL);
   12764     }
   12765     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
   12766 	enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
   12767 	xmlSwitchEncoding(ctxt, enc);
   12768     }
   12769 
   12770     if (input->filename == NULL)
   12771 	input->filename = (char *) systemIdCanonic;
   12772     else
   12773 	xmlFree(systemIdCanonic);
   12774     input->line = 1;
   12775     input->col = 1;
   12776     input->base = ctxt->input->cur;
   12777     input->cur = ctxt->input->cur;
   12778     input->free = NULL;
   12779 
   12780     /*
   12781      * let's parse that entity knowing it's an external subset.
   12782      */
   12783     ctxt->inSubset = 2;
   12784     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
   12785     if (ctxt->myDoc == NULL) {
   12786 	xmlErrMemory(ctxt, "New Doc failed");
   12787         if (sax != NULL) ctxt->sax = NULL;
   12788 	xmlFreeParserCtxt(ctxt);
   12789 	return(NULL);
   12790     }
   12791     ctxt->myDoc->properties = XML_DOC_INTERNAL;
   12792     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
   12793 	                               ExternalID, SystemID);
   12794     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
   12795 
   12796     if (ctxt->myDoc != NULL) {
   12797 	if (ctxt->wellFormed) {
   12798 	    ret = ctxt->myDoc->extSubset;
   12799 	    ctxt->myDoc->extSubset = NULL;
   12800 	    if (ret != NULL) {
   12801 		xmlNodePtr tmp;
   12802 
   12803 		ret->doc = NULL;
   12804 		tmp = ret->children;
   12805 		while (tmp != NULL) {
   12806 		    tmp->doc = NULL;
   12807 		    tmp = tmp->next;
   12808 		}
   12809 	    }
   12810 	} else {
   12811 	    ret = NULL;
   12812 	}
   12813         xmlFreeDoc(ctxt->myDoc);
   12814         ctxt->myDoc = NULL;
   12815     }
   12816     if (sax != NULL) ctxt->sax = NULL;
   12817     xmlFreeParserCtxt(ctxt);
   12818 
   12819     return(ret);
   12820 }
   12821 
   12822 
   12823 /**
   12824  * xmlParseDTD:
   12825  * @ExternalID:  a NAME* containing the External ID of the DTD
   12826  * @SystemID:  a NAME* containing the URL to the DTD
   12827  *
   12828  * Load and parse an external subset.
   12829  *
   12830  * Returns the resulting xmlDtdPtr or NULL in case of error.
   12831  */
   12832 
   12833 xmlDtdPtr
   12834 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
   12835     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
   12836 }
   12837 #endif /* LIBXML_VALID_ENABLED */
   12838 
   12839 /************************************************************************
   12840  *									*
   12841  *		Front ends when parsing an Entity			*
   12842  *									*
   12843  ************************************************************************/
   12844 
   12845 /**
   12846  * xmlParseCtxtExternalEntity:
   12847  * @ctx:  the existing parsing context
   12848  * @URL:  the URL for the entity to load
   12849  * @ID:  the System ID for the entity to load
   12850  * @lst:  the return value for the set of parsed nodes
   12851  *
   12852  * Parse an external general entity within an existing parsing context
   12853  * An external general parsed entity is well-formed if it matches the
   12854  * production labeled extParsedEnt.
   12855  *
   12856  * [78] extParsedEnt ::= TextDecl? content
   12857  *
   12858  * Returns 0 if the entity is well formed, -1 in case of args problem and
   12859  *    the parser error code otherwise
   12860  */
   12861 
   12862 int
   12863 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
   12864 	               const xmlChar *ID, xmlNodePtr *lst) {
   12865     xmlParserCtxtPtr ctxt;
   12866     xmlDocPtr newDoc;
   12867     xmlNodePtr newRoot;
   12868     xmlSAXHandlerPtr oldsax = NULL;
   12869     int ret = 0;
   12870     xmlChar start[4];
   12871     xmlCharEncoding enc;
   12872 
   12873     if (ctx == NULL) return(-1);
   12874 
   12875     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
   12876         (ctx->depth > 1024)) {
   12877 	return(XML_ERR_ENTITY_LOOP);
   12878     }
   12879 
   12880     if (lst != NULL)
   12881         *lst = NULL;
   12882     if ((URL == NULL) && (ID == NULL))
   12883 	return(-1);
   12884     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
   12885 	return(-1);
   12886 
   12887     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
   12888     if (ctxt == NULL) {
   12889 	return(-1);
   12890     }
   12891 
   12892     oldsax = ctxt->sax;
   12893     ctxt->sax = ctx->sax;
   12894     xmlDetectSAX2(ctxt);
   12895     newDoc = xmlNewDoc(BAD_CAST "1.0");
   12896     if (newDoc == NULL) {
   12897 	xmlFreeParserCtxt(ctxt);
   12898 	return(-1);
   12899     }
   12900     newDoc->properties = XML_DOC_INTERNAL;
   12901     if (ctx->myDoc->dict) {
   12902 	newDoc->dict = ctx->myDoc->dict;
   12903 	xmlDictReference(newDoc->dict);
   12904     }
   12905     if (ctx->myDoc != NULL) {
   12906 	newDoc->intSubset = ctx->myDoc->intSubset;
   12907 	newDoc->extSubset = ctx->myDoc->extSubset;
   12908     }
   12909     if (ctx->myDoc->URL != NULL) {
   12910 	newDoc->URL = xmlStrdup(ctx->myDoc->URL);
   12911     }
   12912     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
   12913     if (newRoot == NULL) {
   12914 	ctxt->sax = oldsax;
   12915 	xmlFreeParserCtxt(ctxt);
   12916 	newDoc->intSubset = NULL;
   12917 	newDoc->extSubset = NULL;
   12918         xmlFreeDoc(newDoc);
   12919 	return(-1);
   12920     }
   12921     xmlAddChild((xmlNodePtr) newDoc, newRoot);
   12922     nodePush(ctxt, newDoc->children);
   12923     if (ctx->myDoc == NULL) {
   12924 	ctxt->myDoc = newDoc;
   12925     } else {
   12926 	ctxt->myDoc = ctx->myDoc;
   12927 	newDoc->children->doc = ctx->myDoc;
   12928     }
   12929 
   12930     /*
   12931      * Get the 4 first bytes and decode the charset
   12932      * if enc != XML_CHAR_ENCODING_NONE
   12933      * plug some encoding conversion routines.
   12934      */
   12935     GROW
   12936     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
   12937 	start[0] = RAW;
   12938 	start[1] = NXT(1);
   12939 	start[2] = NXT(2);
   12940 	start[3] = NXT(3);
   12941 	enc = xmlDetectCharEncoding(start, 4);
   12942 	if (enc != XML_CHAR_ENCODING_NONE) {
   12943 	    xmlSwitchEncoding(ctxt, enc);
   12944 	}
   12945     }
   12946 
   12947     /*
   12948      * Parse a possible text declaration first
   12949      */
   12950     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
   12951 	xmlParseTextDecl(ctxt);
   12952 	/*
   12953 	 * An XML-1.0 document can't reference an entity not XML-1.0
   12954 	 */
   12955 	if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
   12956 	    (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
   12957 	    xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
   12958 	                   "Version mismatch between document and entity\n");
   12959 	}
   12960     }
   12961 
   12962     /*
   12963      * If the user provided its own SAX callbacks then reuse the
   12964      * useData callback field, otherwise the expected setup in a
   12965      * DOM builder is to have userData == ctxt
   12966      */
   12967     if (ctx->userData == ctx)
   12968         ctxt->userData = ctxt;
   12969     else
   12970         ctxt->userData = ctx->userData;
   12971 
   12972     /*
   12973      * Doing validity checking on chunk doesn't make sense
   12974      */
   12975     ctxt->instate = XML_PARSER_CONTENT;
   12976     ctxt->validate = ctx->validate;
   12977     ctxt->valid = ctx->valid;
   12978     ctxt->loadsubset = ctx->loadsubset;
   12979     ctxt->depth = ctx->depth + 1;
   12980     ctxt->replaceEntities = ctx->replaceEntities;
   12981     if (ctxt->validate) {
   12982 	ctxt->vctxt.error = ctx->vctxt.error;
   12983 	ctxt->vctxt.warning = ctx->vctxt.warning;
   12984     } else {
   12985 	ctxt->vctxt.error = NULL;
   12986 	ctxt->vctxt.warning = NULL;
   12987     }
   12988     ctxt->vctxt.nodeTab = NULL;
   12989     ctxt->vctxt.nodeNr = 0;
   12990     ctxt->vctxt.nodeMax = 0;
   12991     ctxt->vctxt.node = NULL;
   12992     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
   12993     ctxt->dict = ctx->dict;
   12994     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
   12995     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
   12996     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
   12997     ctxt->dictNames = ctx->dictNames;
   12998     ctxt->attsDefault = ctx->attsDefault;
   12999     ctxt->attsSpecial = ctx->attsSpecial;
   13000     ctxt->linenumbers = ctx->linenumbers;
   13001 
   13002     xmlParseContent(ctxt);
   13003 
   13004     ctx->validate = ctxt->validate;
   13005     ctx->valid = ctxt->valid;
   13006     if ((RAW == '<') && (NXT(1) == '/')) {
   13007 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13008     } else if (RAW != 0) {
   13009 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
   13010     }
   13011     if (ctxt->node != newDoc->children) {
   13012 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13013     }
   13014 
   13015     if (!ctxt->wellFormed) {
   13016         if (ctxt->errNo == 0)
   13017 	    ret = 1;
   13018 	else
   13019 	    ret = ctxt->errNo;
   13020     } else {
   13021 	if (lst != NULL) {
   13022 	    xmlNodePtr cur;
   13023 
   13024 	    /*
   13025 	     * Return the newly created nodeset after unlinking it from
   13026 	     * they pseudo parent.
   13027 	     */
   13028 	    cur = newDoc->children->children;
   13029 	    *lst = cur;
   13030 	    while (cur != NULL) {
   13031 		cur->parent = NULL;
   13032 		cur = cur->next;
   13033 	    }
   13034             newDoc->children->children = NULL;
   13035 	}
   13036 	ret = 0;
   13037     }
   13038     ctxt->sax = oldsax;
   13039     ctxt->dict = NULL;
   13040     ctxt->attsDefault = NULL;
   13041     ctxt->attsSpecial = NULL;
   13042     xmlFreeParserCtxt(ctxt);
   13043     newDoc->intSubset = NULL;
   13044     newDoc->extSubset = NULL;
   13045     xmlFreeDoc(newDoc);
   13046 
   13047     return(ret);
   13048 }
   13049 
   13050 /**
   13051  * xmlParseExternalEntityPrivate:
   13052  * @doc:  the document the chunk pertains to
   13053  * @oldctxt:  the previous parser context if available
   13054  * @sax:  the SAX handler bloc (possibly NULL)
   13055  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
   13056  * @depth:  Used for loop detection, use 0
   13057  * @URL:  the URL for the entity to load
   13058  * @ID:  the System ID for the entity to load
   13059  * @list:  the return value for the set of parsed nodes
   13060  *
   13061  * Private version of xmlParseExternalEntity()
   13062  *
   13063  * Returns 0 if the entity is well formed, -1 in case of args problem and
   13064  *    the parser error code otherwise
   13065  */
   13066 
   13067 static xmlParserErrors
   13068 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
   13069 	              xmlSAXHandlerPtr sax,
   13070 		      void *user_data, int depth, const xmlChar *URL,
   13071 		      const xmlChar *ID, xmlNodePtr *list) {
   13072     xmlParserCtxtPtr ctxt;
   13073     xmlDocPtr newDoc;
   13074     xmlNodePtr newRoot;
   13075     xmlSAXHandlerPtr oldsax = NULL;
   13076     xmlParserErrors ret = XML_ERR_OK;
   13077     xmlChar start[4];
   13078     xmlCharEncoding enc;
   13079 
   13080     if (((depth > 40) &&
   13081 	((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
   13082 	(depth > 1024)) {
   13083 	return(XML_ERR_ENTITY_LOOP);
   13084     }
   13085 
   13086     if (list != NULL)
   13087         *list = NULL;
   13088     if ((URL == NULL) && (ID == NULL))
   13089 	return(XML_ERR_INTERNAL_ERROR);
   13090     if (doc == NULL)
   13091 	return(XML_ERR_INTERNAL_ERROR);
   13092 
   13093 
   13094     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
   13095     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
   13096     ctxt->userData = ctxt;
   13097     if (oldctxt != NULL) {
   13098 	ctxt->_private = oldctxt->_private;
   13099 	ctxt->loadsubset = oldctxt->loadsubset;
   13100 	ctxt->validate = oldctxt->validate;
   13101 	ctxt->external = oldctxt->external;
   13102 	ctxt->record_info = oldctxt->record_info;
   13103 	ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
   13104 	ctxt->node_seq.length = oldctxt->node_seq.length;
   13105 	ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
   13106     } else {
   13107 	/*
   13108 	 * Doing validity checking on chunk without context
   13109 	 * doesn't make sense
   13110 	 */
   13111 	ctxt->_private = NULL;
   13112 	ctxt->validate = 0;
   13113 	ctxt->external = 2;
   13114 	ctxt->loadsubset = 0;
   13115     }
   13116     if (sax != NULL) {
   13117 	oldsax = ctxt->sax;
   13118         ctxt->sax = sax;
   13119 	if (user_data != NULL)
   13120 	    ctxt->userData = user_data;
   13121     }
   13122     xmlDetectSAX2(ctxt);
   13123     newDoc = xmlNewDoc(BAD_CAST "1.0");
   13124     if (newDoc == NULL) {
   13125 	ctxt->node_seq.maximum = 0;
   13126 	ctxt->node_seq.length = 0;
   13127 	ctxt->node_seq.buffer = NULL;
   13128 	xmlFreeParserCtxt(ctxt);
   13129 	return(XML_ERR_INTERNAL_ERROR);
   13130     }
   13131     newDoc->properties = XML_DOC_INTERNAL;
   13132     newDoc->intSubset = doc->intSubset;
   13133     newDoc->extSubset = doc->extSubset;
   13134     newDoc->dict = doc->dict;
   13135     xmlDictReference(newDoc->dict);
   13136 
   13137     if (doc->URL != NULL) {
   13138 	newDoc->URL = xmlStrdup(doc->URL);
   13139     }
   13140     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
   13141     if (newRoot == NULL) {
   13142 	if (sax != NULL)
   13143 	    ctxt->sax = oldsax;
   13144 	ctxt->node_seq.maximum = 0;
   13145 	ctxt->node_seq.length = 0;
   13146 	ctxt->node_seq.buffer = NULL;
   13147 	xmlFreeParserCtxt(ctxt);
   13148 	newDoc->intSubset = NULL;
   13149 	newDoc->extSubset = NULL;
   13150         xmlFreeDoc(newDoc);
   13151 	return(XML_ERR_INTERNAL_ERROR);
   13152     }
   13153     xmlAddChild((xmlNodePtr) newDoc, newRoot);
   13154     nodePush(ctxt, newDoc->children);
   13155     ctxt->myDoc = doc;
   13156     newRoot->doc = doc;
   13157 
   13158     /*
   13159      * Get the 4 first bytes and decode the charset
   13160      * if enc != XML_CHAR_ENCODING_NONE
   13161      * plug some encoding conversion routines.
   13162      */
   13163     GROW;
   13164     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
   13165 	start[0] = RAW;
   13166 	start[1] = NXT(1);
   13167 	start[2] = NXT(2);
   13168 	start[3] = NXT(3);
   13169 	enc = xmlDetectCharEncoding(start, 4);
   13170 	if (enc != XML_CHAR_ENCODING_NONE) {
   13171 	    xmlSwitchEncoding(ctxt, enc);
   13172 	}
   13173     }
   13174 
   13175     /*
   13176      * Parse a possible text declaration first
   13177      */
   13178     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
   13179 	xmlParseTextDecl(ctxt);
   13180     }
   13181 
   13182     ctxt->instate = XML_PARSER_CONTENT;
   13183     ctxt->depth = depth;
   13184 
   13185     xmlParseContent(ctxt);
   13186 
   13187     if ((RAW == '<') && (NXT(1) == '/')) {
   13188 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13189     } else if (RAW != 0) {
   13190 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
   13191     }
   13192     if (ctxt->node != newDoc->children) {
   13193 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13194     }
   13195 
   13196     if (!ctxt->wellFormed) {
   13197         if (ctxt->errNo == 0)
   13198 	    ret = XML_ERR_INTERNAL_ERROR;
   13199 	else
   13200 	    ret = (xmlParserErrors)ctxt->errNo;
   13201     } else {
   13202 	if (list != NULL) {
   13203 	    xmlNodePtr cur;
   13204 
   13205 	    /*
   13206 	     * Return the newly created nodeset after unlinking it from
   13207 	     * they pseudo parent.
   13208 	     */
   13209 	    cur = newDoc->children->children;
   13210 	    *list = cur;
   13211 	    while (cur != NULL) {
   13212 		cur->parent = NULL;
   13213 		cur = cur->next;
   13214 	    }
   13215             newDoc->children->children = NULL;
   13216 	}
   13217 	ret = XML_ERR_OK;
   13218     }
   13219 
   13220     /*
   13221      * Record in the parent context the number of entities replacement
   13222      * done when parsing that reference.
   13223      */
   13224     if (oldctxt != NULL)
   13225         oldctxt->nbentities += ctxt->nbentities;
   13226 
   13227     /*
   13228      * Also record the size of the entity parsed
   13229      */
   13230     if (ctxt->input != NULL) {
   13231 	oldctxt->sizeentities += ctxt->input->consumed;
   13232 	oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
   13233     }
   13234     /*
   13235      * And record the last error if any
   13236      */
   13237     if (ctxt->lastError.code != XML_ERR_OK)
   13238         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
   13239 
   13240     if (sax != NULL)
   13241 	ctxt->sax = oldsax;
   13242     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
   13243     oldctxt->node_seq.length = ctxt->node_seq.length;
   13244     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
   13245     ctxt->node_seq.maximum = 0;
   13246     ctxt->node_seq.length = 0;
   13247     ctxt->node_seq.buffer = NULL;
   13248     xmlFreeParserCtxt(ctxt);
   13249     newDoc->intSubset = NULL;
   13250     newDoc->extSubset = NULL;
   13251     xmlFreeDoc(newDoc);
   13252 
   13253     return(ret);
   13254 }
   13255 
   13256 #ifdef LIBXML_SAX1_ENABLED
   13257 /**
   13258  * xmlParseExternalEntity:
   13259  * @doc:  the document the chunk pertains to
   13260  * @sax:  the SAX handler bloc (possibly NULL)
   13261  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
   13262  * @depth:  Used for loop detection, use 0
   13263  * @URL:  the URL for the entity to load
   13264  * @ID:  the System ID for the entity to load
   13265  * @lst:  the return value for the set of parsed nodes
   13266  *
   13267  * Parse an external general entity
   13268  * An external general parsed entity is well-formed if it matches the
   13269  * production labeled extParsedEnt.
   13270  *
   13271  * [78] extParsedEnt ::= TextDecl? content
   13272  *
   13273  * Returns 0 if the entity is well formed, -1 in case of args problem and
   13274  *    the parser error code otherwise
   13275  */
   13276 
   13277 int
   13278 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
   13279 	  int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
   13280     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
   13281 		                       ID, lst));
   13282 }
   13283 
   13284 /**
   13285  * xmlParseBalancedChunkMemory:
   13286  * @doc:  the document the chunk pertains to
   13287  * @sax:  the SAX handler bloc (possibly NULL)
   13288  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
   13289  * @depth:  Used for loop detection, use 0
   13290  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
   13291  * @lst:  the return value for the set of parsed nodes
   13292  *
   13293  * Parse a well-balanced chunk of an XML document
   13294  * called by the parser
   13295  * The allowed sequence for the Well Balanced Chunk is the one defined by
   13296  * the content production in the XML grammar:
   13297  *
   13298  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
   13299  *
   13300  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
   13301  *    the parser error code otherwise
   13302  */
   13303 
   13304 int
   13305 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
   13306      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
   13307     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
   13308                                                 depth, string, lst, 0 );
   13309 }
   13310 #endif /* LIBXML_SAX1_ENABLED */
   13311 
   13312 /**
   13313  * xmlParseBalancedChunkMemoryInternal:
   13314  * @oldctxt:  the existing parsing context
   13315  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
   13316  * @user_data:  the user data field for the parser context
   13317  * @lst:  the return value for the set of parsed nodes
   13318  *
   13319  *
   13320  * Parse a well-balanced chunk of an XML document
   13321  * called by the parser
   13322  * The allowed sequence for the Well Balanced Chunk is the one defined by
   13323  * the content production in the XML grammar:
   13324  *
   13325  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
   13326  *
   13327  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
   13328  * error code otherwise
   13329  *
   13330  * In case recover is set to 1, the nodelist will not be empty even if
   13331  * the parsed chunk is not well balanced.
   13332  */
   13333 static xmlParserErrors
   13334 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
   13335 	const xmlChar *string, void *user_data, xmlNodePtr *lst) {
   13336     xmlParserCtxtPtr ctxt;
   13337     xmlDocPtr newDoc = NULL;
   13338     xmlNodePtr newRoot;
   13339     xmlSAXHandlerPtr oldsax = NULL;
   13340     xmlNodePtr content = NULL;
   13341     xmlNodePtr last = NULL;
   13342     int size;
   13343     xmlParserErrors ret = XML_ERR_OK;
   13344 #ifdef SAX2
   13345     int i;
   13346 #endif
   13347 
   13348     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
   13349         (oldctxt->depth >  1024)) {
   13350 	return(XML_ERR_ENTITY_LOOP);
   13351     }
   13352 
   13353 
   13354     if (lst != NULL)
   13355         *lst = NULL;
   13356     if (string == NULL)
   13357         return(XML_ERR_INTERNAL_ERROR);
   13358 
   13359     size = xmlStrlen(string);
   13360 
   13361     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
   13362     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
   13363     if (user_data != NULL)
   13364 	ctxt->userData = user_data;
   13365     else
   13366 	ctxt->userData = ctxt;
   13367     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
   13368     ctxt->dict = oldctxt->dict;
   13369     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
   13370     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
   13371     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
   13372 
   13373 #ifdef SAX2
   13374     /* propagate namespaces down the entity */
   13375     for (i = 0;i < oldctxt->nsNr;i += 2) {
   13376         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
   13377     }
   13378 #endif
   13379 
   13380     oldsax = ctxt->sax;
   13381     ctxt->sax = oldctxt->sax;
   13382     xmlDetectSAX2(ctxt);
   13383     ctxt->replaceEntities = oldctxt->replaceEntities;
   13384     ctxt->options = oldctxt->options;
   13385 
   13386     ctxt->_private = oldctxt->_private;
   13387     if (oldctxt->myDoc == NULL) {
   13388 	newDoc = xmlNewDoc(BAD_CAST "1.0");
   13389 	if (newDoc == NULL) {
   13390 	    ctxt->sax = oldsax;
   13391 	    ctxt->dict = NULL;
   13392 	    xmlFreeParserCtxt(ctxt);
   13393 	    return(XML_ERR_INTERNAL_ERROR);
   13394 	}
   13395 	newDoc->properties = XML_DOC_INTERNAL;
   13396 	newDoc->dict = ctxt->dict;
   13397 	xmlDictReference(newDoc->dict);
   13398 	ctxt->myDoc = newDoc;
   13399     } else {
   13400 	ctxt->myDoc = oldctxt->myDoc;
   13401         content = ctxt->myDoc->children;
   13402 	last = ctxt->myDoc->last;
   13403     }
   13404     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
   13405     if (newRoot == NULL) {
   13406 	ctxt->sax = oldsax;
   13407 	ctxt->dict = NULL;
   13408 	xmlFreeParserCtxt(ctxt);
   13409 	if (newDoc != NULL) {
   13410 	    xmlFreeDoc(newDoc);
   13411 	}
   13412 	return(XML_ERR_INTERNAL_ERROR);
   13413     }
   13414     ctxt->myDoc->children = NULL;
   13415     ctxt->myDoc->last = NULL;
   13416     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
   13417     nodePush(ctxt, ctxt->myDoc->children);
   13418     ctxt->instate = XML_PARSER_CONTENT;
   13419     ctxt->depth = oldctxt->depth + 1;
   13420 
   13421     ctxt->validate = 0;
   13422     ctxt->loadsubset = oldctxt->loadsubset;
   13423     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
   13424 	/*
   13425 	 * ID/IDREF registration will be done in xmlValidateElement below
   13426 	 */
   13427 	ctxt->loadsubset |= XML_SKIP_IDS;
   13428     }
   13429     ctxt->dictNames = oldctxt->dictNames;
   13430     ctxt->attsDefault = oldctxt->attsDefault;
   13431     ctxt->attsSpecial = oldctxt->attsSpecial;
   13432 
   13433     xmlParseContent(ctxt);
   13434     if ((RAW == '<') && (NXT(1) == '/')) {
   13435 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13436     } else if (RAW != 0) {
   13437 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
   13438     }
   13439     if (ctxt->node != ctxt->myDoc->children) {
   13440 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13441     }
   13442 
   13443     if (!ctxt->wellFormed) {
   13444         if (ctxt->errNo == 0)
   13445 	    ret = XML_ERR_INTERNAL_ERROR;
   13446 	else
   13447 	    ret = (xmlParserErrors)ctxt->errNo;
   13448     } else {
   13449       ret = XML_ERR_OK;
   13450     }
   13451 
   13452     if ((lst != NULL) && (ret == XML_ERR_OK)) {
   13453 	xmlNodePtr cur;
   13454 
   13455 	/*
   13456 	 * Return the newly created nodeset after unlinking it from
   13457 	 * they pseudo parent.
   13458 	 */
   13459 	cur = ctxt->myDoc->children->children;
   13460 	*lst = cur;
   13461 	while (cur != NULL) {
   13462 #ifdef LIBXML_VALID_ENABLED
   13463 	    if ((oldctxt->validate) && (oldctxt->wellFormed) &&
   13464 		(oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
   13465 		(cur->type == XML_ELEMENT_NODE)) {
   13466 		oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
   13467 			oldctxt->myDoc, cur);
   13468 	    }
   13469 #endif /* LIBXML_VALID_ENABLED */
   13470 	    cur->parent = NULL;
   13471 	    cur = cur->next;
   13472 	}
   13473 	ctxt->myDoc->children->children = NULL;
   13474     }
   13475     if (ctxt->myDoc != NULL) {
   13476 	xmlFreeNode(ctxt->myDoc->children);
   13477         ctxt->myDoc->children = content;
   13478         ctxt->myDoc->last = last;
   13479     }
   13480 
   13481     /*
   13482      * Record in the parent context the number of entities replacement
   13483      * done when parsing that reference.
   13484      */
   13485     if (oldctxt != NULL)
   13486         oldctxt->nbentities += ctxt->nbentities;
   13487 
   13488     /*
   13489      * Also record the last error if any
   13490      */
   13491     if (ctxt->lastError.code != XML_ERR_OK)
   13492         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
   13493 
   13494     ctxt->sax = oldsax;
   13495     ctxt->dict = NULL;
   13496     ctxt->attsDefault = NULL;
   13497     ctxt->attsSpecial = NULL;
   13498     xmlFreeParserCtxt(ctxt);
   13499     if (newDoc != NULL) {
   13500 	xmlFreeDoc(newDoc);
   13501     }
   13502 
   13503     return(ret);
   13504 }
   13505 
   13506 /**
   13507  * xmlParseInNodeContext:
   13508  * @node:  the context node
   13509  * @data:  the input string
   13510  * @datalen:  the input string length in bytes
   13511  * @options:  a combination of xmlParserOption
   13512  * @lst:  the return value for the set of parsed nodes
   13513  *
   13514  * Parse a well-balanced chunk of an XML document
   13515  * within the context (DTD, namespaces, etc ...) of the given node.
   13516  *
   13517  * The allowed sequence for the data is a Well Balanced Chunk defined by
   13518  * the content production in the XML grammar:
   13519  *
   13520  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
   13521  *
   13522  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
   13523  * error code otherwise
   13524  */
   13525 xmlParserErrors
   13526 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
   13527                       int options, xmlNodePtr *lst) {
   13528 #ifdef SAX2
   13529     xmlParserCtxtPtr ctxt;
   13530     xmlDocPtr doc = NULL;
   13531     xmlNodePtr fake, cur;
   13532     int nsnr = 0;
   13533 
   13534     xmlParserErrors ret = XML_ERR_OK;
   13535 
   13536     /*
   13537      * check all input parameters, grab the document
   13538      */
   13539     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
   13540         return(XML_ERR_INTERNAL_ERROR);
   13541     switch (node->type) {
   13542         case XML_ELEMENT_NODE:
   13543         case XML_ATTRIBUTE_NODE:
   13544         case XML_TEXT_NODE:
   13545         case XML_CDATA_SECTION_NODE:
   13546         case XML_ENTITY_REF_NODE:
   13547         case XML_PI_NODE:
   13548         case XML_COMMENT_NODE:
   13549         case XML_DOCUMENT_NODE:
   13550         case XML_HTML_DOCUMENT_NODE:
   13551 	    break;
   13552 	default:
   13553 	    return(XML_ERR_INTERNAL_ERROR);
   13554 
   13555     }
   13556     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
   13557            (node->type != XML_DOCUMENT_NODE) &&
   13558 	   (node->type != XML_HTML_DOCUMENT_NODE))
   13559 	node = node->parent;
   13560     if (node == NULL)
   13561 	return(XML_ERR_INTERNAL_ERROR);
   13562     if (node->type == XML_ELEMENT_NODE)
   13563 	doc = node->doc;
   13564     else
   13565         doc = (xmlDocPtr) node;
   13566     if (doc == NULL)
   13567 	return(XML_ERR_INTERNAL_ERROR);
   13568 
   13569     /*
   13570      * allocate a context and set-up everything not related to the
   13571      * node position in the tree
   13572      */
   13573     if (doc->type == XML_DOCUMENT_NODE)
   13574 	ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
   13575 #ifdef LIBXML_HTML_ENABLED
   13576     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
   13577 	ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
   13578         /*
   13579          * When parsing in context, it makes no sense to add implied
   13580          * elements like html/body/etc...
   13581          */
   13582         options |= HTML_PARSE_NOIMPLIED;
   13583     }
   13584 #endif
   13585     else
   13586         return(XML_ERR_INTERNAL_ERROR);
   13587 
   13588     if (ctxt == NULL)
   13589         return(XML_ERR_NO_MEMORY);
   13590 
   13591     /*
   13592      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
   13593      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
   13594      * we must wait until the last moment to free the original one.
   13595      */
   13596     if (doc->dict != NULL) {
   13597         if (ctxt->dict != NULL)
   13598 	    xmlDictFree(ctxt->dict);
   13599 	ctxt->dict = doc->dict;
   13600     } else
   13601         options |= XML_PARSE_NODICT;
   13602 
   13603     if (doc->encoding != NULL) {
   13604         xmlCharEncodingHandlerPtr hdlr;
   13605 
   13606         if (ctxt->encoding != NULL)
   13607 	    xmlFree((xmlChar *) ctxt->encoding);
   13608         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
   13609 
   13610         hdlr = xmlFindCharEncodingHandler(doc->encoding);
   13611         if (hdlr != NULL) {
   13612             xmlSwitchToEncoding(ctxt, hdlr);
   13613 	} else {
   13614             return(XML_ERR_UNSUPPORTED_ENCODING);
   13615         }
   13616     }
   13617 
   13618     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
   13619     xmlDetectSAX2(ctxt);
   13620     ctxt->myDoc = doc;
   13621 
   13622     fake = xmlNewComment(NULL);
   13623     if (fake == NULL) {
   13624         xmlFreeParserCtxt(ctxt);
   13625 	return(XML_ERR_NO_MEMORY);
   13626     }
   13627     xmlAddChild(node, fake);
   13628 
   13629     if (node->type == XML_ELEMENT_NODE) {
   13630 	nodePush(ctxt, node);
   13631 	/*
   13632 	 * initialize the SAX2 namespaces stack
   13633 	 */
   13634 	cur = node;
   13635 	while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
   13636 	    xmlNsPtr ns = cur->nsDef;
   13637 	    const xmlChar *iprefix, *ihref;
   13638 
   13639 	    while (ns != NULL) {
   13640 		if (ctxt->dict) {
   13641 		    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
   13642 		    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
   13643 		} else {
   13644 		    iprefix = ns->prefix;
   13645 		    ihref = ns->href;
   13646 		}
   13647 
   13648 	        if (xmlGetNamespace(ctxt, iprefix) == NULL) {
   13649 		    nsPush(ctxt, iprefix, ihref);
   13650 		    nsnr++;
   13651 		}
   13652 		ns = ns->next;
   13653 	    }
   13654 	    cur = cur->parent;
   13655 	}
   13656 	ctxt->instate = XML_PARSER_CONTENT;
   13657     }
   13658 
   13659     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
   13660 	/*
   13661 	 * ID/IDREF registration will be done in xmlValidateElement below
   13662 	 */
   13663 	ctxt->loadsubset |= XML_SKIP_IDS;
   13664     }
   13665 
   13666 #ifdef LIBXML_HTML_ENABLED
   13667     if (doc->type == XML_HTML_DOCUMENT_NODE)
   13668         __htmlParseContent(ctxt);
   13669     else
   13670 #endif
   13671 	xmlParseContent(ctxt);
   13672 
   13673     nsPop(ctxt, nsnr);
   13674     if ((RAW == '<') && (NXT(1) == '/')) {
   13675 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13676     } else if (RAW != 0) {
   13677 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
   13678     }
   13679     if ((ctxt->node != NULL) && (ctxt->node != node)) {
   13680 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13681 	ctxt->wellFormed = 0;
   13682     }
   13683 
   13684     if (!ctxt->wellFormed) {
   13685         if (ctxt->errNo == 0)
   13686 	    ret = XML_ERR_INTERNAL_ERROR;
   13687 	else
   13688 	    ret = (xmlParserErrors)ctxt->errNo;
   13689     } else {
   13690         ret = XML_ERR_OK;
   13691     }
   13692 
   13693     /*
   13694      * Return the newly created nodeset after unlinking it from
   13695      * the pseudo sibling.
   13696      */
   13697 
   13698     cur = fake->next;
   13699     fake->next = NULL;
   13700     node->last = fake;
   13701 
   13702     if (cur != NULL) {
   13703 	cur->prev = NULL;
   13704     }
   13705 
   13706     *lst = cur;
   13707 
   13708     while (cur != NULL) {
   13709 	cur->parent = NULL;
   13710 	cur = cur->next;
   13711     }
   13712 
   13713     xmlUnlinkNode(fake);
   13714     xmlFreeNode(fake);
   13715 
   13716 
   13717     if (ret != XML_ERR_OK) {
   13718         xmlFreeNodeList(*lst);
   13719 	*lst = NULL;
   13720     }
   13721 
   13722     if (doc->dict != NULL)
   13723         ctxt->dict = NULL;
   13724     xmlFreeParserCtxt(ctxt);
   13725 
   13726     return(ret);
   13727 #else /* !SAX2 */
   13728     return(XML_ERR_INTERNAL_ERROR);
   13729 #endif
   13730 }
   13731 
   13732 #ifdef LIBXML_SAX1_ENABLED
   13733 /**
   13734  * xmlParseBalancedChunkMemoryRecover:
   13735  * @doc:  the document the chunk pertains to
   13736  * @sax:  the SAX handler bloc (possibly NULL)
   13737  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
   13738  * @depth:  Used for loop detection, use 0
   13739  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
   13740  * @lst:  the return value for the set of parsed nodes
   13741  * @recover: return nodes even if the data is broken (use 0)
   13742  *
   13743  *
   13744  * Parse a well-balanced chunk of an XML document
   13745  * called by the parser
   13746  * The allowed sequence for the Well Balanced Chunk is the one defined by
   13747  * the content production in the XML grammar:
   13748  *
   13749  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
   13750  *
   13751  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
   13752  *    the parser error code otherwise
   13753  *
   13754  * In case recover is set to 1, the nodelist will not be empty even if
   13755  * the parsed chunk is not well balanced, assuming the parsing succeeded to
   13756  * some extent.
   13757  */
   13758 int
   13759 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
   13760      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
   13761      int recover) {
   13762     xmlParserCtxtPtr ctxt;
   13763     xmlDocPtr newDoc;
   13764     xmlSAXHandlerPtr oldsax = NULL;
   13765     xmlNodePtr content, newRoot;
   13766     int size;
   13767     int ret = 0;
   13768 
   13769     if (depth > 40) {
   13770 	return(XML_ERR_ENTITY_LOOP);
   13771     }
   13772 
   13773 
   13774     if (lst != NULL)
   13775         *lst = NULL;
   13776     if (string == NULL)
   13777         return(-1);
   13778 
   13779     size = xmlStrlen(string);
   13780 
   13781     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
   13782     if (ctxt == NULL) return(-1);
   13783     ctxt->userData = ctxt;
   13784     if (sax != NULL) {
   13785 	oldsax = ctxt->sax;
   13786         ctxt->sax = sax;
   13787 	if (user_data != NULL)
   13788 	    ctxt->userData = user_data;
   13789     }
   13790     newDoc = xmlNewDoc(BAD_CAST "1.0");
   13791     if (newDoc == NULL) {
   13792 	xmlFreeParserCtxt(ctxt);
   13793 	return(-1);
   13794     }
   13795     newDoc->properties = XML_DOC_INTERNAL;
   13796     if ((doc != NULL) && (doc->dict != NULL)) {
   13797         xmlDictFree(ctxt->dict);
   13798 	ctxt->dict = doc->dict;
   13799 	xmlDictReference(ctxt->dict);
   13800 	ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
   13801 	ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
   13802 	ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
   13803 	ctxt->dictNames = 1;
   13804     } else {
   13805 	xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
   13806     }
   13807     if (doc != NULL) {
   13808 	newDoc->intSubset = doc->intSubset;
   13809 	newDoc->extSubset = doc->extSubset;
   13810     }
   13811     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
   13812     if (newRoot == NULL) {
   13813 	if (sax != NULL)
   13814 	    ctxt->sax = oldsax;
   13815 	xmlFreeParserCtxt(ctxt);
   13816 	newDoc->intSubset = NULL;
   13817 	newDoc->extSubset = NULL;
   13818         xmlFreeDoc(newDoc);
   13819 	return(-1);
   13820     }
   13821     xmlAddChild((xmlNodePtr) newDoc, newRoot);
   13822     nodePush(ctxt, newRoot);
   13823     if (doc == NULL) {
   13824 	ctxt->myDoc = newDoc;
   13825     } else {
   13826 	ctxt->myDoc = newDoc;
   13827 	newDoc->children->doc = doc;
   13828 	/* Ensure that doc has XML spec namespace */
   13829 	xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
   13830 	newDoc->oldNs = doc->oldNs;
   13831     }
   13832     ctxt->instate = XML_PARSER_CONTENT;
   13833     ctxt->depth = depth;
   13834 
   13835     /*
   13836      * Doing validity checking on chunk doesn't make sense
   13837      */
   13838     ctxt->validate = 0;
   13839     ctxt->loadsubset = 0;
   13840     xmlDetectSAX2(ctxt);
   13841 
   13842     if ( doc != NULL ){
   13843         content = doc->children;
   13844         doc->children = NULL;
   13845         xmlParseContent(ctxt);
   13846         doc->children = content;
   13847     }
   13848     else {
   13849         xmlParseContent(ctxt);
   13850     }
   13851     if ((RAW == '<') && (NXT(1) == '/')) {
   13852 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13853     } else if (RAW != 0) {
   13854 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
   13855     }
   13856     if (ctxt->node != newDoc->children) {
   13857 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
   13858     }
   13859 
   13860     if (!ctxt->wellFormed) {
   13861         if (ctxt->errNo == 0)
   13862 	    ret = 1;
   13863 	else
   13864 	    ret = ctxt->errNo;
   13865     } else {
   13866       ret = 0;
   13867     }
   13868 
   13869     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
   13870 	xmlNodePtr cur;
   13871 
   13872 	/*
   13873 	 * Return the newly created nodeset after unlinking it from
   13874 	 * they pseudo parent.
   13875 	 */
   13876 	cur = newDoc->children->children;
   13877 	*lst = cur;
   13878 	while (cur != NULL) {
   13879 	    xmlSetTreeDoc(cur, doc);
   13880 	    cur->parent = NULL;
   13881 	    cur = cur->next;
   13882 	}
   13883 	newDoc->children->children = NULL;
   13884     }
   13885 
   13886     if (sax != NULL)
   13887 	ctxt->sax = oldsax;
   13888     xmlFreeParserCtxt(ctxt);
   13889     newDoc->intSubset = NULL;
   13890     newDoc->extSubset = NULL;
   13891     newDoc->oldNs = NULL;
   13892     xmlFreeDoc(newDoc);
   13893 
   13894     return(ret);
   13895 }
   13896 
   13897 /**
   13898  * xmlSAXParseEntity:
   13899  * @sax:  the SAX handler block
   13900  * @filename:  the filename
   13901  *
   13902  * parse an XML external entity out of context and build a tree.
   13903  * It use the given SAX function block to handle the parsing callback.
   13904  * If sax is NULL, fallback to the default DOM tree building routines.
   13905  *
   13906  * [78] extParsedEnt ::= TextDecl? content
   13907  *
   13908  * This correspond to a "Well Balanced" chunk
   13909  *
   13910  * Returns the resulting document tree
   13911  */
   13912 
   13913 xmlDocPtr
   13914 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
   13915     xmlDocPtr ret;
   13916     xmlParserCtxtPtr ctxt;
   13917 
   13918     ctxt = xmlCreateFileParserCtxt(filename);
   13919     if (ctxt == NULL) {
   13920 	return(NULL);
   13921     }
   13922     if (sax != NULL) {
   13923 	if (ctxt->sax != NULL)
   13924 	    xmlFree(ctxt->sax);
   13925         ctxt->sax = sax;
   13926         ctxt->userData = NULL;
   13927     }
   13928 
   13929     xmlParseExtParsedEnt(ctxt);
   13930 
   13931     if (ctxt->wellFormed)
   13932 	ret = ctxt->myDoc;
   13933     else {
   13934         ret = NULL;
   13935         xmlFreeDoc(ctxt->myDoc);
   13936         ctxt->myDoc = NULL;
   13937     }
   13938     if (sax != NULL)
   13939         ctxt->sax = NULL;
   13940     xmlFreeParserCtxt(ctxt);
   13941 
   13942     return(ret);
   13943 }
   13944 
   13945 /**
   13946  * xmlParseEntity:
   13947  * @filename:  the filename
   13948  *
   13949  * parse an XML external entity out of context and build a tree.
   13950  *
   13951  * [78] extParsedEnt ::= TextDecl? content
   13952  *
   13953  * This correspond to a "Well Balanced" chunk
   13954  *
   13955  * Returns the resulting document tree
   13956  */
   13957 
   13958 xmlDocPtr
   13959 xmlParseEntity(const char *filename) {
   13960     return(xmlSAXParseEntity(NULL, filename));
   13961 }
   13962 #endif /* LIBXML_SAX1_ENABLED */
   13963 
   13964 /**
   13965  * xmlCreateEntityParserCtxtInternal:
   13966  * @URL:  the entity URL
   13967  * @ID:  the entity PUBLIC ID
   13968  * @base:  a possible base for the target URI
   13969  * @pctx:  parser context used to set options on new context
   13970  *
   13971  * Create a parser context for an external entity
   13972  * Automatic support for ZLIB/Compress compressed document is provided
   13973  * by default if found at compile-time.
   13974  *
   13975  * Returns the new parser context or NULL
   13976  */
   13977 static xmlParserCtxtPtr
   13978 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
   13979 	                  const xmlChar *base, xmlParserCtxtPtr pctx) {
   13980     xmlParserCtxtPtr ctxt;
   13981     xmlParserInputPtr inputStream;
   13982     char *directory = NULL;
   13983     xmlChar *uri;
   13984 
   13985     ctxt = xmlNewParserCtxt();
   13986     if (ctxt == NULL) {
   13987 	return(NULL);
   13988     }
   13989 
   13990     if (pctx != NULL) {
   13991         ctxt->options = pctx->options;
   13992         ctxt->_private = pctx->_private;
   13993     }
   13994 
   13995     uri = xmlBuildURI(URL, base);
   13996 
   13997     if (uri == NULL) {
   13998 	inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
   13999 	if (inputStream == NULL) {
   14000 	    xmlFreeParserCtxt(ctxt);
   14001 	    return(NULL);
   14002 	}
   14003 
   14004 	inputPush(ctxt, inputStream);
   14005 
   14006 	if ((ctxt->directory == NULL) && (directory == NULL))
   14007 	    directory = xmlParserGetDirectory((char *)URL);
   14008 	if ((ctxt->directory == NULL) && (directory != NULL))
   14009 	    ctxt->directory = directory;
   14010     } else {
   14011 	inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
   14012 	if (inputStream == NULL) {
   14013 	    xmlFree(uri);
   14014 	    xmlFreeParserCtxt(ctxt);
   14015 	    return(NULL);
   14016 	}
   14017 
   14018 	inputPush(ctxt, inputStream);
   14019 
   14020 	if ((ctxt->directory == NULL) && (directory == NULL))
   14021 	    directory = xmlParserGetDirectory((char *)uri);
   14022 	if ((ctxt->directory == NULL) && (directory != NULL))
   14023 	    ctxt->directory = directory;
   14024 	xmlFree(uri);
   14025     }
   14026     return(ctxt);
   14027 }
   14028 
   14029 /**
   14030  * xmlCreateEntityParserCtxt:
   14031  * @URL:  the entity URL
   14032  * @ID:  the entity PUBLIC ID
   14033  * @base:  a possible base for the target URI
   14034  *
   14035  * Create a parser context for an external entity
   14036  * Automatic support for ZLIB/Compress compressed document is provided
   14037  * by default if found at compile-time.
   14038  *
   14039  * Returns the new parser context or NULL
   14040  */
   14041 xmlParserCtxtPtr
   14042 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
   14043 	                  const xmlChar *base) {
   14044     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
   14045 
   14046 }
   14047 
   14048 /************************************************************************
   14049  *									*
   14050  *		Front ends when parsing from a file			*
   14051  *									*
   14052  ************************************************************************/
   14053 
   14054 /**
   14055  * xmlCreateURLParserCtxt:
   14056  * @filename:  the filename or URL
   14057  * @options:  a combination of xmlParserOption
   14058  *
   14059  * Create a parser context for a file or URL content.
   14060  * Automatic support for ZLIB/Compress compressed document is provided
   14061  * by default if found at compile-time and for file accesses
   14062  *
   14063  * Returns the new parser context or NULL
   14064  */
   14065 xmlParserCtxtPtr
   14066 xmlCreateURLParserCtxt(const char *filename, int options)
   14067 {
   14068     xmlParserCtxtPtr ctxt;
   14069     xmlParserInputPtr inputStream;
   14070     char *directory = NULL;
   14071 
   14072     ctxt = xmlNewParserCtxt();
   14073     if (ctxt == NULL) {
   14074 	xmlErrMemory(NULL, "cannot allocate parser context");
   14075 	return(NULL);
   14076     }
   14077 
   14078     if (options)
   14079 	xmlCtxtUseOptionsInternal(ctxt, options, NULL);
   14080     ctxt->linenumbers = 1;
   14081 
   14082     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
   14083     if (inputStream == NULL) {
   14084 	xmlFreeParserCtxt(ctxt);
   14085 	return(NULL);
   14086     }
   14087 
   14088     inputPush(ctxt, inputStream);
   14089     if ((ctxt->directory == NULL) && (directory == NULL))
   14090         directory = xmlParserGetDirectory(filename);
   14091     if ((ctxt->directory == NULL) && (directory != NULL))
   14092         ctxt->directory = directory;
   14093 
   14094     return(ctxt);
   14095 }
   14096 
   14097 /**
   14098  * xmlCreateFileParserCtxt:
   14099  * @filename:  the filename
   14100  *
   14101  * Create a parser context for a file content.
   14102  * Automatic support for ZLIB/Compress compressed document is provided
   14103  * by default if found at compile-time.
   14104  *
   14105  * Returns the new parser context or NULL
   14106  */
   14107 xmlParserCtxtPtr
   14108 xmlCreateFileParserCtxt(const char *filename)
   14109 {
   14110     return(xmlCreateURLParserCtxt(filename, 0));
   14111 }
   14112 
   14113 #ifdef LIBXML_SAX1_ENABLED
   14114 /**
   14115  * xmlSAXParseFileWithData:
   14116  * @sax:  the SAX handler block
   14117  * @filename:  the filename
   14118  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
   14119  *             documents
   14120  * @data:  the userdata
   14121  *
   14122  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
   14123  * compressed document is provided by default if found at compile-time.
   14124  * It use the given SAX function block to handle the parsing callback.
   14125  * If sax is NULL, fallback to the default DOM tree building routines.
   14126  *
   14127  * User data (void *) is stored within the parser context in the
   14128  * context's _private member, so it is available nearly everywhere in libxml
   14129  *
   14130  * Returns the resulting document tree
   14131  */
   14132 
   14133 xmlDocPtr
   14134 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
   14135                         int recovery, void *data) {
   14136     xmlDocPtr ret;
   14137     xmlParserCtxtPtr ctxt;
   14138 
   14139     xmlInitParser();
   14140 
   14141     ctxt = xmlCreateFileParserCtxt(filename);
   14142     if (ctxt == NULL) {
   14143 	return(NULL);
   14144     }
   14145     if (sax != NULL) {
   14146 	if (ctxt->sax != NULL)
   14147 	    xmlFree(ctxt->sax);
   14148         ctxt->sax = sax;
   14149     }
   14150     xmlDetectSAX2(ctxt);
   14151     if (data!=NULL) {
   14152 	ctxt->_private = data;
   14153     }
   14154 
   14155     if (ctxt->directory == NULL)
   14156         ctxt->directory = xmlParserGetDirectory(filename);
   14157 
   14158     ctxt->recovery = recovery;
   14159 
   14160     xmlParseDocument(ctxt);
   14161 
   14162     if ((ctxt->wellFormed) || recovery) {
   14163         ret = ctxt->myDoc;
   14164 	if (ret != NULL) {
   14165 	    if (ctxt->input->buf->compressed > 0)
   14166 		ret->compression = 9;
   14167 	    else
   14168 		ret->compression = ctxt->input->buf->compressed;
   14169 	}
   14170     }
   14171     else {
   14172        ret = NULL;
   14173        xmlFreeDoc(ctxt->myDoc);
   14174        ctxt->myDoc = NULL;
   14175     }
   14176     if (sax != NULL)
   14177         ctxt->sax = NULL;
   14178     xmlFreeParserCtxt(ctxt);
   14179 
   14180     return(ret);
   14181 }
   14182 
   14183 /**
   14184  * xmlSAXParseFile:
   14185  * @sax:  the SAX handler block
   14186  * @filename:  the filename
   14187  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
   14188  *             documents
   14189  *
   14190  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
   14191  * compressed document is provided by default if found at compile-time.
   14192  * It use the given SAX function block to handle the parsing callback.
   14193  * If sax is NULL, fallback to the default DOM tree building routines.
   14194  *
   14195  * Returns the resulting document tree
   14196  */
   14197 
   14198 xmlDocPtr
   14199 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
   14200                           int recovery) {
   14201     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
   14202 }
   14203 
   14204 /**
   14205  * xmlRecoverDoc:
   14206  * @cur:  a pointer to an array of xmlChar
   14207  *
   14208  * parse an XML in-memory document and build a tree.
   14209  * In the case the document is not Well Formed, a attempt to build a
   14210  * tree is tried anyway
   14211  *
   14212  * Returns the resulting document tree or NULL in case of failure
   14213  */
   14214 
   14215 xmlDocPtr
   14216 xmlRecoverDoc(const xmlChar *cur) {
   14217     return(xmlSAXParseDoc(NULL, cur, 1));
   14218 }
   14219 
   14220 /**
   14221  * xmlParseFile:
   14222  * @filename:  the filename
   14223  *
   14224  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
   14225  * compressed document is provided by default if found at compile-time.
   14226  *
   14227  * Returns the resulting document tree if the file was wellformed,
   14228  * NULL otherwise.
   14229  */
   14230 
   14231 xmlDocPtr
   14232 xmlParseFile(const char *filename) {
   14233     return(xmlSAXParseFile(NULL, filename, 0));
   14234 }
   14235 
   14236 /**
   14237  * xmlRecoverFile:
   14238  * @filename:  the filename
   14239  *
   14240  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
   14241  * compressed document is provided by default if found at compile-time.
   14242  * In the case the document is not Well Formed, it attempts to build
   14243  * a tree anyway
   14244  *
   14245  * Returns the resulting document tree or NULL in case of failure
   14246  */
   14247 
   14248 xmlDocPtr
   14249 xmlRecoverFile(const char *filename) {
   14250     return(xmlSAXParseFile(NULL, filename, 1));
   14251 }
   14252 
   14253 
   14254 /**
   14255  * xmlSetupParserForBuffer:
   14256  * @ctxt:  an XML parser context
   14257  * @buffer:  a xmlChar * buffer
   14258  * @filename:  a file name
   14259  *
   14260  * Setup the parser context to parse a new buffer; Clears any prior
   14261  * contents from the parser context. The buffer parameter must not be
   14262  * NULL, but the filename parameter can be
   14263  */
   14264 void
   14265 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
   14266                              const char* filename)
   14267 {
   14268     xmlParserInputPtr input;
   14269 
   14270     if ((ctxt == NULL) || (buffer == NULL))
   14271         return;
   14272 
   14273     input = xmlNewInputStream(ctxt);
   14274     if (input == NULL) {
   14275         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
   14276         xmlClearParserCtxt(ctxt);
   14277         return;
   14278     }
   14279 
   14280     xmlClearParserCtxt(ctxt);
   14281     if (filename != NULL)
   14282         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
   14283     input->base = buffer;
   14284     input->cur = buffer;
   14285     input->end = &buffer[xmlStrlen(buffer)];
   14286     inputPush(ctxt, input);
   14287 }
   14288 
   14289 /**
   14290  * xmlSAXUserParseFile:
   14291  * @sax:  a SAX handler
   14292  * @user_data:  The user data returned on SAX callbacks
   14293  * @filename:  a file name
   14294  *
   14295  * parse an XML file and call the given SAX handler routines.
   14296  * Automatic support for ZLIB/Compress compressed document is provided
   14297  *
   14298  * Returns 0 in case of success or a error number otherwise
   14299  */
   14300 int
   14301 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
   14302                     const char *filename) {
   14303     int ret = 0;
   14304     xmlParserCtxtPtr ctxt;
   14305 
   14306     ctxt = xmlCreateFileParserCtxt(filename);
   14307     if (ctxt == NULL) return -1;
   14308     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
   14309 	xmlFree(ctxt->sax);
   14310     ctxt->sax = sax;
   14311     xmlDetectSAX2(ctxt);
   14312 
   14313     if (user_data != NULL)
   14314 	ctxt->userData = user_data;
   14315 
   14316     xmlParseDocument(ctxt);
   14317 
   14318     if (ctxt->wellFormed)
   14319 	ret = 0;
   14320     else {
   14321         if (ctxt->errNo != 0)
   14322 	    ret = ctxt->errNo;
   14323 	else
   14324 	    ret = -1;
   14325     }
   14326     if (sax != NULL)
   14327 	ctxt->sax = NULL;
   14328     if (ctxt->myDoc != NULL) {
   14329         xmlFreeDoc(ctxt->myDoc);
   14330 	ctxt->myDoc = NULL;
   14331     }
   14332     xmlFreeParserCtxt(ctxt);
   14333 
   14334     return ret;
   14335 }
   14336 #endif /* LIBXML_SAX1_ENABLED */
   14337 
   14338 /************************************************************************
   14339  *									*
   14340  *		Front ends when parsing from memory			*
   14341  *									*
   14342  ************************************************************************/
   14343 
   14344 /**
   14345  * xmlCreateMemoryParserCtxt:
   14346  * @buffer:  a pointer to a char array
   14347  * @size:  the size of the array
   14348  *
   14349  * Create a parser context for an XML in-memory document.
   14350  *
   14351  * Returns the new parser context or NULL
   14352  */
   14353 xmlParserCtxtPtr
   14354 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
   14355     xmlParserCtxtPtr ctxt;
   14356     xmlParserInputPtr input;
   14357     xmlParserInputBufferPtr buf;
   14358 
   14359     if (buffer == NULL)
   14360 	return(NULL);
   14361     if (size <= 0)
   14362 	return(NULL);
   14363 
   14364     ctxt = xmlNewParserCtxt();
   14365     if (ctxt == NULL)
   14366 	return(NULL);
   14367 
   14368     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
   14369     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
   14370     if (buf == NULL) {
   14371 	xmlFreeParserCtxt(ctxt);
   14372 	return(NULL);
   14373     }
   14374 
   14375     input = xmlNewInputStream(ctxt);
   14376     if (input == NULL) {
   14377 	xmlFreeParserInputBuffer(buf);
   14378 	xmlFreeParserCtxt(ctxt);
   14379 	return(NULL);
   14380     }
   14381 
   14382     input->filename = NULL;
   14383     input->buf = buf;
   14384     xmlBufResetInput(input->buf->buffer, input);
   14385 
   14386     inputPush(ctxt, input);
   14387     return(ctxt);
   14388 }
   14389 
   14390 #ifdef LIBXML_SAX1_ENABLED
   14391 /**
   14392  * xmlSAXParseMemoryWithData:
   14393  * @sax:  the SAX handler block
   14394  * @buffer:  an pointer to a char array
   14395  * @size:  the size of the array
   14396  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
   14397  *             documents
   14398  * @data:  the userdata
   14399  *
   14400  * parse an XML in-memory block and use the given SAX function block
   14401  * to handle the parsing callback. If sax is NULL, fallback to the default
   14402  * DOM tree building routines.
   14403  *
   14404  * User data (void *) is stored within the parser context in the
   14405  * context's _private member, so it is available nearly everywhere in libxml
   14406  *
   14407  * Returns the resulting document tree
   14408  */
   14409 
   14410 xmlDocPtr
   14411 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
   14412 	          int size, int recovery, void *data) {
   14413     xmlDocPtr ret;
   14414     xmlParserCtxtPtr ctxt;
   14415 
   14416     xmlInitParser();
   14417 
   14418     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
   14419     if (ctxt == NULL) return(NULL);
   14420     if (sax != NULL) {
   14421 	if (ctxt->sax != NULL)
   14422 	    xmlFree(ctxt->sax);
   14423         ctxt->sax = sax;
   14424     }
   14425     xmlDetectSAX2(ctxt);
   14426     if (data!=NULL) {
   14427 	ctxt->_private=data;
   14428     }
   14429 
   14430     ctxt->recovery = recovery;
   14431 
   14432     xmlParseDocument(ctxt);
   14433 
   14434     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
   14435     else {
   14436        ret = NULL;
   14437        xmlFreeDoc(ctxt->myDoc);
   14438        ctxt->myDoc = NULL;
   14439     }
   14440     if (sax != NULL)
   14441 	ctxt->sax = NULL;
   14442     xmlFreeParserCtxt(ctxt);
   14443 
   14444     return(ret);
   14445 }
   14446 
   14447 /**
   14448  * xmlSAXParseMemory:
   14449  * @sax:  the SAX handler block
   14450  * @buffer:  an pointer to a char array
   14451  * @size:  the size of the array
   14452  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
   14453  *             documents
   14454  *
   14455  * parse an XML in-memory block and use the given SAX function block
   14456  * to handle the parsing callback. If sax is NULL, fallback to the default
   14457  * DOM tree building routines.
   14458  *
   14459  * Returns the resulting document tree
   14460  */
   14461 xmlDocPtr
   14462 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
   14463 	          int size, int recovery) {
   14464     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
   14465 }
   14466 
   14467 /**
   14468  * xmlParseMemory:
   14469  * @buffer:  an pointer to a char array
   14470  * @size:  the size of the array
   14471  *
   14472  * parse an XML in-memory block and build a tree.
   14473  *
   14474  * Returns the resulting document tree
   14475  */
   14476 
   14477 xmlDocPtr xmlParseMemory(const char *buffer, int size) {
   14478    return(xmlSAXParseMemory(NULL, buffer, size, 0));
   14479 }
   14480 
   14481 /**
   14482  * xmlRecoverMemory:
   14483  * @buffer:  an pointer to a char array
   14484  * @size:  the size of the array
   14485  *
   14486  * parse an XML in-memory block and build a tree.
   14487  * In the case the document is not Well Formed, an attempt to
   14488  * build a tree is tried anyway
   14489  *
   14490  * Returns the resulting document tree or NULL in case of error
   14491  */
   14492 
   14493 xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
   14494    return(xmlSAXParseMemory(NULL, buffer, size, 1));
   14495 }
   14496 
   14497 /**
   14498  * xmlSAXUserParseMemory:
   14499  * @sax:  a SAX handler
   14500  * @user_data:  The user data returned on SAX callbacks
   14501  * @buffer:  an in-memory XML document input
   14502  * @size:  the length of the XML document in bytes
   14503  *
   14504  * A better SAX parsing routine.
   14505  * parse an XML in-memory buffer and call the given SAX handler routines.
   14506  *
   14507  * Returns 0 in case of success or a error number otherwise
   14508  */
   14509 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
   14510 			  const char *buffer, int size) {
   14511     int ret = 0;
   14512     xmlParserCtxtPtr ctxt;
   14513 
   14514     xmlInitParser();
   14515 
   14516     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
   14517     if (ctxt == NULL) return -1;
   14518     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
   14519         xmlFree(ctxt->sax);
   14520     ctxt->sax = sax;
   14521     xmlDetectSAX2(ctxt);
   14522 
   14523     if (user_data != NULL)
   14524 	ctxt->userData = user_data;
   14525 
   14526     xmlParseDocument(ctxt);
   14527 
   14528     if (ctxt->wellFormed)
   14529 	ret = 0;
   14530     else {
   14531         if (ctxt->errNo != 0)
   14532 	    ret = ctxt->errNo;
   14533 	else
   14534 	    ret = -1;
   14535     }
   14536     if (sax != NULL)
   14537         ctxt->sax = NULL;
   14538     if (ctxt->myDoc != NULL) {
   14539         xmlFreeDoc(ctxt->myDoc);
   14540 	ctxt->myDoc = NULL;
   14541     }
   14542     xmlFreeParserCtxt(ctxt);
   14543 
   14544     return ret;
   14545 }
   14546 #endif /* LIBXML_SAX1_ENABLED */
   14547 
   14548 /**
   14549  * xmlCreateDocParserCtxt:
   14550  * @cur:  a pointer to an array of xmlChar
   14551  *
   14552  * Creates a parser context for an XML in-memory document.
   14553  *
   14554  * Returns the new parser context or NULL
   14555  */
   14556 xmlParserCtxtPtr
   14557 xmlCreateDocParserCtxt(const xmlChar *cur) {
   14558     int len;
   14559 
   14560     if (cur == NULL)
   14561 	return(NULL);
   14562     len = xmlStrlen(cur);
   14563     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
   14564 }
   14565 
   14566 #ifdef LIBXML_SAX1_ENABLED
   14567 /**
   14568  * xmlSAXParseDoc:
   14569  * @sax:  the SAX handler block
   14570  * @cur:  a pointer to an array of xmlChar
   14571  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
   14572  *             documents
   14573  *
   14574  * parse an XML in-memory document and build a tree.
   14575  * It use the given SAX function block to handle the parsing callback.
   14576  * If sax is NULL, fallback to the default DOM tree building routines.
   14577  *
   14578  * Returns the resulting document tree
   14579  */
   14580 
   14581 xmlDocPtr
   14582 xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
   14583     xmlDocPtr ret;
   14584     xmlParserCtxtPtr ctxt;
   14585     xmlSAXHandlerPtr oldsax = NULL;
   14586 
   14587     if (cur == NULL) return(NULL);
   14588 
   14589 
   14590     ctxt = xmlCreateDocParserCtxt(cur);
   14591     if (ctxt == NULL) return(NULL);
   14592     if (sax != NULL) {
   14593         oldsax = ctxt->sax;
   14594         ctxt->sax = sax;
   14595         ctxt->userData = NULL;
   14596     }
   14597     xmlDetectSAX2(ctxt);
   14598 
   14599     xmlParseDocument(ctxt);
   14600     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
   14601     else {
   14602        ret = NULL;
   14603        xmlFreeDoc(ctxt->myDoc);
   14604        ctxt->myDoc = NULL;
   14605     }
   14606     if (sax != NULL)
   14607 	ctxt->sax = oldsax;
   14608     xmlFreeParserCtxt(ctxt);
   14609 
   14610     return(ret);
   14611 }
   14612 
   14613 /**
   14614  * xmlParseDoc:
   14615  * @cur:  a pointer to an array of xmlChar
   14616  *
   14617  * parse an XML in-memory document and build a tree.
   14618  *
   14619  * Returns the resulting document tree
   14620  */
   14621 
   14622 xmlDocPtr
   14623 xmlParseDoc(const xmlChar *cur) {
   14624     return(xmlSAXParseDoc(NULL, cur, 0));
   14625 }
   14626 #endif /* LIBXML_SAX1_ENABLED */
   14627 
   14628 #ifdef LIBXML_LEGACY_ENABLED
   14629 /************************************************************************
   14630  *									*
   14631  *	Specific function to keep track of entities references		*
   14632  *	and used by the XSLT debugger					*
   14633  *									*
   14634  ************************************************************************/
   14635 
   14636 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
   14637 
   14638 /**
   14639  * xmlAddEntityReference:
   14640  * @ent : A valid entity
   14641  * @firstNode : A valid first node for children of entity
   14642  * @lastNode : A valid last node of children entity
   14643  *
   14644  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
   14645  */
   14646 static void
   14647 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
   14648                       xmlNodePtr lastNode)
   14649 {
   14650     if (xmlEntityRefFunc != NULL) {
   14651         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
   14652     }
   14653 }
   14654 
   14655 
   14656 /**
   14657  * xmlSetEntityReferenceFunc:
   14658  * @func: A valid function
   14659  *
   14660  * Set the function to call call back when a xml reference has been made
   14661  */
   14662 void
   14663 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
   14664 {
   14665     xmlEntityRefFunc = func;
   14666 }
   14667 #endif /* LIBXML_LEGACY_ENABLED */
   14668 
   14669 /************************************************************************
   14670  *									*
   14671  *				Miscellaneous				*
   14672  *									*
   14673  ************************************************************************/
   14674 
   14675 #ifdef LIBXML_XPATH_ENABLED
   14676 #include <libxml/xpath.h>
   14677 #endif
   14678 
   14679 extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
   14680 static int xmlParserInitialized = 0;
   14681 
   14682 /**
   14683  * xmlInitParser:
   14684  *
   14685  * Initialization function for the XML parser.
   14686  * This is not reentrant. Call once before processing in case of
   14687  * use in multithreaded programs.
   14688  */
   14689 
   14690 void
   14691 xmlInitParser(void) {
   14692     if (xmlParserInitialized != 0)
   14693 	return;
   14694 
   14695 #ifdef LIBXML_THREAD_ENABLED
   14696     __xmlGlobalInitMutexLock();
   14697     if (xmlParserInitialized == 0) {
   14698 #endif
   14699 	xmlInitThreads();
   14700 	xmlInitGlobals();
   14701 	if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
   14702 	    (xmlGenericError == NULL))
   14703 	    initGenericErrorDefaultFunc(NULL);
   14704 	xmlInitMemory();
   14705         xmlInitializeDict();
   14706 	xmlInitCharEncodingHandlers();
   14707 	xmlDefaultSAXHandlerInit();
   14708 	xmlRegisterDefaultInputCallbacks();
   14709 #ifdef LIBXML_OUTPUT_ENABLED
   14710 	xmlRegisterDefaultOutputCallbacks();
   14711 #endif /* LIBXML_OUTPUT_ENABLED */
   14712 #ifdef LIBXML_HTML_ENABLED
   14713 	htmlInitAutoClose();
   14714 	htmlDefaultSAXHandlerInit();
   14715 #endif
   14716 #ifdef LIBXML_XPATH_ENABLED
   14717 	xmlXPathInit();
   14718 #endif
   14719 	xmlParserInitialized = 1;
   14720 #ifdef LIBXML_THREAD_ENABLED
   14721     }
   14722     __xmlGlobalInitMutexUnlock();
   14723 #endif
   14724 }
   14725 
   14726 /**
   14727  * xmlCleanupParser:
   14728  *
   14729  * This function name is somewhat misleading. It does not clean up
   14730  * parser state, it cleans up memory allocated by the library itself.
   14731  * It is a cleanup function for the XML library. It tries to reclaim all
   14732  * related global memory allocated for the library processing.
   14733  * It doesn't deallocate any document related memory. One should
   14734  * call xmlCleanupParser() only when the process has finished using
   14735  * the library and all XML/HTML documents built with it.
   14736  * See also xmlInitParser() which has the opposite function of preparing
   14737  * the library for operations.
   14738  *
   14739  * WARNING: if your application is multithreaded or has plugin support
   14740  *          calling this may crash the application if another thread or
   14741  *          a plugin is still using libxml2. It's sometimes very hard to
   14742  *          guess if libxml2 is in use in the application, some libraries
   14743  *          or plugins may use it without notice. In case of doubt abstain
   14744  *          from calling this function or do it just before calling exit()
   14745  *          to avoid leak reports from valgrind !
   14746  */
   14747 
   14748 void
   14749 xmlCleanupParser(void) {
   14750     if (!xmlParserInitialized)
   14751 	return;
   14752 
   14753     xmlCleanupCharEncodingHandlers();
   14754 #ifdef LIBXML_CATALOG_ENABLED
   14755     xmlCatalogCleanup();
   14756 #endif
   14757     xmlDictCleanup();
   14758     xmlCleanupInputCallbacks();
   14759 #ifdef LIBXML_OUTPUT_ENABLED
   14760     xmlCleanupOutputCallbacks();
   14761 #endif
   14762 #ifdef LIBXML_SCHEMAS_ENABLED
   14763     xmlSchemaCleanupTypes();
   14764     xmlRelaxNGCleanupTypes();
   14765 #endif
   14766     xmlCleanupGlobals();
   14767     xmlResetLastError();
   14768     xmlCleanupThreads(); /* must be last if called not from the main thread */
   14769     xmlCleanupMemory();
   14770     xmlParserInitialized = 0;
   14771 }
   14772 
   14773 /************************************************************************
   14774  *									*
   14775  *	New set (2.6.0) of simpler and more flexible APIs		*
   14776  *									*
   14777  ************************************************************************/
   14778 
   14779 /**
   14780  * DICT_FREE:
   14781  * @str:  a string
   14782  *
   14783  * Free a string if it is not owned by the "dict" dictionnary in the
   14784  * current scope
   14785  */
   14786 #define DICT_FREE(str)						\
   14787 	if ((str) && ((!dict) ||				\
   14788 	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
   14789 	    xmlFree((char *)(str));
   14790 
   14791 /**
   14792  * xmlCtxtReset:
   14793  * @ctxt: an XML parser context
   14794  *
   14795  * Reset a parser context
   14796  */
   14797 void
   14798 xmlCtxtReset(xmlParserCtxtPtr ctxt)
   14799 {
   14800     xmlParserInputPtr input;
   14801     xmlDictPtr dict;
   14802 
   14803     if (ctxt == NULL)
   14804         return;
   14805 
   14806     dict = ctxt->dict;
   14807 
   14808     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
   14809         xmlFreeInputStream(input);
   14810     }
   14811     ctxt->inputNr = 0;
   14812     ctxt->input = NULL;
   14813 
   14814     ctxt->spaceNr = 0;
   14815     if (ctxt->spaceTab != NULL) {
   14816 	ctxt->spaceTab[0] = -1;
   14817 	ctxt->space = &ctxt->spaceTab[0];
   14818     } else {
   14819         ctxt->space = NULL;
   14820     }
   14821 
   14822 
   14823     ctxt->nodeNr = 0;
   14824     ctxt->node = NULL;
   14825 
   14826     ctxt->nameNr = 0;
   14827     ctxt->name = NULL;
   14828 
   14829     DICT_FREE(ctxt->version);
   14830     ctxt->version = NULL;
   14831     DICT_FREE(ctxt->encoding);
   14832     ctxt->encoding = NULL;
   14833     DICT_FREE(ctxt->directory);
   14834     ctxt->directory = NULL;
   14835     DICT_FREE(ctxt->extSubURI);
   14836     ctxt->extSubURI = NULL;
   14837     DICT_FREE(ctxt->extSubSystem);
   14838     ctxt->extSubSystem = NULL;
   14839     if (ctxt->myDoc != NULL)
   14840         xmlFreeDoc(ctxt->myDoc);
   14841     ctxt->myDoc = NULL;
   14842 
   14843     ctxt->standalone = -1;
   14844     ctxt->hasExternalSubset = 0;
   14845     ctxt->hasPErefs = 0;
   14846     ctxt->html = 0;
   14847     ctxt->external = 0;
   14848     ctxt->instate = XML_PARSER_START;
   14849     ctxt->token = 0;
   14850 
   14851     ctxt->wellFormed = 1;
   14852     ctxt->nsWellFormed = 1;
   14853     ctxt->disableSAX = 0;
   14854     ctxt->valid = 1;
   14855 #if 0
   14856     ctxt->vctxt.userData = ctxt;
   14857     ctxt->vctxt.error = xmlParserValidityError;
   14858     ctxt->vctxt.warning = xmlParserValidityWarning;
   14859 #endif
   14860     ctxt->record_info = 0;
   14861     ctxt->nbChars = 0;
   14862     ctxt->checkIndex = 0;
   14863     ctxt->inSubset = 0;
   14864     ctxt->errNo = XML_ERR_OK;
   14865     ctxt->depth = 0;
   14866     ctxt->charset = XML_CHAR_ENCODING_UTF8;
   14867     ctxt->catalogs = NULL;
   14868     ctxt->nbentities = 0;
   14869     ctxt->sizeentities = 0;
   14870     ctxt->sizeentcopy = 0;
   14871     xmlInitNodeInfoSeq(&ctxt->node_seq);
   14872 
   14873     if (ctxt->attsDefault != NULL) {
   14874         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
   14875         ctxt->attsDefault = NULL;
   14876     }
   14877     if (ctxt->attsSpecial != NULL) {
   14878         xmlHashFree(ctxt->attsSpecial, NULL);
   14879         ctxt->attsSpecial = NULL;
   14880     }
   14881 
   14882 #ifdef LIBXML_CATALOG_ENABLED
   14883     if (ctxt->catalogs != NULL)
   14884 	xmlCatalogFreeLocal(ctxt->catalogs);
   14885 #endif
   14886     if (ctxt->lastError.code != XML_ERR_OK)
   14887         xmlResetError(&ctxt->lastError);
   14888 }
   14889 
   14890 /**
   14891  * xmlCtxtResetPush:
   14892  * @ctxt: an XML parser context
   14893  * @chunk:  a pointer to an array of chars
   14894  * @size:  number of chars in the array
   14895  * @filename:  an optional file name or URI
   14896  * @encoding:  the document encoding, or NULL
   14897  *
   14898  * Reset a push parser context
   14899  *
   14900  * Returns 0 in case of success and 1 in case of error
   14901  */
   14902 int
   14903 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
   14904                  int size, const char *filename, const char *encoding)
   14905 {
   14906     xmlParserInputPtr inputStream;
   14907     xmlParserInputBufferPtr buf;
   14908     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
   14909 
   14910     if (ctxt == NULL)
   14911         return(1);
   14912 
   14913     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
   14914         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
   14915 
   14916     buf = xmlAllocParserInputBuffer(enc);
   14917     if (buf == NULL)
   14918         return(1);
   14919 
   14920     if (ctxt == NULL) {
   14921         xmlFreeParserInputBuffer(buf);
   14922         return(1);
   14923     }
   14924 
   14925     xmlCtxtReset(ctxt);
   14926 
   14927     if (ctxt->pushTab == NULL) {
   14928         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
   14929 	                                    sizeof(xmlChar *));
   14930         if (ctxt->pushTab == NULL) {
   14931 	    xmlErrMemory(ctxt, NULL);
   14932             xmlFreeParserInputBuffer(buf);
   14933             return(1);
   14934         }
   14935     }
   14936 
   14937     if (filename == NULL) {
   14938         ctxt->directory = NULL;
   14939     } else {
   14940         ctxt->directory = xmlParserGetDirectory(filename);
   14941     }
   14942 
   14943     inputStream = xmlNewInputStream(ctxt);
   14944     if (inputStream == NULL) {
   14945         xmlFreeParserInputBuffer(buf);
   14946         return(1);
   14947     }
   14948 
   14949     if (filename == NULL)
   14950         inputStream->filename = NULL;
   14951     else
   14952         inputStream->filename = (char *)
   14953             xmlCanonicPath((const xmlChar *) filename);
   14954     inputStream->buf = buf;
   14955     xmlBufResetInput(buf->buffer, inputStream);
   14956 
   14957     inputPush(ctxt, inputStream);
   14958 
   14959     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
   14960         (ctxt->input->buf != NULL)) {
   14961 	size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
   14962         size_t cur = ctxt->input->cur - ctxt->input->base;
   14963 
   14964         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
   14965 
   14966         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
   14967 #ifdef DEBUG_PUSH
   14968         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
   14969 #endif
   14970     }
   14971 
   14972     if (encoding != NULL) {
   14973         xmlCharEncodingHandlerPtr hdlr;
   14974 
   14975         if (ctxt->encoding != NULL)
   14976 	    xmlFree((xmlChar *) ctxt->encoding);
   14977         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
   14978 
   14979         hdlr = xmlFindCharEncodingHandler(encoding);
   14980         if (hdlr != NULL) {
   14981             xmlSwitchToEncoding(ctxt, hdlr);
   14982 	} else {
   14983 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
   14984 			      "Unsupported encoding %s\n", BAD_CAST encoding);
   14985         }
   14986     } else if (enc != XML_CHAR_ENCODING_NONE) {
   14987         xmlSwitchEncoding(ctxt, enc);
   14988     }
   14989 
   14990     return(0);
   14991 }
   14992 
   14993 
   14994 /**
   14995  * xmlCtxtUseOptionsInternal:
   14996  * @ctxt: an XML parser context
   14997  * @options:  a combination of xmlParserOption
   14998  * @encoding:  the user provided encoding to use
   14999  *
   15000  * Applies the options to the parser context
   15001  *
   15002  * Returns 0 in case of success, the set of unknown or unimplemented options
   15003  *         in case of error.
   15004  */
   15005 static int
   15006 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
   15007 {
   15008     if (ctxt == NULL)
   15009         return(-1);
   15010     if (encoding != NULL) {
   15011         if (ctxt->encoding != NULL)
   15012 	    xmlFree((xmlChar *) ctxt->encoding);
   15013         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
   15014     }
   15015     if (options & XML_PARSE_RECOVER) {
   15016         ctxt->recovery = 1;
   15017         options -= XML_PARSE_RECOVER;
   15018 	ctxt->options |= XML_PARSE_RECOVER;
   15019     } else
   15020         ctxt->recovery = 0;
   15021     if (options & XML_PARSE_DTDLOAD) {
   15022         ctxt->loadsubset = XML_DETECT_IDS;
   15023         options -= XML_PARSE_DTDLOAD;
   15024 	ctxt->options |= XML_PARSE_DTDLOAD;
   15025     } else
   15026         ctxt->loadsubset = 0;
   15027     if (options & XML_PARSE_DTDATTR) {
   15028         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
   15029         options -= XML_PARSE_DTDATTR;
   15030 	ctxt->options |= XML_PARSE_DTDATTR;
   15031     }
   15032     if (options & XML_PARSE_NOENT) {
   15033         ctxt->replaceEntities = 1;
   15034         /* ctxt->loadsubset |= XML_DETECT_IDS; */
   15035         options -= XML_PARSE_NOENT;
   15036 	ctxt->options |= XML_PARSE_NOENT;
   15037     } else
   15038         ctxt->replaceEntities = 0;
   15039     if (options & XML_PARSE_PEDANTIC) {
   15040         ctxt->pedantic = 1;
   15041         options -= XML_PARSE_PEDANTIC;
   15042 	ctxt->options |= XML_PARSE_PEDANTIC;
   15043     } else
   15044         ctxt->pedantic = 0;
   15045     if (options & XML_PARSE_NOBLANKS) {
   15046         ctxt->keepBlanks = 0;
   15047         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
   15048         options -= XML_PARSE_NOBLANKS;
   15049 	ctxt->options |= XML_PARSE_NOBLANKS;
   15050     } else
   15051         ctxt->keepBlanks = 1;
   15052     if (options & XML_PARSE_DTDVALID) {
   15053         ctxt->validate = 1;
   15054         if (options & XML_PARSE_NOWARNING)
   15055             ctxt->vctxt.warning = NULL;
   15056         if (options & XML_PARSE_NOERROR)
   15057             ctxt->vctxt.error = NULL;
   15058         options -= XML_PARSE_DTDVALID;
   15059 	ctxt->options |= XML_PARSE_DTDVALID;
   15060     } else
   15061         ctxt->validate = 0;
   15062     if (options & XML_PARSE_NOWARNING) {
   15063         ctxt->sax->warning = NULL;
   15064         options -= XML_PARSE_NOWARNING;
   15065     }
   15066     if (options & XML_PARSE_NOERROR) {
   15067         ctxt->sax->error = NULL;
   15068         ctxt->sax->fatalError = NULL;
   15069         options -= XML_PARSE_NOERROR;
   15070     }
   15071 #ifdef LIBXML_SAX1_ENABLED
   15072     if (options & XML_PARSE_SAX1) {
   15073         ctxt->sax->startElement = xmlSAX2StartElement;
   15074         ctxt->sax->endElement = xmlSAX2EndElement;
   15075         ctxt->sax->startElementNs = NULL;
   15076         ctxt->sax->endElementNs = NULL;
   15077         ctxt->sax->initialized = 1;
   15078         options -= XML_PARSE_SAX1;
   15079 	ctxt->options |= XML_PARSE_SAX1;
   15080     }
   15081 #endif /* LIBXML_SAX1_ENABLED */
   15082     if (options & XML_PARSE_NODICT) {
   15083         ctxt->dictNames = 0;
   15084         options -= XML_PARSE_NODICT;
   15085 	ctxt->options |= XML_PARSE_NODICT;
   15086     } else {
   15087         ctxt->dictNames = 1;
   15088     }
   15089     if (options & XML_PARSE_NOCDATA) {
   15090         ctxt->sax->cdataBlock = NULL;
   15091         options -= XML_PARSE_NOCDATA;
   15092 	ctxt->options |= XML_PARSE_NOCDATA;
   15093     }
   15094     if (options & XML_PARSE_NSCLEAN) {
   15095 	ctxt->options |= XML_PARSE_NSCLEAN;
   15096         options -= XML_PARSE_NSCLEAN;
   15097     }
   15098     if (options & XML_PARSE_NONET) {
   15099 	ctxt->options |= XML_PARSE_NONET;
   15100         options -= XML_PARSE_NONET;
   15101     }
   15102     if (options & XML_PARSE_COMPACT) {
   15103 	ctxt->options |= XML_PARSE_COMPACT;
   15104         options -= XML_PARSE_COMPACT;
   15105     }
   15106     if (options & XML_PARSE_OLD10) {
   15107 	ctxt->options |= XML_PARSE_OLD10;
   15108         options -= XML_PARSE_OLD10;
   15109     }
   15110     if (options & XML_PARSE_NOBASEFIX) {
   15111 	ctxt->options |= XML_PARSE_NOBASEFIX;
   15112         options -= XML_PARSE_NOBASEFIX;
   15113     }
   15114     if (options & XML_PARSE_HUGE) {
   15115 	ctxt->options |= XML_PARSE_HUGE;
   15116         options -= XML_PARSE_HUGE;
   15117         if (ctxt->dict != NULL)
   15118             xmlDictSetLimit(ctxt->dict, 0);
   15119     }
   15120     if (options & XML_PARSE_OLDSAX) {
   15121 	ctxt->options |= XML_PARSE_OLDSAX;
   15122         options -= XML_PARSE_OLDSAX;
   15123     }
   15124     if (options & XML_PARSE_IGNORE_ENC) {
   15125 	ctxt->options |= XML_PARSE_IGNORE_ENC;
   15126         options -= XML_PARSE_IGNORE_ENC;
   15127     }
   15128     if (options & XML_PARSE_BIG_LINES) {
   15129 	ctxt->options |= XML_PARSE_BIG_LINES;
   15130         options -= XML_PARSE_BIG_LINES;
   15131     }
   15132     ctxt->linenumbers = 1;
   15133     return (options);
   15134 }
   15135 
   15136 /**
   15137  * xmlCtxtUseOptions:
   15138  * @ctxt: an XML parser context
   15139  * @options:  a combination of xmlParserOption
   15140  *
   15141  * Applies the options to the parser context
   15142  *
   15143  * Returns 0 in case of success, the set of unknown or unimplemented options
   15144  *         in case of error.
   15145  */
   15146 int
   15147 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
   15148 {
   15149    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
   15150 }
   15151 
   15152 /**
   15153  * xmlDoRead:
   15154  * @ctxt:  an XML parser context
   15155  * @URL:  the base URL to use for the document
   15156  * @encoding:  the document encoding, or NULL
   15157  * @options:  a combination of xmlParserOption
   15158  * @reuse:  keep the context for reuse
   15159  *
   15160  * Common front-end for the xmlRead functions
   15161  *
   15162  * Returns the resulting document tree or NULL
   15163  */
   15164 static xmlDocPtr
   15165 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
   15166           int options, int reuse)
   15167 {
   15168     xmlDocPtr ret;
   15169 
   15170     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
   15171     if (encoding != NULL) {
   15172         xmlCharEncodingHandlerPtr hdlr;
   15173 
   15174 	hdlr = xmlFindCharEncodingHandler(encoding);
   15175 	if (hdlr != NULL)
   15176 	    xmlSwitchToEncoding(ctxt, hdlr);
   15177     }
   15178     if ((URL != NULL) && (ctxt->input != NULL) &&
   15179         (ctxt->input->filename == NULL))
   15180         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
   15181     xmlParseDocument(ctxt);
   15182     if ((ctxt->wellFormed) || ctxt->recovery)
   15183         ret = ctxt->myDoc;
   15184     else {
   15185         ret = NULL;
   15186 	if (ctxt->myDoc != NULL) {
   15187 	    xmlFreeDoc(ctxt->myDoc);
   15188 	}
   15189     }
   15190     ctxt->myDoc = NULL;
   15191     if (!reuse) {
   15192 	xmlFreeParserCtxt(ctxt);
   15193     }
   15194 
   15195     return (ret);
   15196 }
   15197 
   15198 /**
   15199  * xmlReadDoc:
   15200  * @cur:  a pointer to a zero terminated string
   15201  * @URL:  the base URL to use for the document
   15202  * @encoding:  the document encoding, or NULL
   15203  * @options:  a combination of xmlParserOption
   15204  *
   15205  * parse an XML in-memory document and build a tree.
   15206  *
   15207  * Returns the resulting document tree
   15208  */
   15209 xmlDocPtr
   15210 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
   15211 {
   15212     xmlParserCtxtPtr ctxt;
   15213 
   15214     if (cur == NULL)
   15215         return (NULL);
   15216 
   15217     ctxt = xmlCreateDocParserCtxt(cur);
   15218     if (ctxt == NULL)
   15219         return (NULL);
   15220     return (xmlDoRead(ctxt, URL, encoding, options, 0));
   15221 }
   15222 
   15223 /**
   15224  * xmlReadFile:
   15225  * @filename:  a file or URL
   15226  * @encoding:  the document encoding, or NULL
   15227  * @options:  a combination of xmlParserOption
   15228  *
   15229  * parse an XML file from the filesystem or the network.
   15230  *
   15231  * Returns the resulting document tree
   15232  */
   15233 xmlDocPtr
   15234 xmlReadFile(const char *filename, const char *encoding, int options)
   15235 {
   15236     xmlParserCtxtPtr ctxt;
   15237 
   15238     ctxt = xmlCreateURLParserCtxt(filename, options);
   15239     if (ctxt == NULL)
   15240         return (NULL);
   15241     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
   15242 }
   15243 
   15244 /**
   15245  * xmlReadMemory:
   15246  * @buffer:  a pointer to a char array
   15247  * @size:  the size of the array
   15248  * @URL:  the base URL to use for the document
   15249  * @encoding:  the document encoding, or NULL
   15250  * @options:  a combination of xmlParserOption
   15251  *
   15252  * parse an XML in-memory document and build a tree.
   15253  *
   15254  * Returns the resulting document tree
   15255  */
   15256 xmlDocPtr
   15257 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
   15258 {
   15259     xmlParserCtxtPtr ctxt;
   15260 
   15261     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
   15262     if (ctxt == NULL)
   15263         return (NULL);
   15264     return (xmlDoRead(ctxt, URL, encoding, options, 0));
   15265 }
   15266 
   15267 /**
   15268  * xmlReadFd:
   15269  * @fd:  an open file descriptor
   15270  * @URL:  the base URL to use for the document
   15271  * @encoding:  the document encoding, or NULL
   15272  * @options:  a combination of xmlParserOption
   15273  *
   15274  * parse an XML from a file descriptor and build a tree.
   15275  * NOTE that the file descriptor will not be closed when the
   15276  *      reader is closed or reset.
   15277  *
   15278  * Returns the resulting document tree
   15279  */
   15280 xmlDocPtr
   15281 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
   15282 {
   15283     xmlParserCtxtPtr ctxt;
   15284     xmlParserInputBufferPtr input;
   15285     xmlParserInputPtr stream;
   15286 
   15287     if (fd < 0)
   15288         return (NULL);
   15289 
   15290     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
   15291     if (input == NULL)
   15292         return (NULL);
   15293     input->closecallback = NULL;
   15294     ctxt = xmlNewParserCtxt();
   15295     if (ctxt == NULL) {
   15296         xmlFreeParserInputBuffer(input);
   15297         return (NULL);
   15298     }
   15299     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
   15300     if (stream == NULL) {
   15301         xmlFreeParserInputBuffer(input);
   15302 	xmlFreeParserCtxt(ctxt);
   15303         return (NULL);
   15304     }
   15305     inputPush(ctxt, stream);
   15306     return (xmlDoRead(ctxt, URL, encoding, options, 0));
   15307 }
   15308 
   15309 /**
   15310  * xmlReadIO:
   15311  * @ioread:  an I/O read function
   15312  * @ioclose:  an I/O close function
   15313  * @ioctx:  an I/O handler
   15314  * @URL:  the base URL to use for the document
   15315  * @encoding:  the document encoding, or NULL
   15316  * @options:  a combination of xmlParserOption
   15317  *
   15318  * parse an XML document from I/O functions and source and build a tree.
   15319  *
   15320  * Returns the resulting document tree
   15321  */
   15322 xmlDocPtr
   15323 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
   15324           void *ioctx, const char *URL, const char *encoding, int options)
   15325 {
   15326     xmlParserCtxtPtr ctxt;
   15327     xmlParserInputBufferPtr input;
   15328     xmlParserInputPtr stream;
   15329 
   15330     if (ioread == NULL)
   15331         return (NULL);
   15332 
   15333     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
   15334                                          XML_CHAR_ENCODING_NONE);
   15335     if (input == NULL) {
   15336         if (ioclose != NULL)
   15337             ioclose(ioctx);
   15338         return (NULL);
   15339     }
   15340     ctxt = xmlNewParserCtxt();
   15341     if (ctxt == NULL) {
   15342         xmlFreeParserInputBuffer(input);
   15343         return (NULL);
   15344     }
   15345     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
   15346     if (stream == NULL) {
   15347         xmlFreeParserInputBuffer(input);
   15348 	xmlFreeParserCtxt(ctxt);
   15349         return (NULL);
   15350     }
   15351     inputPush(ctxt, stream);
   15352     return (xmlDoRead(ctxt, URL, encoding, options, 0));
   15353 }
   15354 
   15355 /**
   15356  * xmlCtxtReadDoc:
   15357  * @ctxt:  an XML parser context
   15358  * @cur:  a pointer to a zero terminated string
   15359  * @URL:  the base URL to use for the document
   15360  * @encoding:  the document encoding, or NULL
   15361  * @options:  a combination of xmlParserOption
   15362  *
   15363  * parse an XML in-memory document and build a tree.
   15364  * This reuses the existing @ctxt parser context
   15365  *
   15366  * Returns the resulting document tree
   15367  */
   15368 xmlDocPtr
   15369 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
   15370                const char *URL, const char *encoding, int options)
   15371 {
   15372     xmlParserInputPtr stream;
   15373 
   15374     if (cur == NULL)
   15375         return (NULL);
   15376     if (ctxt == NULL)
   15377         return (NULL);
   15378 
   15379     xmlCtxtReset(ctxt);
   15380 
   15381     stream = xmlNewStringInputStream(ctxt, cur);
   15382     if (stream == NULL) {
   15383         return (NULL);
   15384     }
   15385     inputPush(ctxt, stream);
   15386     return (xmlDoRead(ctxt, URL, encoding, options, 1));
   15387 }
   15388 
   15389 /**
   15390  * xmlCtxtReadFile:
   15391  * @ctxt:  an XML parser context
   15392  * @filename:  a file or URL
   15393  * @encoding:  the document encoding, or NULL
   15394  * @options:  a combination of xmlParserOption
   15395  *
   15396  * parse an XML file from the filesystem or the network.
   15397  * This reuses the existing @ctxt parser context
   15398  *
   15399  * Returns the resulting document tree
   15400  */
   15401 xmlDocPtr
   15402 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
   15403                 const char *encoding, int options)
   15404 {
   15405     xmlParserInputPtr stream;
   15406 
   15407     if (filename == NULL)
   15408         return (NULL);
   15409     if (ctxt == NULL)
   15410         return (NULL);
   15411 
   15412     xmlCtxtReset(ctxt);
   15413 
   15414     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
   15415     if (stream == NULL) {
   15416         return (NULL);
   15417     }
   15418     inputPush(ctxt, stream);
   15419     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
   15420 }
   15421 
   15422 /**
   15423  * xmlCtxtReadMemory:
   15424  * @ctxt:  an XML parser context
   15425  * @buffer:  a pointer to a char array
   15426  * @size:  the size of the array
   15427  * @URL:  the base URL to use for the document
   15428  * @encoding:  the document encoding, or NULL
   15429  * @options:  a combination of xmlParserOption
   15430  *
   15431  * parse an XML in-memory document and build a tree.
   15432  * This reuses the existing @ctxt parser context
   15433  *
   15434  * Returns the resulting document tree
   15435  */
   15436 xmlDocPtr
   15437 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
   15438                   const char *URL, const char *encoding, int options)
   15439 {
   15440     xmlParserInputBufferPtr input;
   15441     xmlParserInputPtr stream;
   15442 
   15443     if (ctxt == NULL)
   15444         return (NULL);
   15445     if (buffer == NULL)
   15446         return (NULL);
   15447 
   15448     xmlCtxtReset(ctxt);
   15449 
   15450     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
   15451     if (input == NULL) {
   15452 	return(NULL);
   15453     }
   15454 
   15455     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
   15456     if (stream == NULL) {
   15457 	xmlFreeParserInputBuffer(input);
   15458 	return(NULL);
   15459     }
   15460 
   15461     inputPush(ctxt, stream);
   15462     return (xmlDoRead(ctxt, URL, encoding, options, 1));
   15463 }
   15464 
   15465 /**
   15466  * xmlCtxtReadFd:
   15467  * @ctxt:  an XML parser context
   15468  * @fd:  an open file descriptor
   15469  * @URL:  the base URL to use for the document
   15470  * @encoding:  the document encoding, or NULL
   15471  * @options:  a combination of xmlParserOption
   15472  *
   15473  * parse an XML from a file descriptor and build a tree.
   15474  * This reuses the existing @ctxt parser context
   15475  * NOTE that the file descriptor will not be closed when the
   15476  *      reader is closed or reset.
   15477  *
   15478  * Returns the resulting document tree
   15479  */
   15480 xmlDocPtr
   15481 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
   15482               const char *URL, const char *encoding, int options)
   15483 {
   15484     xmlParserInputBufferPtr input;
   15485     xmlParserInputPtr stream;
   15486 
   15487     if (fd < 0)
   15488         return (NULL);
   15489     if (ctxt == NULL)
   15490         return (NULL);
   15491 
   15492     xmlCtxtReset(ctxt);
   15493 
   15494 
   15495     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
   15496     if (input == NULL)
   15497         return (NULL);
   15498     input->closecallback = NULL;
   15499     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
   15500     if (stream == NULL) {
   15501         xmlFreeParserInputBuffer(input);
   15502         return (NULL);
   15503     }
   15504     inputPush(ctxt, stream);
   15505     return (xmlDoRead(ctxt, URL, encoding, options, 1));
   15506 }
   15507 
   15508 /**
   15509  * xmlCtxtReadIO:
   15510  * @ctxt:  an XML parser context
   15511  * @ioread:  an I/O read function
   15512  * @ioclose:  an I/O close function
   15513  * @ioctx:  an I/O handler
   15514  * @URL:  the base URL to use for the document
   15515  * @encoding:  the document encoding, or NULL
   15516  * @options:  a combination of xmlParserOption
   15517  *
   15518  * parse an XML document from I/O functions and source and build a tree.
   15519  * This reuses the existing @ctxt parser context
   15520  *
   15521  * Returns the resulting document tree
   15522  */
   15523 xmlDocPtr
   15524 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
   15525               xmlInputCloseCallback ioclose, void *ioctx,
   15526 	      const char *URL,
   15527               const char *encoding, int options)
   15528 {
   15529     xmlParserInputBufferPtr input;
   15530     xmlParserInputPtr stream;
   15531 
   15532     if (ioread == NULL)
   15533         return (NULL);
   15534     if (ctxt == NULL)
   15535         return (NULL);
   15536 
   15537     xmlCtxtReset(ctxt);
   15538 
   15539     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
   15540                                          XML_CHAR_ENCODING_NONE);
   15541     if (input == NULL) {
   15542         if (ioclose != NULL)
   15543             ioclose(ioctx);
   15544         return (NULL);
   15545     }
   15546     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
   15547     if (stream == NULL) {
   15548         xmlFreeParserInputBuffer(input);
   15549         return (NULL);
   15550     }
   15551     inputPush(ctxt, stream);
   15552     return (xmlDoRead(ctxt, URL, encoding, options, 1));
   15553 }
   15554 
   15555 #define bottom_parser
   15556 #include "elfgcchack.h"
   15557