File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / parser.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 19:53:29 2014 UTC (9 years, 11 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, HEAD
libxml2 2.9.1

    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@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"

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>