File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / parser.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:37:57 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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 <string.h>
   44: #include <stdarg.h>
   45: #include <libxml/xmlmemory.h>
   46: #include <libxml/threads.h>
   47: #include <libxml/globals.h>
   48: #include <libxml/tree.h>
   49: #include <libxml/parser.h>
   50: #include <libxml/parserInternals.h>
   51: #include <libxml/valid.h>
   52: #include <libxml/entities.h>
   53: #include <libxml/xmlerror.h>
   54: #include <libxml/encoding.h>
   55: #include <libxml/xmlIO.h>
   56: #include <libxml/uri.h>
   57: #ifdef LIBXML_CATALOG_ENABLED
   58: #include <libxml/catalog.h>
   59: #endif
   60: #ifdef LIBXML_SCHEMAS_ENABLED
   61: #include <libxml/xmlschemastypes.h>
   62: #include <libxml/relaxng.h>
   63: #endif
   64: #ifdef HAVE_CTYPE_H
   65: #include <ctype.h>
   66: #endif
   67: #ifdef HAVE_STDLIB_H
   68: #include <stdlib.h>
   69: #endif
   70: #ifdef HAVE_SYS_STAT_H
   71: #include <sys/stat.h>
   72: #endif
   73: #ifdef HAVE_FCNTL_H
   74: #include <fcntl.h>
   75: #endif
   76: #ifdef HAVE_UNISTD_H
   77: #include <unistd.h>
   78: #endif
   79: #ifdef HAVE_ZLIB_H
   80: #include <zlib.h>
   81: #endif
   82: 
   83: static void
   84: xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
   85: 
   86: static xmlParserCtxtPtr
   87: xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
   88: 	                  const xmlChar *base, xmlParserCtxtPtr pctx);
   89: 
   90: /************************************************************************
   91:  *									*
   92:  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
   93:  *									*
   94:  ************************************************************************/
   95: 
   96: #define XML_PARSER_BIG_ENTITY 1000
   97: #define XML_PARSER_LOT_ENTITY 5000
   98: 
   99: /*
  100:  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
  101:  *    replacement over the size in byte of the input indicates that you have
  102:  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
  103:  *    replacement per byte of input.
  104:  */
  105: #define XML_PARSER_NON_LINEAR 10
  106: 
  107: /*
  108:  * xmlParserEntityCheck
  109:  *
  110:  * Function to check non-linear entity expansion behaviour
  111:  * This is here to detect and stop exponential linear entity expansion
  112:  * This is not a limitation of the parser but a safety
  113:  * boundary feature. It can be disabled with the XML_PARSE_HUGE
  114:  * parser option.
  115:  */
  116: static int
  117: xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
  118:                      xmlEntityPtr ent)
  119: {
  120:     unsigned long consumed = 0;
  121: 
  122:     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
  123:         return (0);
  124:     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
  125:         return (1);
  126:     if (size != 0) {
  127:         /*
  128:          * Do the check based on the replacement size of the entity
  129:          */
  130:         if (size < XML_PARSER_BIG_ENTITY)
  131: 	    return(0);
  132: 
  133:         /*
  134:          * A limit on the amount of text data reasonably used
  135:          */
  136:         if (ctxt->input != NULL) {
  137:             consumed = ctxt->input->consumed +
  138:                 (ctxt->input->cur - ctxt->input->base);
  139:         }
  140:         consumed += ctxt->sizeentities;
  141: 
  142:         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
  143: 	    (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
  144:             return (0);
  145:     } else if (ent != NULL) {
  146:         /*
  147:          * use the number of parsed entities in the replacement
  148:          */
  149:         size = ent->checked;
  150: 
  151:         /*
  152:          * The amount of data parsed counting entities size only once
  153:          */
  154:         if (ctxt->input != NULL) {
  155:             consumed = ctxt->input->consumed +
  156:                 (ctxt->input->cur - ctxt->input->base);
  157:         }
  158:         consumed += ctxt->sizeentities;
  159: 
  160:         /*
  161:          * Check the density of entities for the amount of data
  162: 	 * knowing an entity reference will take at least 3 bytes
  163:          */
  164:         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
  165:             return (0);
  166:     } else {
  167:         /*
  168:          * strange we got no data for checking just return
  169:          */
  170:         return (0);
  171:     }
  172: 
  173:     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
  174:     return (1);
  175: }
  176: 
  177: /**
  178:  * xmlParserMaxDepth:
  179:  *
  180:  * arbitrary depth limit for the XML documents that we allow to
  181:  * process. This is not a limitation of the parser but a safety
  182:  * boundary feature. It can be disabled with the XML_PARSE_HUGE
  183:  * parser option.
  184:  */
  185: unsigned int xmlParserMaxDepth = 256;
  186: 
  187: 
  188: 
  189: #define SAX2 1
  190: #define XML_PARSER_BIG_BUFFER_SIZE 300
  191: #define XML_PARSER_BUFFER_SIZE 100
  192: #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
  193: 
  194: /*
  195:  * List of XML prefixed PI allowed by W3C specs
  196:  */
  197: 
  198: static const char *xmlW3CPIs[] = {
  199:     "xml-stylesheet",
  200:     NULL
  201: };
  202: 
  203: 
  204: /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
  205: static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
  206:                                               const xmlChar **str);
  207: 
  208: static xmlParserErrors
  209: xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
  210: 	              xmlSAXHandlerPtr sax,
  211: 		      void *user_data, int depth, const xmlChar *URL,
  212: 		      const xmlChar *ID, xmlNodePtr *list);
  213: 
  214: static int
  215: xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
  216:                           const char *encoding);
  217: #ifdef LIBXML_LEGACY_ENABLED
  218: static void
  219: xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
  220:                       xmlNodePtr lastNode);
  221: #endif /* LIBXML_LEGACY_ENABLED */
  222: 
  223: static xmlParserErrors
  224: xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
  225: 		      const xmlChar *string, void *user_data, xmlNodePtr *lst);
  226: 
  227: static int
  228: xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
  229: 
  230: /************************************************************************
  231:  *									*
  232:  * 		Some factorized error routines				*
  233:  *									*
  234:  ************************************************************************/
  235: 
  236: /**
  237:  * xmlErrAttributeDup:
  238:  * @ctxt:  an XML parser context
  239:  * @prefix:  the attribute prefix
  240:  * @localname:  the attribute localname
  241:  *
  242:  * Handle a redefinition of attribute error
  243:  */
  244: static void
  245: xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
  246:                    const xmlChar * localname)
  247: {
  248:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  249:         (ctxt->instate == XML_PARSER_EOF))
  250: 	return;
  251:     if (ctxt != NULL)
  252: 	ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
  253: 
  254:     if (prefix == NULL)
  255:         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
  256:                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
  257:                         (const char *) localname, NULL, NULL, 0, 0,
  258:                         "Attribute %s redefined\n", localname);
  259:     else
  260:         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
  261:                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
  262:                         (const char *) prefix, (const char *) localname,
  263:                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
  264:                         localname);
  265:     if (ctxt != NULL) {
  266: 	ctxt->wellFormed = 0;
  267: 	if (ctxt->recovery == 0)
  268: 	    ctxt->disableSAX = 1;
  269:     }
  270: }
  271: 
  272: /**
  273:  * xmlFatalErr:
  274:  * @ctxt:  an XML parser context
  275:  * @error:  the error number
  276:  * @extra:  extra information string
  277:  *
  278:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  279:  */
  280: static void
  281: xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
  282: {
  283:     const char *errmsg;
  284: 
  285:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  286:         (ctxt->instate == XML_PARSER_EOF))
  287: 	return;
  288:     switch (error) {
  289:         case XML_ERR_INVALID_HEX_CHARREF:
  290:             errmsg = "CharRef: invalid hexadecimal value\n";
  291:             break;
  292:         case XML_ERR_INVALID_DEC_CHARREF:
  293:             errmsg = "CharRef: invalid decimal value\n";
  294:             break;
  295:         case XML_ERR_INVALID_CHARREF:
  296:             errmsg = "CharRef: invalid value\n";
  297:             break;
  298:         case XML_ERR_INTERNAL_ERROR:
  299:             errmsg = "internal error";
  300:             break;
  301:         case XML_ERR_PEREF_AT_EOF:
  302:             errmsg = "PEReference at end of document\n";
  303:             break;
  304:         case XML_ERR_PEREF_IN_PROLOG:
  305:             errmsg = "PEReference in prolog\n";
  306:             break;
  307:         case XML_ERR_PEREF_IN_EPILOG:
  308:             errmsg = "PEReference in epilog\n";
  309:             break;
  310:         case XML_ERR_PEREF_NO_NAME:
  311:             errmsg = "PEReference: no name\n";
  312:             break;
  313:         case XML_ERR_PEREF_SEMICOL_MISSING:
  314:             errmsg = "PEReference: expecting ';'\n";
  315:             break;
  316:         case XML_ERR_ENTITY_LOOP:
  317:             errmsg = "Detected an entity reference loop\n";
  318:             break;
  319:         case XML_ERR_ENTITY_NOT_STARTED:
  320:             errmsg = "EntityValue: \" or ' expected\n";
  321:             break;
  322:         case XML_ERR_ENTITY_PE_INTERNAL:
  323:             errmsg = "PEReferences forbidden in internal subset\n";
  324:             break;
  325:         case XML_ERR_ENTITY_NOT_FINISHED:
  326:             errmsg = "EntityValue: \" or ' expected\n";
  327:             break;
  328:         case XML_ERR_ATTRIBUTE_NOT_STARTED:
  329:             errmsg = "AttValue: \" or ' expected\n";
  330:             break;
  331:         case XML_ERR_LT_IN_ATTRIBUTE:
  332:             errmsg = "Unescaped '<' not allowed in attributes values\n";
  333:             break;
  334:         case XML_ERR_LITERAL_NOT_STARTED:
  335:             errmsg = "SystemLiteral \" or ' expected\n";
  336:             break;
  337:         case XML_ERR_LITERAL_NOT_FINISHED:
  338:             errmsg = "Unfinished System or Public ID \" or ' expected\n";
  339:             break;
  340:         case XML_ERR_MISPLACED_CDATA_END:
  341:             errmsg = "Sequence ']]>' not allowed in content\n";
  342:             break;
  343:         case XML_ERR_URI_REQUIRED:
  344:             errmsg = "SYSTEM or PUBLIC, the URI is missing\n";
  345:             break;
  346:         case XML_ERR_PUBID_REQUIRED:
  347:             errmsg = "PUBLIC, the Public Identifier is missing\n";
  348:             break;
  349:         case XML_ERR_HYPHEN_IN_COMMENT:
  350:             errmsg = "Comment must not contain '--' (double-hyphen)\n";
  351:             break;
  352:         case XML_ERR_PI_NOT_STARTED:
  353:             errmsg = "xmlParsePI : no target name\n";
  354:             break;
  355:         case XML_ERR_RESERVED_XML_NAME:
  356:             errmsg = "Invalid PI name\n";
  357:             break;
  358:         case XML_ERR_NOTATION_NOT_STARTED:
  359:             errmsg = "NOTATION: Name expected here\n";
  360:             break;
  361:         case XML_ERR_NOTATION_NOT_FINISHED:
  362:             errmsg = "'>' required to close NOTATION declaration\n";
  363:             break;
  364:         case XML_ERR_VALUE_REQUIRED:
  365:             errmsg = "Entity value required\n";
  366:             break;
  367:         case XML_ERR_URI_FRAGMENT:
  368:             errmsg = "Fragment not allowed";
  369:             break;
  370:         case XML_ERR_ATTLIST_NOT_STARTED:
  371:             errmsg = "'(' required to start ATTLIST enumeration\n";
  372:             break;
  373:         case XML_ERR_NMTOKEN_REQUIRED:
  374:             errmsg = "NmToken expected in ATTLIST enumeration\n";
  375:             break;
  376:         case XML_ERR_ATTLIST_NOT_FINISHED:
  377:             errmsg = "')' required to finish ATTLIST enumeration\n";
  378:             break;
  379:         case XML_ERR_MIXED_NOT_STARTED:
  380:             errmsg = "MixedContentDecl : '|' or ')*' expected\n";
  381:             break;
  382:         case XML_ERR_PCDATA_REQUIRED:
  383:             errmsg = "MixedContentDecl : '#PCDATA' expected\n";
  384:             break;
  385:         case XML_ERR_ELEMCONTENT_NOT_STARTED:
  386:             errmsg = "ContentDecl : Name or '(' expected\n";
  387:             break;
  388:         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
  389:             errmsg = "ContentDecl : ',' '|' or ')' expected\n";
  390:             break;
  391:         case XML_ERR_PEREF_IN_INT_SUBSET:
  392:             errmsg =
  393:                 "PEReference: forbidden within markup decl in internal subset\n";
  394:             break;
  395:         case XML_ERR_GT_REQUIRED:
  396:             errmsg = "expected '>'\n";
  397:             break;
  398:         case XML_ERR_CONDSEC_INVALID:
  399:             errmsg = "XML conditional section '[' expected\n";
  400:             break;
  401:         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
  402:             errmsg = "Content error in the external subset\n";
  403:             break;
  404:         case XML_ERR_CONDSEC_INVALID_KEYWORD:
  405:             errmsg =
  406:                 "conditional section INCLUDE or IGNORE keyword expected\n";
  407:             break;
  408:         case XML_ERR_CONDSEC_NOT_FINISHED:
  409:             errmsg = "XML conditional section not closed\n";
  410:             break;
  411:         case XML_ERR_XMLDECL_NOT_STARTED:
  412:             errmsg = "Text declaration '<?xml' required\n";
  413:             break;
  414:         case XML_ERR_XMLDECL_NOT_FINISHED:
  415:             errmsg = "parsing XML declaration: '?>' expected\n";
  416:             break;
  417:         case XML_ERR_EXT_ENTITY_STANDALONE:
  418:             errmsg = "external parsed entities cannot be standalone\n";
  419:             break;
  420:         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
  421:             errmsg = "EntityRef: expecting ';'\n";
  422:             break;
  423:         case XML_ERR_DOCTYPE_NOT_FINISHED:
  424:             errmsg = "DOCTYPE improperly terminated\n";
  425:             break;
  426:         case XML_ERR_LTSLASH_REQUIRED:
  427:             errmsg = "EndTag: '</' not found\n";
  428:             break;
  429:         case XML_ERR_EQUAL_REQUIRED:
  430:             errmsg = "expected '='\n";
  431:             break;
  432:         case XML_ERR_STRING_NOT_CLOSED:
  433:             errmsg = "String not closed expecting \" or '\n";
  434:             break;
  435:         case XML_ERR_STRING_NOT_STARTED:
  436:             errmsg = "String not started expecting ' or \"\n";
  437:             break;
  438:         case XML_ERR_ENCODING_NAME:
  439:             errmsg = "Invalid XML encoding name\n";
  440:             break;
  441:         case XML_ERR_STANDALONE_VALUE:
  442:             errmsg = "standalone accepts only 'yes' or 'no'\n";
  443:             break;
  444:         case XML_ERR_DOCUMENT_EMPTY:
  445:             errmsg = "Document is empty\n";
  446:             break;
  447:         case XML_ERR_DOCUMENT_END:
  448:             errmsg = "Extra content at the end of the document\n";
  449:             break;
  450:         case XML_ERR_NOT_WELL_BALANCED:
  451:             errmsg = "chunk is not well balanced\n";
  452:             break;
  453:         case XML_ERR_EXTRA_CONTENT:
  454:             errmsg = "extra content at the end of well balanced chunk\n";
  455:             break;
  456:         case XML_ERR_VERSION_MISSING:
  457:             errmsg = "Malformed declaration expecting version\n";
  458:             break;
  459: #if 0
  460:         case:
  461:             errmsg = "\n";
  462:             break;
  463: #endif
  464:         default:
  465:             errmsg = "Unregistered error message\n";
  466:     }
  467:     if (ctxt != NULL)
  468: 	ctxt->errNo = error;
  469:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
  470:                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
  471:                     info);
  472:     if (ctxt != NULL) {
  473: 	ctxt->wellFormed = 0;
  474: 	if (ctxt->recovery == 0)
  475: 	    ctxt->disableSAX = 1;
  476:     }
  477: }
  478: 
  479: /**
  480:  * xmlFatalErrMsg:
  481:  * @ctxt:  an XML parser context
  482:  * @error:  the error number
  483:  * @msg:  the error message
  484:  *
  485:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  486:  */
  487: static void
  488: xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  489:                const char *msg)
  490: {
  491:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  492:         (ctxt->instate == XML_PARSER_EOF))
  493: 	return;
  494:     if (ctxt != NULL)
  495: 	ctxt->errNo = error;
  496:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
  497:                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
  498:     if (ctxt != NULL) {
  499: 	ctxt->wellFormed = 0;
  500: 	if (ctxt->recovery == 0)
  501: 	    ctxt->disableSAX = 1;
  502:     }
  503: }
  504: 
  505: /**
  506:  * xmlWarningMsg:
  507:  * @ctxt:  an XML parser context
  508:  * @error:  the error number
  509:  * @msg:  the error message
  510:  * @str1:  extra data
  511:  * @str2:  extra data
  512:  *
  513:  * Handle a warning.
  514:  */
  515: static void
  516: xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  517:               const char *msg, const xmlChar *str1, const xmlChar *str2)
  518: {
  519:     xmlStructuredErrorFunc schannel = NULL;
  520: 
  521:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  522:         (ctxt->instate == XML_PARSER_EOF))
  523: 	return;
  524:     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
  525:         (ctxt->sax->initialized == XML_SAX2_MAGIC))
  526:         schannel = ctxt->sax->serror;
  527:     if (ctxt != NULL) {
  528:         __xmlRaiseError(schannel,
  529:                     (ctxt->sax) ? ctxt->sax->warning : NULL,
  530:                     ctxt->userData,
  531:                     ctxt, NULL, XML_FROM_PARSER, error,
  532:                     XML_ERR_WARNING, NULL, 0,
  533: 		    (const char *) str1, (const char *) str2, NULL, 0, 0,
  534: 		    msg, (const char *) str1, (const char *) str2);
  535:     } else {
  536:         __xmlRaiseError(schannel, NULL, NULL,
  537:                     ctxt, NULL, XML_FROM_PARSER, error,
  538:                     XML_ERR_WARNING, NULL, 0,
  539: 		    (const char *) str1, (const char *) str2, NULL, 0, 0,
  540: 		    msg, (const char *) str1, (const char *) str2);
  541:     }
  542: }
  543: 
  544: /**
  545:  * xmlValidityError:
  546:  * @ctxt:  an XML parser context
  547:  * @error:  the error number
  548:  * @msg:  the error message
  549:  * @str1:  extra data
  550:  *
  551:  * Handle a validity error.
  552:  */
  553: static void
  554: xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  555:               const char *msg, const xmlChar *str1, const xmlChar *str2)
  556: {
  557:     xmlStructuredErrorFunc schannel = NULL;
  558: 
  559:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  560:         (ctxt->instate == XML_PARSER_EOF))
  561: 	return;
  562:     if (ctxt != NULL) {
  563: 	ctxt->errNo = error;
  564: 	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
  565: 	    schannel = ctxt->sax->serror;
  566:     }
  567:     if (ctxt != NULL) {
  568:         __xmlRaiseError(schannel,
  569:                     ctxt->vctxt.error, ctxt->vctxt.userData,
  570:                     ctxt, NULL, XML_FROM_DTD, error,
  571:                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
  572: 		    (const char *) str2, NULL, 0, 0,
  573: 		    msg, (const char *) str1, (const char *) str2);
  574: 	ctxt->valid = 0;
  575:     } else {
  576:         __xmlRaiseError(schannel, NULL, NULL,
  577:                     ctxt, NULL, XML_FROM_DTD, error,
  578:                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
  579: 		    (const char *) str2, NULL, 0, 0,
  580: 		    msg, (const char *) str1, (const char *) str2);
  581:     }
  582: }
  583: 
  584: /**
  585:  * xmlFatalErrMsgInt:
  586:  * @ctxt:  an XML parser context
  587:  * @error:  the error number
  588:  * @msg:  the error message
  589:  * @val:  an integer value
  590:  *
  591:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  592:  */
  593: static void
  594: xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  595:                   const char *msg, int val)
  596: {
  597:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  598:         (ctxt->instate == XML_PARSER_EOF))
  599: 	return;
  600:     if (ctxt != NULL)
  601: 	ctxt->errNo = error;
  602:     __xmlRaiseError(NULL, NULL, NULL,
  603:                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
  604:                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
  605:     if (ctxt != NULL) {
  606: 	ctxt->wellFormed = 0;
  607: 	if (ctxt->recovery == 0)
  608: 	    ctxt->disableSAX = 1;
  609:     }
  610: }
  611: 
  612: /**
  613:  * xmlFatalErrMsgStrIntStr:
  614:  * @ctxt:  an XML parser context
  615:  * @error:  the error number
  616:  * @msg:  the error message
  617:  * @str1:  an string info
  618:  * @val:  an integer value
  619:  * @str2:  an string info
  620:  *
  621:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  622:  */
  623: static void
  624: xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  625:                   const char *msg, const xmlChar *str1, int val, 
  626: 		  const xmlChar *str2)
  627: {
  628:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  629:         (ctxt->instate == XML_PARSER_EOF))
  630: 	return;
  631:     if (ctxt != NULL)
  632: 	ctxt->errNo = error;
  633:     __xmlRaiseError(NULL, NULL, NULL,
  634:                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
  635:                     NULL, 0, (const char *) str1, (const char *) str2,
  636: 		    NULL, val, 0, msg, str1, val, str2);
  637:     if (ctxt != NULL) {
  638: 	ctxt->wellFormed = 0;
  639: 	if (ctxt->recovery == 0)
  640: 	    ctxt->disableSAX = 1;
  641:     }
  642: }
  643: 
  644: /**
  645:  * xmlFatalErrMsgStr:
  646:  * @ctxt:  an XML parser context
  647:  * @error:  the error number
  648:  * @msg:  the error message
  649:  * @val:  a string value
  650:  *
  651:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  652:  */
  653: static void
  654: xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  655:                   const char *msg, const xmlChar * val)
  656: {
  657:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  658:         (ctxt->instate == XML_PARSER_EOF))
  659: 	return;
  660:     if (ctxt != NULL)
  661: 	ctxt->errNo = error;
  662:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
  663:                     XML_FROM_PARSER, error, XML_ERR_FATAL,
  664:                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
  665:                     val);
  666:     if (ctxt != NULL) {
  667: 	ctxt->wellFormed = 0;
  668: 	if (ctxt->recovery == 0)
  669: 	    ctxt->disableSAX = 1;
  670:     }
  671: }
  672: 
  673: /**
  674:  * xmlErrMsgStr:
  675:  * @ctxt:  an XML parser context
  676:  * @error:  the error number
  677:  * @msg:  the error message
  678:  * @val:  a string value
  679:  *
  680:  * Handle a non fatal parser error
  681:  */
  682: static void
  683: xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  684:                   const char *msg, const xmlChar * val)
  685: {
  686:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  687:         (ctxt->instate == XML_PARSER_EOF))
  688: 	return;
  689:     if (ctxt != NULL)
  690: 	ctxt->errNo = error;
  691:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
  692:                     XML_FROM_PARSER, error, XML_ERR_ERROR,
  693:                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
  694:                     val);
  695: }
  696: 
  697: /**
  698:  * xmlNsErr:
  699:  * @ctxt:  an XML parser context
  700:  * @error:  the error number
  701:  * @msg:  the message
  702:  * @info1:  extra information string
  703:  * @info2:  extra information string
  704:  *
  705:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  706:  */
  707: static void
  708: xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  709:          const char *msg,
  710:          const xmlChar * info1, const xmlChar * info2,
  711:          const xmlChar * info3)
  712: {
  713:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  714:         (ctxt->instate == XML_PARSER_EOF))
  715: 	return;
  716:     if (ctxt != NULL)
  717: 	ctxt->errNo = error;
  718:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
  719:                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
  720:                     (const char *) info2, (const char *) info3, 0, 0, msg,
  721:                     info1, info2, info3);
  722:     if (ctxt != NULL)
  723: 	ctxt->nsWellFormed = 0;
  724: }
  725: 
  726: /**
  727:  * xmlNsWarn
  728:  * @ctxt:  an XML parser context
  729:  * @error:  the error number
  730:  * @msg:  the message
  731:  * @info1:  extra information string
  732:  * @info2:  extra information string
  733:  *
  734:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  735:  */
  736: static void
  737: xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  738:          const char *msg,
  739:          const xmlChar * info1, const xmlChar * info2,
  740:          const xmlChar * info3)
  741: {
  742:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  743:         (ctxt->instate == XML_PARSER_EOF))
  744: 	return;
  745:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
  746:                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
  747:                     (const char *) info2, (const char *) info3, 0, 0, msg,
  748:                     info1, info2, info3);
  749: }
  750: 
  751: /************************************************************************
  752:  *									*
  753:  * 		Library wide options					*
  754:  *									*
  755:  ************************************************************************/
  756: 
  757: /**
  758:   * xmlHasFeature:
  759:   * @feature: the feature to be examined
  760:   *
  761:   * Examines if the library has been compiled with a given feature.
  762:   *
  763:   * Returns a non-zero value if the feature exist, otherwise zero.
  764:   * Returns zero (0) if the feature does not exist or an unknown
  765:   * unknown feature is requested, non-zero otherwise.
  766:   */
  767: int
  768: xmlHasFeature(xmlFeature feature)
  769: {
  770:     switch (feature) {
  771: 	case XML_WITH_THREAD:
  772: #ifdef LIBXML_THREAD_ENABLED
  773: 	    return(1);
  774: #else
  775: 	    return(0);
  776: #endif
  777:         case XML_WITH_TREE:
  778: #ifdef LIBXML_TREE_ENABLED
  779:             return(1);
  780: #else
  781:             return(0);
  782: #endif
  783:         case XML_WITH_OUTPUT:
  784: #ifdef LIBXML_OUTPUT_ENABLED
  785:             return(1);
  786: #else
  787:             return(0);
  788: #endif
  789:         case XML_WITH_PUSH:
  790: #ifdef LIBXML_PUSH_ENABLED
  791:             return(1);
  792: #else
  793:             return(0);
  794: #endif
  795:         case XML_WITH_READER:
  796: #ifdef LIBXML_READER_ENABLED
  797:             return(1);
  798: #else
  799:             return(0);
  800: #endif
  801:         case XML_WITH_PATTERN:
  802: #ifdef LIBXML_PATTERN_ENABLED
  803:             return(1);
  804: #else
  805:             return(0);
  806: #endif
  807:         case XML_WITH_WRITER:
  808: #ifdef LIBXML_WRITER_ENABLED
  809:             return(1);
  810: #else
  811:             return(0);
  812: #endif
  813:         case XML_WITH_SAX1:
  814: #ifdef LIBXML_SAX1_ENABLED
  815:             return(1);
  816: #else
  817:             return(0);
  818: #endif
  819:         case XML_WITH_FTP:
  820: #ifdef LIBXML_FTP_ENABLED
  821:             return(1);
  822: #else
  823:             return(0);
  824: #endif
  825:         case XML_WITH_HTTP:
  826: #ifdef LIBXML_HTTP_ENABLED
  827:             return(1);
  828: #else
  829:             return(0);
  830: #endif
  831:         case XML_WITH_VALID:
  832: #ifdef LIBXML_VALID_ENABLED
  833:             return(1);
  834: #else
  835:             return(0);
  836: #endif
  837:         case XML_WITH_HTML:
  838: #ifdef LIBXML_HTML_ENABLED
  839:             return(1);
  840: #else
  841:             return(0);
  842: #endif
  843:         case XML_WITH_LEGACY:
  844: #ifdef LIBXML_LEGACY_ENABLED
  845:             return(1);
  846: #else
  847:             return(0);
  848: #endif
  849:         case XML_WITH_C14N:
  850: #ifdef LIBXML_C14N_ENABLED
  851:             return(1);
  852: #else
  853:             return(0);
  854: #endif
  855:         case XML_WITH_CATALOG:
  856: #ifdef LIBXML_CATALOG_ENABLED
  857:             return(1);
  858: #else
  859:             return(0);
  860: #endif
  861:         case XML_WITH_XPATH:
  862: #ifdef LIBXML_XPATH_ENABLED
  863:             return(1);
  864: #else
  865:             return(0);
  866: #endif
  867:         case XML_WITH_XPTR:
  868: #ifdef LIBXML_XPTR_ENABLED
  869:             return(1);
  870: #else
  871:             return(0);
  872: #endif
  873:         case XML_WITH_XINCLUDE:
  874: #ifdef LIBXML_XINCLUDE_ENABLED
  875:             return(1);
  876: #else
  877:             return(0);
  878: #endif
  879:         case XML_WITH_ICONV:
  880: #ifdef LIBXML_ICONV_ENABLED
  881:             return(1);
  882: #else
  883:             return(0);
  884: #endif
  885:         case XML_WITH_ISO8859X:
  886: #ifdef LIBXML_ISO8859X_ENABLED
  887:             return(1);
  888: #else
  889:             return(0);
  890: #endif
  891:         case XML_WITH_UNICODE:
  892: #ifdef LIBXML_UNICODE_ENABLED
  893:             return(1);
  894: #else
  895:             return(0);
  896: #endif
  897:         case XML_WITH_REGEXP:
  898: #ifdef LIBXML_REGEXP_ENABLED
  899:             return(1);
  900: #else
  901:             return(0);
  902: #endif
  903:         case XML_WITH_AUTOMATA:
  904: #ifdef LIBXML_AUTOMATA_ENABLED
  905:             return(1);
  906: #else
  907:             return(0);
  908: #endif
  909:         case XML_WITH_EXPR:
  910: #ifdef LIBXML_EXPR_ENABLED
  911:             return(1);
  912: #else
  913:             return(0);
  914: #endif
  915:         case XML_WITH_SCHEMAS:
  916: #ifdef LIBXML_SCHEMAS_ENABLED
  917:             return(1);
  918: #else
  919:             return(0);
  920: #endif
  921:         case XML_WITH_SCHEMATRON:
  922: #ifdef LIBXML_SCHEMATRON_ENABLED
  923:             return(1);
  924: #else
  925:             return(0);
  926: #endif
  927:         case XML_WITH_MODULES:
  928: #ifdef LIBXML_MODULES_ENABLED
  929:             return(1);
  930: #else
  931:             return(0);
  932: #endif
  933:         case XML_WITH_DEBUG:
  934: #ifdef LIBXML_DEBUG_ENABLED
  935:             return(1);
  936: #else
  937:             return(0);
  938: #endif
  939:         case XML_WITH_DEBUG_MEM:
  940: #ifdef DEBUG_MEMORY_LOCATION
  941:             return(1);
  942: #else
  943:             return(0);
  944: #endif
  945:         case XML_WITH_DEBUG_RUN:
  946: #ifdef LIBXML_DEBUG_RUNTIME
  947:             return(1);
  948: #else
  949:             return(0);
  950: #endif
  951:         case XML_WITH_ZLIB:
  952: #ifdef LIBXML_ZLIB_ENABLED
  953:             return(1);
  954: #else
  955:             return(0);
  956: #endif
  957:         case XML_WITH_ICU:
  958: #ifdef LIBXML_ICU_ENABLED
  959:             return(1);
  960: #else
  961:             return(0);
  962: #endif
  963:         default:
  964: 	    break;
  965:      }
  966:      return(0);
  967: }
  968: 
  969: /************************************************************************
  970:  *									*
  971:  * 		SAX2 defaulted attributes handling			*
  972:  *									*
  973:  ************************************************************************/
  974: 
  975: /**
  976:  * xmlDetectSAX2:
  977:  * @ctxt:  an XML parser context
  978:  *
  979:  * Do the SAX2 detection and specific intialization
  980:  */
  981: static void
  982: xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
  983:     if (ctxt == NULL) return;
  984: #ifdef LIBXML_SAX1_ENABLED
  985:     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
  986:         ((ctxt->sax->startElementNs != NULL) ||
  987:          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
  988: #else
  989:     ctxt->sax2 = 1;
  990: #endif /* LIBXML_SAX1_ENABLED */
  991: 
  992:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
  993:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
  994:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
  995:     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || 
  996:     		(ctxt->str_xml_ns == NULL)) {
  997:         xmlErrMemory(ctxt, NULL);
  998:     }
  999: }
 1000: 
 1001: typedef struct _xmlDefAttrs xmlDefAttrs;
 1002: typedef xmlDefAttrs *xmlDefAttrsPtr;
 1003: struct _xmlDefAttrs {
 1004:     int nbAttrs;	/* number of defaulted attributes on that element */
 1005:     int maxAttrs;       /* the size of the array */
 1006:     const xmlChar *values[5]; /* array of localname/prefix/values/external */
 1007: };
 1008: 
 1009: /**
 1010:  * xmlAttrNormalizeSpace:
 1011:  * @src: the source string
 1012:  * @dst: the target string
 1013:  *
 1014:  * Normalize the space in non CDATA attribute values:
 1015:  * If the attribute type is not CDATA, then the XML processor MUST further
 1016:  * process the normalized attribute value by discarding any leading and
 1017:  * trailing space (#x20) characters, and by replacing sequences of space
 1018:  * (#x20) characters by a single space (#x20) character.
 1019:  * Note that the size of dst need to be at least src, and if one doesn't need
 1020:  * to preserve dst (and it doesn't come from a dictionary or read-only) then
 1021:  * passing src as dst is just fine.
 1022:  *
 1023:  * Returns a pointer to the normalized value (dst) or NULL if no conversion
 1024:  *         is needed.
 1025:  */
 1026: static xmlChar *
 1027: xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
 1028: {
 1029:     if ((src == NULL) || (dst == NULL))
 1030:         return(NULL);
 1031: 
 1032:     while (*src == 0x20) src++;
 1033:     while (*src != 0) {
 1034: 	if (*src == 0x20) {
 1035: 	    while (*src == 0x20) src++;
 1036: 	    if (*src != 0)
 1037: 		*dst++ = 0x20;
 1038: 	} else {
 1039: 	    *dst++ = *src++;
 1040: 	}
 1041:     }
 1042:     *dst = 0;
 1043:     if (dst == src)
 1044:        return(NULL);
 1045:     return(dst);
 1046: }
 1047: 
 1048: /**
 1049:  * xmlAttrNormalizeSpace2:
 1050:  * @src: the source string
 1051:  *
 1052:  * Normalize the space in non CDATA attribute values, a slightly more complex
 1053:  * front end to avoid allocation problems when running on attribute values
 1054:  * coming from the input.
 1055:  *
 1056:  * Returns a pointer to the normalized value (dst) or NULL if no conversion
 1057:  *         is needed.
 1058:  */
 1059: static const xmlChar *
 1060: xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
 1061: {
 1062:     int i;
 1063:     int remove_head = 0;
 1064:     int need_realloc = 0;
 1065:     const xmlChar *cur;
 1066: 
 1067:     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
 1068:         return(NULL);
 1069:     i = *len;
 1070:     if (i <= 0)
 1071:         return(NULL);
 1072: 
 1073:     cur = src;
 1074:     while (*cur == 0x20) {
 1075:         cur++;
 1076: 	remove_head++;
 1077:     }
 1078:     while (*cur != 0) {
 1079: 	if (*cur == 0x20) {
 1080: 	    cur++;
 1081: 	    if ((*cur == 0x20) || (*cur == 0)) {
 1082: 	        need_realloc = 1;
 1083: 		break;
 1084: 	    }
 1085: 	} else
 1086: 	    cur++;
 1087:     }
 1088:     if (need_realloc) {
 1089:         xmlChar *ret;
 1090: 
 1091: 	ret = xmlStrndup(src + remove_head, i - remove_head + 1);
 1092: 	if (ret == NULL) {
 1093: 	    xmlErrMemory(ctxt, NULL);
 1094: 	    return(NULL);
 1095: 	}
 1096: 	xmlAttrNormalizeSpace(ret, ret);
 1097: 	*len = (int) strlen((const char *)ret);
 1098:         return(ret);
 1099:     } else if (remove_head) {
 1100:         *len -= remove_head;
 1101:         memmove(src, src + remove_head, 1 + *len);
 1102: 	return(src);
 1103:     }
 1104:     return(NULL);
 1105: }
 1106: 
 1107: /**
 1108:  * xmlAddDefAttrs:
 1109:  * @ctxt:  an XML parser context
 1110:  * @fullname:  the element fullname
 1111:  * @fullattr:  the attribute fullname
 1112:  * @value:  the attribute value
 1113:  *
 1114:  * Add a defaulted attribute for an element
 1115:  */
 1116: static void
 1117: xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
 1118:                const xmlChar *fullname,
 1119:                const xmlChar *fullattr,
 1120:                const xmlChar *value) {
 1121:     xmlDefAttrsPtr defaults;
 1122:     int len;
 1123:     const xmlChar *name;
 1124:     const xmlChar *prefix;
 1125: 
 1126:     /*
 1127:      * Allows to detect attribute redefinitions
 1128:      */
 1129:     if (ctxt->attsSpecial != NULL) {
 1130:         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
 1131: 	    return;
 1132:     }
 1133: 
 1134:     if (ctxt->attsDefault == NULL) {
 1135:         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
 1136: 	if (ctxt->attsDefault == NULL)
 1137: 	    goto mem_error;
 1138:     }
 1139: 
 1140:     /*
 1141:      * split the element name into prefix:localname , the string found
 1142:      * are within the DTD and then not associated to namespace names.
 1143:      */
 1144:     name = xmlSplitQName3(fullname, &len);
 1145:     if (name == NULL) {
 1146:         name = xmlDictLookup(ctxt->dict, fullname, -1);
 1147: 	prefix = NULL;
 1148:     } else {
 1149:         name = xmlDictLookup(ctxt->dict, name, -1);
 1150: 	prefix = xmlDictLookup(ctxt->dict, fullname, len);
 1151:     }
 1152: 
 1153:     /*
 1154:      * make sure there is some storage
 1155:      */
 1156:     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
 1157:     if (defaults == NULL) {
 1158:         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
 1159: 	                   (4 * 5) * sizeof(const xmlChar *));
 1160: 	if (defaults == NULL)
 1161: 	    goto mem_error;
 1162: 	defaults->nbAttrs = 0;
 1163: 	defaults->maxAttrs = 4;
 1164: 	if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
 1165: 	                        defaults, NULL) < 0) {
 1166: 	    xmlFree(defaults);
 1167: 	    goto mem_error;
 1168: 	}
 1169:     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
 1170:         xmlDefAttrsPtr temp;
 1171: 
 1172:         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
 1173: 		       (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
 1174: 	if (temp == NULL)
 1175: 	    goto mem_error;
 1176: 	defaults = temp;
 1177: 	defaults->maxAttrs *= 2;
 1178: 	if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
 1179: 	                        defaults, NULL) < 0) {
 1180: 	    xmlFree(defaults);
 1181: 	    goto mem_error;
 1182: 	}
 1183:     }
 1184: 
 1185:     /*
 1186:      * Split the element name into prefix:localname , the string found
 1187:      * are within the DTD and hen not associated to namespace names.
 1188:      */
 1189:     name = xmlSplitQName3(fullattr, &len);
 1190:     if (name == NULL) {
 1191:         name = xmlDictLookup(ctxt->dict, fullattr, -1);
 1192: 	prefix = NULL;
 1193:     } else {
 1194:         name = xmlDictLookup(ctxt->dict, name, -1);
 1195: 	prefix = xmlDictLookup(ctxt->dict, fullattr, len);
 1196:     }
 1197: 
 1198:     defaults->values[5 * defaults->nbAttrs] = name;
 1199:     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
 1200:     /* intern the string and precompute the end */
 1201:     len = xmlStrlen(value);
 1202:     value = xmlDictLookup(ctxt->dict, value, len);
 1203:     defaults->values[5 * defaults->nbAttrs + 2] = value;
 1204:     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
 1205:     if (ctxt->external)
 1206:         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
 1207:     else
 1208:         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
 1209:     defaults->nbAttrs++;
 1210: 
 1211:     return;
 1212: 
 1213: mem_error:
 1214:     xmlErrMemory(ctxt, NULL);
 1215:     return;
 1216: }
 1217: 
 1218: /**
 1219:  * xmlAddSpecialAttr:
 1220:  * @ctxt:  an XML parser context
 1221:  * @fullname:  the element fullname
 1222:  * @fullattr:  the attribute fullname
 1223:  * @type:  the attribute type
 1224:  *
 1225:  * Register this attribute type
 1226:  */
 1227: static void
 1228: xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
 1229: 		  const xmlChar *fullname,
 1230: 		  const xmlChar *fullattr,
 1231: 		  int type)
 1232: {
 1233:     if (ctxt->attsSpecial == NULL) {
 1234:         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
 1235: 	if (ctxt->attsSpecial == NULL)
 1236: 	    goto mem_error;
 1237:     }
 1238: 
 1239:     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
 1240:         return;
 1241: 
 1242:     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
 1243:                      (void *) (long) type);
 1244:     return;
 1245: 
 1246: mem_error:
 1247:     xmlErrMemory(ctxt, NULL);
 1248:     return;
 1249: }
 1250: 
 1251: /**
 1252:  * xmlCleanSpecialAttrCallback:
 1253:  *
 1254:  * Removes CDATA attributes from the special attribute table
 1255:  */
 1256: static void
 1257: xmlCleanSpecialAttrCallback(void *payload, void *data,
 1258:                             const xmlChar *fullname, const xmlChar *fullattr,
 1259:                             const xmlChar *unused ATTRIBUTE_UNUSED) {
 1260:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
 1261: 
 1262:     if (((long) payload) == XML_ATTRIBUTE_CDATA) {
 1263:         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
 1264:     }
 1265: }
 1266: 
 1267: /**
 1268:  * xmlCleanSpecialAttr:
 1269:  * @ctxt:  an XML parser context
 1270:  *
 1271:  * Trim the list of attributes defined to remove all those of type
 1272:  * CDATA as they are not special. This call should be done when finishing
 1273:  * to parse the DTD and before starting to parse the document root.
 1274:  */
 1275: static void
 1276: xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
 1277: {
 1278:     if (ctxt->attsSpecial == NULL)
 1279:         return;
 1280: 
 1281:     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
 1282: 
 1283:     if (xmlHashSize(ctxt->attsSpecial) == 0) {
 1284:         xmlHashFree(ctxt->attsSpecial, NULL);
 1285:         ctxt->attsSpecial = NULL;
 1286:     }
 1287:     return;
 1288: }
 1289: 
 1290: /**
 1291:  * xmlCheckLanguageID:
 1292:  * @lang:  pointer to the string value
 1293:  *
 1294:  * Checks that the value conforms to the LanguageID production:
 1295:  *
 1296:  * NOTE: this is somewhat deprecated, those productions were removed from
 1297:  *       the XML Second edition.
 1298:  *
 1299:  * [33] LanguageID ::= Langcode ('-' Subcode)*
 1300:  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
 1301:  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
 1302:  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
 1303:  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
 1304:  * [38] Subcode ::= ([a-z] | [A-Z])+
 1305:  *
 1306:  * The current REC reference the sucessors of RFC 1766, currently 5646
 1307:  *
 1308:  * http://www.rfc-editor.org/rfc/rfc5646.txt
 1309:  * langtag       = language
 1310:  *                 ["-" script]
 1311:  *                 ["-" region]
 1312:  *                 *("-" variant)
 1313:  *                 *("-" extension)
 1314:  *                 ["-" privateuse]
 1315:  * language      = 2*3ALPHA            ; shortest ISO 639 code
 1316:  *                 ["-" extlang]       ; sometimes followed by
 1317:  *                                     ; extended language subtags
 1318:  *               / 4ALPHA              ; or reserved for future use
 1319:  *               / 5*8ALPHA            ; or registered language subtag
 1320:  *
 1321:  * extlang       = 3ALPHA              ; selected ISO 639 codes
 1322:  *                 *2("-" 3ALPHA)      ; permanently reserved
 1323:  *
 1324:  * script        = 4ALPHA              ; ISO 15924 code
 1325:  *
 1326:  * region        = 2ALPHA              ; ISO 3166-1 code
 1327:  *               / 3DIGIT              ; UN M.49 code
 1328:  *
 1329:  * variant       = 5*8alphanum         ; registered variants
 1330:  *               / (DIGIT 3alphanum)
 1331:  *
 1332:  * extension     = singleton 1*("-" (2*8alphanum))
 1333:  *
 1334:  *                                     ; Single alphanumerics
 1335:  *                                     ; "x" reserved for private use
 1336:  * singleton     = DIGIT               ; 0 - 9
 1337:  *               / %x41-57             ; A - W
 1338:  *               / %x59-5A             ; Y - Z
 1339:  *               / %x61-77             ; a - w
 1340:  *               / %x79-7A             ; y - z
 1341:  *
 1342:  * it sounds right to still allow Irregular i-xxx IANA and user codes too
 1343:  * The parser below doesn't try to cope with extension or privateuse
 1344:  * that could be added but that's not interoperable anyway
 1345:  *
 1346:  * Returns 1 if correct 0 otherwise
 1347:  **/
 1348: int
 1349: xmlCheckLanguageID(const xmlChar * lang)
 1350: {
 1351:     const xmlChar *cur = lang, *nxt;
 1352: 
 1353:     if (cur == NULL)
 1354:         return (0);
 1355:     if (((cur[0] == 'i') && (cur[1] == '-')) ||
 1356:         ((cur[0] == 'I') && (cur[1] == '-')) ||
 1357:         ((cur[0] == 'x') && (cur[1] == '-')) ||
 1358:         ((cur[0] == 'X') && (cur[1] == '-'))) {
 1359:         /*
 1360:          * Still allow IANA code and user code which were coming
 1361:          * from the previous version of the XML-1.0 specification
 1362:          * it's deprecated but we should not fail
 1363:          */
 1364:         cur += 2;
 1365:         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
 1366:                ((cur[0] >= 'a') && (cur[0] <= 'z')))
 1367:             cur++;
 1368:         return(cur[0] == 0);
 1369:     }
 1370:     nxt = cur;
 1371:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
 1372:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
 1373:            nxt++;
 1374:     if (nxt - cur >= 4) {
 1375:         /*
 1376:          * Reserved
 1377:          */
 1378:         if ((nxt - cur > 8) || (nxt[0] != 0))
 1379:             return(0);
 1380:         return(1);
 1381:     }
 1382:     if (nxt - cur < 2)
 1383:         return(0);
 1384:     /* we got an ISO 639 code */
 1385:     if (nxt[0] == 0)
 1386:         return(1);
 1387:     if (nxt[0] != '-')
 1388:         return(0);
 1389: 
 1390:     nxt++;
 1391:     cur = nxt;
 1392:     /* now we can have extlang or script or region or variant */
 1393:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
 1394:         goto region_m49;
 1395: 
 1396:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
 1397:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
 1398:            nxt++;
 1399:     if (nxt - cur == 4)
 1400:         goto script;
 1401:     if (nxt - cur == 2)
 1402:         goto region;
 1403:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
 1404:         goto variant;
 1405:     if (nxt - cur != 3)
 1406:         return(0);
 1407:     /* we parsed an extlang */
 1408:     if (nxt[0] == 0)
 1409:         return(1);
 1410:     if (nxt[0] != '-')
 1411:         return(0);
 1412: 
 1413:     nxt++;
 1414:     cur = nxt;
 1415:     /* now we can have script or region or variant */
 1416:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
 1417:         goto region_m49;
 1418: 
 1419:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
 1420:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
 1421:            nxt++;
 1422:     if (nxt - cur == 2)
 1423:         goto region;
 1424:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
 1425:         goto variant;
 1426:     if (nxt - cur != 4)
 1427:         return(0);
 1428:     /* we parsed a script */
 1429: script:
 1430:     if (nxt[0] == 0)
 1431:         return(1);
 1432:     if (nxt[0] != '-')
 1433:         return(0);
 1434: 
 1435:     nxt++;
 1436:     cur = nxt;
 1437:     /* now we can have region or variant */
 1438:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
 1439:         goto region_m49;
 1440: 
 1441:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
 1442:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
 1443:            nxt++;
 1444: 
 1445:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
 1446:         goto variant;
 1447:     if (nxt - cur != 2)
 1448:         return(0);
 1449:     /* we parsed a region */
 1450: region:
 1451:     if (nxt[0] == 0)
 1452:         return(1);
 1453:     if (nxt[0] != '-')
 1454:         return(0);
 1455: 
 1456:     nxt++;
 1457:     cur = nxt;
 1458:     /* now we can just have a variant */
 1459:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
 1460:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
 1461:            nxt++;
 1462: 
 1463:     if ((nxt - cur < 5) || (nxt - cur > 8))
 1464:         return(0);
 1465: 
 1466:     /* we parsed a variant */
 1467: variant:
 1468:     if (nxt[0] == 0)
 1469:         return(1);
 1470:     if (nxt[0] != '-')
 1471:         return(0);
 1472:     /* extensions and private use subtags not checked */
 1473:     return (1);
 1474: 
 1475: region_m49:
 1476:     if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
 1477:         ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
 1478:         nxt += 3;
 1479:         goto region;
 1480:     }
 1481:     return(0);
 1482: }
 1483: 
 1484: /************************************************************************
 1485:  *									*
 1486:  *		Parser stacks related functions and macros		*
 1487:  *									*
 1488:  ************************************************************************/
 1489: 
 1490: static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
 1491:                                             const xmlChar ** str);
 1492: 
 1493: #ifdef SAX2
 1494: /**
 1495:  * nsPush:
 1496:  * @ctxt:  an XML parser context
 1497:  * @prefix:  the namespace prefix or NULL
 1498:  * @URL:  the namespace name
 1499:  *
 1500:  * Pushes a new parser namespace on top of the ns stack
 1501:  *
 1502:  * Returns -1 in case of error, -2 if the namespace should be discarded
 1503:  *	   and the index in the stack otherwise.
 1504:  */
 1505: static int
 1506: nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
 1507: {
 1508:     if (ctxt->options & XML_PARSE_NSCLEAN) {
 1509:         int i;
 1510: 	for (i = 0;i < ctxt->nsNr;i += 2) {
 1511: 	    if (ctxt->nsTab[i] == prefix) {
 1512: 		/* in scope */
 1513: 	        if (ctxt->nsTab[i + 1] == URL)
 1514: 		    return(-2);
 1515: 		/* out of scope keep it */
 1516: 		break;
 1517: 	    }
 1518: 	}
 1519:     }
 1520:     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
 1521: 	ctxt->nsMax = 10;
 1522: 	ctxt->nsNr = 0;
 1523: 	ctxt->nsTab = (const xmlChar **)
 1524: 	              xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
 1525: 	if (ctxt->nsTab == NULL) {
 1526: 	    xmlErrMemory(ctxt, NULL);
 1527: 	    ctxt->nsMax = 0;
 1528:             return (-1);
 1529: 	}
 1530:     } else if (ctxt->nsNr >= ctxt->nsMax) {
 1531:         const xmlChar ** tmp;
 1532:         ctxt->nsMax *= 2;
 1533:         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
 1534: 				    ctxt->nsMax * sizeof(ctxt->nsTab[0]));
 1535:         if (tmp == NULL) {
 1536:             xmlErrMemory(ctxt, NULL);
 1537: 	    ctxt->nsMax /= 2;
 1538:             return (-1);
 1539:         }
 1540: 	ctxt->nsTab = tmp;
 1541:     }
 1542:     ctxt->nsTab[ctxt->nsNr++] = prefix;
 1543:     ctxt->nsTab[ctxt->nsNr++] = URL;
 1544:     return (ctxt->nsNr);
 1545: }
 1546: /**
 1547:  * nsPop:
 1548:  * @ctxt: an XML parser context
 1549:  * @nr:  the number to pop
 1550:  *
 1551:  * Pops the top @nr parser prefix/namespace from the ns stack
 1552:  *
 1553:  * Returns the number of namespaces removed
 1554:  */
 1555: static int
 1556: nsPop(xmlParserCtxtPtr ctxt, int nr)
 1557: {
 1558:     int i;
 1559: 
 1560:     if (ctxt->nsTab == NULL) return(0);
 1561:     if (ctxt->nsNr < nr) {
 1562:         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
 1563:         nr = ctxt->nsNr;
 1564:     }
 1565:     if (ctxt->nsNr <= 0)
 1566:         return (0);
 1567: 
 1568:     for (i = 0;i < nr;i++) {
 1569:          ctxt->nsNr--;
 1570: 	 ctxt->nsTab[ctxt->nsNr] = NULL;
 1571:     }
 1572:     return(nr);
 1573: }
 1574: #endif
 1575: 
 1576: static int
 1577: xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
 1578:     const xmlChar **atts;
 1579:     int *attallocs;
 1580:     int maxatts;
 1581: 
 1582:     if (ctxt->atts == NULL) {
 1583: 	maxatts = 55; /* allow for 10 attrs by default */
 1584: 	atts = (const xmlChar **)
 1585: 	       xmlMalloc(maxatts * sizeof(xmlChar *));
 1586: 	if (atts == NULL) goto mem_error;
 1587: 	ctxt->atts = atts;
 1588: 	attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
 1589: 	if (attallocs == NULL) goto mem_error;
 1590: 	ctxt->attallocs = attallocs;
 1591: 	ctxt->maxatts = maxatts;
 1592:     } else if (nr + 5 > ctxt->maxatts) {
 1593: 	maxatts = (nr + 5) * 2;
 1594: 	atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
 1595: 				     maxatts * sizeof(const xmlChar *));
 1596: 	if (atts == NULL) goto mem_error;
 1597: 	ctxt->atts = atts;
 1598: 	attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
 1599: 	                             (maxatts / 5) * sizeof(int));
 1600: 	if (attallocs == NULL) goto mem_error;
 1601: 	ctxt->attallocs = attallocs;
 1602: 	ctxt->maxatts = maxatts;
 1603:     }
 1604:     return(ctxt->maxatts);
 1605: mem_error:
 1606:     xmlErrMemory(ctxt, NULL);
 1607:     return(-1);
 1608: }
 1609: 
 1610: /**
 1611:  * inputPush:
 1612:  * @ctxt:  an XML parser context
 1613:  * @value:  the parser input
 1614:  *
 1615:  * Pushes a new parser input on top of the input stack
 1616:  *
 1617:  * Returns -1 in case of error, the index in the stack otherwise
 1618:  */
 1619: int
 1620: inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
 1621: {
 1622:     if ((ctxt == NULL) || (value == NULL))
 1623:         return(-1);
 1624:     if (ctxt->inputNr >= ctxt->inputMax) {
 1625:         ctxt->inputMax *= 2;
 1626:         ctxt->inputTab =
 1627:             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
 1628:                                              ctxt->inputMax *
 1629:                                              sizeof(ctxt->inputTab[0]));
 1630:         if (ctxt->inputTab == NULL) {
 1631:             xmlErrMemory(ctxt, NULL);
 1632: 	    xmlFreeInputStream(value);
 1633: 	    ctxt->inputMax /= 2;
 1634: 	    value = NULL;
 1635:             return (-1);
 1636:         }
 1637:     }
 1638:     ctxt->inputTab[ctxt->inputNr] = value;
 1639:     ctxt->input = value;
 1640:     return (ctxt->inputNr++);
 1641: }
 1642: /**
 1643:  * inputPop:
 1644:  * @ctxt: an XML parser context
 1645:  *
 1646:  * Pops the top parser input from the input stack
 1647:  *
 1648:  * Returns the input just removed
 1649:  */
 1650: xmlParserInputPtr
 1651: inputPop(xmlParserCtxtPtr ctxt)
 1652: {
 1653:     xmlParserInputPtr ret;
 1654: 
 1655:     if (ctxt == NULL)
 1656:         return(NULL);
 1657:     if (ctxt->inputNr <= 0)
 1658:         return (NULL);
 1659:     ctxt->inputNr--;
 1660:     if (ctxt->inputNr > 0)
 1661:         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
 1662:     else
 1663:         ctxt->input = NULL;
 1664:     ret = ctxt->inputTab[ctxt->inputNr];
 1665:     ctxt->inputTab[ctxt->inputNr] = NULL;
 1666:     return (ret);
 1667: }
 1668: /**
 1669:  * nodePush:
 1670:  * @ctxt:  an XML parser context
 1671:  * @value:  the element node
 1672:  *
 1673:  * Pushes a new element node on top of the node stack
 1674:  *
 1675:  * Returns -1 in case of error, the index in the stack otherwise
 1676:  */
 1677: int
 1678: nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
 1679: {
 1680:     if (ctxt == NULL) return(0);
 1681:     if (ctxt->nodeNr >= ctxt->nodeMax) {
 1682:         xmlNodePtr *tmp;
 1683: 
 1684: 	tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
 1685:                                       ctxt->nodeMax * 2 *
 1686:                                       sizeof(ctxt->nodeTab[0]));
 1687:         if (tmp == NULL) {
 1688:             xmlErrMemory(ctxt, NULL);
 1689:             return (-1);
 1690:         }
 1691:         ctxt->nodeTab = tmp;
 1692: 	ctxt->nodeMax *= 2;
 1693:     }
 1694:     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
 1695:         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
 1696: 	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
 1697: 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
 1698: 			  xmlParserMaxDepth);
 1699: 	ctxt->instate = XML_PARSER_EOF;
 1700: 	return(-1);
 1701:     }
 1702:     ctxt->nodeTab[ctxt->nodeNr] = value;
 1703:     ctxt->node = value;
 1704:     return (ctxt->nodeNr++);
 1705: }
 1706: 
 1707: /**
 1708:  * nodePop:
 1709:  * @ctxt: an XML parser context
 1710:  *
 1711:  * Pops the top element node from the node stack
 1712:  *
 1713:  * Returns the node just removed
 1714:  */
 1715: xmlNodePtr
 1716: nodePop(xmlParserCtxtPtr ctxt)
 1717: {
 1718:     xmlNodePtr ret;
 1719: 
 1720:     if (ctxt == NULL) return(NULL);
 1721:     if (ctxt->nodeNr <= 0)
 1722:         return (NULL);
 1723:     ctxt->nodeNr--;
 1724:     if (ctxt->nodeNr > 0)
 1725:         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
 1726:     else
 1727:         ctxt->node = NULL;
 1728:     ret = ctxt->nodeTab[ctxt->nodeNr];
 1729:     ctxt->nodeTab[ctxt->nodeNr] = NULL;
 1730:     return (ret);
 1731: }
 1732: 
 1733: #ifdef LIBXML_PUSH_ENABLED
 1734: /**
 1735:  * nameNsPush:
 1736:  * @ctxt:  an XML parser context
 1737:  * @value:  the element name
 1738:  * @prefix:  the element prefix
 1739:  * @URI:  the element namespace name
 1740:  *
 1741:  * Pushes a new element name/prefix/URL on top of the name stack
 1742:  *
 1743:  * Returns -1 in case of error, the index in the stack otherwise
 1744:  */
 1745: static int
 1746: nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
 1747:            const xmlChar *prefix, const xmlChar *URI, int nsNr)
 1748: {
 1749:     if (ctxt->nameNr >= ctxt->nameMax) {
 1750:         const xmlChar * *tmp;
 1751:         void **tmp2;
 1752:         ctxt->nameMax *= 2;
 1753:         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
 1754:                                     ctxt->nameMax *
 1755:                                     sizeof(ctxt->nameTab[0]));
 1756:         if (tmp == NULL) {
 1757: 	    ctxt->nameMax /= 2;
 1758: 	    goto mem_error;
 1759:         }
 1760: 	ctxt->nameTab = tmp;
 1761:         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
 1762:                                     ctxt->nameMax * 3 *
 1763:                                     sizeof(ctxt->pushTab[0]));
 1764:         if (tmp2 == NULL) {
 1765: 	    ctxt->nameMax /= 2;
 1766: 	    goto mem_error;
 1767:         }
 1768: 	ctxt->pushTab = tmp2;
 1769:     }
 1770:     ctxt->nameTab[ctxt->nameNr] = value;
 1771:     ctxt->name = value;
 1772:     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
 1773:     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
 1774:     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
 1775:     return (ctxt->nameNr++);
 1776: mem_error:
 1777:     xmlErrMemory(ctxt, NULL);
 1778:     return (-1);
 1779: }
 1780: /**
 1781:  * nameNsPop:
 1782:  * @ctxt: an XML parser context
 1783:  *
 1784:  * Pops the top element/prefix/URI name from the name stack
 1785:  *
 1786:  * Returns the name just removed
 1787:  */
 1788: static const xmlChar *
 1789: nameNsPop(xmlParserCtxtPtr ctxt)
 1790: {
 1791:     const xmlChar *ret;
 1792: 
 1793:     if (ctxt->nameNr <= 0)
 1794:         return (NULL);
 1795:     ctxt->nameNr--;
 1796:     if (ctxt->nameNr > 0)
 1797:         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
 1798:     else
 1799:         ctxt->name = NULL;
 1800:     ret = ctxt->nameTab[ctxt->nameNr];
 1801:     ctxt->nameTab[ctxt->nameNr] = NULL;
 1802:     return (ret);
 1803: }
 1804: #endif /* LIBXML_PUSH_ENABLED */
 1805: 
 1806: /**
 1807:  * namePush:
 1808:  * @ctxt:  an XML parser context
 1809:  * @value:  the element name
 1810:  *
 1811:  * Pushes a new element name on top of the name stack
 1812:  *
 1813:  * Returns -1 in case of error, the index in the stack otherwise
 1814:  */
 1815: int
 1816: namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
 1817: {
 1818:     if (ctxt == NULL) return (-1);
 1819: 
 1820:     if (ctxt->nameNr >= ctxt->nameMax) {
 1821:         const xmlChar * *tmp;
 1822:         ctxt->nameMax *= 2;
 1823:         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
 1824:                                     ctxt->nameMax *
 1825:                                     sizeof(ctxt->nameTab[0]));
 1826:         if (tmp == NULL) {
 1827: 	    ctxt->nameMax /= 2;
 1828: 	    goto mem_error;
 1829:         }
 1830: 	ctxt->nameTab = tmp;
 1831:     }
 1832:     ctxt->nameTab[ctxt->nameNr] = value;
 1833:     ctxt->name = value;
 1834:     return (ctxt->nameNr++);
 1835: mem_error:
 1836:     xmlErrMemory(ctxt, NULL);
 1837:     return (-1);
 1838: }
 1839: /**
 1840:  * namePop:
 1841:  * @ctxt: an XML parser context
 1842:  *
 1843:  * Pops the top element name from the name stack
 1844:  *
 1845:  * Returns the name just removed
 1846:  */
 1847: const xmlChar *
 1848: namePop(xmlParserCtxtPtr ctxt)
 1849: {
 1850:     const xmlChar *ret;
 1851: 
 1852:     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
 1853:         return (NULL);
 1854:     ctxt->nameNr--;
 1855:     if (ctxt->nameNr > 0)
 1856:         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
 1857:     else
 1858:         ctxt->name = NULL;
 1859:     ret = ctxt->nameTab[ctxt->nameNr];
 1860:     ctxt->nameTab[ctxt->nameNr] = NULL;
 1861:     return (ret);
 1862: }
 1863: 
 1864: static int spacePush(xmlParserCtxtPtr ctxt, int val) {
 1865:     if (ctxt->spaceNr >= ctxt->spaceMax) {
 1866:         int *tmp;
 1867: 
 1868: 	ctxt->spaceMax *= 2;
 1869:         tmp = (int *) xmlRealloc(ctxt->spaceTab,
 1870: 	                         ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
 1871:         if (tmp == NULL) {
 1872: 	    xmlErrMemory(ctxt, NULL);
 1873: 	    ctxt->spaceMax /=2;
 1874: 	    return(-1);
 1875: 	}
 1876: 	ctxt->spaceTab = tmp;
 1877:     }
 1878:     ctxt->spaceTab[ctxt->spaceNr] = val;
 1879:     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
 1880:     return(ctxt->spaceNr++);
 1881: }
 1882: 
 1883: static int spacePop(xmlParserCtxtPtr ctxt) {
 1884:     int ret;
 1885:     if (ctxt->spaceNr <= 0) return(0);
 1886:     ctxt->spaceNr--;
 1887:     if (ctxt->spaceNr > 0)
 1888: 	ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
 1889:     else
 1890:         ctxt->space = &ctxt->spaceTab[0];
 1891:     ret = ctxt->spaceTab[ctxt->spaceNr];
 1892:     ctxt->spaceTab[ctxt->spaceNr] = -1;
 1893:     return(ret);
 1894: }
 1895: 
 1896: /*
 1897:  * Macros for accessing the content. Those should be used only by the parser,
 1898:  * and not exported.
 1899:  *
 1900:  * Dirty macros, i.e. one often need to make assumption on the context to
 1901:  * use them
 1902:  *
 1903:  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
 1904:  *           To be used with extreme caution since operations consuming
 1905:  *           characters may move the input buffer to a different location !
 1906:  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
 1907:  *           This should be used internally by the parser
 1908:  *           only to compare to ASCII values otherwise it would break when
 1909:  *           running with UTF-8 encoding.
 1910:  *   RAW     same as CUR but in the input buffer, bypass any token
 1911:  *           extraction that may have been done
 1912:  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
 1913:  *           to compare on ASCII based substring.
 1914:  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
 1915:  *           strings without newlines within the parser.
 1916:  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII 
 1917:  *           defined char within the parser.
 1918:  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
 1919:  *
 1920:  *   NEXT    Skip to the next character, this does the proper decoding
 1921:  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
 1922:  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
 1923:  *   CUR_CHAR(l) returns the current unicode character (int), set l
 1924:  *           to the number of xmlChars used for the encoding [0-5].
 1925:  *   CUR_SCHAR  same but operate on a string instead of the context
 1926:  *   COPY_BUF  copy the current unicode char to the target buffer, increment
 1927:  *            the index
 1928:  *   GROW, SHRINK  handling of input buffers
 1929:  */
 1930: 
 1931: #define RAW (*ctxt->input->cur)
 1932: #define CUR (*ctxt->input->cur)
 1933: #define NXT(val) ctxt->input->cur[(val)]
 1934: #define CUR_PTR ctxt->input->cur
 1935: 
 1936: #define CMP4( s, c1, c2, c3, c4 ) \
 1937:   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
 1938:     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
 1939: #define CMP5( s, c1, c2, c3, c4, c5 ) \
 1940:   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
 1941: #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
 1942:   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
 1943: #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
 1944:   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
 1945: #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
 1946:   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
 1947: #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
 1948:   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
 1949:     ((unsigned char *) s)[ 8 ] == c9 )
 1950: #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
 1951:   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
 1952:     ((unsigned char *) s)[ 9 ] == c10 )
 1953: 
 1954: #define SKIP(val) do {							\
 1955:     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);			\
 1956:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
 1957:     if ((*ctxt->input->cur == 0) &&					\
 1958:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
 1959: 	    xmlPopInput(ctxt);						\
 1960:   } while (0)
 1961: 
 1962: #define SKIPL(val) do {							\
 1963:     int skipl;								\
 1964:     for(skipl=0; skipl<val; skipl++) {					\
 1965:     	if (*(ctxt->input->cur) == '\n') {				\
 1966: 	ctxt->input->line++; ctxt->input->col = 1;			\
 1967:     	} else ctxt->input->col++;					\
 1968:     	ctxt->nbChars++;						\
 1969: 	ctxt->input->cur++;						\
 1970:     }									\
 1971:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
 1972:     if ((*ctxt->input->cur == 0) &&					\
 1973:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\
 1974: 	    xmlPopInput(ctxt);						\
 1975:   } while (0)
 1976: 
 1977: #define SHRINK if ((ctxt->progressive == 0) &&				\
 1978: 		   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
 1979: 		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
 1980: 	xmlSHRINK (ctxt);
 1981: 
 1982: static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
 1983:     xmlParserInputShrink(ctxt->input);
 1984:     if ((*ctxt->input->cur == 0) &&
 1985:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
 1986: 	    xmlPopInput(ctxt);
 1987:   }
 1988: 
 1989: #define GROW if ((ctxt->progressive == 0) &&				\
 1990: 		 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))	\
 1991: 	xmlGROW (ctxt);
 1992: 
 1993: static void xmlGROW (xmlParserCtxtPtr ctxt) {
 1994:     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
 1995:     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
 1996:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
 1997: 	    xmlPopInput(ctxt);
 1998: }
 1999: 
 2000: #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
 2001: 
 2002: #define NEXT xmlNextChar(ctxt)
 2003: 
 2004: #define NEXT1 {								\
 2005: 	ctxt->input->col++;						\
 2006: 	ctxt->input->cur++;						\
 2007: 	ctxt->nbChars++;						\
 2008: 	if (*ctxt->input->cur == 0)					\
 2009: 	    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);		\
 2010:     }
 2011: 
 2012: #define NEXTL(l) do {							\
 2013:     if (*(ctxt->input->cur) == '\n') {					\
 2014: 	ctxt->input->line++; ctxt->input->col = 1;			\
 2015:     } else ctxt->input->col++;						\
 2016:     ctxt->input->cur += l;				\
 2017:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
 2018:   } while (0)
 2019: 
 2020: #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
 2021: #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
 2022: 
 2023: #define COPY_BUF(l,b,i,v)						\
 2024:     if (l == 1) b[i++] = (xmlChar) v;					\
 2025:     else i += xmlCopyCharMultiByte(&b[i],v)
 2026: 
 2027: /**
 2028:  * xmlSkipBlankChars:
 2029:  * @ctxt:  the XML parser context
 2030:  *
 2031:  * skip all blanks character found at that point in the input streams.
 2032:  * It pops up finished entities in the process if allowable at that point.
 2033:  *
 2034:  * Returns the number of space chars skipped
 2035:  */
 2036: 
 2037: int
 2038: xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
 2039:     int res = 0;
 2040: 
 2041:     /*
 2042:      * It's Okay to use CUR/NEXT here since all the blanks are on
 2043:      * the ASCII range.
 2044:      */
 2045:     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
 2046: 	const xmlChar *cur;
 2047: 	/*
 2048: 	 * if we are in the document content, go really fast
 2049: 	 */
 2050: 	cur = ctxt->input->cur;
 2051: 	while (IS_BLANK_CH(*cur)) {
 2052: 	    if (*cur == '\n') {
 2053: 		ctxt->input->line++; ctxt->input->col = 1;
 2054: 	    }
 2055: 	    cur++;
 2056: 	    res++;
 2057: 	    if (*cur == 0) {
 2058: 		ctxt->input->cur = cur;
 2059: 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
 2060: 		cur = ctxt->input->cur;
 2061: 	    }
 2062: 	}
 2063: 	ctxt->input->cur = cur;
 2064:     } else {
 2065: 	int cur;
 2066: 	do {
 2067: 	    cur = CUR;
 2068: 	    while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
 2069: 		NEXT;
 2070: 		cur = CUR;
 2071: 		res++;
 2072: 	    }
 2073: 	    while ((cur == 0) && (ctxt->inputNr > 1) &&
 2074: 		   (ctxt->instate != XML_PARSER_COMMENT)) {
 2075: 		xmlPopInput(ctxt);
 2076: 		cur = CUR;
 2077: 	    }
 2078: 	    /*
 2079: 	     * Need to handle support of entities branching here
 2080: 	     */
 2081: 	    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
 2082: 	} while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
 2083:     }
 2084:     return(res);
 2085: }
 2086: 
 2087: /************************************************************************
 2088:  *									*
 2089:  *		Commodity functions to handle entities			*
 2090:  *									*
 2091:  ************************************************************************/
 2092: 
 2093: /**
 2094:  * xmlPopInput:
 2095:  * @ctxt:  an XML parser context
 2096:  *
 2097:  * xmlPopInput: the current input pointed by ctxt->input came to an end
 2098:  *          pop it and return the next char.
 2099:  *
 2100:  * Returns the current xmlChar in the parser context
 2101:  */
 2102: xmlChar
 2103: xmlPopInput(xmlParserCtxtPtr ctxt) {
 2104:     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
 2105:     if (xmlParserDebugEntities)
 2106: 	xmlGenericError(xmlGenericErrorContext,
 2107: 		"Popping input %d\n", ctxt->inputNr);
 2108:     xmlFreeInputStream(inputPop(ctxt));
 2109:     if ((*ctxt->input->cur == 0) &&
 2110:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
 2111: 	    return(xmlPopInput(ctxt));
 2112:     return(CUR);
 2113: }
 2114: 
 2115: /**
 2116:  * xmlPushInput:
 2117:  * @ctxt:  an XML parser context
 2118:  * @input:  an XML parser input fragment (entity, XML fragment ...).
 2119:  *
 2120:  * xmlPushInput: switch to a new input stream which is stacked on top
 2121:  *               of the previous one(s).
 2122:  * Returns -1 in case of error or the index in the input stack
 2123:  */
 2124: int
 2125: xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
 2126:     int ret;
 2127:     if (input == NULL) return(-1);
 2128: 
 2129:     if (xmlParserDebugEntities) {
 2130: 	if ((ctxt->input != NULL) && (ctxt->input->filename))
 2131: 	    xmlGenericError(xmlGenericErrorContext,
 2132: 		    "%s(%d): ", ctxt->input->filename,
 2133: 		    ctxt->input->line);
 2134: 	xmlGenericError(xmlGenericErrorContext,
 2135: 		"Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
 2136:     }
 2137:     ret = inputPush(ctxt, input);
 2138:     GROW;
 2139:     return(ret);
 2140: }
 2141: 
 2142: /**
 2143:  * xmlParseCharRef:
 2144:  * @ctxt:  an XML parser context
 2145:  *
 2146:  * parse Reference declarations
 2147:  *
 2148:  * [66] CharRef ::= '&#' [0-9]+ ';' |
 2149:  *                  '&#x' [0-9a-fA-F]+ ';'
 2150:  *
 2151:  * [ WFC: Legal Character ]
 2152:  * Characters referred to using character references must match the
 2153:  * production for Char. 
 2154:  *
 2155:  * Returns the value parsed (as an int), 0 in case of error
 2156:  */
 2157: int
 2158: xmlParseCharRef(xmlParserCtxtPtr ctxt) {
 2159:     unsigned int val = 0;
 2160:     int count = 0;
 2161:     unsigned int outofrange = 0;
 2162: 
 2163:     /*
 2164:      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
 2165:      */
 2166:     if ((RAW == '&') && (NXT(1) == '#') &&
 2167:         (NXT(2) == 'x')) {
 2168: 	SKIP(3);
 2169: 	GROW;
 2170: 	while (RAW != ';') { /* loop blocked by count */
 2171: 	    if (count++ > 20) {
 2172: 		count = 0;
 2173: 		GROW;
 2174: 	    }
 2175: 	    if ((RAW >= '0') && (RAW <= '9')) 
 2176: 	        val = val * 16 + (CUR - '0');
 2177: 	    else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
 2178: 	        val = val * 16 + (CUR - 'a') + 10;
 2179: 	    else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
 2180: 	        val = val * 16 + (CUR - 'A') + 10;
 2181: 	    else {
 2182: 		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
 2183: 		val = 0;
 2184: 		break;
 2185: 	    }
 2186: 	    if (val > 0x10FFFF)
 2187: 	        outofrange = val;
 2188: 
 2189: 	    NEXT;
 2190: 	    count++;
 2191: 	}
 2192: 	if (RAW == ';') {
 2193: 	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */
 2194: 	    ctxt->input->col++;
 2195: 	    ctxt->nbChars ++;
 2196: 	    ctxt->input->cur++;
 2197: 	}
 2198:     } else if  ((RAW == '&') && (NXT(1) == '#')) {
 2199: 	SKIP(2);
 2200: 	GROW;
 2201: 	while (RAW != ';') { /* loop blocked by count */
 2202: 	    if (count++ > 20) {
 2203: 		count = 0;
 2204: 		GROW;
 2205: 	    }
 2206: 	    if ((RAW >= '0') && (RAW <= '9')) 
 2207: 	        val = val * 10 + (CUR - '0');
 2208: 	    else {
 2209: 		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
 2210: 		val = 0;
 2211: 		break;
 2212: 	    }
 2213: 	    if (val > 0x10FFFF)
 2214: 	        outofrange = val;
 2215: 
 2216: 	    NEXT;
 2217: 	    count++;
 2218: 	}
 2219: 	if (RAW == ';') {
 2220: 	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */
 2221: 	    ctxt->input->col++;
 2222: 	    ctxt->nbChars ++;
 2223: 	    ctxt->input->cur++;
 2224: 	}
 2225:     } else {
 2226:         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
 2227:     }
 2228: 
 2229:     /*
 2230:      * [ WFC: Legal Character ]
 2231:      * Characters referred to using character references must match the
 2232:      * production for Char. 
 2233:      */
 2234:     if ((IS_CHAR(val) && (outofrange == 0))) {
 2235:         return(val);
 2236:     } else {
 2237:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 2238:                           "xmlParseCharRef: invalid xmlChar value %d\n",
 2239: 	                  val);
 2240:     }
 2241:     return(0);
 2242: }
 2243: 
 2244: /**
 2245:  * xmlParseStringCharRef:
 2246:  * @ctxt:  an XML parser context
 2247:  * @str:  a pointer to an index in the string
 2248:  *
 2249:  * parse Reference declarations, variant parsing from a string rather
 2250:  * than an an input flow.
 2251:  *
 2252:  * [66] CharRef ::= '&#' [0-9]+ ';' |
 2253:  *                  '&#x' [0-9a-fA-F]+ ';'
 2254:  *
 2255:  * [ WFC: Legal Character ]
 2256:  * Characters referred to using character references must match the
 2257:  * production for Char. 
 2258:  *
 2259:  * Returns the value parsed (as an int), 0 in case of error, str will be
 2260:  *         updated to the current value of the index
 2261:  */
 2262: static int
 2263: xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
 2264:     const xmlChar *ptr;
 2265:     xmlChar cur;
 2266:     unsigned int val = 0;
 2267:     unsigned int outofrange = 0;
 2268: 
 2269:     if ((str == NULL) || (*str == NULL)) return(0);
 2270:     ptr = *str;
 2271:     cur = *ptr;
 2272:     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
 2273: 	ptr += 3;
 2274: 	cur = *ptr;
 2275: 	while (cur != ';') { /* Non input consuming loop */
 2276: 	    if ((cur >= '0') && (cur <= '9')) 
 2277: 	        val = val * 16 + (cur - '0');
 2278: 	    else if ((cur >= 'a') && (cur <= 'f'))
 2279: 	        val = val * 16 + (cur - 'a') + 10;
 2280: 	    else if ((cur >= 'A') && (cur <= 'F'))
 2281: 	        val = val * 16 + (cur - 'A') + 10;
 2282: 	    else {
 2283: 		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
 2284: 		val = 0;
 2285: 		break;
 2286: 	    }
 2287: 	    if (val > 0x10FFFF)
 2288: 	        outofrange = val;
 2289: 
 2290: 	    ptr++;
 2291: 	    cur = *ptr;
 2292: 	}
 2293: 	if (cur == ';')
 2294: 	    ptr++;
 2295:     } else if  ((cur == '&') && (ptr[1] == '#')){
 2296: 	ptr += 2;
 2297: 	cur = *ptr;
 2298: 	while (cur != ';') { /* Non input consuming loops */
 2299: 	    if ((cur >= '0') && (cur <= '9')) 
 2300: 	        val = val * 10 + (cur - '0');
 2301: 	    else {
 2302: 		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
 2303: 		val = 0;
 2304: 		break;
 2305: 	    }
 2306: 	    if (val > 0x10FFFF)
 2307: 	        outofrange = val;
 2308: 
 2309: 	    ptr++;
 2310: 	    cur = *ptr;
 2311: 	}
 2312: 	if (cur == ';')
 2313: 	    ptr++;
 2314:     } else {
 2315: 	xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
 2316: 	return(0);
 2317:     }
 2318:     *str = ptr;
 2319: 
 2320:     /*
 2321:      * [ WFC: Legal Character ]
 2322:      * Characters referred to using character references must match the
 2323:      * production for Char. 
 2324:      */
 2325:     if ((IS_CHAR(val) && (outofrange == 0))) {
 2326:         return(val);
 2327:     } else {
 2328:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 2329: 			  "xmlParseStringCharRef: invalid xmlChar value %d\n",
 2330: 			  val);
 2331:     }
 2332:     return(0);
 2333: }
 2334: 
 2335: /**
 2336:  * xmlNewBlanksWrapperInputStream:
 2337:  * @ctxt:  an XML parser context
 2338:  * @entity:  an Entity pointer
 2339:  *
 2340:  * Create a new input stream for wrapping
 2341:  * blanks around a PEReference
 2342:  *
 2343:  * Returns the new input stream or NULL
 2344:  */
 2345:  
 2346: static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
 2347:  
 2348: static xmlParserInputPtr
 2349: xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
 2350:     xmlParserInputPtr input;
 2351:     xmlChar *buffer;
 2352:     size_t length;
 2353:     if (entity == NULL) {
 2354: 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 2355: 	            "xmlNewBlanksWrapperInputStream entity\n");
 2356: 	return(NULL);
 2357:     }
 2358:     if (xmlParserDebugEntities)
 2359: 	xmlGenericError(xmlGenericErrorContext,
 2360: 		"new blanks wrapper for entity: %s\n", entity->name);
 2361:     input = xmlNewInputStream(ctxt);
 2362:     if (input == NULL) {
 2363: 	return(NULL);
 2364:     }
 2365:     length = xmlStrlen(entity->name) + 5;
 2366:     buffer = xmlMallocAtomic(length);
 2367:     if (buffer == NULL) {
 2368: 	xmlErrMemory(ctxt, NULL);
 2369:         xmlFree(input);
 2370:     	return(NULL);
 2371:     }
 2372:     buffer [0] = ' ';
 2373:     buffer [1] = '%';
 2374:     buffer [length-3] = ';';
 2375:     buffer [length-2] = ' ';
 2376:     buffer [length-1] = 0;
 2377:     memcpy(buffer + 2, entity->name, length - 5);
 2378:     input->free = deallocblankswrapper;
 2379:     input->base = buffer;
 2380:     input->cur = buffer;
 2381:     input->length = length;
 2382:     input->end = &buffer[length];
 2383:     return(input);
 2384: }
 2385: 
 2386: /**
 2387:  * xmlParserHandlePEReference:
 2388:  * @ctxt:  the parser context
 2389:  * 
 2390:  * [69] PEReference ::= '%' Name ';'
 2391:  *
 2392:  * [ WFC: No Recursion ]
 2393:  * A parsed entity must not contain a recursive
 2394:  * reference to itself, either directly or indirectly. 
 2395:  *
 2396:  * [ WFC: Entity Declared ]
 2397:  * In a document without any DTD, a document with only an internal DTD
 2398:  * subset which contains no parameter entity references, or a document
 2399:  * with "standalone='yes'", ...  ... The declaration of a parameter
 2400:  * entity must precede any reference to it...
 2401:  *
 2402:  * [ VC: Entity Declared ]
 2403:  * In a document with an external subset or external parameter entities
 2404:  * with "standalone='no'", ...  ... The declaration of a parameter entity
 2405:  * must precede any reference to it...
 2406:  *
 2407:  * [ WFC: In DTD ]
 2408:  * Parameter-entity references may only appear in the DTD.
 2409:  * NOTE: misleading but this is handled.
 2410:  *
 2411:  * A PEReference may have been detected in the current input stream
 2412:  * the handling is done accordingly to 
 2413:  *      http://www.w3.org/TR/REC-xml#entproc
 2414:  * i.e. 
 2415:  *   - Included in literal in entity values
 2416:  *   - Included as Parameter Entity reference within DTDs
 2417:  */
 2418: void
 2419: xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
 2420:     const xmlChar *name;
 2421:     xmlEntityPtr entity = NULL;
 2422:     xmlParserInputPtr input;
 2423: 
 2424:     if (RAW != '%') return;
 2425:     switch(ctxt->instate) {
 2426: 	case XML_PARSER_CDATA_SECTION:
 2427: 	    return;
 2428:         case XML_PARSER_COMMENT:
 2429: 	    return;
 2430: 	case XML_PARSER_START_TAG:
 2431: 	    return;
 2432: 	case XML_PARSER_END_TAG:
 2433: 	    return;
 2434:         case XML_PARSER_EOF:
 2435: 	    xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
 2436: 	    return;
 2437:         case XML_PARSER_PROLOG:
 2438: 	case XML_PARSER_START:
 2439: 	case XML_PARSER_MISC:
 2440: 	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
 2441: 	    return;
 2442: 	case XML_PARSER_ENTITY_DECL:
 2443:         case XML_PARSER_CONTENT:
 2444:         case XML_PARSER_ATTRIBUTE_VALUE:
 2445:         case XML_PARSER_PI:
 2446: 	case XML_PARSER_SYSTEM_LITERAL:
 2447: 	case XML_PARSER_PUBLIC_LITERAL:
 2448: 	    /* we just ignore it there */
 2449: 	    return;
 2450:         case XML_PARSER_EPILOG:
 2451: 	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
 2452: 	    return;
 2453: 	case XML_PARSER_ENTITY_VALUE:
 2454: 	    /*
 2455: 	     * NOTE: in the case of entity values, we don't do the
 2456: 	     *       substitution here since we need the literal
 2457: 	     *       entity value to be able to save the internal
 2458: 	     *       subset of the document.
 2459: 	     *       This will be handled by xmlStringDecodeEntities
 2460: 	     */
 2461: 	    return;
 2462:         case XML_PARSER_DTD:
 2463: 	    /*
 2464: 	     * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
 2465: 	     * In the internal DTD subset, parameter-entity references
 2466: 	     * can occur only where markup declarations can occur, not
 2467: 	     * within markup declarations.
 2468: 	     * In that case this is handled in xmlParseMarkupDecl
 2469: 	     */
 2470: 	    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
 2471: 		return;
 2472: 	    if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
 2473: 		return;
 2474:             break;
 2475:         case XML_PARSER_IGNORE:
 2476:             return;
 2477:     }
 2478: 
 2479:     NEXT;
 2480:     name = xmlParseName(ctxt);
 2481:     if (xmlParserDebugEntities)
 2482: 	xmlGenericError(xmlGenericErrorContext,
 2483: 		"PEReference: %s\n", name);
 2484:     if (name == NULL) {
 2485: 	xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
 2486:     } else {
 2487: 	if (RAW == ';') {
 2488: 	    NEXT;
 2489: 	    if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
 2490: 		entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
 2491: 	    if (entity == NULL) {
 2492: 	        
 2493: 		/*
 2494: 		 * [ WFC: Entity Declared ]
 2495: 		 * In a document without any DTD, a document with only an
 2496: 		 * internal DTD subset which contains no parameter entity
 2497: 		 * references, or a document with "standalone='yes'", ...
 2498: 		 * ... The declaration of a parameter entity must precede
 2499: 		 * any reference to it...
 2500: 		 */
 2501: 		if ((ctxt->standalone == 1) ||
 2502: 		    ((ctxt->hasExternalSubset == 0) &&
 2503: 		     (ctxt->hasPErefs == 0))) {
 2504: 		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 2505: 			 "PEReference: %%%s; not found\n", name);
 2506: 	        } else {
 2507: 		    /*
 2508: 		     * [ VC: Entity Declared ]
 2509: 		     * In a document with an external subset or external
 2510: 		     * parameter entities with "standalone='no'", ...
 2511: 		     * ... The declaration of a parameter entity must precede
 2512: 		     * any reference to it...
 2513: 		     */
 2514: 		    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
 2515: 		        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
 2516: 			                 "PEReference: %%%s; not found\n",
 2517: 				         name, NULL);
 2518: 		    } else 
 2519: 		        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
 2520: 			              "PEReference: %%%s; not found\n",
 2521: 				      name, NULL);
 2522: 		    ctxt->valid = 0;
 2523: 		}
 2524: 	    } else if (ctxt->input->free != deallocblankswrapper) {
 2525: 		    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
 2526: 		    if (xmlPushInput(ctxt, input) < 0)
 2527: 		        return;
 2528: 	    } else {
 2529: 	        if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
 2530: 		    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
 2531: 		    xmlChar start[4];
 2532: 		    xmlCharEncoding enc;
 2533: 
 2534: 		    /*
 2535: 		     * handle the extra spaces added before and after
 2536: 		     * c.f. http://www.w3.org/TR/REC-xml#as-PE
 2537: 		     * this is done independently.
 2538: 		     */
 2539: 		    input = xmlNewEntityInputStream(ctxt, entity);
 2540: 		    if (xmlPushInput(ctxt, input) < 0)
 2541: 		        return;
 2542: 
 2543: 		    /* 
 2544: 		     * Get the 4 first bytes and decode the charset
 2545: 		     * if enc != XML_CHAR_ENCODING_NONE
 2546: 		     * plug some encoding conversion routines.
 2547: 		     * Note that, since we may have some non-UTF8
 2548: 		     * encoding (like UTF16, bug 135229), the 'length'
 2549: 		     * is not known, but we can calculate based upon
 2550: 		     * the amount of data in the buffer.
 2551: 		     */
 2552: 		    GROW
 2553: 		    if ((ctxt->input->end - ctxt->input->cur)>=4) {
 2554: 			start[0] = RAW;
 2555: 			start[1] = NXT(1);
 2556: 			start[2] = NXT(2);
 2557: 			start[3] = NXT(3);
 2558: 			enc = xmlDetectCharEncoding(start, 4);
 2559: 			if (enc != XML_CHAR_ENCODING_NONE) {
 2560: 			    xmlSwitchEncoding(ctxt, enc);
 2561: 			}
 2562: 		    }
 2563: 
 2564: 		    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
 2565: 			(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
 2566: 			(IS_BLANK_CH(NXT(5)))) {
 2567: 			xmlParseTextDecl(ctxt);
 2568: 		    }
 2569: 		} else {
 2570: 		    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
 2571: 			     "PEReference: %s is not a parameter entity\n",
 2572: 				      name);
 2573: 		}
 2574: 	    }
 2575: 	} else {
 2576: 	    xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
 2577: 	}
 2578:     }
 2579: }
 2580: 
 2581: /*
 2582:  * Macro used to grow the current buffer.
 2583:  */
 2584: #define growBuffer(buffer, n) {						\
 2585:     xmlChar *tmp;							\
 2586:     buffer##_size *= 2;							\
 2587:     buffer##_size += n;							\
 2588:     tmp = (xmlChar *)							\
 2589: 		xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));	\
 2590:     if (tmp == NULL) goto mem_error;					\
 2591:     buffer = tmp;							\
 2592: }
 2593: 
 2594: /**
 2595:  * xmlStringLenDecodeEntities:
 2596:  * @ctxt:  the parser context
 2597:  * @str:  the input string
 2598:  * @len: the string length
 2599:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
 2600:  * @end:  an end marker xmlChar, 0 if none
 2601:  * @end2:  an end marker xmlChar, 0 if none
 2602:  * @end3:  an end marker xmlChar, 0 if none
 2603:  * 
 2604:  * Takes a entity string content and process to do the adequate substitutions.
 2605:  *
 2606:  * [67] Reference ::= EntityRef | CharRef
 2607:  *
 2608:  * [69] PEReference ::= '%' Name ';'
 2609:  *
 2610:  * Returns A newly allocated string with the substitution done. The caller
 2611:  *      must deallocate it !
 2612:  */
 2613: xmlChar *
 2614: xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
 2615: 		      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
 2616:     xmlChar *buffer = NULL;
 2617:     int buffer_size = 0;
 2618: 
 2619:     xmlChar *current = NULL;
 2620:     xmlChar *rep = NULL;
 2621:     const xmlChar *last;
 2622:     xmlEntityPtr ent;
 2623:     int c,l;
 2624:     int nbchars = 0;
 2625: 
 2626:     if ((ctxt == NULL) || (str == NULL) || (len < 0))
 2627: 	return(NULL);
 2628:     last = str + len;
 2629: 
 2630:     if (((ctxt->depth > 40) &&
 2631:          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
 2632: 	(ctxt->depth > 1024)) {
 2633: 	xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
 2634: 	return(NULL);
 2635:     }
 2636: 
 2637:     /*
 2638:      * allocate a translation buffer.
 2639:      */
 2640:     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
 2641:     buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
 2642:     if (buffer == NULL) goto mem_error;
 2643: 
 2644:     /*
 2645:      * OK loop until we reach one of the ending char or a size limit.
 2646:      * we are operating on already parsed values.
 2647:      */
 2648:     if (str < last)
 2649: 	c = CUR_SCHAR(str, l);
 2650:     else
 2651:         c = 0;
 2652:     while ((c != 0) && (c != end) && /* non input consuming loop */
 2653: 	   (c != end2) && (c != end3)) {
 2654: 
 2655: 	if (c == 0) break;
 2656:         if ((c == '&') && (str[1] == '#')) {
 2657: 	    int val = xmlParseStringCharRef(ctxt, &str);
 2658: 	    if (val != 0) {
 2659: 		COPY_BUF(0,buffer,nbchars,val);
 2660: 	    }
 2661: 	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
 2662: 	        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
 2663: 	    }
 2664: 	} else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
 2665: 	    if (xmlParserDebugEntities)
 2666: 		xmlGenericError(xmlGenericErrorContext,
 2667: 			"String decoding Entity Reference: %.30s\n",
 2668: 			str);
 2669: 	    ent = xmlParseStringEntityRef(ctxt, &str);
 2670: 	    if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
 2671: 	        (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
 2672: 	        goto int_error;
 2673: 	    if (ent != NULL)
 2674: 	        ctxt->nbentities += ent->checked;
 2675: 	    if ((ent != NULL) &&
 2676: 		(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
 2677: 		if (ent->content != NULL) {
 2678: 		    COPY_BUF(0,buffer,nbchars,ent->content[0]);
 2679: 		    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
 2680: 			growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
 2681: 		    }
 2682: 		} else {
 2683: 		    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
 2684: 			    "predefined entity has no content\n");
 2685: 		}
 2686: 	    } else if ((ent != NULL) && (ent->content != NULL)) {
 2687: 		ctxt->depth++;
 2688: 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
 2689: 			                      0, 0, 0);
 2690: 		ctxt->depth--;
 2691: 
 2692: 		if (rep != NULL) {
 2693: 		    current = rep;
 2694: 		    while (*current != 0) { /* non input consuming loop */
 2695: 			buffer[nbchars++] = *current++;
 2696: 			if (nbchars >
 2697: 		            buffer_size - XML_PARSER_BUFFER_SIZE) {
 2698: 			    if (xmlParserEntityCheck(ctxt, nbchars, ent))
 2699: 				goto int_error;
 2700: 			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
 2701: 			}
 2702: 		    }
 2703: 		    xmlFree(rep);
 2704: 		    rep = NULL;
 2705: 		}
 2706: 	    } else if (ent != NULL) {
 2707: 		int i = xmlStrlen(ent->name);
 2708: 		const xmlChar *cur = ent->name;
 2709: 
 2710: 		buffer[nbchars++] = '&';
 2711: 		if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
 2712: 		    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
 2713: 		}
 2714: 		for (;i > 0;i--)
 2715: 		    buffer[nbchars++] = *cur++;
 2716: 		buffer[nbchars++] = ';';
 2717: 	    }
 2718: 	} else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
 2719: 	    if (xmlParserDebugEntities)
 2720: 		xmlGenericError(xmlGenericErrorContext,
 2721: 			"String decoding PE Reference: %.30s\n", str);
 2722: 	    ent = xmlParseStringPEReference(ctxt, &str);
 2723: 	    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
 2724: 	        goto int_error;
 2725: 	    if (ent != NULL)
 2726: 	        ctxt->nbentities += ent->checked;
 2727: 	    if (ent != NULL) {
 2728:                 if (ent->content == NULL) {
 2729: 		    xmlLoadEntityContent(ctxt, ent);
 2730: 		}
 2731: 		ctxt->depth++;
 2732: 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
 2733: 			                      0, 0, 0);
 2734: 		ctxt->depth--;
 2735: 		if (rep != NULL) {
 2736: 		    current = rep;
 2737: 		    while (*current != 0) { /* non input consuming loop */
 2738: 			buffer[nbchars++] = *current++;
 2739: 			if (nbchars >
 2740: 		            buffer_size - XML_PARSER_BUFFER_SIZE) {
 2741: 			    if (xmlParserEntityCheck(ctxt, nbchars, ent))
 2742: 			        goto int_error;
 2743: 			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
 2744: 			}
 2745: 		    }
 2746: 		    xmlFree(rep);
 2747: 		    rep = NULL;
 2748: 		}
 2749: 	    }
 2750: 	} else {
 2751: 	    COPY_BUF(l,buffer,nbchars,c);
 2752: 	    str += l;
 2753: 	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
 2754: 	      growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
 2755: 	    }
 2756: 	}
 2757: 	if (str < last)
 2758: 	    c = CUR_SCHAR(str, l);
 2759: 	else
 2760: 	    c = 0;
 2761:     }
 2762:     buffer[nbchars] = 0;
 2763:     return(buffer);
 2764: 
 2765: mem_error:
 2766:     xmlErrMemory(ctxt, NULL);
 2767: int_error:
 2768:     if (rep != NULL)
 2769:         xmlFree(rep);
 2770:     if (buffer != NULL)
 2771:         xmlFree(buffer);
 2772:     return(NULL);
 2773: }
 2774: 
 2775: /**
 2776:  * xmlStringDecodeEntities:
 2777:  * @ctxt:  the parser context
 2778:  * @str:  the input string
 2779:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
 2780:  * @end:  an end marker xmlChar, 0 if none
 2781:  * @end2:  an end marker xmlChar, 0 if none
 2782:  * @end3:  an end marker xmlChar, 0 if none
 2783:  * 
 2784:  * Takes a entity string content and process to do the adequate substitutions.
 2785:  *
 2786:  * [67] Reference ::= EntityRef | CharRef
 2787:  *
 2788:  * [69] PEReference ::= '%' Name ';'
 2789:  *
 2790:  * Returns A newly allocated string with the substitution done. The caller
 2791:  *      must deallocate it !
 2792:  */
 2793: xmlChar *
 2794: xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
 2795: 		        xmlChar end, xmlChar  end2, xmlChar end3) {
 2796:     if ((ctxt == NULL) || (str == NULL)) return(NULL);
 2797:     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
 2798:            end, end2, end3));
 2799: }
 2800: 
 2801: /************************************************************************
 2802:  *									*
 2803:  *		Commodity functions, cleanup needed ?			*
 2804:  *									*
 2805:  ************************************************************************/
 2806: 
 2807: /**
 2808:  * areBlanks:
 2809:  * @ctxt:  an XML parser context
 2810:  * @str:  a xmlChar *
 2811:  * @len:  the size of @str
 2812:  * @blank_chars: we know the chars are blanks
 2813:  *
 2814:  * Is this a sequence of blank chars that one can ignore ?
 2815:  *
 2816:  * Returns 1 if ignorable 0 otherwise.
 2817:  */
 2818: 
 2819: static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
 2820:                      int blank_chars) {
 2821:     int i, ret;
 2822:     xmlNodePtr lastChild;
 2823: 
 2824:     /*
 2825:      * Don't spend time trying to differentiate them, the same callback is
 2826:      * used !
 2827:      */
 2828:     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
 2829: 	return(0);
 2830: 
 2831:     /*
 2832:      * Check for xml:space value.
 2833:      */
 2834:     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
 2835:         (*(ctxt->space) == -2))
 2836: 	return(0);
 2837: 
 2838:     /*
 2839:      * Check that the string is made of blanks
 2840:      */
 2841:     if (blank_chars == 0) {
 2842: 	for (i = 0;i < len;i++)
 2843: 	    if (!(IS_BLANK_CH(str[i]))) return(0);
 2844:     }
 2845: 
 2846:     /*
 2847:      * Look if the element is mixed content in the DTD if available
 2848:      */
 2849:     if (ctxt->node == NULL) return(0);
 2850:     if (ctxt->myDoc != NULL) {
 2851: 	ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
 2852:         if (ret == 0) return(1);
 2853:         if (ret == 1) return(0);
 2854:     }
 2855: 
 2856:     /*
 2857:      * Otherwise, heuristic :-\
 2858:      */
 2859:     if ((RAW != '<') && (RAW != 0xD)) return(0);
 2860:     if ((ctxt->node->children == NULL) &&
 2861: 	(RAW == '<') && (NXT(1) == '/')) return(0);
 2862: 
 2863:     lastChild = xmlGetLastChild(ctxt->node);
 2864:     if (lastChild == NULL) {
 2865:         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
 2866:             (ctxt->node->content != NULL)) return(0);
 2867:     } else if (xmlNodeIsText(lastChild))
 2868:         return(0);
 2869:     else if ((ctxt->node->children != NULL) &&
 2870:              (xmlNodeIsText(ctxt->node->children)))
 2871:         return(0);
 2872:     return(1);
 2873: }
 2874: 
 2875: /************************************************************************
 2876:  *									*
 2877:  *		Extra stuff for namespace support			*
 2878:  *	Relates to http://www.w3.org/TR/WD-xml-names			*
 2879:  *									*
 2880:  ************************************************************************/
 2881: 
 2882: /**
 2883:  * xmlSplitQName:
 2884:  * @ctxt:  an XML parser context
 2885:  * @name:  an XML parser context
 2886:  * @prefix:  a xmlChar **
 2887:  *
 2888:  * parse an UTF8 encoded XML qualified name string
 2889:  *
 2890:  * [NS 5] QName ::= (Prefix ':')? LocalPart
 2891:  *
 2892:  * [NS 6] Prefix ::= NCName
 2893:  *
 2894:  * [NS 7] LocalPart ::= NCName
 2895:  *
 2896:  * Returns the local part, and prefix is updated
 2897:  *   to get the Prefix if any.
 2898:  */
 2899: 
 2900: xmlChar *
 2901: xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
 2902:     xmlChar buf[XML_MAX_NAMELEN + 5];
 2903:     xmlChar *buffer = NULL;
 2904:     int len = 0;
 2905:     int max = XML_MAX_NAMELEN;
 2906:     xmlChar *ret = NULL;
 2907:     const xmlChar *cur = name;
 2908:     int c;
 2909: 
 2910:     if (prefix == NULL) return(NULL);
 2911:     *prefix = NULL;
 2912: 
 2913:     if (cur == NULL) return(NULL);
 2914: 
 2915: #ifndef XML_XML_NAMESPACE
 2916:     /* xml: prefix is not really a namespace */
 2917:     if ((cur[0] == 'x') && (cur[1] == 'm') &&
 2918:         (cur[2] == 'l') && (cur[3] == ':'))
 2919: 	return(xmlStrdup(name));
 2920: #endif
 2921: 
 2922:     /* nasty but well=formed */
 2923:     if (cur[0] == ':')
 2924: 	return(xmlStrdup(name));
 2925: 
 2926:     c = *cur++;
 2927:     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
 2928: 	buf[len++] = c;
 2929: 	c = *cur++;
 2930:     }
 2931:     if (len >= max) {
 2932: 	/*
 2933: 	 * Okay someone managed to make a huge name, so he's ready to pay
 2934: 	 * for the processing speed.
 2935: 	 */
 2936: 	max = len * 2;
 2937: 
 2938: 	buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
 2939: 	if (buffer == NULL) {
 2940: 	    xmlErrMemory(ctxt, NULL);
 2941: 	    return(NULL);
 2942: 	}
 2943: 	memcpy(buffer, buf, len);
 2944: 	while ((c != 0) && (c != ':')) { /* tested bigname.xml */
 2945: 	    if (len + 10 > max) {
 2946: 	        xmlChar *tmp;
 2947: 
 2948: 		max *= 2;
 2949: 		tmp = (xmlChar *) xmlRealloc(buffer,
 2950: 						max * sizeof(xmlChar));
 2951: 		if (tmp == NULL) {
 2952: 		    xmlFree(buffer);
 2953: 		    xmlErrMemory(ctxt, NULL);
 2954: 		    return(NULL);
 2955: 		}
 2956: 		buffer = tmp;
 2957: 	    }
 2958: 	    buffer[len++] = c;
 2959: 	    c = *cur++;
 2960: 	}
 2961: 	buffer[len] = 0;
 2962:     }
 2963: 
 2964:     if ((c == ':') && (*cur == 0)) {
 2965:         if (buffer != NULL)
 2966: 	    xmlFree(buffer);
 2967: 	*prefix = NULL;
 2968: 	return(xmlStrdup(name));
 2969:     }
 2970: 
 2971:     if (buffer == NULL)
 2972: 	ret = xmlStrndup(buf, len);
 2973:     else {
 2974: 	ret = buffer;
 2975: 	buffer = NULL;
 2976: 	max = XML_MAX_NAMELEN;
 2977:     }
 2978: 
 2979: 
 2980:     if (c == ':') {
 2981: 	c = *cur;
 2982:         *prefix = ret;
 2983: 	if (c == 0) {
 2984: 	    return(xmlStrndup(BAD_CAST "", 0));
 2985: 	}
 2986: 	len = 0;
 2987: 
 2988: 	/*
 2989: 	 * Check that the first character is proper to start
 2990: 	 * a new name
 2991: 	 */
 2992: 	if (!(((c >= 0x61) && (c <= 0x7A)) ||
 2993: 	      ((c >= 0x41) && (c <= 0x5A)) ||
 2994: 	      (c == '_') || (c == ':'))) {
 2995: 	    int l;
 2996: 	    int first = CUR_SCHAR(cur, l);
 2997: 
 2998: 	    if (!IS_LETTER(first) && (first != '_')) {
 2999: 		xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
 3000: 			    "Name %s is not XML Namespace compliant\n",
 3001: 				  name);
 3002: 	    }
 3003: 	}
 3004: 	cur++;
 3005: 
 3006: 	while ((c != 0) && (len < max)) { /* tested bigname2.xml */
 3007: 	    buf[len++] = c;
 3008: 	    c = *cur++;
 3009: 	}
 3010: 	if (len >= max) {
 3011: 	    /*
 3012: 	     * Okay someone managed to make a huge name, so he's ready to pay
 3013: 	     * for the processing speed.
 3014: 	     */
 3015: 	    max = len * 2;
 3016: 
 3017: 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
 3018: 	    if (buffer == NULL) {
 3019: 	        xmlErrMemory(ctxt, NULL);
 3020: 		return(NULL);
 3021: 	    }
 3022: 	    memcpy(buffer, buf, len);
 3023: 	    while (c != 0) { /* tested bigname2.xml */
 3024: 		if (len + 10 > max) {
 3025: 		    xmlChar *tmp;
 3026: 
 3027: 		    max *= 2;
 3028: 		    tmp = (xmlChar *) xmlRealloc(buffer,
 3029: 						    max * sizeof(xmlChar));
 3030: 		    if (tmp == NULL) {
 3031: 			xmlErrMemory(ctxt, NULL);
 3032: 			xmlFree(buffer);
 3033: 			return(NULL);
 3034: 		    }
 3035: 		    buffer = tmp;
 3036: 		}
 3037: 		buffer[len++] = c;
 3038: 		c = *cur++;
 3039: 	    }
 3040: 	    buffer[len] = 0;
 3041: 	}
 3042: 
 3043: 	if (buffer == NULL)
 3044: 	    ret = xmlStrndup(buf, len);
 3045: 	else {
 3046: 	    ret = buffer;
 3047: 	}
 3048:     }
 3049: 
 3050:     return(ret);
 3051: }
 3052: 
 3053: /************************************************************************
 3054:  *									*
 3055:  *			The parser itself				*
 3056:  *	Relates to http://www.w3.org/TR/REC-xml				*
 3057:  *									*
 3058:  ************************************************************************/
 3059: 
 3060: /************************************************************************
 3061:  *									*
 3062:  *	Routines to parse Name, NCName and NmToken			*
 3063:  *									*
 3064:  ************************************************************************/
 3065: #ifdef DEBUG
 3066: static unsigned long nbParseName = 0;
 3067: static unsigned long nbParseNmToken = 0;
 3068: static unsigned long nbParseNCName = 0;
 3069: static unsigned long nbParseNCNameComplex = 0;
 3070: static unsigned long nbParseNameComplex = 0;
 3071: static unsigned long nbParseStringName = 0;
 3072: #endif
 3073: 
 3074: /*
 3075:  * The two following functions are related to the change of accepted
 3076:  * characters for Name and NmToken in the Revision 5 of XML-1.0
 3077:  * They correspond to the modified production [4] and the new production [4a]
 3078:  * changes in that revision. Also note that the macros used for the
 3079:  * productions Letter, Digit, CombiningChar and Extender are not needed
 3080:  * anymore.
 3081:  * We still keep compatibility to pre-revision5 parsing semantic if the
 3082:  * new XML_PARSE_OLD10 option is given to the parser.
 3083:  */
 3084: static int
 3085: xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
 3086:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
 3087:         /*
 3088: 	 * Use the new checks of production [4] [4a] amd [5] of the
 3089: 	 * Update 5 of XML-1.0
 3090: 	 */
 3091: 	if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
 3092: 	    (((c >= 'a') && (c <= 'z')) ||
 3093: 	     ((c >= 'A') && (c <= 'Z')) ||
 3094: 	     (c == '_') || (c == ':') ||
 3095: 	     ((c >= 0xC0) && (c <= 0xD6)) ||
 3096: 	     ((c >= 0xD8) && (c <= 0xF6)) ||
 3097: 	     ((c >= 0xF8) && (c <= 0x2FF)) ||
 3098: 	     ((c >= 0x370) && (c <= 0x37D)) ||
 3099: 	     ((c >= 0x37F) && (c <= 0x1FFF)) ||
 3100: 	     ((c >= 0x200C) && (c <= 0x200D)) ||
 3101: 	     ((c >= 0x2070) && (c <= 0x218F)) ||
 3102: 	     ((c >= 0x2C00) && (c <= 0x2FEF)) ||
 3103: 	     ((c >= 0x3001) && (c <= 0xD7FF)) ||
 3104: 	     ((c >= 0xF900) && (c <= 0xFDCF)) ||
 3105: 	     ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
 3106: 	     ((c >= 0x10000) && (c <= 0xEFFFF))))
 3107: 	    return(1);
 3108:     } else {
 3109:         if (IS_LETTER(c) || (c == '_') || (c == ':'))
 3110: 	    return(1);
 3111:     }
 3112:     return(0);
 3113: }
 3114: 
 3115: static int
 3116: xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
 3117:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
 3118:         /*
 3119: 	 * Use the new checks of production [4] [4a] amd [5] of the
 3120: 	 * Update 5 of XML-1.0
 3121: 	 */
 3122: 	if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
 3123: 	    (((c >= 'a') && (c <= 'z')) ||
 3124: 	     ((c >= 'A') && (c <= 'Z')) ||
 3125: 	     ((c >= '0') && (c <= '9')) || /* !start */
 3126: 	     (c == '_') || (c == ':') ||
 3127: 	     (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
 3128: 	     ((c >= 0xC0) && (c <= 0xD6)) ||
 3129: 	     ((c >= 0xD8) && (c <= 0xF6)) ||
 3130: 	     ((c >= 0xF8) && (c <= 0x2FF)) ||
 3131: 	     ((c >= 0x300) && (c <= 0x36F)) || /* !start */
 3132: 	     ((c >= 0x370) && (c <= 0x37D)) ||
 3133: 	     ((c >= 0x37F) && (c <= 0x1FFF)) ||
 3134: 	     ((c >= 0x200C) && (c <= 0x200D)) ||
 3135: 	     ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
 3136: 	     ((c >= 0x2070) && (c <= 0x218F)) ||
 3137: 	     ((c >= 0x2C00) && (c <= 0x2FEF)) ||
 3138: 	     ((c >= 0x3001) && (c <= 0xD7FF)) ||
 3139: 	     ((c >= 0xF900) && (c <= 0xFDCF)) ||
 3140: 	     ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
 3141: 	     ((c >= 0x10000) && (c <= 0xEFFFF))))
 3142: 	     return(1);
 3143:     } else {
 3144:         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
 3145:             (c == '.') || (c == '-') ||
 3146: 	    (c == '_') || (c == ':') || 
 3147: 	    (IS_COMBINING(c)) ||
 3148: 	    (IS_EXTENDER(c)))
 3149: 	    return(1);
 3150:     }
 3151:     return(0);
 3152: }
 3153: 
 3154: static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
 3155:                                           int *len, int *alloc, int normalize);
 3156: 
 3157: static const xmlChar *
 3158: xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
 3159:     int len = 0, l;
 3160:     int c;
 3161:     int count = 0;
 3162: 
 3163: #ifdef DEBUG
 3164:     nbParseNameComplex++;
 3165: #endif
 3166: 
 3167:     /*
 3168:      * Handler for more complex cases
 3169:      */
 3170:     GROW;
 3171:     c = CUR_CHAR(l);
 3172:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
 3173:         /*
 3174: 	 * Use the new checks of production [4] [4a] amd [5] of the
 3175: 	 * Update 5 of XML-1.0
 3176: 	 */
 3177: 	if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
 3178: 	    (!(((c >= 'a') && (c <= 'z')) ||
 3179: 	       ((c >= 'A') && (c <= 'Z')) ||
 3180: 	       (c == '_') || (c == ':') ||
 3181: 	       ((c >= 0xC0) && (c <= 0xD6)) ||
 3182: 	       ((c >= 0xD8) && (c <= 0xF6)) ||
 3183: 	       ((c >= 0xF8) && (c <= 0x2FF)) ||
 3184: 	       ((c >= 0x370) && (c <= 0x37D)) ||
 3185: 	       ((c >= 0x37F) && (c <= 0x1FFF)) ||
 3186: 	       ((c >= 0x200C) && (c <= 0x200D)) ||
 3187: 	       ((c >= 0x2070) && (c <= 0x218F)) ||
 3188: 	       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
 3189: 	       ((c >= 0x3001) && (c <= 0xD7FF)) ||
 3190: 	       ((c >= 0xF900) && (c <= 0xFDCF)) ||
 3191: 	       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
 3192: 	       ((c >= 0x10000) && (c <= 0xEFFFF))))) {
 3193: 	    return(NULL);
 3194: 	}
 3195: 	len += l;
 3196: 	NEXTL(l);
 3197: 	c = CUR_CHAR(l);
 3198: 	while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
 3199: 	       (((c >= 'a') && (c <= 'z')) ||
 3200: 	        ((c >= 'A') && (c <= 'Z')) ||
 3201: 	        ((c >= '0') && (c <= '9')) || /* !start */
 3202: 	        (c == '_') || (c == ':') ||
 3203: 	        (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
 3204: 	        ((c >= 0xC0) && (c <= 0xD6)) ||
 3205: 	        ((c >= 0xD8) && (c <= 0xF6)) ||
 3206: 	        ((c >= 0xF8) && (c <= 0x2FF)) ||
 3207: 	        ((c >= 0x300) && (c <= 0x36F)) || /* !start */
 3208: 	        ((c >= 0x370) && (c <= 0x37D)) ||
 3209: 	        ((c >= 0x37F) && (c <= 0x1FFF)) ||
 3210: 	        ((c >= 0x200C) && (c <= 0x200D)) ||
 3211: 	        ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
 3212: 	        ((c >= 0x2070) && (c <= 0x218F)) ||
 3213: 	        ((c >= 0x2C00) && (c <= 0x2FEF)) ||
 3214: 	        ((c >= 0x3001) && (c <= 0xD7FF)) ||
 3215: 	        ((c >= 0xF900) && (c <= 0xFDCF)) ||
 3216: 	        ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
 3217: 	        ((c >= 0x10000) && (c <= 0xEFFFF))
 3218: 		)) {
 3219: 	    if (count++ > 100) {
 3220: 		count = 0;
 3221: 		GROW;
 3222: 	    }
 3223: 	    len += l;
 3224: 	    NEXTL(l);
 3225: 	    c = CUR_CHAR(l);
 3226: 	}
 3227:     } else {
 3228: 	if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
 3229: 	    (!IS_LETTER(c) && (c != '_') &&
 3230: 	     (c != ':'))) {
 3231: 	    return(NULL);
 3232: 	}
 3233: 	len += l;
 3234: 	NEXTL(l);
 3235: 	c = CUR_CHAR(l);
 3236: 
 3237: 	while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
 3238: 	       ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
 3239: 		(c == '.') || (c == '-') ||
 3240: 		(c == '_') || (c == ':') || 
 3241: 		(IS_COMBINING(c)) ||
 3242: 		(IS_EXTENDER(c)))) {
 3243: 	    if (count++ > 100) {
 3244: 		count = 0;
 3245: 		GROW;
 3246: 	    }
 3247: 	    len += l;
 3248: 	    NEXTL(l);
 3249: 	    c = CUR_CHAR(l);
 3250: 	}
 3251:     }
 3252:     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
 3253:         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
 3254:     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
 3255: }
 3256: 
 3257: /**
 3258:  * xmlParseName:
 3259:  * @ctxt:  an XML parser context
 3260:  *
 3261:  * parse an XML name.
 3262:  *
 3263:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
 3264:  *                  CombiningChar | Extender
 3265:  *
 3266:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
 3267:  *
 3268:  * [6] Names ::= Name (#x20 Name)*
 3269:  *
 3270:  * Returns the Name parsed or NULL
 3271:  */
 3272: 
 3273: const xmlChar *
 3274: xmlParseName(xmlParserCtxtPtr ctxt) {
 3275:     const xmlChar *in;
 3276:     const xmlChar *ret;
 3277:     int count = 0;
 3278: 
 3279:     GROW;
 3280: 
 3281: #ifdef DEBUG
 3282:     nbParseName++;
 3283: #endif
 3284: 
 3285:     /*
 3286:      * Accelerator for simple ASCII names
 3287:      */
 3288:     in = ctxt->input->cur;
 3289:     if (((*in >= 0x61) && (*in <= 0x7A)) ||
 3290: 	((*in >= 0x41) && (*in <= 0x5A)) ||
 3291: 	(*in == '_') || (*in == ':')) {
 3292: 	in++;
 3293: 	while (((*in >= 0x61) && (*in <= 0x7A)) ||
 3294: 	       ((*in >= 0x41) && (*in <= 0x5A)) ||
 3295: 	       ((*in >= 0x30) && (*in <= 0x39)) ||
 3296: 	       (*in == '_') || (*in == '-') ||
 3297: 	       (*in == ':') || (*in == '.'))
 3298: 	    in++;
 3299: 	if ((*in > 0) && (*in < 0x80)) {
 3300: 	    count = in - ctxt->input->cur;
 3301: 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
 3302: 	    ctxt->input->cur = in;
 3303: 	    ctxt->nbChars += count;
 3304: 	    ctxt->input->col += count;
 3305: 	    if (ret == NULL)
 3306: 	        xmlErrMemory(ctxt, NULL);
 3307: 	    return(ret);
 3308: 	}
 3309:     }
 3310:     /* accelerator for special cases */
 3311:     return(xmlParseNameComplex(ctxt));
 3312: }
 3313: 
 3314: static const xmlChar *
 3315: xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
 3316:     int len = 0, l;
 3317:     int c;
 3318:     int count = 0;
 3319: 
 3320: #ifdef DEBUG
 3321:     nbParseNCNameComplex++;
 3322: #endif
 3323: 
 3324:     /*
 3325:      * Handler for more complex cases
 3326:      */
 3327:     GROW;
 3328:     c = CUR_CHAR(l);
 3329:     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
 3330: 	(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
 3331: 	return(NULL);
 3332:     }
 3333: 
 3334:     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
 3335: 	   (xmlIsNameChar(ctxt, c) && (c != ':'))) {
 3336: 	if (count++ > 100) {
 3337: 	    count = 0;
 3338: 	    GROW;
 3339: 	}
 3340: 	len += l;
 3341: 	NEXTL(l);
 3342: 	c = CUR_CHAR(l);
 3343:     }
 3344:     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
 3345: }
 3346: 
 3347: /**
 3348:  * xmlParseNCName:
 3349:  * @ctxt:  an XML parser context
 3350:  * @len:  lenght of the string parsed
 3351:  *
 3352:  * parse an XML name.
 3353:  *
 3354:  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
 3355:  *                      CombiningChar | Extender
 3356:  *
 3357:  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
 3358:  *
 3359:  * Returns the Name parsed or NULL
 3360:  */
 3361: 
 3362: static const xmlChar *
 3363: xmlParseNCName(xmlParserCtxtPtr ctxt) {
 3364:     const xmlChar *in;
 3365:     const xmlChar *ret;
 3366:     int count = 0;
 3367: 
 3368: #ifdef DEBUG
 3369:     nbParseNCName++;
 3370: #endif
 3371: 
 3372:     /*
 3373:      * Accelerator for simple ASCII names
 3374:      */
 3375:     in = ctxt->input->cur;
 3376:     if (((*in >= 0x61) && (*in <= 0x7A)) ||
 3377: 	((*in >= 0x41) && (*in <= 0x5A)) ||
 3378: 	(*in == '_')) {
 3379: 	in++;
 3380: 	while (((*in >= 0x61) && (*in <= 0x7A)) ||
 3381: 	       ((*in >= 0x41) && (*in <= 0x5A)) ||
 3382: 	       ((*in >= 0x30) && (*in <= 0x39)) ||
 3383: 	       (*in == '_') || (*in == '-') ||
 3384: 	       (*in == '.'))
 3385: 	    in++;
 3386: 	if ((*in > 0) && (*in < 0x80)) {
 3387: 	    count = in - ctxt->input->cur;
 3388: 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
 3389: 	    ctxt->input->cur = in;
 3390: 	    ctxt->nbChars += count;
 3391: 	    ctxt->input->col += count;
 3392: 	    if (ret == NULL) {
 3393: 	        xmlErrMemory(ctxt, NULL);
 3394: 	    }
 3395: 	    return(ret);
 3396: 	}
 3397:     }
 3398:     return(xmlParseNCNameComplex(ctxt));
 3399: }
 3400: 
 3401: /**
 3402:  * xmlParseNameAndCompare:
 3403:  * @ctxt:  an XML parser context
 3404:  *
 3405:  * parse an XML name and compares for match
 3406:  * (specialized for endtag parsing)
 3407:  *
 3408:  * Returns NULL for an illegal name, (xmlChar*) 1 for success
 3409:  * and the name for mismatch
 3410:  */
 3411: 
 3412: static const xmlChar *
 3413: xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
 3414:     register const xmlChar *cmp = other;
 3415:     register const xmlChar *in;
 3416:     const xmlChar *ret;
 3417: 
 3418:     GROW;
 3419: 
 3420:     in = ctxt->input->cur;
 3421:     while (*in != 0 && *in == *cmp) {
 3422: 	++in;
 3423: 	++cmp;
 3424: 	ctxt->input->col++;
 3425:     }
 3426:     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
 3427: 	/* success */
 3428: 	ctxt->input->cur = in;
 3429: 	return (const xmlChar*) 1;
 3430:     }
 3431:     /* failure (or end of input buffer), check with full function */
 3432:     ret = xmlParseName (ctxt);
 3433:     /* strings coming from the dictionnary direct compare possible */
 3434:     if (ret == other) {
 3435: 	return (const xmlChar*) 1;
 3436:     }
 3437:     return ret;
 3438: }
 3439: 
 3440: /**
 3441:  * xmlParseStringName:
 3442:  * @ctxt:  an XML parser context
 3443:  * @str:  a pointer to the string pointer (IN/OUT)
 3444:  *
 3445:  * parse an XML name.
 3446:  *
 3447:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
 3448:  *                  CombiningChar | Extender
 3449:  *
 3450:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
 3451:  *
 3452:  * [6] Names ::= Name (#x20 Name)*
 3453:  *
 3454:  * Returns the Name parsed or NULL. The @str pointer 
 3455:  * is updated to the current location in the string.
 3456:  */
 3457: 
 3458: static xmlChar *
 3459: xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
 3460:     xmlChar buf[XML_MAX_NAMELEN + 5];
 3461:     const xmlChar *cur = *str;
 3462:     int len = 0, l;
 3463:     int c;
 3464: 
 3465: #ifdef DEBUG
 3466:     nbParseStringName++;
 3467: #endif
 3468: 
 3469:     c = CUR_SCHAR(cur, l);
 3470:     if (!xmlIsNameStartChar(ctxt, c)) {
 3471: 	return(NULL);
 3472:     }
 3473: 
 3474:     COPY_BUF(l,buf,len,c);
 3475:     cur += l;
 3476:     c = CUR_SCHAR(cur, l);
 3477:     while (xmlIsNameChar(ctxt, c)) {
 3478: 	COPY_BUF(l,buf,len,c);
 3479: 	cur += l;
 3480: 	c = CUR_SCHAR(cur, l);
 3481: 	if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
 3482: 	    /*
 3483: 	     * Okay someone managed to make a huge name, so he's ready to pay
 3484: 	     * for the processing speed.
 3485: 	     */
 3486: 	    xmlChar *buffer;
 3487: 	    int max = len * 2;
 3488: 
 3489: 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
 3490: 	    if (buffer == NULL) {
 3491: 	        xmlErrMemory(ctxt, NULL);
 3492: 		return(NULL);
 3493: 	    }
 3494: 	    memcpy(buffer, buf, len);
 3495: 	    while (xmlIsNameChar(ctxt, c)) {
 3496: 		if (len + 10 > max) {
 3497: 		    xmlChar *tmp;
 3498: 		    max *= 2;
 3499: 		    tmp = (xmlChar *) xmlRealloc(buffer,
 3500: 			                            max * sizeof(xmlChar));
 3501: 		    if (tmp == NULL) {
 3502: 			xmlErrMemory(ctxt, NULL);
 3503: 			xmlFree(buffer);
 3504: 			return(NULL);
 3505: 		    }
 3506: 		    buffer = tmp;
 3507: 		}
 3508: 		COPY_BUF(l,buffer,len,c);
 3509: 		cur += l;
 3510: 		c = CUR_SCHAR(cur, l);
 3511: 	    }
 3512: 	    buffer[len] = 0;
 3513: 	    *str = cur;
 3514: 	    return(buffer);
 3515: 	}
 3516:     }
 3517:     *str = cur;
 3518:     return(xmlStrndup(buf, len));
 3519: }
 3520: 
 3521: /**
 3522:  * xmlParseNmtoken:
 3523:  * @ctxt:  an XML parser context
 3524:  *
 3525:  * parse an XML Nmtoken.
 3526:  *
 3527:  * [7] Nmtoken ::= (NameChar)+
 3528:  *
 3529:  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
 3530:  *
 3531:  * Returns the Nmtoken parsed or NULL
 3532:  */
 3533: 
 3534: xmlChar *
 3535: xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
 3536:     xmlChar buf[XML_MAX_NAMELEN + 5];
 3537:     int len = 0, l;
 3538:     int c;
 3539:     int count = 0;
 3540: 
 3541: #ifdef DEBUG
 3542:     nbParseNmToken++;
 3543: #endif
 3544: 
 3545:     GROW;
 3546:     c = CUR_CHAR(l);
 3547: 
 3548:     while (xmlIsNameChar(ctxt, c)) {
 3549: 	if (count++ > 100) {
 3550: 	    count = 0;
 3551: 	    GROW;
 3552: 	}
 3553: 	COPY_BUF(l,buf,len,c);
 3554: 	NEXTL(l);
 3555: 	c = CUR_CHAR(l);
 3556: 	if (len >= XML_MAX_NAMELEN) {
 3557: 	    /*
 3558: 	     * Okay someone managed to make a huge token, so he's ready to pay
 3559: 	     * for the processing speed.
 3560: 	     */
 3561: 	    xmlChar *buffer;
 3562: 	    int max = len * 2;
 3563: 
 3564: 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
 3565: 	    if (buffer == NULL) {
 3566: 	        xmlErrMemory(ctxt, NULL);
 3567: 		return(NULL);
 3568: 	    }
 3569: 	    memcpy(buffer, buf, len);
 3570: 	    while (xmlIsNameChar(ctxt, c)) {
 3571: 		if (count++ > 100) {
 3572: 		    count = 0;
 3573: 		    GROW;
 3574: 		}
 3575: 		if (len + 10 > max) {
 3576: 		    xmlChar *tmp;
 3577: 
 3578: 		    max *= 2;
 3579: 		    tmp = (xmlChar *) xmlRealloc(buffer,
 3580: 			                            max * sizeof(xmlChar));
 3581: 		    if (tmp == NULL) {
 3582: 			xmlErrMemory(ctxt, NULL);
 3583: 			xmlFree(buffer);
 3584: 			return(NULL);
 3585: 		    }
 3586: 		    buffer = tmp;
 3587: 		}
 3588: 		COPY_BUF(l,buffer,len,c);
 3589: 		NEXTL(l);
 3590: 		c = CUR_CHAR(l);
 3591: 	    }
 3592: 	    buffer[len] = 0;
 3593: 	    return(buffer);
 3594: 	}
 3595:     }
 3596:     if (len == 0)
 3597:         return(NULL);
 3598:     return(xmlStrndup(buf, len));
 3599: }
 3600: 
 3601: /**
 3602:  * xmlParseEntityValue:
 3603:  * @ctxt:  an XML parser context
 3604:  * @orig:  if non-NULL store a copy of the original entity value
 3605:  *
 3606:  * parse a value for ENTITY declarations
 3607:  *
 3608:  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
 3609:  *	               "'" ([^%&'] | PEReference | Reference)* "'"
 3610:  *
 3611:  * Returns the EntityValue parsed with reference substituted or NULL
 3612:  */
 3613: 
 3614: xmlChar *
 3615: xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
 3616:     xmlChar *buf = NULL;
 3617:     int len = 0;
 3618:     int size = XML_PARSER_BUFFER_SIZE;
 3619:     int c, l;
 3620:     xmlChar stop;
 3621:     xmlChar *ret = NULL;
 3622:     const xmlChar *cur = NULL;
 3623:     xmlParserInputPtr input;
 3624: 
 3625:     if (RAW == '"') stop = '"';
 3626:     else if (RAW == '\'') stop = '\'';
 3627:     else {
 3628: 	xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
 3629: 	return(NULL);
 3630:     }
 3631:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 3632:     if (buf == NULL) {
 3633: 	xmlErrMemory(ctxt, NULL);
 3634: 	return(NULL);
 3635:     }
 3636: 
 3637:     /*
 3638:      * The content of the entity definition is copied in a buffer.
 3639:      */
 3640: 
 3641:     ctxt->instate = XML_PARSER_ENTITY_VALUE;
 3642:     input = ctxt->input;
 3643:     GROW;
 3644:     NEXT;
 3645:     c = CUR_CHAR(l);
 3646:     /*
 3647:      * NOTE: 4.4.5 Included in Literal
 3648:      * When a parameter entity reference appears in a literal entity
 3649:      * value, ... a single or double quote character in the replacement
 3650:      * text is always treated as a normal data character and will not
 3651:      * terminate the literal. 
 3652:      * In practice it means we stop the loop only when back at parsing
 3653:      * the initial entity and the quote is found
 3654:      */
 3655:     while ((IS_CHAR(c)) && ((c != stop) || /* checked */
 3656: 	   (ctxt->input != input))) {
 3657: 	if (len + 5 >= size) {
 3658: 	    xmlChar *tmp;
 3659: 
 3660: 	    size *= 2;
 3661: 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 3662: 	    if (tmp == NULL) {
 3663: 		xmlErrMemory(ctxt, NULL);
 3664: 		xmlFree(buf);
 3665: 		return(NULL);
 3666: 	    }
 3667: 	    buf = tmp;
 3668: 	}
 3669: 	COPY_BUF(l,buf,len,c);
 3670: 	NEXTL(l);
 3671: 	/*
 3672: 	 * Pop-up of finished entities.
 3673: 	 */
 3674: 	while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
 3675: 	    xmlPopInput(ctxt);
 3676: 
 3677: 	GROW;
 3678: 	c = CUR_CHAR(l);
 3679: 	if (c == 0) {
 3680: 	    GROW;
 3681: 	    c = CUR_CHAR(l);
 3682: 	}
 3683:     }
 3684:     buf[len] = 0;
 3685: 
 3686:     /*
 3687:      * Raise problem w.r.t. '&' and '%' being used in non-entities
 3688:      * reference constructs. Note Charref will be handled in
 3689:      * xmlStringDecodeEntities()
 3690:      */
 3691:     cur = buf;
 3692:     while (*cur != 0) { /* non input consuming */
 3693: 	if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
 3694: 	    xmlChar *name;
 3695: 	    xmlChar tmp = *cur;
 3696: 
 3697: 	    cur++;
 3698: 	    name = xmlParseStringName(ctxt, &cur);
 3699:             if ((name == NULL) || (*cur != ';')) {
 3700: 		xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
 3701: 	    "EntityValue: '%c' forbidden except for entities references\n",
 3702: 	                          tmp);
 3703: 	    }
 3704: 	    if ((tmp == '%') && (ctxt->inSubset == 1) &&
 3705: 		(ctxt->inputNr == 1)) {
 3706: 		xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
 3707: 	    }
 3708: 	    if (name != NULL)
 3709: 		xmlFree(name);
 3710: 	    if (*cur == 0)
 3711: 	        break;
 3712: 	}
 3713: 	cur++;
 3714:     }
 3715: 
 3716:     /*
 3717:      * Then PEReference entities are substituted.
 3718:      */
 3719:     if (c != stop) {
 3720: 	xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
 3721: 	xmlFree(buf);
 3722:     } else {
 3723: 	NEXT;
 3724: 	/*
 3725: 	 * NOTE: 4.4.7 Bypassed
 3726: 	 * When a general entity reference appears in the EntityValue in
 3727: 	 * an entity declaration, it is bypassed and left as is.
 3728: 	 * so XML_SUBSTITUTE_REF is not set here.
 3729: 	 */
 3730: 	ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
 3731: 				      0, 0, 0);
 3732: 	if (orig != NULL) 
 3733: 	    *orig = buf;
 3734: 	else
 3735: 	    xmlFree(buf);
 3736:     }
 3737:     
 3738:     return(ret);
 3739: }
 3740: 
 3741: /**
 3742:  * xmlParseAttValueComplex:
 3743:  * @ctxt:  an XML parser context
 3744:  * @len:   the resulting attribute len
 3745:  * @normalize:  wether to apply the inner normalization
 3746:  *
 3747:  * parse a value for an attribute, this is the fallback function
 3748:  * of xmlParseAttValue() when the attribute parsing requires handling
 3749:  * of non-ASCII characters, or normalization compaction.
 3750:  *
 3751:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
 3752:  */
 3753: static xmlChar *
 3754: xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
 3755:     xmlChar limit = 0;
 3756:     xmlChar *buf = NULL;
 3757:     xmlChar *rep = NULL;
 3758:     int len = 0;
 3759:     int buf_size = 0;
 3760:     int c, l, in_space = 0;
 3761:     xmlChar *current = NULL;
 3762:     xmlEntityPtr ent;
 3763: 
 3764:     if (NXT(0) == '"') {
 3765: 	ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
 3766: 	limit = '"';
 3767:         NEXT;
 3768:     } else if (NXT(0) == '\'') {
 3769: 	limit = '\'';
 3770: 	ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
 3771:         NEXT;
 3772:     } else {
 3773: 	xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
 3774: 	return(NULL);
 3775:     }
 3776: 
 3777:     /*
 3778:      * allocate a translation buffer.
 3779:      */
 3780:     buf_size = XML_PARSER_BUFFER_SIZE;
 3781:     buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
 3782:     if (buf == NULL) goto mem_error;
 3783: 
 3784:     /*
 3785:      * OK loop until we reach one of the ending char or a size limit.
 3786:      */
 3787:     c = CUR_CHAR(l);
 3788:     while ((NXT(0) != limit) && /* checked */
 3789:            (IS_CHAR(c)) && (c != '<')) {
 3790: 	if (c == 0) break;
 3791: 	if (c == '&') {
 3792: 	    in_space = 0;
 3793: 	    if (NXT(1) == '#') {
 3794: 		int val = xmlParseCharRef(ctxt);
 3795: 
 3796: 		if (val == '&') {
 3797: 		    if (ctxt->replaceEntities) {
 3798: 			if (len > buf_size - 10) {
 3799: 			    growBuffer(buf, 10);
 3800: 			}
 3801: 			buf[len++] = '&';
 3802: 		    } else {
 3803: 			/*
 3804: 			 * The reparsing will be done in xmlStringGetNodeList()
 3805: 			 * called by the attribute() function in SAX.c
 3806: 			 */
 3807: 			if (len > buf_size - 10) {
 3808: 			    growBuffer(buf, 10);
 3809: 			}
 3810: 			buf[len++] = '&';
 3811: 			buf[len++] = '#';
 3812: 			buf[len++] = '3';
 3813: 			buf[len++] = '8';
 3814: 			buf[len++] = ';';
 3815: 		    }
 3816: 		} else if (val != 0) {
 3817: 		    if (len > buf_size - 10) {
 3818: 			growBuffer(buf, 10);
 3819: 		    }
 3820: 		    len += xmlCopyChar(0, &buf[len], val);
 3821: 		}
 3822: 	    } else {
 3823: 		ent = xmlParseEntityRef(ctxt);
 3824: 		ctxt->nbentities++;
 3825: 		if (ent != NULL)
 3826: 		    ctxt->nbentities += ent->owner;
 3827: 		if ((ent != NULL) &&
 3828: 		    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
 3829: 		    if (len > buf_size - 10) {
 3830: 			growBuffer(buf, 10);
 3831: 		    }
 3832: 		    if ((ctxt->replaceEntities == 0) &&
 3833: 		        (ent->content[0] == '&')) {
 3834: 			buf[len++] = '&';
 3835: 			buf[len++] = '#';
 3836: 			buf[len++] = '3';
 3837: 			buf[len++] = '8';
 3838: 			buf[len++] = ';';
 3839: 		    } else {
 3840: 			buf[len++] = ent->content[0];
 3841: 		    }
 3842: 		} else if ((ent != NULL) && 
 3843: 		           (ctxt->replaceEntities != 0)) {
 3844: 		    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
 3845: 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 3846: 						      XML_SUBSTITUTE_REF,
 3847: 						      0, 0, 0);
 3848: 			if (rep != NULL) {
 3849: 			    current = rep;
 3850: 			    while (*current != 0) { /* non input consuming */
 3851:                                 if ((*current == 0xD) || (*current == 0xA) ||
 3852:                                     (*current == 0x9)) {
 3853:                                     buf[len++] = 0x20;
 3854:                                     current++;
 3855:                                 } else
 3856:                                     buf[len++] = *current++;
 3857: 				if (len > buf_size - 10) {
 3858: 				    growBuffer(buf, 10);
 3859: 				}
 3860: 			    }
 3861: 			    xmlFree(rep);
 3862: 			    rep = NULL;
 3863: 			}
 3864: 		    } else {
 3865: 			if (len > buf_size - 10) {
 3866: 			    growBuffer(buf, 10);
 3867: 			}
 3868: 			if (ent->content != NULL)
 3869: 			    buf[len++] = ent->content[0];
 3870: 		    }
 3871: 		} else if (ent != NULL) {
 3872: 		    int i = xmlStrlen(ent->name);
 3873: 		    const xmlChar *cur = ent->name;
 3874: 
 3875: 		    /*
 3876: 		     * This may look absurd but is needed to detect
 3877: 		     * entities problems
 3878: 		     */
 3879: 		    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
 3880: 			(ent->content != NULL)) {
 3881: 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 3882: 						  XML_SUBSTITUTE_REF, 0, 0, 0);
 3883: 			if (rep != NULL) {
 3884: 			    xmlFree(rep);
 3885: 			    rep = NULL;
 3886: 			}
 3887: 		    }
 3888: 
 3889: 		    /*
 3890: 		     * Just output the reference
 3891: 		     */
 3892: 		    buf[len++] = '&';
 3893: 		    while (len > buf_size - i - 10) {
 3894: 			growBuffer(buf, i + 10);
 3895: 		    }
 3896: 		    for (;i > 0;i--)
 3897: 			buf[len++] = *cur++;
 3898: 		    buf[len++] = ';';
 3899: 		}
 3900: 	    }
 3901: 	} else {
 3902: 	    if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
 3903: 	        if ((len != 0) || (!normalize)) {
 3904: 		    if ((!normalize) || (!in_space)) {
 3905: 			COPY_BUF(l,buf,len,0x20);
 3906: 			while (len > buf_size - 10) {
 3907: 			    growBuffer(buf, 10);
 3908: 			}
 3909: 		    }
 3910: 		    in_space = 1;
 3911: 		}
 3912: 	    } else {
 3913: 	        in_space = 0;
 3914: 		COPY_BUF(l,buf,len,c);
 3915: 		if (len > buf_size - 10) {
 3916: 		    growBuffer(buf, 10);
 3917: 		}
 3918: 	    }
 3919: 	    NEXTL(l);
 3920: 	}
 3921: 	GROW;
 3922: 	c = CUR_CHAR(l);
 3923:     }
 3924:     if ((in_space) && (normalize)) {
 3925:         while (buf[len - 1] == 0x20) len--;
 3926:     }
 3927:     buf[len] = 0;
 3928:     if (RAW == '<') {
 3929: 	xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
 3930:     } else if (RAW != limit) {
 3931: 	if ((c != 0) && (!IS_CHAR(c))) {
 3932: 	    xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
 3933: 			   "invalid character in attribute value\n");
 3934: 	} else {
 3935: 	    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
 3936: 			   "AttValue: ' expected\n");
 3937:         }
 3938:     } else
 3939: 	NEXT;
 3940:     if (attlen != NULL) *attlen = len;
 3941:     return(buf);
 3942: 
 3943: mem_error:
 3944:     xmlErrMemory(ctxt, NULL);
 3945:     if (buf != NULL)
 3946:         xmlFree(buf);
 3947:     if (rep != NULL)
 3948:         xmlFree(rep);
 3949:     return(NULL);
 3950: }
 3951: 
 3952: /**
 3953:  * xmlParseAttValue:
 3954:  * @ctxt:  an XML parser context
 3955:  *
 3956:  * parse a value for an attribute
 3957:  * Note: the parser won't do substitution of entities here, this
 3958:  * will be handled later in xmlStringGetNodeList
 3959:  *
 3960:  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
 3961:  *                   "'" ([^<&'] | Reference)* "'"
 3962:  *
 3963:  * 3.3.3 Attribute-Value Normalization:
 3964:  * Before the value of an attribute is passed to the application or
 3965:  * checked for validity, the XML processor must normalize it as follows: 
 3966:  * - a character reference is processed by appending the referenced
 3967:  *   character to the attribute value
 3968:  * - an entity reference is processed by recursively processing the
 3969:  *   replacement text of the entity 
 3970:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
 3971:  *   appending #x20 to the normalized value, except that only a single
 3972:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
 3973:  *   parsed entity or the literal entity value of an internal parsed entity 
 3974:  * - other characters are processed by appending them to the normalized value 
 3975:  * If the declared value is not CDATA, then the XML processor must further
 3976:  * process the normalized attribute value by discarding any leading and
 3977:  * trailing space (#x20) characters, and by replacing sequences of space
 3978:  * (#x20) characters by a single space (#x20) character.  
 3979:  * All attributes for which no declaration has been read should be treated
 3980:  * by a non-validating parser as if declared CDATA.
 3981:  *
 3982:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
 3983:  */
 3984: 
 3985: 
 3986: xmlChar *
 3987: xmlParseAttValue(xmlParserCtxtPtr ctxt) {
 3988:     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
 3989:     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
 3990: }
 3991: 
 3992: /**
 3993:  * xmlParseSystemLiteral:
 3994:  * @ctxt:  an XML parser context
 3995:  * 
 3996:  * parse an XML Literal
 3997:  *
 3998:  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
 3999:  *
 4000:  * Returns the SystemLiteral parsed or NULL
 4001:  */
 4002: 
 4003: xmlChar *
 4004: xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
 4005:     xmlChar *buf = NULL;
 4006:     int len = 0;
 4007:     int size = XML_PARSER_BUFFER_SIZE;
 4008:     int cur, l;
 4009:     xmlChar stop;
 4010:     int state = ctxt->instate;
 4011:     int count = 0;
 4012: 
 4013:     SHRINK;
 4014:     if (RAW == '"') {
 4015:         NEXT;
 4016: 	stop = '"';
 4017:     } else if (RAW == '\'') {
 4018:         NEXT;
 4019: 	stop = '\'';
 4020:     } else {
 4021: 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
 4022: 	return(NULL);
 4023:     }
 4024:     
 4025:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 4026:     if (buf == NULL) {
 4027:         xmlErrMemory(ctxt, NULL);
 4028: 	return(NULL);
 4029:     }
 4030:     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
 4031:     cur = CUR_CHAR(l);
 4032:     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
 4033: 	if (len + 5 >= size) {
 4034: 	    xmlChar *tmp;
 4035: 
 4036: 	    size *= 2;
 4037: 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 4038: 	    if (tmp == NULL) {
 4039: 	        xmlFree(buf);
 4040: 		xmlErrMemory(ctxt, NULL);
 4041: 		ctxt->instate = (xmlParserInputState) state;
 4042: 		return(NULL);
 4043: 	    }
 4044: 	    buf = tmp;
 4045: 	}
 4046: 	count++;
 4047: 	if (count > 50) {
 4048: 	    GROW;
 4049: 	    count = 0;
 4050: 	}
 4051: 	COPY_BUF(l,buf,len,cur);
 4052: 	NEXTL(l);
 4053: 	cur = CUR_CHAR(l);
 4054: 	if (cur == 0) {
 4055: 	    GROW;
 4056: 	    SHRINK;
 4057: 	    cur = CUR_CHAR(l);
 4058: 	}
 4059:     }
 4060:     buf[len] = 0;
 4061:     ctxt->instate = (xmlParserInputState) state;
 4062:     if (!IS_CHAR(cur)) {
 4063: 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
 4064:     } else {
 4065: 	NEXT;
 4066:     }
 4067:     return(buf);
 4068: }
 4069: 
 4070: /**
 4071:  * xmlParsePubidLiteral:
 4072:  * @ctxt:  an XML parser context
 4073:  *
 4074:  * parse an XML public literal
 4075:  *
 4076:  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
 4077:  *
 4078:  * Returns the PubidLiteral parsed or NULL.
 4079:  */
 4080: 
 4081: xmlChar *
 4082: xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
 4083:     xmlChar *buf = NULL;
 4084:     int len = 0;
 4085:     int size = XML_PARSER_BUFFER_SIZE;
 4086:     xmlChar cur;
 4087:     xmlChar stop;
 4088:     int count = 0;
 4089:     xmlParserInputState oldstate = ctxt->instate;
 4090: 
 4091:     SHRINK;
 4092:     if (RAW == '"') {
 4093:         NEXT;
 4094: 	stop = '"';
 4095:     } else if (RAW == '\'') {
 4096:         NEXT;
 4097: 	stop = '\'';
 4098:     } else {
 4099: 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
 4100: 	return(NULL);
 4101:     }
 4102:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 4103:     if (buf == NULL) {
 4104: 	xmlErrMemory(ctxt, NULL);
 4105: 	return(NULL);
 4106:     }
 4107:     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
 4108:     cur = CUR;
 4109:     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
 4110: 	if (len + 1 >= size) {
 4111: 	    xmlChar *tmp;
 4112: 
 4113: 	    size *= 2;
 4114: 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 4115: 	    if (tmp == NULL) {
 4116: 		xmlErrMemory(ctxt, NULL);
 4117: 		xmlFree(buf);
 4118: 		return(NULL);
 4119: 	    }
 4120: 	    buf = tmp;
 4121: 	}
 4122: 	buf[len++] = cur;
 4123: 	count++;
 4124: 	if (count > 50) {
 4125: 	    GROW;
 4126: 	    count = 0;
 4127: 	}
 4128: 	NEXT;
 4129: 	cur = CUR;
 4130: 	if (cur == 0) {
 4131: 	    GROW;
 4132: 	    SHRINK;
 4133: 	    cur = CUR;
 4134: 	}
 4135:     }
 4136:     buf[len] = 0;
 4137:     if (cur != stop) {
 4138: 	xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
 4139:     } else {
 4140: 	NEXT;
 4141:     }
 4142:     ctxt->instate = oldstate;
 4143:     return(buf);
 4144: }
 4145: 
 4146: static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
 4147: 
 4148: /*
 4149:  * used for the test in the inner loop of the char data testing
 4150:  */
 4151: static const unsigned char test_char_data[256] = {
 4152:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4153:     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
 4154:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4155:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4156:     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
 4157:     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
 4158:     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
 4159:     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
 4160:     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
 4161:     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
 4162:     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
 4163:     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
 4164:     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
 4165:     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
 4166:     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
 4167:     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
 4168:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
 4169:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4170:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4171:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4172:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4173:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4174:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4175:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4176:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4177:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4178:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4179:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4180:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4181:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4182:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 4183:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 4184: };
 4185: 
 4186: /**
 4187:  * xmlParseCharData:
 4188:  * @ctxt:  an XML parser context
 4189:  * @cdata:  int indicating whether we are within a CDATA section
 4190:  *
 4191:  * parse a CharData section.
 4192:  * if we are within a CDATA section ']]>' marks an end of section.
 4193:  *
 4194:  * The right angle bracket (>) may be represented using the string "&gt;",
 4195:  * and must, for compatibility, be escaped using "&gt;" or a character
 4196:  * reference when it appears in the string "]]>" in content, when that
 4197:  * string is not marking the end of a CDATA section. 
 4198:  *
 4199:  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
 4200:  */
 4201: 
 4202: void
 4203: xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
 4204:     const xmlChar *in;
 4205:     int nbchar = 0;
 4206:     int line = ctxt->input->line;
 4207:     int col = ctxt->input->col;
 4208:     int ccol;
 4209: 
 4210:     SHRINK;
 4211:     GROW;
 4212:     /*
 4213:      * Accelerated common case where input don't need to be
 4214:      * modified before passing it to the handler.
 4215:      */
 4216:     if (!cdata) {
 4217: 	in = ctxt->input->cur;
 4218: 	do {
 4219: get_more_space:
 4220: 	    while (*in == 0x20) { in++; ctxt->input->col++; }
 4221: 	    if (*in == 0xA) {
 4222: 		do {
 4223: 		    ctxt->input->line++; ctxt->input->col = 1;
 4224: 		    in++;
 4225: 		} while (*in == 0xA);
 4226: 		goto get_more_space;
 4227: 	    }
 4228: 	    if (*in == '<') {
 4229: 		nbchar = in - ctxt->input->cur;
 4230: 		if (nbchar > 0) {
 4231: 		    const xmlChar *tmp = ctxt->input->cur;
 4232: 		    ctxt->input->cur = in;
 4233: 
 4234: 		    if ((ctxt->sax != NULL) &&
 4235: 		        (ctxt->sax->ignorableWhitespace !=
 4236: 		         ctxt->sax->characters)) {
 4237: 			if (areBlanks(ctxt, tmp, nbchar, 1)) {
 4238: 			    if (ctxt->sax->ignorableWhitespace != NULL)
 4239: 				ctxt->sax->ignorableWhitespace(ctxt->userData,
 4240: 						       tmp, nbchar);
 4241: 			} else {
 4242: 			    if (ctxt->sax->characters != NULL)
 4243: 				ctxt->sax->characters(ctxt->userData,
 4244: 						      tmp, nbchar);
 4245: 			    if (*ctxt->space == -1)
 4246: 			        *ctxt->space = -2;
 4247: 			}
 4248: 		    } else if ((ctxt->sax != NULL) &&
 4249: 		               (ctxt->sax->characters != NULL)) {
 4250: 			ctxt->sax->characters(ctxt->userData,
 4251: 					      tmp, nbchar);
 4252: 		    }
 4253: 		}
 4254: 		return;
 4255: 	    }
 4256: 
 4257: get_more:
 4258:             ccol = ctxt->input->col;
 4259: 	    while (test_char_data[*in]) {
 4260: 		in++;
 4261: 		ccol++;
 4262: 	    }
 4263: 	    ctxt->input->col = ccol;
 4264: 	    if (*in == 0xA) {
 4265: 		do {
 4266: 		    ctxt->input->line++; ctxt->input->col = 1;
 4267: 		    in++;
 4268: 		} while (*in == 0xA);
 4269: 		goto get_more;
 4270: 	    }
 4271: 	    if (*in == ']') {
 4272: 		if ((in[1] == ']') && (in[2] == '>')) {
 4273: 		    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
 4274: 		    ctxt->input->cur = in;
 4275: 		    return;
 4276: 		}
 4277: 		in++;
 4278: 		ctxt->input->col++;
 4279: 		goto get_more;
 4280: 	    }
 4281: 	    nbchar = in - ctxt->input->cur;
 4282: 	    if (nbchar > 0) {
 4283: 		if ((ctxt->sax != NULL) &&
 4284: 		    (ctxt->sax->ignorableWhitespace !=
 4285: 		     ctxt->sax->characters) &&
 4286: 		    (IS_BLANK_CH(*ctxt->input->cur))) {
 4287: 		    const xmlChar *tmp = ctxt->input->cur;
 4288: 		    ctxt->input->cur = in;
 4289: 
 4290: 		    if (areBlanks(ctxt, tmp, nbchar, 0)) {
 4291: 		        if (ctxt->sax->ignorableWhitespace != NULL)
 4292: 			    ctxt->sax->ignorableWhitespace(ctxt->userData,
 4293: 							   tmp, nbchar);
 4294: 		    } else {
 4295: 		        if (ctxt->sax->characters != NULL)
 4296: 			    ctxt->sax->characters(ctxt->userData,
 4297: 						  tmp, nbchar);
 4298: 			if (*ctxt->space == -1)
 4299: 			    *ctxt->space = -2;
 4300: 		    }
 4301:                     line = ctxt->input->line;
 4302:                     col = ctxt->input->col;
 4303: 		} else if (ctxt->sax != NULL) {
 4304: 		    if (ctxt->sax->characters != NULL)
 4305: 			ctxt->sax->characters(ctxt->userData,
 4306: 					      ctxt->input->cur, nbchar);
 4307:                     line = ctxt->input->line;
 4308:                     col = ctxt->input->col;
 4309: 		}
 4310:                 /* something really bad happened in the SAX callback */
 4311:                 if (ctxt->instate != XML_PARSER_CONTENT)
 4312:                     return;
 4313: 	    }
 4314: 	    ctxt->input->cur = in;
 4315: 	    if (*in == 0xD) {
 4316: 		in++;
 4317: 		if (*in == 0xA) {
 4318: 		    ctxt->input->cur = in;
 4319: 		    in++;
 4320: 		    ctxt->input->line++; ctxt->input->col = 1;
 4321: 		    continue; /* while */
 4322: 		}
 4323: 		in--;
 4324: 	    }
 4325: 	    if (*in == '<') {
 4326: 		return;
 4327: 	    }
 4328: 	    if (*in == '&') {
 4329: 		return;
 4330: 	    }
 4331: 	    SHRINK;
 4332: 	    GROW;
 4333: 	    in = ctxt->input->cur;
 4334: 	} while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
 4335: 	nbchar = 0;
 4336:     }
 4337:     ctxt->input->line = line;
 4338:     ctxt->input->col = col;
 4339:     xmlParseCharDataComplex(ctxt, cdata);
 4340: }
 4341: 
 4342: /**
 4343:  * xmlParseCharDataComplex:
 4344:  * @ctxt:  an XML parser context
 4345:  * @cdata:  int indicating whether we are within a CDATA section
 4346:  *
 4347:  * parse a CharData section.this is the fallback function
 4348:  * of xmlParseCharData() when the parsing requires handling
 4349:  * of non-ASCII characters.
 4350:  */
 4351: static void
 4352: xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
 4353:     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
 4354:     int nbchar = 0;
 4355:     int cur, l;
 4356:     int count = 0;
 4357: 
 4358:     SHRINK;
 4359:     GROW;
 4360:     cur = CUR_CHAR(l);
 4361:     while ((cur != '<') && /* checked */
 4362:            (cur != '&') && 
 4363: 	   (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
 4364: 	if ((cur == ']') && (NXT(1) == ']') &&
 4365: 	    (NXT(2) == '>')) {
 4366: 	    if (cdata) break;
 4367: 	    else {
 4368: 		xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
 4369: 	    }
 4370: 	}
 4371: 	COPY_BUF(l,buf,nbchar,cur);
 4372: 	if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
 4373: 	    buf[nbchar] = 0;
 4374: 
 4375: 	    /*
 4376: 	     * OK the segment is to be consumed as chars.
 4377: 	     */
 4378: 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
 4379: 		if (areBlanks(ctxt, buf, nbchar, 0)) {
 4380: 		    if (ctxt->sax->ignorableWhitespace != NULL)
 4381: 			ctxt->sax->ignorableWhitespace(ctxt->userData,
 4382: 			                               buf, nbchar);
 4383: 		} else {
 4384: 		    if (ctxt->sax->characters != NULL)
 4385: 			ctxt->sax->characters(ctxt->userData, buf, nbchar);
 4386: 		    if ((ctxt->sax->characters !=
 4387: 		         ctxt->sax->ignorableWhitespace) &&
 4388: 			(*ctxt->space == -1))
 4389: 			*ctxt->space = -2;
 4390: 		}
 4391: 	    }
 4392: 	    nbchar = 0;
 4393:             /* something really bad happened in the SAX callback */
 4394:             if (ctxt->instate != XML_PARSER_CONTENT)
 4395:                 return;
 4396: 	}
 4397: 	count++;
 4398: 	if (count > 50) {
 4399: 	    GROW;
 4400: 	    count = 0;
 4401: 	}
 4402: 	NEXTL(l);
 4403: 	cur = CUR_CHAR(l);
 4404:     }
 4405:     if (nbchar != 0) {
 4406:         buf[nbchar] = 0;
 4407: 	/*
 4408: 	 * OK the segment is to be consumed as chars.
 4409: 	 */
 4410: 	if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
 4411: 	    if (areBlanks(ctxt, buf, nbchar, 0)) {
 4412: 		if (ctxt->sax->ignorableWhitespace != NULL)
 4413: 		    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
 4414: 	    } else {
 4415: 		if (ctxt->sax->characters != NULL)
 4416: 		    ctxt->sax->characters(ctxt->userData, buf, nbchar);
 4417: 		if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
 4418: 		    (*ctxt->space == -1))
 4419: 		    *ctxt->space = -2;
 4420: 	    }
 4421: 	}
 4422:     }
 4423:     if ((cur != 0) && (!IS_CHAR(cur))) {
 4424: 	/* Generate the error and skip the offending character */
 4425:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 4426:                           "PCDATA invalid Char value %d\n",
 4427: 	                  cur);
 4428: 	NEXTL(l);
 4429:     }
 4430: }
 4431: 
 4432: /**
 4433:  * xmlParseExternalID:
 4434:  * @ctxt:  an XML parser context
 4435:  * @publicID:  a xmlChar** receiving PubidLiteral
 4436:  * @strict: indicate whether we should restrict parsing to only
 4437:  *          production [75], see NOTE below
 4438:  *
 4439:  * Parse an External ID or a Public ID
 4440:  *
 4441:  * NOTE: Productions [75] and [83] interact badly since [75] can generate
 4442:  *       'PUBLIC' S PubidLiteral S SystemLiteral
 4443:  *
 4444:  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
 4445:  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
 4446:  *
 4447:  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
 4448:  *
 4449:  * Returns the function returns SystemLiteral and in the second
 4450:  *                case publicID receives PubidLiteral, is strict is off
 4451:  *                it is possible to return NULL and have publicID set.
 4452:  */
 4453: 
 4454: xmlChar *
 4455: xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
 4456:     xmlChar *URI = NULL;
 4457: 
 4458:     SHRINK;
 4459: 
 4460:     *publicID = NULL;
 4461:     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
 4462:         SKIP(6);
 4463: 	if (!IS_BLANK_CH(CUR)) {
 4464: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 4465: 	                   "Space required after 'SYSTEM'\n");
 4466: 	}
 4467:         SKIP_BLANKS;
 4468: 	URI = xmlParseSystemLiteral(ctxt);
 4469: 	if (URI == NULL) {
 4470: 	    xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
 4471:         }
 4472:     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
 4473:         SKIP(6);
 4474: 	if (!IS_BLANK_CH(CUR)) {
 4475: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 4476: 		    "Space required after 'PUBLIC'\n");
 4477: 	}
 4478:         SKIP_BLANKS;
 4479: 	*publicID = xmlParsePubidLiteral(ctxt);
 4480: 	if (*publicID == NULL) {
 4481: 	    xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
 4482: 	}
 4483: 	if (strict) {
 4484: 	    /*
 4485: 	     * We don't handle [83] so "S SystemLiteral" is required.
 4486: 	     */
 4487: 	    if (!IS_BLANK_CH(CUR)) {
 4488: 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 4489: 			"Space required after the Public Identifier\n");
 4490: 	    }
 4491: 	} else {
 4492: 	    /*
 4493: 	     * We handle [83] so we return immediately, if 
 4494: 	     * "S SystemLiteral" is not detected. From a purely parsing
 4495: 	     * point of view that's a nice mess.
 4496: 	     */
 4497: 	    const xmlChar *ptr;
 4498: 	    GROW;
 4499: 
 4500: 	    ptr = CUR_PTR;
 4501: 	    if (!IS_BLANK_CH(*ptr)) return(NULL);
 4502: 	    
 4503: 	    while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
 4504: 	    if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
 4505: 	}
 4506:         SKIP_BLANKS;
 4507: 	URI = xmlParseSystemLiteral(ctxt);
 4508: 	if (URI == NULL) {
 4509: 	    xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
 4510:         }
 4511:     }
 4512:     return(URI);
 4513: }
 4514: 
 4515: /**
 4516:  * xmlParseCommentComplex:
 4517:  * @ctxt:  an XML parser context
 4518:  * @buf:  the already parsed part of the buffer
 4519:  * @len:  number of bytes filles in the buffer
 4520:  * @size:  allocated size of the buffer
 4521:  *
 4522:  * Skip an XML (SGML) comment <!-- .... -->
 4523:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
 4524:  *  must not occur within comments. "
 4525:  * This is the slow routine in case the accelerator for ascii didn't work
 4526:  *
 4527:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
 4528:  */
 4529: static void
 4530: xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
 4531:     int q, ql;
 4532:     int r, rl;
 4533:     int cur, l;
 4534:     int count = 0;
 4535:     int inputid;
 4536: 
 4537:     inputid = ctxt->input->id;
 4538: 
 4539:     if (buf == NULL) {
 4540:         len = 0;
 4541: 	size = XML_PARSER_BUFFER_SIZE;
 4542: 	buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 4543: 	if (buf == NULL) {
 4544: 	    xmlErrMemory(ctxt, NULL);
 4545: 	    return;
 4546: 	}
 4547:     }
 4548:     GROW;	/* Assure there's enough input data */
 4549:     q = CUR_CHAR(ql);
 4550:     if (q == 0)
 4551:         goto not_terminated;
 4552:     if (!IS_CHAR(q)) {
 4553:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 4554:                           "xmlParseComment: invalid xmlChar value %d\n",
 4555: 	                  q);
 4556: 	xmlFree (buf);
 4557: 	return;
 4558:     }
 4559:     NEXTL(ql);
 4560:     r = CUR_CHAR(rl);
 4561:     if (r == 0)
 4562:         goto not_terminated;
 4563:     if (!IS_CHAR(r)) {
 4564:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 4565:                           "xmlParseComment: invalid xmlChar value %d\n",
 4566: 	                  q);
 4567: 	xmlFree (buf);
 4568: 	return;
 4569:     }
 4570:     NEXTL(rl);
 4571:     cur = CUR_CHAR(l);
 4572:     if (cur == 0)
 4573:         goto not_terminated;
 4574:     while (IS_CHAR(cur) && /* checked */
 4575:            ((cur != '>') ||
 4576: 	    (r != '-') || (q != '-'))) {
 4577: 	if ((r == '-') && (q == '-')) {
 4578: 	    xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
 4579: 	}
 4580: 	if (len + 5 >= size) {
 4581: 	    xmlChar *new_buf;
 4582: 	    size *= 2;
 4583: 	    new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 4584: 	    if (new_buf == NULL) {
 4585: 		xmlFree (buf);
 4586: 		xmlErrMemory(ctxt, NULL);
 4587: 		return;
 4588: 	    }
 4589: 	    buf = new_buf;
 4590: 	}
 4591: 	COPY_BUF(ql,buf,len,q);
 4592: 	q = r;
 4593: 	ql = rl;
 4594: 	r = cur;
 4595: 	rl = l;
 4596: 
 4597: 	count++;
 4598: 	if (count > 50) {
 4599: 	    GROW;
 4600: 	    count = 0;
 4601: 	}
 4602: 	NEXTL(l);
 4603: 	cur = CUR_CHAR(l);
 4604: 	if (cur == 0) {
 4605: 	    SHRINK;
 4606: 	    GROW;
 4607: 	    cur = CUR_CHAR(l);
 4608: 	}
 4609:     }
 4610:     buf[len] = 0;
 4611:     if (cur == 0) {
 4612: 	xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
 4613: 	                     "Comment not terminated \n<!--%.50s\n", buf);
 4614:     } else if (!IS_CHAR(cur)) {
 4615:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 4616:                           "xmlParseComment: invalid xmlChar value %d\n",
 4617: 	                  cur);
 4618:     } else {
 4619: 	if (inputid != ctxt->input->id) {
 4620: 	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
 4621: 		"Comment doesn't start and stop in the same entity\n");
 4622: 	}
 4623:         NEXT;
 4624: 	if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
 4625: 	    (!ctxt->disableSAX))
 4626: 	    ctxt->sax->comment(ctxt->userData, buf);
 4627:     }
 4628:     xmlFree(buf);
 4629:     return;
 4630: not_terminated:
 4631:     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
 4632: 			 "Comment not terminated\n", NULL);
 4633:     xmlFree(buf);
 4634:     return;
 4635: }
 4636: 
 4637: /**
 4638:  * xmlParseComment:
 4639:  * @ctxt:  an XML parser context
 4640:  *
 4641:  * Skip an XML (SGML) comment <!-- .... -->
 4642:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
 4643:  *  must not occur within comments. "
 4644:  *
 4645:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
 4646:  */
 4647: void
 4648: xmlParseComment(xmlParserCtxtPtr ctxt) {
 4649:     xmlChar *buf = NULL;
 4650:     int size = XML_PARSER_BUFFER_SIZE;
 4651:     int len = 0;
 4652:     xmlParserInputState state;
 4653:     const xmlChar *in;
 4654:     int nbchar = 0, ccol;
 4655:     int inputid;
 4656: 
 4657:     /*
 4658:      * Check that there is a comment right here.
 4659:      */
 4660:     if ((RAW != '<') || (NXT(1) != '!') ||
 4661:         (NXT(2) != '-') || (NXT(3) != '-')) return;
 4662:     state = ctxt->instate;
 4663:     ctxt->instate = XML_PARSER_COMMENT;
 4664:     inputid = ctxt->input->id;
 4665:     SKIP(4);
 4666:     SHRINK;
 4667:     GROW;
 4668: 
 4669:     /*
 4670:      * Accelerated common case where input don't need to be
 4671:      * modified before passing it to the handler.
 4672:      */
 4673:     in = ctxt->input->cur;
 4674:     do {
 4675: 	if (*in == 0xA) {
 4676: 	    do {
 4677: 		ctxt->input->line++; ctxt->input->col = 1;
 4678: 		in++;
 4679: 	    } while (*in == 0xA);
 4680: 	}
 4681: get_more:
 4682:         ccol = ctxt->input->col;
 4683: 	while (((*in > '-') && (*in <= 0x7F)) ||
 4684: 	       ((*in >= 0x20) && (*in < '-')) ||
 4685: 	       (*in == 0x09)) {
 4686: 		    in++;
 4687: 		    ccol++;
 4688: 	}
 4689: 	ctxt->input->col = ccol;
 4690: 	if (*in == 0xA) {
 4691: 	    do {
 4692: 		ctxt->input->line++; ctxt->input->col = 1;
 4693: 		in++;
 4694: 	    } while (*in == 0xA);
 4695: 	    goto get_more;
 4696: 	}
 4697: 	nbchar = in - ctxt->input->cur;
 4698: 	/*
 4699: 	 * save current set of data
 4700: 	 */
 4701: 	if (nbchar > 0) {
 4702: 	    if ((ctxt->sax != NULL) &&
 4703: 		(ctxt->sax->comment != NULL)) {
 4704: 		if (buf == NULL) {
 4705: 		    if ((*in == '-') && (in[1] == '-'))
 4706: 		        size = nbchar + 1;
 4707: 		    else
 4708: 		        size = XML_PARSER_BUFFER_SIZE + nbchar;
 4709: 		    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 4710: 		    if (buf == NULL) {
 4711: 		        xmlErrMemory(ctxt, NULL);
 4712: 			ctxt->instate = state;
 4713: 			return;
 4714: 		    }
 4715: 		    len = 0;
 4716: 		} else if (len + nbchar + 1 >= size) {
 4717: 		    xmlChar *new_buf;
 4718: 		    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
 4719: 		    new_buf = (xmlChar *) xmlRealloc(buf,
 4720: 		                                     size * sizeof(xmlChar));
 4721: 		    if (new_buf == NULL) {
 4722: 		        xmlFree (buf);
 4723: 			xmlErrMemory(ctxt, NULL);
 4724: 			ctxt->instate = state;
 4725: 			return;
 4726: 		    }
 4727: 		    buf = new_buf;
 4728: 		}
 4729: 		memcpy(&buf[len], ctxt->input->cur, nbchar);
 4730: 		len += nbchar;
 4731: 		buf[len] = 0;
 4732: 	    }
 4733: 	}
 4734: 	ctxt->input->cur = in;
 4735: 	if (*in == 0xA) {
 4736: 	    in++;
 4737: 	    ctxt->input->line++; ctxt->input->col = 1;
 4738: 	}
 4739: 	if (*in == 0xD) {
 4740: 	    in++;
 4741: 	    if (*in == 0xA) {
 4742: 		ctxt->input->cur = in;
 4743: 		in++;
 4744: 		ctxt->input->line++; ctxt->input->col = 1;
 4745: 		continue; /* while */
 4746: 	    }
 4747: 	    in--;
 4748: 	}
 4749: 	SHRINK;
 4750: 	GROW;
 4751: 	in = ctxt->input->cur;
 4752: 	if (*in == '-') {
 4753: 	    if (in[1] == '-') {
 4754: 	        if (in[2] == '>') {
 4755: 		    if (ctxt->input->id != inputid) {
 4756: 			xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
 4757: 			"comment doesn't start and stop in the same entity\n");
 4758: 		    }
 4759: 		    SKIP(3);
 4760: 		    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
 4761: 		        (!ctxt->disableSAX)) {
 4762: 			if (buf != NULL)
 4763: 			    ctxt->sax->comment(ctxt->userData, buf);
 4764: 			else
 4765: 			    ctxt->sax->comment(ctxt->userData, BAD_CAST "");
 4766: 		    }
 4767: 		    if (buf != NULL)
 4768: 		        xmlFree(buf);
 4769: 		    ctxt->instate = state;
 4770: 		    return;
 4771: 		}
 4772: 		if (buf != NULL)
 4773: 		    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
 4774: 		                      "Comment not terminated \n<!--%.50s\n",
 4775: 				      buf);
 4776: 		else
 4777: 		    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
 4778: 		                      "Comment not terminated \n", NULL);
 4779: 		in++;
 4780: 		ctxt->input->col++;
 4781: 	    }
 4782: 	    in++;
 4783: 	    ctxt->input->col++;
 4784: 	    goto get_more;
 4785: 	}
 4786:     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
 4787:     xmlParseCommentComplex(ctxt, buf, len, size);
 4788:     ctxt->instate = state;
 4789:     return;
 4790: }
 4791: 
 4792: 
 4793: /**
 4794:  * xmlParsePITarget:
 4795:  * @ctxt:  an XML parser context
 4796:  * 
 4797:  * parse the name of a PI
 4798:  *
 4799:  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
 4800:  *
 4801:  * Returns the PITarget name or NULL
 4802:  */
 4803: 
 4804: const xmlChar *
 4805: xmlParsePITarget(xmlParserCtxtPtr ctxt) {
 4806:     const xmlChar *name;
 4807: 
 4808:     name = xmlParseName(ctxt);
 4809:     if ((name != NULL) &&
 4810:         ((name[0] == 'x') || (name[0] == 'X')) &&
 4811:         ((name[1] == 'm') || (name[1] == 'M')) &&
 4812:         ((name[2] == 'l') || (name[2] == 'L'))) {
 4813: 	int i;
 4814: 	if ((name[0] == 'x') && (name[1] == 'm') &&
 4815: 	    (name[2] == 'l') && (name[3] == 0)) {
 4816: 	    xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
 4817: 		 "XML declaration allowed only at the start of the document\n");
 4818: 	    return(name);
 4819: 	} else if (name[3] == 0) {
 4820: 	    xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
 4821: 	    return(name);
 4822: 	}
 4823: 	for (i = 0;;i++) {
 4824: 	    if (xmlW3CPIs[i] == NULL) break;
 4825: 	    if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
 4826: 	        return(name);
 4827: 	}
 4828: 	xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
 4829: 		      "xmlParsePITarget: invalid name prefix 'xml'\n",
 4830: 		      NULL, NULL);
 4831:     }
 4832:     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
 4833: 	xmlNsErr(ctxt, XML_NS_ERR_COLON, 
 4834: 		 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
 4835:     }
 4836:     return(name);
 4837: }
 4838: 
 4839: #ifdef LIBXML_CATALOG_ENABLED
 4840: /**
 4841:  * xmlParseCatalogPI:
 4842:  * @ctxt:  an XML parser context
 4843:  * @catalog:  the PI value string
 4844:  * 
 4845:  * parse an XML Catalog Processing Instruction.
 4846:  *
 4847:  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
 4848:  *
 4849:  * Occurs only if allowed by the user and if happening in the Misc
 4850:  * part of the document before any doctype informations
 4851:  * This will add the given catalog to the parsing context in order
 4852:  * to be used if there is a resolution need further down in the document
 4853:  */
 4854: 
 4855: static void
 4856: xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
 4857:     xmlChar *URL = NULL;
 4858:     const xmlChar *tmp, *base;
 4859:     xmlChar marker;
 4860: 
 4861:     tmp = catalog;
 4862:     while (IS_BLANK_CH(*tmp)) tmp++;
 4863:     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
 4864: 	goto error;
 4865:     tmp += 7;
 4866:     while (IS_BLANK_CH(*tmp)) tmp++;
 4867:     if (*tmp != '=') {
 4868: 	return;
 4869:     }
 4870:     tmp++;
 4871:     while (IS_BLANK_CH(*tmp)) tmp++;
 4872:     marker = *tmp;
 4873:     if ((marker != '\'') && (marker != '"'))
 4874: 	goto error;
 4875:     tmp++;
 4876:     base = tmp;
 4877:     while ((*tmp != 0) && (*tmp != marker)) tmp++;
 4878:     if (*tmp == 0)
 4879: 	goto error;
 4880:     URL = xmlStrndup(base, tmp - base);
 4881:     tmp++;
 4882:     while (IS_BLANK_CH(*tmp)) tmp++;
 4883:     if (*tmp != 0)
 4884: 	goto error;
 4885: 
 4886:     if (URL != NULL) {
 4887: 	ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
 4888: 	xmlFree(URL);
 4889:     }
 4890:     return;
 4891: 
 4892: error:
 4893:     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
 4894: 	          "Catalog PI syntax error: %s\n",
 4895: 		  catalog, NULL);
 4896:     if (URL != NULL)
 4897: 	xmlFree(URL);
 4898: }
 4899: #endif
 4900: 
 4901: /**
 4902:  * xmlParsePI:
 4903:  * @ctxt:  an XML parser context
 4904:  * 
 4905:  * parse an XML Processing Instruction.
 4906:  *
 4907:  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
 4908:  *
 4909:  * The processing is transfered to SAX once parsed.
 4910:  */
 4911: 
 4912: void
 4913: xmlParsePI(xmlParserCtxtPtr ctxt) {
 4914:     xmlChar *buf = NULL;
 4915:     int len = 0;
 4916:     int size = XML_PARSER_BUFFER_SIZE;
 4917:     int cur, l;
 4918:     const xmlChar *target;
 4919:     xmlParserInputState state;
 4920:     int count = 0;
 4921: 
 4922:     if ((RAW == '<') && (NXT(1) == '?')) {
 4923: 	xmlParserInputPtr input = ctxt->input;
 4924: 	state = ctxt->instate;
 4925:         ctxt->instate = XML_PARSER_PI;
 4926: 	/*
 4927: 	 * this is a Processing Instruction.
 4928: 	 */
 4929: 	SKIP(2);
 4930: 	SHRINK;
 4931: 
 4932: 	/*
 4933: 	 * Parse the target name and check for special support like
 4934: 	 * namespace.
 4935: 	 */
 4936:         target = xmlParsePITarget(ctxt);
 4937: 	if (target != NULL) {
 4938: 	    if ((RAW == '?') && (NXT(1) == '>')) {
 4939: 		if (input != ctxt->input) {
 4940: 		    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
 4941: 	    "PI declaration doesn't start and stop in the same entity\n");
 4942: 		}
 4943: 		SKIP(2);
 4944: 
 4945: 		/*
 4946: 		 * SAX: PI detected.
 4947: 		 */
 4948: 		if ((ctxt->sax) && (!ctxt->disableSAX) &&
 4949: 		    (ctxt->sax->processingInstruction != NULL))
 4950: 		    ctxt->sax->processingInstruction(ctxt->userData,
 4951: 		                                     target, NULL);
 4952: 		ctxt->instate = state;
 4953: 		return;
 4954: 	    }
 4955: 	    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 4956: 	    if (buf == NULL) {
 4957: 		xmlErrMemory(ctxt, NULL);
 4958: 		ctxt->instate = state;
 4959: 		return;
 4960: 	    }
 4961: 	    cur = CUR;
 4962: 	    if (!IS_BLANK(cur)) {
 4963: 		xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
 4964: 			  "ParsePI: PI %s space expected\n", target);
 4965: 	    }
 4966:             SKIP_BLANKS;
 4967: 	    cur = CUR_CHAR(l);
 4968: 	    while (IS_CHAR(cur) && /* checked */
 4969: 		   ((cur != '?') || (NXT(1) != '>'))) {
 4970: 		if (len + 5 >= size) {
 4971: 		    xmlChar *tmp;
 4972: 
 4973: 		    size *= 2;
 4974: 		    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 4975: 		    if (tmp == NULL) {
 4976: 			xmlErrMemory(ctxt, NULL);
 4977: 			xmlFree(buf);
 4978: 			ctxt->instate = state;
 4979: 			return;
 4980: 		    }
 4981: 		    buf = tmp;
 4982: 		}
 4983: 		count++;
 4984: 		if (count > 50) {
 4985: 		    GROW;
 4986: 		    count = 0;
 4987: 		}
 4988: 		COPY_BUF(l,buf,len,cur);
 4989: 		NEXTL(l);
 4990: 		cur = CUR_CHAR(l);
 4991: 		if (cur == 0) {
 4992: 		    SHRINK;
 4993: 		    GROW;
 4994: 		    cur = CUR_CHAR(l);
 4995: 		}
 4996: 	    }
 4997: 	    buf[len] = 0;
 4998: 	    if (cur != '?') {
 4999: 		xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
 5000: 		      "ParsePI: PI %s never end ...\n", target);
 5001: 	    } else {
 5002: 		if (input != ctxt->input) {
 5003: 		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5004: 	    "PI declaration doesn't start and stop in the same entity\n");
 5005: 		}
 5006: 		SKIP(2);
 5007: 
 5008: #ifdef LIBXML_CATALOG_ENABLED
 5009: 		if (((state == XML_PARSER_MISC) ||
 5010: 	             (state == XML_PARSER_START)) &&
 5011: 		    (xmlStrEqual(target, XML_CATALOG_PI))) {
 5012: 		    xmlCatalogAllow allow = xmlCatalogGetDefaults();
 5013: 		    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
 5014: 			(allow == XML_CATA_ALLOW_ALL))
 5015: 			xmlParseCatalogPI(ctxt, buf);
 5016: 		}
 5017: #endif
 5018: 
 5019: 
 5020: 		/*
 5021: 		 * SAX: PI detected.
 5022: 		 */
 5023: 		if ((ctxt->sax) && (!ctxt->disableSAX) &&
 5024: 		    (ctxt->sax->processingInstruction != NULL))
 5025: 		    ctxt->sax->processingInstruction(ctxt->userData,
 5026: 		                                     target, buf);
 5027: 	    }
 5028: 	    xmlFree(buf);
 5029: 	} else {
 5030: 	    xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
 5031: 	}
 5032: 	ctxt->instate = state;
 5033:     }
 5034: }
 5035: 
 5036: /**
 5037:  * xmlParseNotationDecl:
 5038:  * @ctxt:  an XML parser context
 5039:  *
 5040:  * parse a notation declaration
 5041:  *
 5042:  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
 5043:  *
 5044:  * Hence there is actually 3 choices:
 5045:  *     'PUBLIC' S PubidLiteral
 5046:  *     'PUBLIC' S PubidLiteral S SystemLiteral
 5047:  * and 'SYSTEM' S SystemLiteral
 5048:  *
 5049:  * See the NOTE on xmlParseExternalID().
 5050:  */
 5051: 
 5052: void
 5053: xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
 5054:     const xmlChar *name;
 5055:     xmlChar *Pubid;
 5056:     xmlChar *Systemid;
 5057:     
 5058:     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
 5059: 	xmlParserInputPtr input = ctxt->input;
 5060: 	SHRINK;
 5061: 	SKIP(10);
 5062: 	if (!IS_BLANK_CH(CUR)) {
 5063: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5064: 			   "Space required after '<!NOTATION'\n");
 5065: 	    return;
 5066: 	}
 5067: 	SKIP_BLANKS;
 5068: 
 5069:         name = xmlParseName(ctxt);
 5070: 	if (name == NULL) {
 5071: 	    xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
 5072: 	    return;
 5073: 	}
 5074: 	if (!IS_BLANK_CH(CUR)) {
 5075: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5076: 		     "Space required after the NOTATION name'\n");
 5077: 	    return;
 5078: 	}
 5079: 	if (xmlStrchr(name, ':') != NULL) {
 5080: 	    xmlNsErr(ctxt, XML_NS_ERR_COLON, 
 5081: 		     "colon are forbidden from notation names '%s'\n",
 5082: 		     name, NULL, NULL);
 5083: 	}
 5084: 	SKIP_BLANKS;
 5085: 
 5086: 	/*
 5087: 	 * Parse the IDs.
 5088: 	 */
 5089: 	Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
 5090: 	SKIP_BLANKS;
 5091: 
 5092: 	if (RAW == '>') {
 5093: 	    if (input != ctxt->input) {
 5094: 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5095: 	"Notation declaration doesn't start and stop in the same entity\n");
 5096: 	    }
 5097: 	    NEXT;
 5098: 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
 5099: 		(ctxt->sax->notationDecl != NULL))
 5100: 		ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
 5101: 	} else {
 5102: 	    xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
 5103: 	}
 5104: 	if (Systemid != NULL) xmlFree(Systemid);
 5105: 	if (Pubid != NULL) xmlFree(Pubid);
 5106:     }
 5107: }
 5108: 
 5109: /**
 5110:  * xmlParseEntityDecl:
 5111:  * @ctxt:  an XML parser context
 5112:  *
 5113:  * parse <!ENTITY declarations
 5114:  *
 5115:  * [70] EntityDecl ::= GEDecl | PEDecl
 5116:  *
 5117:  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
 5118:  *
 5119:  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
 5120:  *
 5121:  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
 5122:  *
 5123:  * [74] PEDef ::= EntityValue | ExternalID
 5124:  *
 5125:  * [76] NDataDecl ::= S 'NDATA' S Name
 5126:  *
 5127:  * [ VC: Notation Declared ]
 5128:  * The Name must match the declared name of a notation.
 5129:  */
 5130: 
 5131: void
 5132: xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
 5133:     const xmlChar *name = NULL;
 5134:     xmlChar *value = NULL;
 5135:     xmlChar *URI = NULL, *literal = NULL;
 5136:     const xmlChar *ndata = NULL;
 5137:     int isParameter = 0;
 5138:     xmlChar *orig = NULL;
 5139:     int skipped;
 5140:     
 5141:     /* GROW; done in the caller */
 5142:     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
 5143: 	xmlParserInputPtr input = ctxt->input;
 5144: 	SHRINK;
 5145: 	SKIP(8);
 5146: 	skipped = SKIP_BLANKS;
 5147: 	if (skipped == 0) {
 5148: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5149: 			   "Space required after '<!ENTITY'\n");
 5150: 	}
 5151: 
 5152: 	if (RAW == '%') {
 5153: 	    NEXT;
 5154: 	    skipped = SKIP_BLANKS;
 5155: 	    if (skipped == 0) {
 5156: 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5157: 			       "Space required after '%'\n");
 5158: 	    }
 5159: 	    isParameter = 1;
 5160: 	}
 5161: 
 5162:         name = xmlParseName(ctxt);
 5163: 	if (name == NULL) {
 5164: 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 5165: 	                   "xmlParseEntityDecl: no name\n");
 5166:             return;
 5167: 	}
 5168: 	if (xmlStrchr(name, ':') != NULL) {
 5169: 	    xmlNsErr(ctxt, XML_NS_ERR_COLON, 
 5170: 		     "colon are forbidden from entities names '%s'\n",
 5171: 		     name, NULL, NULL);
 5172: 	}
 5173:         skipped = SKIP_BLANKS;
 5174: 	if (skipped == 0) {
 5175: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5176: 			   "Space required after the entity name\n");
 5177: 	}
 5178: 
 5179: 	ctxt->instate = XML_PARSER_ENTITY_DECL;
 5180: 	/*
 5181: 	 * handle the various case of definitions...
 5182: 	 */
 5183: 	if (isParameter) {
 5184: 	    if ((RAW == '"') || (RAW == '\'')) {
 5185: 	        value = xmlParseEntityValue(ctxt, &orig);
 5186: 		if (value) {
 5187: 		    if ((ctxt->sax != NULL) &&
 5188: 			(!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
 5189: 			ctxt->sax->entityDecl(ctxt->userData, name,
 5190: 		                    XML_INTERNAL_PARAMETER_ENTITY,
 5191: 				    NULL, NULL, value);
 5192: 		}
 5193: 	    } else {
 5194: 	        URI = xmlParseExternalID(ctxt, &literal, 1);
 5195: 		if ((URI == NULL) && (literal == NULL)) {
 5196: 		    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
 5197: 		}
 5198: 		if (URI) {
 5199: 		    xmlURIPtr uri;
 5200: 
 5201: 		    uri = xmlParseURI((const char *) URI);
 5202: 		    if (uri == NULL) {
 5203: 		        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
 5204: 				     "Invalid URI: %s\n", URI);
 5205: 			/*
 5206: 			 * This really ought to be a well formedness error
 5207: 			 * but the XML Core WG decided otherwise c.f. issue
 5208: 			 * E26 of the XML erratas.
 5209: 			 */
 5210: 		    } else {
 5211: 			if (uri->fragment != NULL) {
 5212: 			    /*
 5213: 			     * Okay this is foolish to block those but not
 5214: 			     * invalid URIs.
 5215: 			     */
 5216: 			    xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
 5217: 			} else {
 5218: 			    if ((ctxt->sax != NULL) &&
 5219: 				(!ctxt->disableSAX) &&
 5220: 				(ctxt->sax->entityDecl != NULL))
 5221: 				ctxt->sax->entityDecl(ctxt->userData, name,
 5222: 					    XML_EXTERNAL_PARAMETER_ENTITY,
 5223: 					    literal, URI, NULL);
 5224: 			}
 5225: 			xmlFreeURI(uri);
 5226: 		    }
 5227: 		}
 5228: 	    }
 5229: 	} else {
 5230: 	    if ((RAW == '"') || (RAW == '\'')) {
 5231: 	        value = xmlParseEntityValue(ctxt, &orig);
 5232: 		if ((ctxt->sax != NULL) &&
 5233: 		    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
 5234: 		    ctxt->sax->entityDecl(ctxt->userData, name,
 5235: 				XML_INTERNAL_GENERAL_ENTITY,
 5236: 				NULL, NULL, value);
 5237: 		/*
 5238: 		 * For expat compatibility in SAX mode.
 5239: 		 */
 5240: 		if ((ctxt->myDoc == NULL) ||
 5241: 		    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
 5242: 		    if (ctxt->myDoc == NULL) {
 5243: 			ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
 5244: 			if (ctxt->myDoc == NULL) {
 5245: 			    xmlErrMemory(ctxt, "New Doc failed");
 5246: 			    return;
 5247: 			}
 5248: 			ctxt->myDoc->properties = XML_DOC_INTERNAL;
 5249: 		    }
 5250: 		    if (ctxt->myDoc->intSubset == NULL)
 5251: 			ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
 5252: 					    BAD_CAST "fake", NULL, NULL);
 5253: 
 5254: 		    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
 5255: 			              NULL, NULL, value);
 5256: 		}
 5257: 	    } else {
 5258: 	        URI = xmlParseExternalID(ctxt, &literal, 1);
 5259: 		if ((URI == NULL) && (literal == NULL)) {
 5260: 		    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
 5261: 		}
 5262: 		if (URI) {
 5263: 		    xmlURIPtr uri;
 5264: 
 5265: 		    uri = xmlParseURI((const char *)URI);
 5266: 		    if (uri == NULL) {
 5267: 		        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
 5268: 				     "Invalid URI: %s\n", URI);
 5269: 			/*
 5270: 			 * This really ought to be a well formedness error
 5271: 			 * but the XML Core WG decided otherwise c.f. issue
 5272: 			 * E26 of the XML erratas.
 5273: 			 */
 5274: 		    } else {
 5275: 			if (uri->fragment != NULL) {
 5276: 			    /*
 5277: 			     * Okay this is foolish to block those but not
 5278: 			     * invalid URIs.
 5279: 			     */
 5280: 			    xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
 5281: 			}
 5282: 			xmlFreeURI(uri);
 5283: 		    }
 5284: 		}
 5285: 		if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
 5286: 		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5287: 				   "Space required before 'NDATA'\n");
 5288: 		}
 5289: 		SKIP_BLANKS;
 5290: 		if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
 5291: 		    SKIP(5);
 5292: 		    if (!IS_BLANK_CH(CUR)) {
 5293: 			xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5294: 				       "Space required after 'NDATA'\n");
 5295: 		    }
 5296: 		    SKIP_BLANKS;
 5297: 		    ndata = xmlParseName(ctxt);
 5298: 		    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
 5299: 		        (ctxt->sax->unparsedEntityDecl != NULL))
 5300: 			ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
 5301: 				    literal, URI, ndata);
 5302: 		} else {
 5303: 		    if ((ctxt->sax != NULL) &&
 5304: 		        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
 5305: 			ctxt->sax->entityDecl(ctxt->userData, name,
 5306: 				    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
 5307: 				    literal, URI, NULL);
 5308: 		    /*
 5309: 		     * For expat compatibility in SAX mode.
 5310: 		     * assuming the entity repalcement was asked for
 5311: 		     */
 5312: 		    if ((ctxt->replaceEntities != 0) &&
 5313: 			((ctxt->myDoc == NULL) ||
 5314: 			(xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
 5315: 			if (ctxt->myDoc == NULL) {
 5316: 			    ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
 5317: 			    if (ctxt->myDoc == NULL) {
 5318: 			        xmlErrMemory(ctxt, "New Doc failed");
 5319: 				return;
 5320: 			    }
 5321: 			    ctxt->myDoc->properties = XML_DOC_INTERNAL;
 5322: 			}
 5323: 
 5324: 			if (ctxt->myDoc->intSubset == NULL)
 5325: 			    ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
 5326: 						BAD_CAST "fake", NULL, NULL);
 5327: 			xmlSAX2EntityDecl(ctxt, name,
 5328: 				          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
 5329: 				          literal, URI, NULL);
 5330: 		    }
 5331: 		}
 5332: 	    }
 5333: 	}
 5334: 	SKIP_BLANKS;
 5335: 	if (RAW != '>') {
 5336: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
 5337: 	            "xmlParseEntityDecl: entity %s not terminated\n", name);
 5338: 	} else {
 5339: 	    if (input != ctxt->input) {
 5340: 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
 5341: 	"Entity declaration doesn't start and stop in the same entity\n");
 5342: 	    }
 5343: 	    NEXT;
 5344: 	}
 5345: 	if (orig != NULL) {
 5346: 	    /*
 5347: 	     * Ugly mechanism to save the raw entity value.
 5348: 	     */
 5349: 	    xmlEntityPtr cur = NULL;
 5350: 
 5351: 	    if (isParameter) {
 5352: 	        if ((ctxt->sax != NULL) &&
 5353: 		    (ctxt->sax->getParameterEntity != NULL))
 5354: 		    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
 5355: 	    } else {
 5356: 	        if ((ctxt->sax != NULL) &&
 5357: 		    (ctxt->sax->getEntity != NULL))
 5358: 		    cur = ctxt->sax->getEntity(ctxt->userData, name);
 5359: 		if ((cur == NULL) && (ctxt->userData==ctxt)) {
 5360: 		    cur = xmlSAX2GetEntity(ctxt, name);
 5361: 		}
 5362: 	    }
 5363:             if (cur != NULL) {
 5364: 	        if (cur->orig != NULL)
 5365: 		    xmlFree(orig);
 5366: 		else
 5367: 		    cur->orig = orig;
 5368: 	    } else
 5369: 		xmlFree(orig);
 5370: 	}
 5371: 	if (value != NULL) xmlFree(value);
 5372: 	if (URI != NULL) xmlFree(URI);
 5373: 	if (literal != NULL) xmlFree(literal);
 5374:     }
 5375: }
 5376: 
 5377: /**
 5378:  * xmlParseDefaultDecl:
 5379:  * @ctxt:  an XML parser context
 5380:  * @value:  Receive a possible fixed default value for the attribute
 5381:  *
 5382:  * Parse an attribute default declaration
 5383:  *
 5384:  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
 5385:  *
 5386:  * [ VC: Required Attribute ]
 5387:  * if the default declaration is the keyword #REQUIRED, then the
 5388:  * attribute must be specified for all elements of the type in the
 5389:  * attribute-list declaration.
 5390:  *
 5391:  * [ VC: Attribute Default Legal ]
 5392:  * The declared default value must meet the lexical constraints of
 5393:  * the declared attribute type c.f. xmlValidateAttributeDecl()
 5394:  *
 5395:  * [ VC: Fixed Attribute Default ]
 5396:  * if an attribute has a default value declared with the #FIXED
 5397:  * keyword, instances of that attribute must match the default value. 
 5398:  *
 5399:  * [ WFC: No < in Attribute Values ]
 5400:  * handled in xmlParseAttValue()
 5401:  *
 5402:  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
 5403:  *          or XML_ATTRIBUTE_FIXED. 
 5404:  */
 5405: 
 5406: int
 5407: xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
 5408:     int val;
 5409:     xmlChar *ret;
 5410: 
 5411:     *value = NULL;
 5412:     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
 5413: 	SKIP(9);
 5414: 	return(XML_ATTRIBUTE_REQUIRED);
 5415:     }
 5416:     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
 5417: 	SKIP(8);
 5418: 	return(XML_ATTRIBUTE_IMPLIED);
 5419:     }
 5420:     val = XML_ATTRIBUTE_NONE;
 5421:     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
 5422: 	SKIP(6);
 5423: 	val = XML_ATTRIBUTE_FIXED;
 5424: 	if (!IS_BLANK_CH(CUR)) {
 5425: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5426: 			   "Space required after '#FIXED'\n");
 5427: 	}
 5428: 	SKIP_BLANKS;
 5429:     }
 5430:     ret = xmlParseAttValue(ctxt);
 5431:     ctxt->instate = XML_PARSER_DTD;
 5432:     if (ret == NULL) {
 5433: 	xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
 5434: 		       "Attribute default value declaration error\n");
 5435:     } else
 5436:         *value = ret;
 5437:     return(val);
 5438: }
 5439: 
 5440: /**
 5441:  * xmlParseNotationType:
 5442:  * @ctxt:  an XML parser context
 5443:  *
 5444:  * parse an Notation attribute type.
 5445:  *
 5446:  * Note: the leading 'NOTATION' S part has already being parsed...
 5447:  *
 5448:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
 5449:  *
 5450:  * [ VC: Notation Attributes ]
 5451:  * Values of this type must match one of the notation names included
 5452:  * in the declaration; all notation names in the declaration must be declared. 
 5453:  *
 5454:  * Returns: the notation attribute tree built while parsing
 5455:  */
 5456: 
 5457: xmlEnumerationPtr
 5458: xmlParseNotationType(xmlParserCtxtPtr ctxt) {
 5459:     const xmlChar *name;
 5460:     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
 5461: 
 5462:     if (RAW != '(') {
 5463: 	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
 5464: 	return(NULL);
 5465:     }
 5466:     SHRINK;
 5467:     do {
 5468:         NEXT;
 5469: 	SKIP_BLANKS;
 5470:         name = xmlParseName(ctxt);
 5471: 	if (name == NULL) {
 5472: 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 5473: 			   "Name expected in NOTATION declaration\n");
 5474:             xmlFreeEnumeration(ret);
 5475: 	    return(NULL);
 5476: 	}
 5477: 	tmp = ret;
 5478: 	while (tmp != NULL) {
 5479: 	    if (xmlStrEqual(name, tmp->name)) {
 5480: 		xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
 5481: 	  "standalone: attribute notation value token %s duplicated\n",
 5482: 				 name, NULL);
 5483: 		if (!xmlDictOwns(ctxt->dict, name))
 5484: 		    xmlFree((xmlChar *) name);
 5485: 		break;
 5486: 	    }
 5487: 	    tmp = tmp->next;
 5488: 	}
 5489: 	if (tmp == NULL) {
 5490: 	    cur = xmlCreateEnumeration(name);
 5491: 	    if (cur == NULL) {
 5492:                 xmlFreeEnumeration(ret);
 5493:                 return(NULL);
 5494:             }
 5495: 	    if (last == NULL) ret = last = cur;
 5496: 	    else {
 5497: 		last->next = cur;
 5498: 		last = cur;
 5499: 	    }
 5500: 	}
 5501: 	SKIP_BLANKS;
 5502:     } while (RAW == '|');
 5503:     if (RAW != ')') {
 5504: 	xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
 5505:         xmlFreeEnumeration(ret);
 5506: 	return(NULL);
 5507:     }
 5508:     NEXT;
 5509:     return(ret);
 5510: }
 5511: 
 5512: /**
 5513:  * xmlParseEnumerationType:
 5514:  * @ctxt:  an XML parser context
 5515:  *
 5516:  * parse an Enumeration attribute type.
 5517:  *
 5518:  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
 5519:  *
 5520:  * [ VC: Enumeration ]
 5521:  * Values of this type must match one of the Nmtoken tokens in
 5522:  * the declaration
 5523:  *
 5524:  * Returns: the enumeration attribute tree built while parsing
 5525:  */
 5526: 
 5527: xmlEnumerationPtr
 5528: xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
 5529:     xmlChar *name;
 5530:     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
 5531: 
 5532:     if (RAW != '(') {
 5533: 	xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
 5534: 	return(NULL);
 5535:     }
 5536:     SHRINK;
 5537:     do {
 5538:         NEXT;
 5539: 	SKIP_BLANKS;
 5540:         name = xmlParseNmtoken(ctxt);
 5541: 	if (name == NULL) {
 5542: 	    xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
 5543: 	    return(ret);
 5544: 	}
 5545: 	tmp = ret;
 5546: 	while (tmp != NULL) {
 5547: 	    if (xmlStrEqual(name, tmp->name)) {
 5548: 		xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
 5549: 	  "standalone: attribute enumeration value token %s duplicated\n",
 5550: 				 name, NULL);
 5551: 		if (!xmlDictOwns(ctxt->dict, name))
 5552: 		    xmlFree(name);
 5553: 		break;
 5554: 	    }
 5555: 	    tmp = tmp->next;
 5556: 	}
 5557: 	if (tmp == NULL) {
 5558: 	    cur = xmlCreateEnumeration(name);
 5559: 	    if (!xmlDictOwns(ctxt->dict, name))
 5560: 		xmlFree(name);
 5561: 	    if (cur == NULL) {
 5562:                 xmlFreeEnumeration(ret);
 5563:                 return(NULL);
 5564:             }
 5565: 	    if (last == NULL) ret = last = cur;
 5566: 	    else {
 5567: 		last->next = cur;
 5568: 		last = cur;
 5569: 	    }
 5570: 	}
 5571: 	SKIP_BLANKS;
 5572:     } while (RAW == '|');
 5573:     if (RAW != ')') {
 5574: 	xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
 5575: 	return(ret);
 5576:     }
 5577:     NEXT;
 5578:     return(ret);
 5579: }
 5580: 
 5581: /**
 5582:  * xmlParseEnumeratedType:
 5583:  * @ctxt:  an XML parser context
 5584:  * @tree:  the enumeration tree built while parsing
 5585:  *
 5586:  * parse an Enumerated attribute type.
 5587:  *
 5588:  * [57] EnumeratedType ::= NotationType | Enumeration
 5589:  *
 5590:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
 5591:  *
 5592:  *
 5593:  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
 5594:  */
 5595: 
 5596: int
 5597: xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
 5598:     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
 5599: 	SKIP(8);
 5600: 	if (!IS_BLANK_CH(CUR)) {
 5601: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5602: 			   "Space required after 'NOTATION'\n");
 5603: 	    return(0);
 5604: 	}
 5605:         SKIP_BLANKS;
 5606: 	*tree = xmlParseNotationType(ctxt);
 5607: 	if (*tree == NULL) return(0);
 5608: 	return(XML_ATTRIBUTE_NOTATION);
 5609:     }
 5610:     *tree = xmlParseEnumerationType(ctxt);
 5611:     if (*tree == NULL) return(0);
 5612:     return(XML_ATTRIBUTE_ENUMERATION);
 5613: }
 5614: 
 5615: /**
 5616:  * xmlParseAttributeType:
 5617:  * @ctxt:  an XML parser context
 5618:  * @tree:  the enumeration tree built while parsing
 5619:  *
 5620:  * parse the Attribute list def for an element
 5621:  *
 5622:  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
 5623:  *
 5624:  * [55] StringType ::= 'CDATA'
 5625:  *
 5626:  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
 5627:  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
 5628:  *
 5629:  * Validity constraints for attribute values syntax are checked in
 5630:  * xmlValidateAttributeValue()
 5631:  *
 5632:  * [ VC: ID ]
 5633:  * Values of type ID must match the Name production. A name must not
 5634:  * appear more than once in an XML document as a value of this type;
 5635:  * i.e., ID values must uniquely identify the elements which bear them.
 5636:  *
 5637:  * [ VC: One ID per Element Type ]
 5638:  * No element type may have more than one ID attribute specified.
 5639:  *
 5640:  * [ VC: ID Attribute Default ]
 5641:  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
 5642:  *
 5643:  * [ VC: IDREF ]
 5644:  * Values of type IDREF must match the Name production, and values
 5645:  * of type IDREFS must match Names; each IDREF Name must match the value
 5646:  * of an ID attribute on some element in the XML document; i.e. IDREF
 5647:  * values must match the value of some ID attribute.
 5648:  *
 5649:  * [ VC: Entity Name ]
 5650:  * Values of type ENTITY must match the Name production, values
 5651:  * of type ENTITIES must match Names; each Entity Name must match the
 5652:  * name of an unparsed entity declared in the DTD.  
 5653:  *
 5654:  * [ VC: Name Token ]
 5655:  * Values of type NMTOKEN must match the Nmtoken production; values
 5656:  * of type NMTOKENS must match Nmtokens. 
 5657:  *
 5658:  * Returns the attribute type
 5659:  */
 5660: int 
 5661: xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
 5662:     SHRINK;
 5663:     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
 5664: 	SKIP(5);
 5665: 	return(XML_ATTRIBUTE_CDATA);
 5666:      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
 5667: 	SKIP(6);
 5668: 	return(XML_ATTRIBUTE_IDREFS);
 5669:      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
 5670: 	SKIP(5);
 5671: 	return(XML_ATTRIBUTE_IDREF);
 5672:      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
 5673:         SKIP(2);
 5674: 	return(XML_ATTRIBUTE_ID);
 5675:      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
 5676: 	SKIP(6);
 5677: 	return(XML_ATTRIBUTE_ENTITY);
 5678:      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
 5679: 	SKIP(8);
 5680: 	return(XML_ATTRIBUTE_ENTITIES);
 5681:      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
 5682: 	SKIP(8);
 5683: 	return(XML_ATTRIBUTE_NMTOKENS);
 5684:      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
 5685: 	SKIP(7);
 5686: 	return(XML_ATTRIBUTE_NMTOKEN);
 5687:      }
 5688:      return(xmlParseEnumeratedType(ctxt, tree));
 5689: }
 5690: 
 5691: /**
 5692:  * xmlParseAttributeListDecl:
 5693:  * @ctxt:  an XML parser context
 5694:  *
 5695:  * : parse the Attribute list def for an element
 5696:  *
 5697:  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
 5698:  *
 5699:  * [53] AttDef ::= S Name S AttType S DefaultDecl
 5700:  *
 5701:  */
 5702: void
 5703: xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
 5704:     const xmlChar *elemName;
 5705:     const xmlChar *attrName;
 5706:     xmlEnumerationPtr tree;
 5707: 
 5708:     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
 5709: 	xmlParserInputPtr input = ctxt->input;
 5710: 
 5711: 	SKIP(9);
 5712: 	if (!IS_BLANK_CH(CUR)) {
 5713: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5714: 		                 "Space required after '<!ATTLIST'\n");
 5715: 	}
 5716:         SKIP_BLANKS;
 5717:         elemName = xmlParseName(ctxt);
 5718: 	if (elemName == NULL) {
 5719: 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 5720: 			   "ATTLIST: no name for Element\n");
 5721: 	    return;
 5722: 	}
 5723: 	SKIP_BLANKS;
 5724: 	GROW;
 5725: 	while (RAW != '>') {
 5726: 	    const xmlChar *check = CUR_PTR;
 5727: 	    int type;
 5728: 	    int def;
 5729: 	    xmlChar *defaultValue = NULL;
 5730: 
 5731: 	    GROW;
 5732:             tree = NULL;
 5733: 	    attrName = xmlParseName(ctxt);
 5734: 	    if (attrName == NULL) {
 5735: 		xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 5736: 			       "ATTLIST: no name for Attribute\n");
 5737: 		break;
 5738: 	    }
 5739: 	    GROW;
 5740: 	    if (!IS_BLANK_CH(CUR)) {
 5741: 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5742: 		        "Space required after the attribute name\n");
 5743: 		break;
 5744: 	    }
 5745: 	    SKIP_BLANKS;
 5746: 
 5747: 	    type = xmlParseAttributeType(ctxt, &tree);
 5748: 	    if (type <= 0) {
 5749: 	        break;
 5750: 	    }
 5751: 
 5752: 	    GROW;
 5753: 	    if (!IS_BLANK_CH(CUR)) {
 5754: 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5755: 			       "Space required after the attribute type\n");
 5756: 	        if (tree != NULL)
 5757: 		    xmlFreeEnumeration(tree);
 5758: 		break;
 5759: 	    }
 5760: 	    SKIP_BLANKS;
 5761: 
 5762: 	    def = xmlParseDefaultDecl(ctxt, &defaultValue);
 5763: 	    if (def <= 0) {
 5764:                 if (defaultValue != NULL)
 5765: 		    xmlFree(defaultValue);
 5766: 	        if (tree != NULL)
 5767: 		    xmlFreeEnumeration(tree);
 5768: 	        break;
 5769: 	    }
 5770: 	    if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
 5771: 	        xmlAttrNormalizeSpace(defaultValue, defaultValue);
 5772: 
 5773: 	    GROW;
 5774:             if (RAW != '>') {
 5775: 		if (!IS_BLANK_CH(CUR)) {
 5776: 		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 5777: 			"Space required after the attribute default value\n");
 5778: 		    if (defaultValue != NULL)
 5779: 			xmlFree(defaultValue);
 5780: 		    if (tree != NULL)
 5781: 			xmlFreeEnumeration(tree);
 5782: 		    break;
 5783: 		}
 5784: 		SKIP_BLANKS;
 5785: 	    }
 5786: 	    if (check == CUR_PTR) {
 5787: 		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 5788: 		            "in xmlParseAttributeListDecl\n");
 5789: 		if (defaultValue != NULL)
 5790: 		    xmlFree(defaultValue);
 5791: 	        if (tree != NULL)
 5792: 		    xmlFreeEnumeration(tree);
 5793: 		break;
 5794: 	    }
 5795: 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
 5796: 		(ctxt->sax->attributeDecl != NULL))
 5797: 		ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
 5798: 	                        type, def, defaultValue, tree);
 5799: 	    else if (tree != NULL)
 5800: 		xmlFreeEnumeration(tree);
 5801: 
 5802: 	    if ((ctxt->sax2) && (defaultValue != NULL) &&
 5803: 	        (def != XML_ATTRIBUTE_IMPLIED) && 
 5804: 		(def != XML_ATTRIBUTE_REQUIRED)) {
 5805: 		xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
 5806: 	    }
 5807: 	    if (ctxt->sax2) {
 5808: 		xmlAddSpecialAttr(ctxt, elemName, attrName, type);
 5809: 	    }
 5810: 	    if (defaultValue != NULL)
 5811: 	        xmlFree(defaultValue);
 5812: 	    GROW;
 5813: 	}
 5814: 	if (RAW == '>') {
 5815: 	    if (input != ctxt->input) {
 5816: 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 5817:     "Attribute list declaration doesn't start and stop in the same entity\n",
 5818:                                  NULL, NULL);
 5819: 	    }
 5820: 	    NEXT;
 5821: 	}
 5822:     }
 5823: }
 5824: 
 5825: /**
 5826:  * xmlParseElementMixedContentDecl:
 5827:  * @ctxt:  an XML parser context
 5828:  * @inputchk:  the input used for the current entity, needed for boundary checks
 5829:  *
 5830:  * parse the declaration for a Mixed Element content
 5831:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
 5832:  * 
 5833:  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
 5834:  *                '(' S? '#PCDATA' S? ')'
 5835:  *
 5836:  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
 5837:  *
 5838:  * [ VC: No Duplicate Types ]
 5839:  * The same name must not appear more than once in a single
 5840:  * mixed-content declaration. 
 5841:  *
 5842:  * returns: the list of the xmlElementContentPtr describing the element choices
 5843:  */
 5844: xmlElementContentPtr
 5845: xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
 5846:     xmlElementContentPtr ret = NULL, cur = NULL, n;
 5847:     const xmlChar *elem = NULL;
 5848: 
 5849:     GROW;
 5850:     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
 5851: 	SKIP(7);
 5852: 	SKIP_BLANKS;
 5853: 	SHRINK;
 5854: 	if (RAW == ')') {
 5855: 	    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
 5856: 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 5857: "Element content declaration doesn't start and stop in the same entity\n",
 5858:                                  NULL, NULL);
 5859: 	    }
 5860: 	    NEXT;
 5861: 	    ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
 5862: 	    if (ret == NULL)
 5863: 	        return(NULL);
 5864: 	    if (RAW == '*') {
 5865: 		ret->ocur = XML_ELEMENT_CONTENT_MULT;
 5866: 		NEXT;
 5867: 	    }
 5868: 	    return(ret);
 5869: 	}
 5870: 	if ((RAW == '(') || (RAW == '|')) {
 5871: 	    ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
 5872: 	    if (ret == NULL) return(NULL);
 5873: 	}
 5874: 	while (RAW == '|') {
 5875: 	    NEXT;
 5876: 	    if (elem == NULL) {
 5877: 	        ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
 5878: 		if (ret == NULL) return(NULL);
 5879: 		ret->c1 = cur;
 5880: 		if (cur != NULL)
 5881: 		    cur->parent = ret;
 5882: 		cur = ret;
 5883: 	    } else {
 5884: 	        n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
 5885: 		if (n == NULL) return(NULL);
 5886: 		n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
 5887: 		if (n->c1 != NULL)
 5888: 		    n->c1->parent = n;
 5889: 	        cur->c2 = n;
 5890: 		if (n != NULL)
 5891: 		    n->parent = cur;
 5892: 		cur = n;
 5893: 	    }
 5894: 	    SKIP_BLANKS;
 5895: 	    elem = xmlParseName(ctxt);
 5896: 	    if (elem == NULL) {
 5897: 		xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 5898: 			"xmlParseElementMixedContentDecl : Name expected\n");
 5899: 		xmlFreeDocElementContent(ctxt->myDoc, cur);
 5900: 		return(NULL);
 5901: 	    }
 5902: 	    SKIP_BLANKS;
 5903: 	    GROW;
 5904: 	}
 5905: 	if ((RAW == ')') && (NXT(1) == '*')) {
 5906: 	    if (elem != NULL) {
 5907: 		cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
 5908: 		                               XML_ELEMENT_CONTENT_ELEMENT);
 5909: 		if (cur->c2 != NULL)
 5910: 		    cur->c2->parent = cur;
 5911:             }
 5912:             if (ret != NULL)
 5913:                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
 5914: 	    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
 5915: 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 5916: "Element content declaration doesn't start and stop in the same entity\n",
 5917: 				 NULL, NULL);
 5918: 	    }
 5919: 	    SKIP(2);
 5920: 	} else {
 5921: 	    xmlFreeDocElementContent(ctxt->myDoc, ret);
 5922: 	    xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
 5923: 	    return(NULL);
 5924: 	}
 5925: 
 5926:     } else {
 5927: 	xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
 5928:     }
 5929:     return(ret);
 5930: }
 5931: 
 5932: /**
 5933:  * xmlParseElementChildrenContentDeclPriv:
 5934:  * @ctxt:  an XML parser context
 5935:  * @inputchk:  the input used for the current entity, needed for boundary checks
 5936:  * @depth: the level of recursion
 5937:  *
 5938:  * parse the declaration for a Mixed Element content
 5939:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
 5940:  * 
 5941:  *
 5942:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
 5943:  *
 5944:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
 5945:  *
 5946:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
 5947:  *
 5948:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
 5949:  *
 5950:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
 5951:  * TODO Parameter-entity replacement text must be properly nested
 5952:  *	with parenthesized groups. That is to say, if either of the
 5953:  *	opening or closing parentheses in a choice, seq, or Mixed
 5954:  *	construct is contained in the replacement text for a parameter
 5955:  *	entity, both must be contained in the same replacement text. For
 5956:  *	interoperability, if a parameter-entity reference appears in a
 5957:  *	choice, seq, or Mixed construct, its replacement text should not
 5958:  *	be empty, and neither the first nor last non-blank character of
 5959:  *	the replacement text should be a connector (| or ,).
 5960:  *
 5961:  * Returns the tree of xmlElementContentPtr describing the element 
 5962:  *          hierarchy.
 5963:  */
 5964: static xmlElementContentPtr
 5965: xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
 5966:                                        int depth) {
 5967:     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
 5968:     const xmlChar *elem;
 5969:     xmlChar type = 0;
 5970: 
 5971:     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
 5972:         (depth >  2048)) {
 5973:         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
 5974: "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
 5975:                           depth);
 5976: 	return(NULL);
 5977:     }
 5978:     SKIP_BLANKS;
 5979:     GROW;
 5980:     if (RAW == '(') {
 5981: 	int inputid = ctxt->input->id;
 5982: 
 5983:         /* Recurse on first child */
 5984: 	NEXT;
 5985: 	SKIP_BLANKS;
 5986:         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
 5987:                                                            depth + 1);
 5988: 	SKIP_BLANKS;
 5989: 	GROW;
 5990:     } else {
 5991: 	elem = xmlParseName(ctxt);
 5992: 	if (elem == NULL) {
 5993: 	    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
 5994: 	    return(NULL);
 5995: 	}
 5996:         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
 5997: 	if (cur == NULL) {
 5998: 	    xmlErrMemory(ctxt, NULL);
 5999: 	    return(NULL);
 6000: 	}
 6001: 	GROW;
 6002: 	if (RAW == '?') {
 6003: 	    cur->ocur = XML_ELEMENT_CONTENT_OPT;
 6004: 	    NEXT;
 6005: 	} else if (RAW == '*') {
 6006: 	    cur->ocur = XML_ELEMENT_CONTENT_MULT;
 6007: 	    NEXT;
 6008: 	} else if (RAW == '+') {
 6009: 	    cur->ocur = XML_ELEMENT_CONTENT_PLUS;
 6010: 	    NEXT;
 6011: 	} else {
 6012: 	    cur->ocur = XML_ELEMENT_CONTENT_ONCE;
 6013: 	}
 6014: 	GROW;
 6015:     }
 6016:     SKIP_BLANKS;
 6017:     SHRINK;
 6018:     while (RAW != ')') {
 6019:         /*
 6020: 	 * Each loop we parse one separator and one element.
 6021: 	 */
 6022:         if (RAW == ',') {
 6023: 	    if (type == 0) type = CUR;
 6024: 
 6025: 	    /*
 6026: 	     * Detect "Name | Name , Name" error
 6027: 	     */
 6028: 	    else if (type != CUR) {
 6029: 		xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
 6030: 		    "xmlParseElementChildrenContentDecl : '%c' expected\n",
 6031: 		                  type);
 6032: 		if ((last != NULL) && (last != ret))
 6033: 		    xmlFreeDocElementContent(ctxt->myDoc, last);
 6034: 		if (ret != NULL)
 6035: 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
 6036: 		return(NULL);
 6037: 	    }
 6038: 	    NEXT;
 6039: 
 6040: 	    op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
 6041: 	    if (op == NULL) {
 6042: 		if ((last != NULL) && (last != ret))
 6043: 		    xmlFreeDocElementContent(ctxt->myDoc, last);
 6044: 	        xmlFreeDocElementContent(ctxt->myDoc, ret);
 6045: 		return(NULL);
 6046: 	    }
 6047: 	    if (last == NULL) {
 6048: 		op->c1 = ret;
 6049: 		if (ret != NULL)
 6050: 		    ret->parent = op;
 6051: 		ret = cur = op;
 6052: 	    } else {
 6053: 	        cur->c2 = op;
 6054: 		if (op != NULL)
 6055: 		    op->parent = cur;
 6056: 		op->c1 = last;
 6057: 		if (last != NULL)
 6058: 		    last->parent = op;
 6059: 		cur =op;
 6060: 		last = NULL;
 6061: 	    }
 6062: 	} else if (RAW == '|') {
 6063: 	    if (type == 0) type = CUR;
 6064: 
 6065: 	    /*
 6066: 	     * Detect "Name , Name | Name" error
 6067: 	     */
 6068: 	    else if (type != CUR) {
 6069: 		xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
 6070: 		    "xmlParseElementChildrenContentDecl : '%c' expected\n",
 6071: 				  type);
 6072: 		if ((last != NULL) && (last != ret))
 6073: 		    xmlFreeDocElementContent(ctxt->myDoc, last);
 6074: 		if (ret != NULL)
 6075: 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
 6076: 		return(NULL);
 6077: 	    }
 6078: 	    NEXT;
 6079: 
 6080: 	    op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
 6081: 	    if (op == NULL) {
 6082: 		if ((last != NULL) && (last != ret))
 6083: 		    xmlFreeDocElementContent(ctxt->myDoc, last);
 6084: 		if (ret != NULL)
 6085: 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
 6086: 		return(NULL);
 6087: 	    }
 6088: 	    if (last == NULL) {
 6089: 		op->c1 = ret;
 6090: 		if (ret != NULL)
 6091: 		    ret->parent = op;
 6092: 		ret = cur = op;
 6093: 	    } else {
 6094: 	        cur->c2 = op;
 6095: 		if (op != NULL)
 6096: 		    op->parent = cur;
 6097: 		op->c1 = last;
 6098: 		if (last != NULL)
 6099: 		    last->parent = op;
 6100: 		cur =op;
 6101: 		last = NULL;
 6102: 	    }
 6103: 	} else {
 6104: 	    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
 6105: 	    if ((last != NULL) && (last != ret))
 6106: 	        xmlFreeDocElementContent(ctxt->myDoc, last);
 6107: 	    if (ret != NULL)
 6108: 		xmlFreeDocElementContent(ctxt->myDoc, ret);
 6109: 	    return(NULL);
 6110: 	}
 6111: 	GROW;
 6112: 	SKIP_BLANKS;
 6113: 	GROW;
 6114: 	if (RAW == '(') {
 6115: 	    int inputid = ctxt->input->id;
 6116: 	    /* Recurse on second child */
 6117: 	    NEXT;
 6118: 	    SKIP_BLANKS;
 6119: 	    last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
 6120:                                                           depth + 1);
 6121: 	    SKIP_BLANKS;
 6122: 	} else {
 6123: 	    elem = xmlParseName(ctxt);
 6124: 	    if (elem == NULL) {
 6125: 		xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
 6126: 		if (ret != NULL)
 6127: 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
 6128: 		return(NULL);
 6129: 	    }
 6130: 	    last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
 6131: 	    if (last == NULL) {
 6132: 		if (ret != NULL)
 6133: 		    xmlFreeDocElementContent(ctxt->myDoc, ret);
 6134: 		return(NULL);
 6135: 	    }
 6136: 	    if (RAW == '?') {
 6137: 		last->ocur = XML_ELEMENT_CONTENT_OPT;
 6138: 		NEXT;
 6139: 	    } else if (RAW == '*') {
 6140: 		last->ocur = XML_ELEMENT_CONTENT_MULT;
 6141: 		NEXT;
 6142: 	    } else if (RAW == '+') {
 6143: 		last->ocur = XML_ELEMENT_CONTENT_PLUS;
 6144: 		NEXT;
 6145: 	    } else {
 6146: 		last->ocur = XML_ELEMENT_CONTENT_ONCE;
 6147: 	    }
 6148: 	}
 6149: 	SKIP_BLANKS;
 6150: 	GROW;
 6151:     }
 6152:     if ((cur != NULL) && (last != NULL)) {
 6153:         cur->c2 = last;
 6154: 	if (last != NULL)
 6155: 	    last->parent = cur;
 6156:     }
 6157:     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
 6158: 	xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 6159: "Element content declaration doesn't start and stop in the same entity\n",
 6160: 			 NULL, NULL);
 6161:     }
 6162:     NEXT;
 6163:     if (RAW == '?') {
 6164: 	if (ret != NULL) {
 6165: 	    if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
 6166: 	        (ret->ocur == XML_ELEMENT_CONTENT_MULT))
 6167: 	        ret->ocur = XML_ELEMENT_CONTENT_MULT;
 6168: 	    else
 6169: 	        ret->ocur = XML_ELEMENT_CONTENT_OPT;
 6170: 	}
 6171: 	NEXT;
 6172:     } else if (RAW == '*') {
 6173: 	if (ret != NULL) {
 6174: 	    ret->ocur = XML_ELEMENT_CONTENT_MULT;
 6175: 	    cur = ret;
 6176: 	    /*
 6177: 	     * Some normalization:
 6178: 	     * (a | b* | c?)* == (a | b | c)*
 6179: 	     */
 6180: 	    while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
 6181: 		if ((cur->c1 != NULL) &&
 6182: 	            ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
 6183: 		     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
 6184: 		    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
 6185: 		if ((cur->c2 != NULL) &&
 6186: 	            ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
 6187: 		     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
 6188: 		    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
 6189: 		cur = cur->c2;
 6190: 	    }
 6191: 	}
 6192: 	NEXT;
 6193:     } else if (RAW == '+') {
 6194: 	if (ret != NULL) {
 6195: 	    int found = 0;
 6196: 
 6197: 	    if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
 6198: 	        (ret->ocur == XML_ELEMENT_CONTENT_MULT))
 6199: 	        ret->ocur = XML_ELEMENT_CONTENT_MULT;
 6200: 	    else
 6201: 	        ret->ocur = XML_ELEMENT_CONTENT_PLUS;
 6202: 	    /*
 6203: 	     * Some normalization:
 6204: 	     * (a | b*)+ == (a | b)*
 6205: 	     * (a | b?)+ == (a | b)*
 6206: 	     */
 6207: 	    while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
 6208: 		if ((cur->c1 != NULL) &&
 6209: 	            ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
 6210: 		     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
 6211: 		    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
 6212: 		    found = 1;
 6213: 		}
 6214: 		if ((cur->c2 != NULL) &&
 6215: 	            ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
 6216: 		     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
 6217: 		    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
 6218: 		    found = 1;
 6219: 		}
 6220: 		cur = cur->c2;
 6221: 	    }
 6222: 	    if (found)
 6223: 		ret->ocur = XML_ELEMENT_CONTENT_MULT;
 6224: 	}
 6225: 	NEXT;
 6226:     }
 6227:     return(ret);
 6228: }
 6229: 
 6230: /**
 6231:  * xmlParseElementChildrenContentDecl:
 6232:  * @ctxt:  an XML parser context
 6233:  * @inputchk:  the input used for the current entity, needed for boundary checks
 6234:  *
 6235:  * parse the declaration for a Mixed Element content
 6236:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
 6237:  *
 6238:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
 6239:  *
 6240:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
 6241:  *
 6242:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
 6243:  *
 6244:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
 6245:  *
 6246:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
 6247:  * TODO Parameter-entity replacement text must be properly nested
 6248:  *	with parenthesized groups. That is to say, if either of the
 6249:  *	opening or closing parentheses in a choice, seq, or Mixed
 6250:  *	construct is contained in the replacement text for a parameter
 6251:  *	entity, both must be contained in the same replacement text. For
 6252:  *	interoperability, if a parameter-entity reference appears in a
 6253:  *	choice, seq, or Mixed construct, its replacement text should not
 6254:  *	be empty, and neither the first nor last non-blank character of
 6255:  *	the replacement text should be a connector (| or ,).
 6256:  *
 6257:  * Returns the tree of xmlElementContentPtr describing the element
 6258:  *          hierarchy.
 6259:  */
 6260: xmlElementContentPtr
 6261: xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
 6262:     /* stub left for API/ABI compat */
 6263:     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
 6264: }
 6265: 
 6266: /**
 6267:  * xmlParseElementContentDecl:
 6268:  * @ctxt:  an XML parser context
 6269:  * @name:  the name of the element being defined.
 6270:  * @result:  the Element Content pointer will be stored here if any
 6271:  *
 6272:  * parse the declaration for an Element content either Mixed or Children,
 6273:  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
 6274:  * 
 6275:  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
 6276:  *
 6277:  * returns: the type of element content XML_ELEMENT_TYPE_xxx
 6278:  */
 6279: 
 6280: int
 6281: xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
 6282:                            xmlElementContentPtr *result) {
 6283: 
 6284:     xmlElementContentPtr tree = NULL;
 6285:     int inputid = ctxt->input->id;
 6286:     int res;
 6287: 
 6288:     *result = NULL;
 6289: 
 6290:     if (RAW != '(') {
 6291: 	xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
 6292: 		"xmlParseElementContentDecl : %s '(' expected\n", name);
 6293: 	return(-1);
 6294:     }
 6295:     NEXT;
 6296:     GROW;
 6297:     SKIP_BLANKS;
 6298:     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
 6299:         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
 6300: 	res = XML_ELEMENT_TYPE_MIXED;
 6301:     } else {
 6302:         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
 6303: 	res = XML_ELEMENT_TYPE_ELEMENT;
 6304:     }
 6305:     SKIP_BLANKS;
 6306:     *result = tree;
 6307:     return(res);
 6308: }
 6309: 
 6310: /**
 6311:  * xmlParseElementDecl:
 6312:  * @ctxt:  an XML parser context
 6313:  *
 6314:  * parse an Element declaration.
 6315:  *
 6316:  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
 6317:  *
 6318:  * [ VC: Unique Element Type Declaration ]
 6319:  * No element type may be declared more than once
 6320:  *
 6321:  * Returns the type of the element, or -1 in case of error
 6322:  */
 6323: int
 6324: xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
 6325:     const xmlChar *name;
 6326:     int ret = -1;
 6327:     xmlElementContentPtr content  = NULL;
 6328: 
 6329:     /* GROW; done in the caller */
 6330:     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
 6331: 	xmlParserInputPtr input = ctxt->input;
 6332: 
 6333: 	SKIP(9);
 6334: 	if (!IS_BLANK_CH(CUR)) {
 6335: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 6336: 		           "Space required after 'ELEMENT'\n");
 6337: 	}
 6338:         SKIP_BLANKS;
 6339:         name = xmlParseName(ctxt);
 6340: 	if (name == NULL) {
 6341: 	    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 6342: 			   "xmlParseElementDecl: no name for Element\n");
 6343: 	    return(-1);
 6344: 	}
 6345: 	while ((RAW == 0) && (ctxt->inputNr > 1))
 6346: 	    xmlPopInput(ctxt);
 6347: 	if (!IS_BLANK_CH(CUR)) {
 6348: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 6349: 			   "Space required after the element name\n");
 6350: 	}
 6351:         SKIP_BLANKS;
 6352: 	if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
 6353: 	    SKIP(5);
 6354: 	    /*
 6355: 	     * Element must always be empty.
 6356: 	     */
 6357: 	    ret = XML_ELEMENT_TYPE_EMPTY;
 6358: 	} else if ((RAW == 'A') && (NXT(1) == 'N') &&
 6359: 	           (NXT(2) == 'Y')) {
 6360: 	    SKIP(3);
 6361: 	    /*
 6362: 	     * Element is a generic container.
 6363: 	     */
 6364: 	    ret = XML_ELEMENT_TYPE_ANY;
 6365: 	} else if (RAW == '(') {
 6366: 	    ret = xmlParseElementContentDecl(ctxt, name, &content);
 6367: 	} else {
 6368: 	    /*
 6369: 	     * [ WFC: PEs in Internal Subset ] error handling.
 6370: 	     */
 6371: 	    if ((RAW == '%') && (ctxt->external == 0) &&
 6372: 	        (ctxt->inputNr == 1)) {
 6373: 		xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
 6374: 	  "PEReference: forbidden within markup decl in internal subset\n");
 6375: 	    } else {
 6376: 		xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
 6377: 		      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
 6378:             }
 6379: 	    return(-1);
 6380: 	}
 6381: 
 6382: 	SKIP_BLANKS;
 6383: 	/*
 6384: 	 * Pop-up of finished entities.
 6385: 	 */
 6386: 	while ((RAW == 0) && (ctxt->inputNr > 1))
 6387: 	    xmlPopInput(ctxt);
 6388: 	SKIP_BLANKS;
 6389: 
 6390: 	if (RAW != '>') {
 6391: 	    xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
 6392: 	    if (content != NULL) {
 6393: 		xmlFreeDocElementContent(ctxt->myDoc, content);
 6394: 	    }
 6395: 	} else {
 6396: 	    if (input != ctxt->input) {
 6397: 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
 6398:     "Element declaration doesn't start and stop in the same entity\n");
 6399: 	    }
 6400: 		
 6401: 	    NEXT;
 6402: 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
 6403: 		(ctxt->sax->elementDecl != NULL)) {
 6404: 		if (content != NULL)
 6405: 		    content->parent = NULL;
 6406: 	        ctxt->sax->elementDecl(ctxt->userData, name, ret,
 6407: 		                       content);
 6408: 		if ((content != NULL) && (content->parent == NULL)) {
 6409: 		    /*
 6410: 		     * this is a trick: if xmlAddElementDecl is called,
 6411: 		     * instead of copying the full tree it is plugged directly
 6412: 		     * if called from the parser. Avoid duplicating the 
 6413: 		     * interfaces or change the API/ABI
 6414: 		     */
 6415: 		    xmlFreeDocElementContent(ctxt->myDoc, content);
 6416: 		}
 6417: 	    } else if (content != NULL) {
 6418: 		xmlFreeDocElementContent(ctxt->myDoc, content);
 6419: 	    }
 6420: 	}
 6421:     }
 6422:     return(ret);
 6423: }
 6424: 
 6425: /**
 6426:  * xmlParseConditionalSections
 6427:  * @ctxt:  an XML parser context
 6428:  *
 6429:  * [61] conditionalSect ::= includeSect | ignoreSect 
 6430:  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
 6431:  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
 6432:  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
 6433:  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
 6434:  */
 6435: 
 6436: static void
 6437: xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
 6438:     int id = ctxt->input->id;
 6439: 
 6440:     SKIP(3);
 6441:     SKIP_BLANKS;
 6442:     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
 6443: 	SKIP(7);
 6444: 	SKIP_BLANKS;
 6445: 	if (RAW != '[') {
 6446: 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
 6447: 	} else {
 6448: 	    if (ctxt->input->id != id) {
 6449: 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 6450: 	    "All markup of the conditional section is not in the same entity\n",
 6451: 				     NULL, NULL);
 6452: 	    }
 6453: 	    NEXT;
 6454: 	}
 6455: 	if (xmlParserDebugEntities) {
 6456: 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
 6457: 		xmlGenericError(xmlGenericErrorContext,
 6458: 			"%s(%d): ", ctxt->input->filename,
 6459: 			ctxt->input->line);
 6460: 	    xmlGenericError(xmlGenericErrorContext,
 6461: 		    "Entering INCLUDE Conditional Section\n");
 6462: 	}
 6463: 
 6464: 	while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
 6465: 	       (NXT(2) != '>'))) {
 6466: 	    const xmlChar *check = CUR_PTR;
 6467: 	    unsigned int cons = ctxt->input->consumed;
 6468: 
 6469: 	    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
 6470: 		xmlParseConditionalSections(ctxt);
 6471: 	    } else if (IS_BLANK_CH(CUR)) {
 6472: 		NEXT;
 6473: 	    } else if (RAW == '%') {
 6474: 		xmlParsePEReference(ctxt);
 6475: 	    } else
 6476: 		xmlParseMarkupDecl(ctxt);
 6477: 
 6478: 	    /*
 6479: 	     * Pop-up of finished entities.
 6480: 	     */
 6481: 	    while ((RAW == 0) && (ctxt->inputNr > 1))
 6482: 		xmlPopInput(ctxt);
 6483: 
 6484: 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 6485: 		xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
 6486: 		break;
 6487: 	    }
 6488: 	}
 6489: 	if (xmlParserDebugEntities) {
 6490: 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
 6491: 		xmlGenericError(xmlGenericErrorContext,
 6492: 			"%s(%d): ", ctxt->input->filename,
 6493: 			ctxt->input->line);
 6494: 	    xmlGenericError(xmlGenericErrorContext,
 6495: 		    "Leaving INCLUDE Conditional Section\n");
 6496: 	}
 6497: 
 6498:     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
 6499: 	int state;
 6500: 	xmlParserInputState instate;
 6501: 	int depth = 0;
 6502: 
 6503: 	SKIP(6);
 6504: 	SKIP_BLANKS;
 6505: 	if (RAW != '[') {
 6506: 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
 6507: 	} else {
 6508: 	    if (ctxt->input->id != id) {
 6509: 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 6510: 	    "All markup of the conditional section is not in the same entity\n",
 6511: 				     NULL, NULL);
 6512: 	    }
 6513: 	    NEXT;
 6514: 	}
 6515: 	if (xmlParserDebugEntities) {
 6516: 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
 6517: 		xmlGenericError(xmlGenericErrorContext,
 6518: 			"%s(%d): ", ctxt->input->filename,
 6519: 			ctxt->input->line);
 6520: 	    xmlGenericError(xmlGenericErrorContext,
 6521: 		    "Entering IGNORE Conditional Section\n");
 6522: 	}
 6523: 
 6524: 	/*
 6525: 	 * Parse up to the end of the conditional section
 6526: 	 * But disable SAX event generating DTD building in the meantime
 6527: 	 */
 6528: 	state = ctxt->disableSAX;
 6529: 	instate = ctxt->instate;
 6530: 	if (ctxt->recovery == 0) ctxt->disableSAX = 1;
 6531: 	ctxt->instate = XML_PARSER_IGNORE;
 6532: 
 6533: 	while ((depth >= 0) && (RAW != 0)) {
 6534: 	  if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
 6535: 	    depth++;
 6536: 	    SKIP(3);
 6537: 	    continue;
 6538: 	  }
 6539: 	  if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
 6540: 	    if (--depth >= 0) SKIP(3);
 6541: 	    continue;
 6542: 	  }
 6543: 	  NEXT;
 6544: 	  continue;
 6545: 	}
 6546: 
 6547: 	ctxt->disableSAX = state;
 6548: 	ctxt->instate = instate;
 6549: 
 6550: 	if (xmlParserDebugEntities) {
 6551: 	    if ((ctxt->input != NULL) && (ctxt->input->filename))
 6552: 		xmlGenericError(xmlGenericErrorContext,
 6553: 			"%s(%d): ", ctxt->input->filename,
 6554: 			ctxt->input->line);
 6555: 	    xmlGenericError(xmlGenericErrorContext,
 6556: 		    "Leaving IGNORE Conditional Section\n");
 6557: 	}
 6558: 
 6559:     } else {
 6560: 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
 6561:     }
 6562: 
 6563:     if (RAW == 0)
 6564:         SHRINK;
 6565: 
 6566:     if (RAW == 0) {
 6567: 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
 6568:     } else {
 6569: 	if (ctxt->input->id != id) {
 6570: 	    xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
 6571: 	"All markup of the conditional section is not in the same entity\n",
 6572: 				 NULL, NULL);
 6573: 	}
 6574:         SKIP(3);
 6575:     }
 6576: }
 6577: 
 6578: /**
 6579:  * xmlParseMarkupDecl:
 6580:  * @ctxt:  an XML parser context
 6581:  * 
 6582:  * parse Markup declarations
 6583:  *
 6584:  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
 6585:  *                     NotationDecl | PI | Comment
 6586:  *
 6587:  * [ VC: Proper Declaration/PE Nesting ]
 6588:  * Parameter-entity replacement text must be properly nested with
 6589:  * markup declarations. That is to say, if either the first character
 6590:  * or the last character of a markup declaration (markupdecl above) is
 6591:  * contained in the replacement text for a parameter-entity reference,
 6592:  * both must be contained in the same replacement text.
 6593:  *
 6594:  * [ WFC: PEs in Internal Subset ]
 6595:  * In the internal DTD subset, parameter-entity references can occur
 6596:  * only where markup declarations can occur, not within markup declarations.
 6597:  * (This does not apply to references that occur in external parameter
 6598:  * entities or to the external subset.) 
 6599:  */
 6600: void
 6601: xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
 6602:     GROW;
 6603:     if (CUR == '<') {
 6604:         if (NXT(1) == '!') {
 6605: 	    switch (NXT(2)) {
 6606: 	        case 'E':
 6607: 		    if (NXT(3) == 'L')
 6608: 			xmlParseElementDecl(ctxt);
 6609: 		    else if (NXT(3) == 'N')
 6610: 			xmlParseEntityDecl(ctxt);
 6611: 		    break;
 6612: 	        case 'A':
 6613: 		    xmlParseAttributeListDecl(ctxt);
 6614: 		    break;
 6615: 	        case 'N':
 6616: 		    xmlParseNotationDecl(ctxt);
 6617: 		    break;
 6618: 	        case '-':
 6619: 		    xmlParseComment(ctxt);
 6620: 		    break;
 6621: 		default:
 6622: 		    /* there is an error but it will be detected later */
 6623: 		    break;
 6624: 	    }
 6625: 	} else if (NXT(1) == '?') {
 6626: 	    xmlParsePI(ctxt);
 6627: 	}
 6628:     }
 6629:     /*
 6630:      * This is only for internal subset. On external entities,
 6631:      * the replacement is done before parsing stage
 6632:      */
 6633:     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
 6634: 	xmlParsePEReference(ctxt);
 6635: 
 6636:     /*
 6637:      * Conditional sections are allowed from entities included
 6638:      * by PE References in the internal subset.
 6639:      */
 6640:     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
 6641:         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
 6642: 	    xmlParseConditionalSections(ctxt);
 6643: 	}
 6644:     }
 6645: 
 6646:     ctxt->instate = XML_PARSER_DTD;
 6647: }
 6648: 
 6649: /**
 6650:  * xmlParseTextDecl:
 6651:  * @ctxt:  an XML parser context
 6652:  *
 6653:  * parse an XML declaration header for external entities
 6654:  *
 6655:  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
 6656:  */
 6657: 
 6658: void
 6659: xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
 6660:     xmlChar *version;
 6661:     const xmlChar *encoding;
 6662: 
 6663:     /*
 6664:      * We know that '<?xml' is here.
 6665:      */
 6666:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
 6667: 	SKIP(5);
 6668:     } else {
 6669: 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
 6670: 	return;
 6671:     }
 6672: 
 6673:     if (!IS_BLANK_CH(CUR)) {
 6674: 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 6675: 		       "Space needed after '<?xml'\n");
 6676:     }
 6677:     SKIP_BLANKS;
 6678: 
 6679:     /*
 6680:      * We may have the VersionInfo here.
 6681:      */
 6682:     version = xmlParseVersionInfo(ctxt);
 6683:     if (version == NULL)
 6684: 	version = xmlCharStrdup(XML_DEFAULT_VERSION);
 6685:     else {
 6686: 	if (!IS_BLANK_CH(CUR)) {
 6687: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 6688: 		           "Space needed here\n");
 6689: 	}
 6690:     }
 6691:     ctxt->input->version = version;
 6692: 
 6693:     /*
 6694:      * We must have the encoding declaration
 6695:      */
 6696:     encoding = xmlParseEncodingDecl(ctxt);
 6697:     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
 6698: 	/*
 6699: 	 * The XML REC instructs us to stop parsing right here
 6700: 	 */
 6701:         return;
 6702:     }
 6703:     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
 6704: 	xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
 6705: 		       "Missing encoding in text declaration\n");
 6706:     }
 6707: 
 6708:     SKIP_BLANKS;
 6709:     if ((RAW == '?') && (NXT(1) == '>')) {
 6710:         SKIP(2);
 6711:     } else if (RAW == '>') {
 6712:         /* Deprecated old WD ... */
 6713: 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
 6714: 	NEXT;
 6715:     } else {
 6716: 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
 6717: 	MOVETO_ENDTAG(CUR_PTR);
 6718: 	NEXT;
 6719:     }
 6720: }
 6721: 
 6722: /**
 6723:  * xmlParseExternalSubset:
 6724:  * @ctxt:  an XML parser context
 6725:  * @ExternalID: the external identifier
 6726:  * @SystemID: the system identifier (or URL)
 6727:  * 
 6728:  * parse Markup declarations from an external subset
 6729:  *
 6730:  * [30] extSubset ::= textDecl? extSubsetDecl
 6731:  *
 6732:  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
 6733:  */
 6734: void
 6735: xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
 6736:                        const xmlChar *SystemID) {
 6737:     xmlDetectSAX2(ctxt);
 6738:     GROW;
 6739: 
 6740:     if ((ctxt->encoding == NULL) &&
 6741:         (ctxt->input->end - ctxt->input->cur >= 4)) {
 6742:         xmlChar start[4];
 6743: 	xmlCharEncoding enc;
 6744: 
 6745: 	start[0] = RAW;
 6746: 	start[1] = NXT(1);
 6747: 	start[2] = NXT(2);
 6748: 	start[3] = NXT(3);
 6749: 	enc = xmlDetectCharEncoding(start, 4);
 6750: 	if (enc != XML_CHAR_ENCODING_NONE)
 6751: 	    xmlSwitchEncoding(ctxt, enc);
 6752:     }
 6753: 
 6754:     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
 6755: 	xmlParseTextDecl(ctxt);
 6756: 	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
 6757: 	    /*
 6758: 	     * The XML REC instructs us to stop parsing right here
 6759: 	     */
 6760: 	    ctxt->instate = XML_PARSER_EOF;
 6761: 	    return;
 6762: 	}
 6763:     }
 6764:     if (ctxt->myDoc == NULL) {
 6765:         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
 6766: 	if (ctxt->myDoc == NULL) {
 6767: 	    xmlErrMemory(ctxt, "New Doc failed");
 6768: 	    return;
 6769: 	}
 6770: 	ctxt->myDoc->properties = XML_DOC_INTERNAL;
 6771:     }
 6772:     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
 6773:         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
 6774: 
 6775:     ctxt->instate = XML_PARSER_DTD;
 6776:     ctxt->external = 1;
 6777:     while (((RAW == '<') && (NXT(1) == '?')) ||
 6778:            ((RAW == '<') && (NXT(1) == '!')) ||
 6779: 	   (RAW == '%') || IS_BLANK_CH(CUR)) {
 6780: 	const xmlChar *check = CUR_PTR;
 6781: 	unsigned int cons = ctxt->input->consumed;
 6782: 
 6783: 	GROW;
 6784:         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
 6785: 	    xmlParseConditionalSections(ctxt);
 6786: 	} else if (IS_BLANK_CH(CUR)) {
 6787: 	    NEXT;
 6788: 	} else if (RAW == '%') {
 6789:             xmlParsePEReference(ctxt);
 6790: 	} else
 6791: 	    xmlParseMarkupDecl(ctxt);
 6792: 
 6793: 	/*
 6794: 	 * Pop-up of finished entities.
 6795: 	 */
 6796: 	while ((RAW == 0) && (ctxt->inputNr > 1))
 6797: 	    xmlPopInput(ctxt);
 6798: 
 6799: 	if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 6800: 	    xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
 6801: 	    break;
 6802: 	}
 6803:     }
 6804:     
 6805:     if (RAW != 0) {
 6806: 	xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
 6807:     }
 6808: 
 6809: }
 6810: 
 6811: /**
 6812:  * xmlParseReference:
 6813:  * @ctxt:  an XML parser context
 6814:  *
 6815:  * parse and handle entity references in content, depending on the SAX
 6816:  * interface, this may end-up in a call to character() if this is a
 6817:  * CharRef, a predefined entity, if there is no reference() callback.
 6818:  * or if the parser was asked to switch to that mode.
 6819:  *
 6820:  * [67] Reference ::= EntityRef | CharRef
 6821:  */
 6822: void
 6823: xmlParseReference(xmlParserCtxtPtr ctxt) {
 6824:     xmlEntityPtr ent;
 6825:     xmlChar *val;
 6826:     int was_checked;
 6827:     xmlNodePtr list = NULL;
 6828:     xmlParserErrors ret = XML_ERR_OK;
 6829: 
 6830: 
 6831:     if (RAW != '&')
 6832:         return;
 6833: 
 6834:     /*
 6835:      * Simple case of a CharRef
 6836:      */
 6837:     if (NXT(1) == '#') {
 6838: 	int i = 0;
 6839: 	xmlChar out[10];
 6840: 	int hex = NXT(2);
 6841: 	int value = xmlParseCharRef(ctxt);
 6842: 
 6843: 	if (value == 0)
 6844: 	    return;
 6845: 	if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
 6846: 	    /*
 6847: 	     * So we are using non-UTF-8 buffers
 6848: 	     * Check that the char fit on 8bits, if not
 6849: 	     * generate a CharRef.
 6850: 	     */
 6851: 	    if (value <= 0xFF) {
 6852: 		out[0] = value;
 6853: 		out[1] = 0;
 6854: 		if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
 6855: 		    (!ctxt->disableSAX))
 6856: 		    ctxt->sax->characters(ctxt->userData, out, 1);
 6857: 	    } else {
 6858: 		if ((hex == 'x') || (hex == 'X'))
 6859: 		    snprintf((char *)out, sizeof(out), "#x%X", value);
 6860: 		else
 6861: 		    snprintf((char *)out, sizeof(out), "#%d", value);
 6862: 		if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
 6863: 		    (!ctxt->disableSAX))
 6864: 		    ctxt->sax->reference(ctxt->userData, out);
 6865: 	    }
 6866: 	} else {
 6867: 	    /*
 6868: 	     * Just encode the value in UTF-8
 6869: 	     */
 6870: 	    COPY_BUF(0 ,out, i, value);
 6871: 	    out[i] = 0;
 6872: 	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
 6873: 		(!ctxt->disableSAX))
 6874: 		ctxt->sax->characters(ctxt->userData, out, i);
 6875: 	}
 6876: 	return;
 6877:     }
 6878: 
 6879:     /*
 6880:      * We are seeing an entity reference
 6881:      */
 6882:     ent = xmlParseEntityRef(ctxt);
 6883:     if (ent == NULL) return;
 6884:     if (!ctxt->wellFormed)
 6885: 	return;
 6886:     was_checked = ent->checked;
 6887: 
 6888:     /* special case of predefined entities */
 6889:     if ((ent->name == NULL) ||
 6890:         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
 6891: 	val = ent->content;
 6892: 	if (val == NULL) return;
 6893: 	/*
 6894: 	 * inline the entity.
 6895: 	 */
 6896: 	if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
 6897: 	    (!ctxt->disableSAX))
 6898: 	    ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
 6899: 	return;
 6900:     }
 6901: 
 6902:     /*
 6903:      * The first reference to the entity trigger a parsing phase
 6904:      * where the ent->children is filled with the result from
 6905:      * the parsing.
 6906:      */
 6907:     if (ent->checked == 0) {
 6908: 	unsigned long oldnbent = ctxt->nbentities;
 6909: 
 6910: 	/*
 6911: 	 * This is a bit hackish but this seems the best
 6912: 	 * way to make sure both SAX and DOM entity support
 6913: 	 * behaves okay.
 6914: 	 */
 6915: 	void *user_data;
 6916: 	if (ctxt->userData == ctxt)
 6917: 	    user_data = NULL;
 6918: 	else
 6919: 	    user_data = ctxt->userData;
 6920: 
 6921: 	/*
 6922: 	 * Check that this entity is well formed
 6923: 	 * 4.3.2: An internal general parsed entity is well-formed
 6924: 	 * if its replacement text matches the production labeled
 6925: 	 * content.
 6926: 	 */
 6927: 	if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
 6928: 	    ctxt->depth++;
 6929: 	    ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
 6930: 	                                              user_data, &list);
 6931: 	    ctxt->depth--;
 6932: 
 6933: 	} else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
 6934: 	    ctxt->depth++;
 6935: 	    ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
 6936: 	                                   user_data, ctxt->depth, ent->URI,
 6937: 					   ent->ExternalID, &list);
 6938: 	    ctxt->depth--;
 6939: 	} else {
 6940: 	    ret = XML_ERR_ENTITY_PE_INTERNAL;
 6941: 	    xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
 6942: 			 "invalid entity type found\n", NULL);
 6943: 	}
 6944: 
 6945: 	/*
 6946: 	 * Store the number of entities needing parsing for this entity
 6947: 	 * content and do checkings
 6948: 	 */
 6949: 	ent->checked = ctxt->nbentities - oldnbent;
 6950: 	if (ret == XML_ERR_ENTITY_LOOP) {
 6951: 	    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
 6952: 	    xmlFreeNodeList(list);
 6953: 	    return;
 6954: 	}
 6955: 	if (xmlParserEntityCheck(ctxt, 0, ent)) {
 6956: 	    xmlFreeNodeList(list);
 6957: 	    return;
 6958: 	}
 6959: 
 6960: 	if ((ret == XML_ERR_OK) && (list != NULL)) {
 6961: 	    if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
 6962: 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
 6963: 		(ent->children == NULL)) {
 6964: 		ent->children = list;
 6965: 		if (ctxt->replaceEntities) {
 6966: 		    /*
 6967: 		     * Prune it directly in the generated document
 6968: 		     * except for single text nodes.
 6969: 		     */
 6970: 		    if (((list->type == XML_TEXT_NODE) &&
 6971: 			 (list->next == NULL)) ||
 6972: 			(ctxt->parseMode == XML_PARSE_READER)) {
 6973: 			list->parent = (xmlNodePtr) ent;
 6974: 			list = NULL;
 6975: 			ent->owner = 1;
 6976: 		    } else {
 6977: 			ent->owner = 0;
 6978: 			while (list != NULL) {
 6979: 			    list->parent = (xmlNodePtr) ctxt->node;
 6980: 			    list->doc = ctxt->myDoc;
 6981: 			    if (list->next == NULL)
 6982: 				ent->last = list;
 6983: 			    list = list->next;
 6984: 			}
 6985: 			list = ent->children;
 6986: #ifdef LIBXML_LEGACY_ENABLED
 6987: 			if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
 6988: 			  xmlAddEntityReference(ent, list, NULL);
 6989: #endif /* LIBXML_LEGACY_ENABLED */
 6990: 		    }
 6991: 		} else {
 6992: 		    ent->owner = 1;
 6993: 		    while (list != NULL) {
 6994: 			list->parent = (xmlNodePtr) ent;
 6995: 			if (list->next == NULL)
 6996: 			    ent->last = list;
 6997: 			list = list->next;
 6998: 		    }
 6999: 		}
 7000: 	    } else {
 7001: 		xmlFreeNodeList(list);
 7002: 		list = NULL;
 7003: 	    }
 7004: 	} else if ((ret != XML_ERR_OK) &&
 7005: 		   (ret != XML_WAR_UNDECLARED_ENTITY)) {
 7006: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 7007: 		     "Entity '%s' failed to parse\n", ent->name);
 7008: 	} else if (list != NULL) {
 7009: 	    xmlFreeNodeList(list);
 7010: 	    list = NULL;
 7011: 	}
 7012: 	if (ent->checked == 0)
 7013: 	    ent->checked = 1;
 7014:     } else if (ent->checked != 1) {
 7015: 	ctxt->nbentities += ent->checked;
 7016:     }
 7017: 
 7018:     /*
 7019:      * Now that the entity content has been gathered
 7020:      * provide it to the application, this can take different forms based
 7021:      * on the parsing modes.
 7022:      */
 7023:     if (ent->children == NULL) {
 7024: 	/*
 7025: 	 * Probably running in SAX mode and the callbacks don't
 7026: 	 * build the entity content. So unless we already went
 7027: 	 * though parsing for first checking go though the entity
 7028: 	 * content to generate callbacks associated to the entity
 7029: 	 */
 7030: 	if (was_checked != 0) {
 7031: 	    void *user_data;
 7032: 	    /*
 7033: 	     * This is a bit hackish but this seems the best
 7034: 	     * way to make sure both SAX and DOM entity support
 7035: 	     * behaves okay.
 7036: 	     */
 7037: 	    if (ctxt->userData == ctxt)
 7038: 		user_data = NULL;
 7039: 	    else
 7040: 		user_data = ctxt->userData;
 7041: 
 7042: 	    if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
 7043: 		ctxt->depth++;
 7044: 		ret = xmlParseBalancedChunkMemoryInternal(ctxt,
 7045: 				   ent->content, user_data, NULL);
 7046: 		ctxt->depth--;
 7047: 	    } else if (ent->etype ==
 7048: 		       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
 7049: 		ctxt->depth++;
 7050: 		ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
 7051: 			   ctxt->sax, user_data, ctxt->depth,
 7052: 			   ent->URI, ent->ExternalID, NULL);
 7053: 		ctxt->depth--;
 7054: 	    } else {
 7055: 		ret = XML_ERR_ENTITY_PE_INTERNAL;
 7056: 		xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
 7057: 			     "invalid entity type found\n", NULL);
 7058: 	    }
 7059: 	    if (ret == XML_ERR_ENTITY_LOOP) {
 7060: 		xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
 7061: 		return;
 7062: 	    }
 7063: 	}
 7064: 	if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
 7065: 	    (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
 7066: 	    /*
 7067: 	     * Entity reference callback comes second, it's somewhat
 7068: 	     * superfluous but a compatibility to historical behaviour
 7069: 	     */
 7070: 	    ctxt->sax->reference(ctxt->userData, ent->name);
 7071: 	}
 7072: 	return;
 7073:     }
 7074: 
 7075:     /*
 7076:      * If we didn't get any children for the entity being built
 7077:      */
 7078:     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
 7079: 	(ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
 7080: 	/*
 7081: 	 * Create a node.
 7082: 	 */
 7083: 	ctxt->sax->reference(ctxt->userData, ent->name);
 7084: 	return;
 7085:     }
 7086: 
 7087:     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
 7088: 	/*
 7089: 	 * There is a problem on the handling of _private for entities
 7090: 	 * (bug 155816): Should we copy the content of the field from
 7091: 	 * the entity (possibly overwriting some value set by the user
 7092: 	 * when a copy is created), should we leave it alone, or should
 7093: 	 * we try to take care of different situations?  The problem
 7094: 	 * is exacerbated by the usage of this field by the xmlReader.
 7095: 	 * To fix this bug, we look at _private on the created node
 7096: 	 * and, if it's NULL, we copy in whatever was in the entity.
 7097: 	 * If it's not NULL we leave it alone.  This is somewhat of a
 7098: 	 * hack - maybe we should have further tests to determine
 7099: 	 * what to do.
 7100: 	 */
 7101: 	if ((ctxt->node != NULL) && (ent->children != NULL)) {
 7102: 	    /*
 7103: 	     * Seems we are generating the DOM content, do
 7104: 	     * a simple tree copy for all references except the first
 7105: 	     * In the first occurrence list contains the replacement.
 7106: 	     * progressive == 2 means we are operating on the Reader
 7107: 	     * and since nodes are discarded we must copy all the time.
 7108: 	     */
 7109: 	    if (((list == NULL) && (ent->owner == 0)) ||
 7110: 		(ctxt->parseMode == XML_PARSE_READER)) {
 7111: 		xmlNodePtr nw = NULL, cur, firstChild = NULL;
 7112: 
 7113: 		/*
 7114: 		 * when operating on a reader, the entities definitions
 7115: 		 * are always owning the entities subtree.
 7116: 		if (ctxt->parseMode == XML_PARSE_READER)
 7117: 		    ent->owner = 1;
 7118: 		 */
 7119: 
 7120: 		cur = ent->children;
 7121: 		while (cur != NULL) {
 7122: 		    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
 7123: 		    if (nw != NULL) {
 7124: 			if (nw->_private == NULL)
 7125: 			    nw->_private = cur->_private;
 7126: 			if (firstChild == NULL){
 7127: 			    firstChild = nw;
 7128: 			}
 7129: 			nw = xmlAddChild(ctxt->node, nw);
 7130: 		    }
 7131: 		    if (cur == ent->last) {
 7132: 			/*
 7133: 			 * needed to detect some strange empty
 7134: 			 * node cases in the reader tests
 7135: 			 */
 7136: 			if ((ctxt->parseMode == XML_PARSE_READER) &&
 7137: 			    (nw != NULL) &&
 7138: 			    (nw->type == XML_ELEMENT_NODE) &&
 7139: 			    (nw->children == NULL))
 7140: 			    nw->extra = 1;
 7141: 
 7142: 			break;
 7143: 		    }
 7144: 		    cur = cur->next;
 7145: 		}
 7146: #ifdef LIBXML_LEGACY_ENABLED
 7147: 		if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
 7148: 		  xmlAddEntityReference(ent, firstChild, nw);
 7149: #endif /* LIBXML_LEGACY_ENABLED */
 7150: 	    } else if (list == NULL) {
 7151: 		xmlNodePtr nw = NULL, cur, next, last,
 7152: 			   firstChild = NULL;
 7153: 		/*
 7154: 		 * Copy the entity child list and make it the new
 7155: 		 * entity child list. The goal is to make sure any
 7156: 		 * ID or REF referenced will be the one from the
 7157: 		 * document content and not the entity copy.
 7158: 		 */
 7159: 		cur = ent->children;
 7160: 		ent->children = NULL;
 7161: 		last = ent->last;
 7162: 		ent->last = NULL;
 7163: 		while (cur != NULL) {
 7164: 		    next = cur->next;
 7165: 		    cur->next = NULL;
 7166: 		    cur->parent = NULL;
 7167: 		    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
 7168: 		    if (nw != NULL) {
 7169: 			if (nw->_private == NULL)
 7170: 			    nw->_private = cur->_private;
 7171: 			if (firstChild == NULL){
 7172: 			    firstChild = cur;
 7173: 			}
 7174: 			xmlAddChild((xmlNodePtr) ent, nw);
 7175: 			xmlAddChild(ctxt->node, cur);
 7176: 		    }
 7177: 		    if (cur == last)
 7178: 			break;
 7179: 		    cur = next;
 7180: 		}
 7181: 		if (ent->owner == 0)
 7182: 		    ent->owner = 1;
 7183: #ifdef LIBXML_LEGACY_ENABLED
 7184: 		if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
 7185: 		  xmlAddEntityReference(ent, firstChild, nw);
 7186: #endif /* LIBXML_LEGACY_ENABLED */
 7187: 	    } else {
 7188: 		const xmlChar *nbktext;
 7189: 
 7190: 		/*
 7191: 		 * the name change is to avoid coalescing of the
 7192: 		 * node with a possible previous text one which
 7193: 		 * would make ent->children a dangling pointer
 7194: 		 */
 7195: 		nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
 7196: 					-1);
 7197: 		if (ent->children->type == XML_TEXT_NODE)
 7198: 		    ent->children->name = nbktext;
 7199: 		if ((ent->last != ent->children) &&
 7200: 		    (ent->last->type == XML_TEXT_NODE))
 7201: 		    ent->last->name = nbktext;
 7202: 		xmlAddChildList(ctxt->node, ent->children);
 7203: 	    }
 7204: 
 7205: 	    /*
 7206: 	     * This is to avoid a nasty side effect, see
 7207: 	     * characters() in SAX.c
 7208: 	     */
 7209: 	    ctxt->nodemem = 0;
 7210: 	    ctxt->nodelen = 0;
 7211: 	    return;
 7212: 	}
 7213:     }
 7214: }
 7215: 
 7216: /**
 7217:  * xmlParseEntityRef:
 7218:  * @ctxt:  an XML parser context
 7219:  *
 7220:  * parse ENTITY references declarations
 7221:  *
 7222:  * [68] EntityRef ::= '&' Name ';'
 7223:  *
 7224:  * [ WFC: Entity Declared ]
 7225:  * In a document without any DTD, a document with only an internal DTD
 7226:  * subset which contains no parameter entity references, or a document
 7227:  * with "standalone='yes'", the Name given in the entity reference
 7228:  * must match that in an entity declaration, except that well-formed
 7229:  * documents need not declare any of the following entities: amp, lt,
 7230:  * gt, apos, quot.  The declaration of a parameter entity must precede
 7231:  * any reference to it.  Similarly, the declaration of a general entity
 7232:  * must precede any reference to it which appears in a default value in an
 7233:  * attribute-list declaration. Note that if entities are declared in the
 7234:  * external subset or in external parameter entities, a non-validating
 7235:  * processor is not obligated to read and process their declarations;
 7236:  * for such documents, the rule that an entity must be declared is a
 7237:  * well-formedness constraint only if standalone='yes'.
 7238:  *
 7239:  * [ WFC: Parsed Entity ]
 7240:  * An entity reference must not contain the name of an unparsed entity
 7241:  *
 7242:  * Returns the xmlEntityPtr if found, or NULL otherwise.
 7243:  */
 7244: xmlEntityPtr
 7245: xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
 7246:     const xmlChar *name;
 7247:     xmlEntityPtr ent = NULL;
 7248: 
 7249:     GROW;
 7250: 
 7251:     if (RAW != '&')
 7252:         return(NULL);
 7253:     NEXT;
 7254:     name = xmlParseName(ctxt);
 7255:     if (name == NULL) {
 7256: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 7257: 		       "xmlParseEntityRef: no name\n");
 7258:         return(NULL);
 7259:     }
 7260:     if (RAW != ';') {
 7261: 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
 7262: 	return(NULL);
 7263:     }
 7264:     NEXT;
 7265: 
 7266:     /*
 7267:      * Predefined entites override any extra definition
 7268:      */
 7269:     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
 7270:         ent = xmlGetPredefinedEntity(name);
 7271:         if (ent != NULL)
 7272:             return(ent);
 7273:     }
 7274: 
 7275:     /*
 7276:      * Increate the number of entity references parsed
 7277:      */
 7278:     ctxt->nbentities++;
 7279: 
 7280:     /*
 7281:      * Ask first SAX for entity resolution, otherwise try the
 7282:      * entities which may have stored in the parser context.
 7283:      */
 7284:     if (ctxt->sax != NULL) {
 7285: 	if (ctxt->sax->getEntity != NULL)
 7286: 	    ent = ctxt->sax->getEntity(ctxt->userData, name);
 7287: 	if ((ctxt->wellFormed == 1 ) && (ent == NULL) && 
 7288: 	    (ctxt->options & XML_PARSE_OLDSAX))
 7289: 	    ent = xmlGetPredefinedEntity(name);
 7290: 	if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
 7291: 	    (ctxt->userData==ctxt)) {
 7292: 	    ent = xmlSAX2GetEntity(ctxt, name);
 7293: 	}
 7294:     }
 7295:     /*
 7296:      * [ WFC: Entity Declared ]
 7297:      * In a document without any DTD, a document with only an
 7298:      * internal DTD subset which contains no parameter entity
 7299:      * references, or a document with "standalone='yes'", the
 7300:      * Name given in the entity reference must match that in an
 7301:      * entity declaration, except that well-formed documents
 7302:      * need not declare any of the following entities: amp, lt,
 7303:      * gt, apos, quot.
 7304:      * The declaration of a parameter entity must precede any
 7305:      * reference to it.
 7306:      * Similarly, the declaration of a general entity must
 7307:      * precede any reference to it which appears in a default
 7308:      * value in an attribute-list declaration. Note that if
 7309:      * entities are declared in the external subset or in
 7310:      * external parameter entities, a non-validating processor
 7311:      * is not obligated to read and process their declarations;
 7312:      * for such documents, the rule that an entity must be
 7313:      * declared is a well-formedness constraint only if
 7314:      * standalone='yes'.
 7315:      */
 7316:     if (ent == NULL) {
 7317: 	if ((ctxt->standalone == 1) ||
 7318: 	    ((ctxt->hasExternalSubset == 0) &&
 7319: 	     (ctxt->hasPErefs == 0))) {
 7320: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 7321: 		     "Entity '%s' not defined\n", name);
 7322: 	} else {
 7323: 	    xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
 7324: 		     "Entity '%s' not defined\n", name);
 7325: 	    if ((ctxt->inSubset == 0) &&
 7326: 		(ctxt->sax != NULL) &&
 7327: 		(ctxt->sax->reference != NULL)) {
 7328: 		ctxt->sax->reference(ctxt->userData, name);
 7329: 	    }
 7330: 	}
 7331: 	ctxt->valid = 0;
 7332:     }
 7333: 
 7334:     /*
 7335:      * [ WFC: Parsed Entity ]
 7336:      * An entity reference must not contain the name of an
 7337:      * unparsed entity
 7338:      */
 7339:     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
 7340: 	xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
 7341: 		 "Entity reference to unparsed entity %s\n", name);
 7342:     }
 7343: 
 7344:     /*
 7345:      * [ WFC: No External Entity References ]
 7346:      * Attribute values cannot contain direct or indirect
 7347:      * entity references to external entities.
 7348:      */
 7349:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
 7350: 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
 7351: 	xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
 7352: 	     "Attribute references external entity '%s'\n", name);
 7353:     }
 7354:     /*
 7355:      * [ WFC: No < in Attribute Values ]
 7356:      * The replacement text of any entity referred to directly or
 7357:      * indirectly in an attribute value (other than "&lt;") must
 7358:      * not contain a <. 
 7359:      */
 7360:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
 7361: 	     (ent != NULL) && (ent->content != NULL) &&
 7362: 	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
 7363: 	     (xmlStrchr(ent->content, '<'))) {
 7364: 	xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
 7365:     "'<' in entity '%s' is not allowed in attributes values\n", name);
 7366:     }
 7367: 
 7368:     /*
 7369:      * Internal check, no parameter entities here ...
 7370:      */
 7371:     else {
 7372: 	switch (ent->etype) {
 7373: 	    case XML_INTERNAL_PARAMETER_ENTITY:
 7374: 	    case XML_EXTERNAL_PARAMETER_ENTITY:
 7375: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
 7376: 	     "Attempt to reference the parameter entity '%s'\n",
 7377: 			      name);
 7378: 	    break;
 7379: 	    default:
 7380: 	    break;
 7381: 	}
 7382:     }
 7383: 
 7384:     /*
 7385:      * [ WFC: No Recursion ]
 7386:      * A parsed entity must not contain a recursive reference
 7387:      * to itself, either directly or indirectly. 
 7388:      * Done somewhere else
 7389:      */
 7390:     return(ent);
 7391: }
 7392: 
 7393: /**
 7394:  * xmlParseStringEntityRef:
 7395:  * @ctxt:  an XML parser context
 7396:  * @str:  a pointer to an index in the string
 7397:  *
 7398:  * parse ENTITY references declarations, but this version parses it from
 7399:  * a string value.
 7400:  *
 7401:  * [68] EntityRef ::= '&' Name ';'
 7402:  *
 7403:  * [ WFC: Entity Declared ]
 7404:  * In a document without any DTD, a document with only an internal DTD
 7405:  * subset which contains no parameter entity references, or a document
 7406:  * with "standalone='yes'", the Name given in the entity reference
 7407:  * must match that in an entity declaration, except that well-formed
 7408:  * documents need not declare any of the following entities: amp, lt,
 7409:  * gt, apos, quot.  The declaration of a parameter entity must precede
 7410:  * any reference to it.  Similarly, the declaration of a general entity
 7411:  * must precede any reference to it which appears in a default value in an
 7412:  * attribute-list declaration. Note that if entities are declared in the
 7413:  * external subset or in external parameter entities, a non-validating
 7414:  * processor is not obligated to read and process their declarations;
 7415:  * for such documents, the rule that an entity must be declared is a
 7416:  * well-formedness constraint only if standalone='yes'.
 7417:  *
 7418:  * [ WFC: Parsed Entity ]
 7419:  * An entity reference must not contain the name of an unparsed entity
 7420:  *
 7421:  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
 7422:  * is updated to the current location in the string.
 7423:  */
 7424: static xmlEntityPtr
 7425: xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
 7426:     xmlChar *name;
 7427:     const xmlChar *ptr;
 7428:     xmlChar cur;
 7429:     xmlEntityPtr ent = NULL;
 7430: 
 7431:     if ((str == NULL) || (*str == NULL))
 7432:         return(NULL);
 7433:     ptr = *str;
 7434:     cur = *ptr;
 7435:     if (cur != '&')
 7436: 	return(NULL);
 7437: 
 7438:     ptr++;
 7439:     name = xmlParseStringName(ctxt, &ptr);
 7440:     if (name == NULL) {
 7441: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 7442: 		       "xmlParseStringEntityRef: no name\n");
 7443: 	*str = ptr;
 7444: 	return(NULL);
 7445:     }
 7446:     if (*ptr != ';') {
 7447: 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
 7448:         xmlFree(name);
 7449: 	*str = ptr;
 7450: 	return(NULL);
 7451:     }
 7452:     ptr++;
 7453: 
 7454: 
 7455:     /*
 7456:      * Predefined entites override any extra definition
 7457:      */
 7458:     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
 7459:         ent = xmlGetPredefinedEntity(name);
 7460:         if (ent != NULL) {
 7461:             xmlFree(name);
 7462:             *str = ptr;
 7463:             return(ent);
 7464:         }
 7465:     }
 7466: 
 7467:     /*
 7468:      * Increate the number of entity references parsed
 7469:      */
 7470:     ctxt->nbentities++;
 7471: 
 7472:     /*
 7473:      * Ask first SAX for entity resolution, otherwise try the
 7474:      * entities which may have stored in the parser context.
 7475:      */
 7476:     if (ctxt->sax != NULL) {
 7477: 	if (ctxt->sax->getEntity != NULL)
 7478: 	    ent = ctxt->sax->getEntity(ctxt->userData, name);
 7479: 	if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
 7480: 	    ent = xmlGetPredefinedEntity(name);
 7481: 	if ((ent == NULL) && (ctxt->userData==ctxt)) {
 7482: 	    ent = xmlSAX2GetEntity(ctxt, name);
 7483: 	}
 7484:     }
 7485: 
 7486:     /*
 7487:      * [ WFC: Entity Declared ]
 7488:      * In a document without any DTD, a document with only an
 7489:      * internal DTD subset which contains no parameter entity
 7490:      * references, or a document with "standalone='yes'", the
 7491:      * Name given in the entity reference must match that in an
 7492:      * entity declaration, except that well-formed documents
 7493:      * need not declare any of the following entities: amp, lt,
 7494:      * gt, apos, quot.
 7495:      * The declaration of a parameter entity must precede any
 7496:      * reference to it.
 7497:      * Similarly, the declaration of a general entity must
 7498:      * precede any reference to it which appears in a default
 7499:      * value in an attribute-list declaration. Note that if
 7500:      * entities are declared in the external subset or in
 7501:      * external parameter entities, a non-validating processor
 7502:      * is not obligated to read and process their declarations;
 7503:      * for such documents, the rule that an entity must be
 7504:      * declared is a well-formedness constraint only if
 7505:      * standalone='yes'. 
 7506:      */
 7507:     if (ent == NULL) {
 7508: 	if ((ctxt->standalone == 1) ||
 7509: 	    ((ctxt->hasExternalSubset == 0) &&
 7510: 	     (ctxt->hasPErefs == 0))) {
 7511: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 7512: 		     "Entity '%s' not defined\n", name);
 7513: 	} else {
 7514: 	    xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
 7515: 			  "Entity '%s' not defined\n",
 7516: 			  name);
 7517: 	}
 7518: 	/* TODO ? check regressions ctxt->valid = 0; */
 7519:     }
 7520: 
 7521:     /*
 7522:      * [ WFC: Parsed Entity ]
 7523:      * An entity reference must not contain the name of an
 7524:      * unparsed entity
 7525:      */
 7526:     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
 7527: 	xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
 7528: 		 "Entity reference to unparsed entity %s\n", name);
 7529:     }
 7530: 
 7531:     /*
 7532:      * [ WFC: No External Entity References ]
 7533:      * Attribute values cannot contain direct or indirect
 7534:      * entity references to external entities.
 7535:      */
 7536:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
 7537: 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
 7538: 	xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
 7539: 	 "Attribute references external entity '%s'\n", name);
 7540:     }
 7541:     /*
 7542:      * [ WFC: No < in Attribute Values ]
 7543:      * The replacement text of any entity referred to directly or
 7544:      * indirectly in an attribute value (other than "&lt;") must
 7545:      * not contain a <.
 7546:      */
 7547:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
 7548: 	     (ent != NULL) && (ent->content != NULL) &&
 7549: 	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
 7550: 	     (xmlStrchr(ent->content, '<'))) {
 7551: 	xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
 7552:      "'<' in entity '%s' is not allowed in attributes values\n",
 7553: 			  name);
 7554:     }
 7555: 
 7556:     /*
 7557:      * Internal check, no parameter entities here ...
 7558:      */
 7559:     else {
 7560: 	switch (ent->etype) {
 7561: 	    case XML_INTERNAL_PARAMETER_ENTITY:
 7562: 	    case XML_EXTERNAL_PARAMETER_ENTITY:
 7563: 		xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
 7564: 	     "Attempt to reference the parameter entity '%s'\n",
 7565: 				  name);
 7566: 	    break;
 7567: 	    default:
 7568: 	    break;
 7569: 	}
 7570:     }
 7571: 
 7572:     /*
 7573:      * [ WFC: No Recursion ]
 7574:      * A parsed entity must not contain a recursive reference
 7575:      * to itself, either directly or indirectly.
 7576:      * Done somewhere else
 7577:      */
 7578: 
 7579:     xmlFree(name);
 7580:     *str = ptr;
 7581:     return(ent);
 7582: }
 7583: 
 7584: /**
 7585:  * xmlParsePEReference:
 7586:  * @ctxt:  an XML parser context
 7587:  *
 7588:  * parse PEReference declarations
 7589:  * The entity content is handled directly by pushing it's content as
 7590:  * a new input stream.
 7591:  *
 7592:  * [69] PEReference ::= '%' Name ';'
 7593:  *
 7594:  * [ WFC: No Recursion ]
 7595:  * A parsed entity must not contain a recursive
 7596:  * reference to itself, either directly or indirectly. 
 7597:  *
 7598:  * [ WFC: Entity Declared ]
 7599:  * In a document without any DTD, a document with only an internal DTD
 7600:  * subset which contains no parameter entity references, or a document
 7601:  * with "standalone='yes'", ...  ... The declaration of a parameter
 7602:  * entity must precede any reference to it...
 7603:  *
 7604:  * [ VC: Entity Declared ]
 7605:  * In a document with an external subset or external parameter entities
 7606:  * with "standalone='no'", ...  ... The declaration of a parameter entity
 7607:  * must precede any reference to it...
 7608:  *
 7609:  * [ WFC: In DTD ]
 7610:  * Parameter-entity references may only appear in the DTD.
 7611:  * NOTE: misleading but this is handled.
 7612:  */
 7613: void
 7614: xmlParsePEReference(xmlParserCtxtPtr ctxt)
 7615: {
 7616:     const xmlChar *name;
 7617:     xmlEntityPtr entity = NULL;
 7618:     xmlParserInputPtr input;
 7619: 
 7620:     if (RAW != '%')
 7621:         return;
 7622:     NEXT;
 7623:     name = xmlParseName(ctxt);
 7624:     if (name == NULL) {
 7625: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 7626: 		       "xmlParsePEReference: no name\n");
 7627: 	return;
 7628:     }
 7629:     if (RAW != ';') {
 7630: 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
 7631:         return;
 7632:     }
 7633: 
 7634:     NEXT;
 7635: 
 7636:     /*
 7637:      * Increate the number of entity references parsed
 7638:      */
 7639:     ctxt->nbentities++;
 7640: 
 7641:     /*
 7642:      * Request the entity from SAX
 7643:      */
 7644:     if ((ctxt->sax != NULL) &&
 7645: 	(ctxt->sax->getParameterEntity != NULL))
 7646: 	entity = ctxt->sax->getParameterEntity(ctxt->userData,
 7647: 					       name);
 7648:     if (entity == NULL) {
 7649: 	/*
 7650: 	 * [ WFC: Entity Declared ]
 7651: 	 * In a document without any DTD, a document with only an
 7652: 	 * internal DTD subset which contains no parameter entity
 7653: 	 * references, or a document with "standalone='yes'", ...
 7654: 	 * ... The declaration of a parameter entity must precede
 7655: 	 * any reference to it...
 7656: 	 */
 7657: 	if ((ctxt->standalone == 1) ||
 7658: 	    ((ctxt->hasExternalSubset == 0) &&
 7659: 	     (ctxt->hasPErefs == 0))) {
 7660: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 7661: 			      "PEReference: %%%s; not found\n",
 7662: 			      name);
 7663: 	} else {
 7664: 	    /*
 7665: 	     * [ VC: Entity Declared ]
 7666: 	     * In a document with an external subset or external
 7667: 	     * parameter entities with "standalone='no'", ...
 7668: 	     * ... The declaration of a parameter entity must
 7669: 	     * precede any reference to it...
 7670: 	     */
 7671: 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
 7672: 			  "PEReference: %%%s; not found\n",
 7673: 			  name, NULL);
 7674: 	    ctxt->valid = 0;
 7675: 	}
 7676:     } else {
 7677: 	/*
 7678: 	 * Internal checking in case the entity quest barfed
 7679: 	 */
 7680: 	if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
 7681: 	    (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
 7682: 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
 7683: 		  "Internal: %%%s; is not a parameter entity\n",
 7684: 			  name, NULL);
 7685: 	} else if (ctxt->input->free != deallocblankswrapper) {
 7686: 	    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
 7687: 	    if (xmlPushInput(ctxt, input) < 0)
 7688: 		return;
 7689: 	} else {
 7690: 	    /*
 7691: 	     * TODO !!!
 7692: 	     * handle the extra spaces added before and after
 7693: 	     * c.f. http://www.w3.org/TR/REC-xml#as-PE
 7694: 	     */
 7695: 	    input = xmlNewEntityInputStream(ctxt, entity);
 7696: 	    if (xmlPushInput(ctxt, input) < 0)
 7697: 		return;
 7698: 	    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
 7699: 		(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
 7700: 		(IS_BLANK_CH(NXT(5)))) {
 7701: 		xmlParseTextDecl(ctxt);
 7702: 		if (ctxt->errNo ==
 7703: 		    XML_ERR_UNSUPPORTED_ENCODING) {
 7704: 		    /*
 7705: 		     * The XML REC instructs us to stop parsing
 7706: 		     * right here
 7707: 		     */
 7708: 		    ctxt->instate = XML_PARSER_EOF;
 7709: 		    return;
 7710: 		}
 7711: 	    }
 7712: 	}
 7713:     }
 7714:     ctxt->hasPErefs = 1;
 7715: }
 7716: 
 7717: /**
 7718:  * xmlLoadEntityContent:
 7719:  * @ctxt:  an XML parser context
 7720:  * @entity: an unloaded system entity
 7721:  *
 7722:  * Load the original content of the given system entity from the
 7723:  * ExternalID/SystemID given. This is to be used for Included in Literal
 7724:  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
 7725:  *
 7726:  * Returns 0 in case of success and -1 in case of failure
 7727:  */
 7728: static int
 7729: xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
 7730:     xmlParserInputPtr input;
 7731:     xmlBufferPtr buf;
 7732:     int l, c;
 7733:     int count = 0;
 7734: 
 7735:     if ((ctxt == NULL) || (entity == NULL) ||
 7736:         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
 7737: 	 (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
 7738: 	(entity->content != NULL)) {
 7739: 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 7740: 	            "xmlLoadEntityContent parameter error");
 7741:         return(-1);
 7742:     }
 7743: 
 7744:     if (xmlParserDebugEntities)
 7745: 	xmlGenericError(xmlGenericErrorContext,
 7746: 		"Reading %s entity content input\n", entity->name);
 7747: 
 7748:     buf = xmlBufferCreate();
 7749:     if (buf == NULL) {
 7750: 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 7751: 	            "xmlLoadEntityContent parameter error");
 7752:         return(-1);
 7753:     }
 7754: 
 7755:     input = xmlNewEntityInputStream(ctxt, entity);
 7756:     if (input == NULL) {
 7757: 	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 7758: 	            "xmlLoadEntityContent input error");
 7759: 	xmlBufferFree(buf);
 7760:         return(-1);
 7761:     }
 7762: 
 7763:     /*
 7764:      * Push the entity as the current input, read char by char
 7765:      * saving to the buffer until the end of the entity or an error
 7766:      */
 7767:     if (xmlPushInput(ctxt, input) < 0) {
 7768:         xmlBufferFree(buf);
 7769: 	return(-1);
 7770:     }
 7771: 
 7772:     GROW;
 7773:     c = CUR_CHAR(l);
 7774:     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
 7775:            (IS_CHAR(c))) {
 7776:         xmlBufferAdd(buf, ctxt->input->cur, l);
 7777: 	if (count++ > 100) {
 7778: 	    count = 0;
 7779: 	    GROW;
 7780: 	}
 7781: 	NEXTL(l);
 7782: 	c = CUR_CHAR(l);
 7783:     }
 7784: 
 7785:     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
 7786:         xmlPopInput(ctxt);
 7787:     } else if (!IS_CHAR(c)) {
 7788:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
 7789:                           "xmlLoadEntityContent: invalid char value %d\n",
 7790: 	                  c);
 7791: 	xmlBufferFree(buf);
 7792: 	return(-1);
 7793:     }
 7794:     entity->content = buf->content;
 7795:     buf->content = NULL;
 7796:     xmlBufferFree(buf);
 7797: 
 7798:     return(0);
 7799: }
 7800: 
 7801: /**
 7802:  * xmlParseStringPEReference:
 7803:  * @ctxt:  an XML parser context
 7804:  * @str:  a pointer to an index in the string
 7805:  *
 7806:  * parse PEReference declarations
 7807:  *
 7808:  * [69] PEReference ::= '%' Name ';'
 7809:  *
 7810:  * [ WFC: No Recursion ]
 7811:  * A parsed entity must not contain a recursive
 7812:  * reference to itself, either directly or indirectly.
 7813:  *
 7814:  * [ WFC: Entity Declared ]
 7815:  * In a document without any DTD, a document with only an internal DTD
 7816:  * subset which contains no parameter entity references, or a document
 7817:  * with "standalone='yes'", ...  ... The declaration of a parameter
 7818:  * entity must precede any reference to it...
 7819:  *
 7820:  * [ VC: Entity Declared ]
 7821:  * In a document with an external subset or external parameter entities
 7822:  * with "standalone='no'", ...  ... The declaration of a parameter entity
 7823:  * must precede any reference to it...
 7824:  *
 7825:  * [ WFC: In DTD ]
 7826:  * Parameter-entity references may only appear in the DTD.
 7827:  * NOTE: misleading but this is handled.
 7828:  *
 7829:  * Returns the string of the entity content.
 7830:  *         str is updated to the current value of the index
 7831:  */
 7832: static xmlEntityPtr
 7833: xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
 7834:     const xmlChar *ptr;
 7835:     xmlChar cur;
 7836:     xmlChar *name;
 7837:     xmlEntityPtr entity = NULL;
 7838: 
 7839:     if ((str == NULL) || (*str == NULL)) return(NULL);
 7840:     ptr = *str;
 7841:     cur = *ptr;
 7842:     if (cur != '%')
 7843:         return(NULL);
 7844:     ptr++;
 7845:     name = xmlParseStringName(ctxt, &ptr);
 7846:     if (name == NULL) {
 7847: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 7848: 		       "xmlParseStringPEReference: no name\n");
 7849: 	*str = ptr;
 7850: 	return(NULL);
 7851:     }
 7852:     cur = *ptr;
 7853:     if (cur != ';') {
 7854: 	xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
 7855: 	xmlFree(name);
 7856: 	*str = ptr;
 7857: 	return(NULL);
 7858:     }
 7859:     ptr++;
 7860: 
 7861:     /*
 7862:      * Increate the number of entity references parsed
 7863:      */
 7864:     ctxt->nbentities++;
 7865: 
 7866:     /*
 7867:      * Request the entity from SAX
 7868:      */
 7869:     if ((ctxt->sax != NULL) &&
 7870: 	(ctxt->sax->getParameterEntity != NULL))
 7871: 	entity = ctxt->sax->getParameterEntity(ctxt->userData,
 7872: 					       name);
 7873:     if (entity == NULL) {
 7874: 	/*
 7875: 	 * [ WFC: Entity Declared ]
 7876: 	 * In a document without any DTD, a document with only an
 7877: 	 * internal DTD subset which contains no parameter entity
 7878: 	 * references, or a document with "standalone='yes'", ...
 7879: 	 * ... The declaration of a parameter entity must precede
 7880: 	 * any reference to it...
 7881: 	 */
 7882: 	if ((ctxt->standalone == 1) ||
 7883: 	    ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
 7884: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 7885: 		 "PEReference: %%%s; not found\n", name);
 7886: 	} else {
 7887: 	    /*
 7888: 	     * [ VC: Entity Declared ]
 7889: 	     * In a document with an external subset or external
 7890: 	     * parameter entities with "standalone='no'", ...
 7891: 	     * ... The declaration of a parameter entity must
 7892: 	     * precede any reference to it...
 7893: 	     */
 7894: 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
 7895: 			  "PEReference: %%%s; not found\n",
 7896: 			  name, NULL);
 7897: 	    ctxt->valid = 0;
 7898: 	}
 7899:     } else {
 7900: 	/*
 7901: 	 * Internal checking in case the entity quest barfed
 7902: 	 */
 7903: 	if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
 7904: 	    (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
 7905: 	    xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
 7906: 			  "%%%s; is not a parameter entity\n",
 7907: 			  name, NULL);
 7908: 	}
 7909:     }
 7910:     ctxt->hasPErefs = 1;
 7911:     xmlFree(name);
 7912:     *str = ptr;
 7913:     return(entity);
 7914: }
 7915: 
 7916: /**
 7917:  * xmlParseDocTypeDecl:
 7918:  * @ctxt:  an XML parser context
 7919:  *
 7920:  * parse a DOCTYPE declaration
 7921:  *
 7922:  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
 7923:  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
 7924:  *
 7925:  * [ VC: Root Element Type ]
 7926:  * The Name in the document type declaration must match the element
 7927:  * type of the root element. 
 7928:  */
 7929: 
 7930: void
 7931: xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
 7932:     const xmlChar *name = NULL;
 7933:     xmlChar *ExternalID = NULL;
 7934:     xmlChar *URI = NULL;
 7935: 
 7936:     /*
 7937:      * We know that '<!DOCTYPE' has been detected.
 7938:      */
 7939:     SKIP(9);
 7940: 
 7941:     SKIP_BLANKS;
 7942: 
 7943:     /*
 7944:      * Parse the DOCTYPE name.
 7945:      */
 7946:     name = xmlParseName(ctxt);
 7947:     if (name == NULL) {
 7948: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 7949: 		       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
 7950:     }
 7951:     ctxt->intSubName = name;
 7952: 
 7953:     SKIP_BLANKS;
 7954: 
 7955:     /*
 7956:      * Check for SystemID and ExternalID
 7957:      */
 7958:     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
 7959: 
 7960:     if ((URI != NULL) || (ExternalID != NULL)) {
 7961:         ctxt->hasExternalSubset = 1;
 7962:     }
 7963:     ctxt->extSubURI = URI;
 7964:     ctxt->extSubSystem = ExternalID;
 7965: 
 7966:     SKIP_BLANKS;
 7967: 
 7968:     /*
 7969:      * Create and update the internal subset.
 7970:      */
 7971:     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
 7972: 	(!ctxt->disableSAX))
 7973: 	ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
 7974: 
 7975:     /*
 7976:      * Is there any internal subset declarations ?
 7977:      * they are handled separately in xmlParseInternalSubset()
 7978:      */
 7979:     if (RAW == '[')
 7980: 	return;
 7981: 
 7982:     /*
 7983:      * We should be at the end of the DOCTYPE declaration.
 7984:      */
 7985:     if (RAW != '>') {
 7986: 	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
 7987:     }
 7988:     NEXT;
 7989: }
 7990: 
 7991: /**
 7992:  * xmlParseInternalSubset:
 7993:  * @ctxt:  an XML parser context
 7994:  *
 7995:  * parse the internal subset declaration
 7996:  *
 7997:  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
 7998:  */
 7999: 
 8000: static void
 8001: xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
 8002:     /*
 8003:      * Is there any DTD definition ?
 8004:      */
 8005:     if (RAW == '[') {
 8006:         ctxt->instate = XML_PARSER_DTD;
 8007:         NEXT;
 8008: 	/*
 8009: 	 * Parse the succession of Markup declarations and 
 8010: 	 * PEReferences.
 8011: 	 * Subsequence (markupdecl | PEReference | S)*
 8012: 	 */
 8013: 	while (RAW != ']') {
 8014: 	    const xmlChar *check = CUR_PTR;
 8015: 	    unsigned int cons = ctxt->input->consumed;
 8016: 
 8017: 	    SKIP_BLANKS;
 8018: 	    xmlParseMarkupDecl(ctxt);
 8019: 	    xmlParsePEReference(ctxt);
 8020: 
 8021: 	    /*
 8022: 	     * Pop-up of finished entities.
 8023: 	     */
 8024: 	    while ((RAW == 0) && (ctxt->inputNr > 1))
 8025: 		xmlPopInput(ctxt);
 8026: 
 8027: 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 8028: 		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 8029: 	     "xmlParseInternalSubset: error detected in Markup declaration\n");
 8030: 		break;
 8031: 	    }
 8032: 	}
 8033: 	if (RAW == ']') { 
 8034: 	    NEXT;
 8035: 	    SKIP_BLANKS;
 8036: 	}
 8037:     }
 8038: 
 8039:     /*
 8040:      * We should be at the end of the DOCTYPE declaration.
 8041:      */
 8042:     if (RAW != '>') {
 8043: 	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
 8044:     }
 8045:     NEXT;
 8046: }
 8047: 
 8048: #ifdef LIBXML_SAX1_ENABLED
 8049: /**
 8050:  * xmlParseAttribute:
 8051:  * @ctxt:  an XML parser context
 8052:  * @value:  a xmlChar ** used to store the value of the attribute
 8053:  *
 8054:  * parse an attribute
 8055:  *
 8056:  * [41] Attribute ::= Name Eq AttValue
 8057:  *
 8058:  * [ WFC: No External Entity References ]
 8059:  * Attribute values cannot contain direct or indirect entity references
 8060:  * to external entities.
 8061:  *
 8062:  * [ WFC: No < in Attribute Values ]
 8063:  * The replacement text of any entity referred to directly or indirectly in
 8064:  * an attribute value (other than "&lt;") must not contain a <. 
 8065:  * 
 8066:  * [ VC: Attribute Value Type ]
 8067:  * The attribute must have been declared; the value must be of the type
 8068:  * declared for it.
 8069:  *
 8070:  * [25] Eq ::= S? '=' S?
 8071:  *
 8072:  * With namespace:
 8073:  *
 8074:  * [NS 11] Attribute ::= QName Eq AttValue
 8075:  *
 8076:  * Also the case QName == xmlns:??? is handled independently as a namespace
 8077:  * definition.
 8078:  *
 8079:  * Returns the attribute name, and the value in *value.
 8080:  */
 8081: 
 8082: const xmlChar *
 8083: xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
 8084:     const xmlChar *name;
 8085:     xmlChar *val;
 8086: 
 8087:     *value = NULL;
 8088:     GROW;
 8089:     name = xmlParseName(ctxt);
 8090:     if (name == NULL) {
 8091: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 8092: 	               "error parsing attribute name\n");
 8093:         return(NULL);
 8094:     }
 8095: 
 8096:     /*
 8097:      * read the value
 8098:      */
 8099:     SKIP_BLANKS;
 8100:     if (RAW == '=') {
 8101:         NEXT;
 8102: 	SKIP_BLANKS;
 8103: 	val = xmlParseAttValue(ctxt);
 8104: 	ctxt->instate = XML_PARSER_CONTENT;
 8105:     } else {
 8106: 	xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
 8107: 	       "Specification mandate value for attribute %s\n", name);
 8108: 	return(NULL);
 8109:     }
 8110: 
 8111:     /*
 8112:      * Check that xml:lang conforms to the specification
 8113:      * No more registered as an error, just generate a warning now
 8114:      * since this was deprecated in XML second edition
 8115:      */
 8116:     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
 8117: 	if (!xmlCheckLanguageID(val)) {
 8118: 	    xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
 8119: 		          "Malformed value for xml:lang : %s\n",
 8120: 			  val, NULL);
 8121: 	}
 8122:     }
 8123: 
 8124:     /*
 8125:      * Check that xml:space conforms to the specification
 8126:      */
 8127:     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
 8128: 	if (xmlStrEqual(val, BAD_CAST "default"))
 8129: 	    *(ctxt->space) = 0;
 8130: 	else if (xmlStrEqual(val, BAD_CAST "preserve"))
 8131: 	    *(ctxt->space) = 1;
 8132: 	else {
 8133: 		xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
 8134: "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
 8135:                                  val, NULL);
 8136: 	}
 8137:     }
 8138: 
 8139:     *value = val;
 8140:     return(name);
 8141: }
 8142: 
 8143: /**
 8144:  * xmlParseStartTag:
 8145:  * @ctxt:  an XML parser context
 8146:  * 
 8147:  * parse a start of tag either for rule element or
 8148:  * EmptyElement. In both case we don't parse the tag closing chars.
 8149:  *
 8150:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
 8151:  *
 8152:  * [ WFC: Unique Att Spec ]
 8153:  * No attribute name may appear more than once in the same start-tag or
 8154:  * empty-element tag. 
 8155:  *
 8156:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
 8157:  *
 8158:  * [ WFC: Unique Att Spec ]
 8159:  * No attribute name may appear more than once in the same start-tag or
 8160:  * empty-element tag. 
 8161:  *
 8162:  * With namespace:
 8163:  *
 8164:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
 8165:  *
 8166:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
 8167:  *
 8168:  * Returns the element name parsed
 8169:  */
 8170: 
 8171: const xmlChar *
 8172: xmlParseStartTag(xmlParserCtxtPtr ctxt) {
 8173:     const xmlChar *name;
 8174:     const xmlChar *attname;
 8175:     xmlChar *attvalue;
 8176:     const xmlChar **atts = ctxt->atts;
 8177:     int nbatts = 0;
 8178:     int maxatts = ctxt->maxatts;
 8179:     int i;
 8180: 
 8181:     if (RAW != '<') return(NULL);
 8182:     NEXT1;
 8183: 
 8184:     name = xmlParseName(ctxt);
 8185:     if (name == NULL) {
 8186: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 8187: 	     "xmlParseStartTag: invalid element name\n");
 8188:         return(NULL);
 8189:     }
 8190: 
 8191:     /*
 8192:      * Now parse the attributes, it ends up with the ending
 8193:      *
 8194:      * (S Attribute)* S?
 8195:      */
 8196:     SKIP_BLANKS;
 8197:     GROW;
 8198: 
 8199:     while ((RAW != '>') && 
 8200: 	   ((RAW != '/') || (NXT(1) != '>')) &&
 8201: 	   (IS_BYTE_CHAR(RAW))) {
 8202: 	const xmlChar *q = CUR_PTR;
 8203: 	unsigned int cons = ctxt->input->consumed;
 8204: 
 8205: 	attname = xmlParseAttribute(ctxt, &attvalue);
 8206:         if ((attname != NULL) && (attvalue != NULL)) {
 8207: 	    /*
 8208: 	     * [ WFC: Unique Att Spec ]
 8209: 	     * No attribute name may appear more than once in the same
 8210: 	     * start-tag or empty-element tag. 
 8211: 	     */
 8212: 	    for (i = 0; i < nbatts;i += 2) {
 8213: 	        if (xmlStrEqual(atts[i], attname)) {
 8214: 		    xmlErrAttributeDup(ctxt, NULL, attname);
 8215: 		    xmlFree(attvalue);
 8216: 		    goto failed;
 8217: 		}
 8218: 	    }
 8219: 	    /*
 8220: 	     * Add the pair to atts
 8221: 	     */
 8222: 	    if (atts == NULL) {
 8223: 	        maxatts = 22; /* allow for 10 attrs by default */
 8224: 	        atts = (const xmlChar **)
 8225: 		       xmlMalloc(maxatts * sizeof(xmlChar *));
 8226: 		if (atts == NULL) {
 8227: 		    xmlErrMemory(ctxt, NULL);
 8228: 		    if (attvalue != NULL)
 8229: 			xmlFree(attvalue);
 8230: 		    goto failed;
 8231: 		}
 8232: 		ctxt->atts = atts;
 8233: 		ctxt->maxatts = maxatts;
 8234: 	    } else if (nbatts + 4 > maxatts) {
 8235: 	        const xmlChar **n;
 8236: 
 8237: 	        maxatts *= 2;
 8238: 	        n = (const xmlChar **) xmlRealloc((void *) atts,
 8239: 					     maxatts * sizeof(const xmlChar *));
 8240: 		if (n == NULL) {
 8241: 		    xmlErrMemory(ctxt, NULL);
 8242: 		    if (attvalue != NULL)
 8243: 			xmlFree(attvalue);
 8244: 		    goto failed;
 8245: 		}
 8246: 		atts = n;
 8247: 		ctxt->atts = atts;
 8248: 		ctxt->maxatts = maxatts;
 8249: 	    }
 8250: 	    atts[nbatts++] = attname;
 8251: 	    atts[nbatts++] = attvalue;
 8252: 	    atts[nbatts] = NULL;
 8253: 	    atts[nbatts + 1] = NULL;
 8254: 	} else {
 8255: 	    if (attvalue != NULL)
 8256: 		xmlFree(attvalue);
 8257: 	}
 8258: 
 8259: failed:     
 8260: 
 8261: 	GROW
 8262: 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
 8263: 	    break;
 8264: 	if (!IS_BLANK_CH(RAW)) {
 8265: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 8266: 			   "attributes construct error\n");
 8267: 	}
 8268: 	SKIP_BLANKS;
 8269:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
 8270:             (attname == NULL) && (attvalue == NULL)) {
 8271: 	    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
 8272: 			   "xmlParseStartTag: problem parsing attributes\n");
 8273: 	    break;
 8274: 	}
 8275: 	SHRINK;
 8276:         GROW;
 8277:     }
 8278: 
 8279:     /*
 8280:      * SAX: Start of Element !
 8281:      */
 8282:     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
 8283: 	(!ctxt->disableSAX)) {
 8284: 	if (nbatts > 0)
 8285: 	    ctxt->sax->startElement(ctxt->userData, name, atts);
 8286: 	else
 8287: 	    ctxt->sax->startElement(ctxt->userData, name, NULL);
 8288:     }
 8289: 
 8290:     if (atts != NULL) {
 8291:         /* Free only the content strings */
 8292:         for (i = 1;i < nbatts;i+=2)
 8293: 	    if (atts[i] != NULL)
 8294: 	       xmlFree((xmlChar *) atts[i]);
 8295:     }
 8296:     return(name);
 8297: }
 8298: 
 8299: /**
 8300:  * xmlParseEndTag1:
 8301:  * @ctxt:  an XML parser context
 8302:  * @line:  line of the start tag
 8303:  * @nsNr:  number of namespaces on the start tag
 8304:  *
 8305:  * parse an end of tag
 8306:  *
 8307:  * [42] ETag ::= '</' Name S? '>'
 8308:  *
 8309:  * With namespace
 8310:  *
 8311:  * [NS 9] ETag ::= '</' QName S? '>'
 8312:  */
 8313: 
 8314: static void
 8315: xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
 8316:     const xmlChar *name;
 8317: 
 8318:     GROW;
 8319:     if ((RAW != '<') || (NXT(1) != '/')) {
 8320: 	xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
 8321: 		       "xmlParseEndTag: '</' not found\n");
 8322: 	return;
 8323:     }
 8324:     SKIP(2);
 8325: 
 8326:     name = xmlParseNameAndCompare(ctxt,ctxt->name);
 8327: 
 8328:     /*
 8329:      * We should definitely be at the ending "S? '>'" part
 8330:      */
 8331:     GROW;
 8332:     SKIP_BLANKS;
 8333:     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
 8334: 	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
 8335:     } else
 8336: 	NEXT1;
 8337: 
 8338:     /*
 8339:      * [ WFC: Element Type Match ]
 8340:      * The Name in an element's end-tag must match the element type in the
 8341:      * start-tag. 
 8342:      *
 8343:      */
 8344:     if (name != (xmlChar*)1) {
 8345:         if (name == NULL) name = BAD_CAST "unparseable";
 8346:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
 8347: 		     "Opening and ending tag mismatch: %s line %d and %s\n",
 8348: 		                ctxt->name, line, name);
 8349:     }
 8350: 
 8351:     /*
 8352:      * SAX: End of Tag
 8353:      */
 8354:     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
 8355: 	(!ctxt->disableSAX))
 8356:         ctxt->sax->endElement(ctxt->userData, ctxt->name);
 8357: 
 8358:     namePop(ctxt);
 8359:     spacePop(ctxt);
 8360:     return;
 8361: }
 8362: 
 8363: /**
 8364:  * xmlParseEndTag:
 8365:  * @ctxt:  an XML parser context
 8366:  *
 8367:  * parse an end of tag
 8368:  *
 8369:  * [42] ETag ::= '</' Name S? '>'
 8370:  *
 8371:  * With namespace
 8372:  *
 8373:  * [NS 9] ETag ::= '</' QName S? '>'
 8374:  */
 8375: 
 8376: void
 8377: xmlParseEndTag(xmlParserCtxtPtr ctxt) {
 8378:     xmlParseEndTag1(ctxt, 0);
 8379: }
 8380: #endif /* LIBXML_SAX1_ENABLED */
 8381: 
 8382: /************************************************************************
 8383:  *									*
 8384:  *		      SAX 2 specific operations				*
 8385:  *									*
 8386:  ************************************************************************/
 8387: 
 8388: /*
 8389:  * xmlGetNamespace:
 8390:  * @ctxt:  an XML parser context
 8391:  * @prefix:  the prefix to lookup
 8392:  *
 8393:  * Lookup the namespace name for the @prefix (which ca be NULL)
 8394:  * The prefix must come from the @ctxt->dict dictionnary
 8395:  *
 8396:  * Returns the namespace name or NULL if not bound
 8397:  */
 8398: static const xmlChar *
 8399: xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
 8400:     int i;
 8401: 
 8402:     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
 8403:     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
 8404:         if (ctxt->nsTab[i] == prefix) {
 8405: 	    if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
 8406: 	        return(NULL);
 8407: 	    return(ctxt->nsTab[i + 1]);
 8408: 	}
 8409:     return(NULL);
 8410: }
 8411: 
 8412: /**
 8413:  * xmlParseQName:
 8414:  * @ctxt:  an XML parser context
 8415:  * @prefix:  pointer to store the prefix part
 8416:  *
 8417:  * parse an XML Namespace QName
 8418:  *
 8419:  * [6]  QName  ::= (Prefix ':')? LocalPart
 8420:  * [7]  Prefix  ::= NCName
 8421:  * [8]  LocalPart  ::= NCName
 8422:  *
 8423:  * Returns the Name parsed or NULL
 8424:  */
 8425: 
 8426: static const xmlChar *
 8427: xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
 8428:     const xmlChar *l, *p;
 8429: 
 8430:     GROW;
 8431: 
 8432:     l = xmlParseNCName(ctxt);
 8433:     if (l == NULL) {
 8434:         if (CUR == ':') {
 8435: 	    l = xmlParseName(ctxt);
 8436: 	    if (l != NULL) {
 8437: 	        xmlNsErr(ctxt, XML_NS_ERR_QNAME, 
 8438: 		         "Failed to parse QName '%s'\n", l, NULL, NULL);
 8439: 		*prefix = NULL;
 8440: 		return(l);
 8441: 	    }
 8442: 	}
 8443:         return(NULL);
 8444:     }
 8445:     if (CUR == ':') {
 8446:         NEXT;
 8447: 	p = l;
 8448: 	l = xmlParseNCName(ctxt);
 8449: 	if (l == NULL) {
 8450: 	    xmlChar *tmp;
 8451: 
 8452:             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
 8453: 	             "Failed to parse QName '%s:'\n", p, NULL, NULL);
 8454: 	    l = xmlParseNmtoken(ctxt);
 8455: 	    if (l == NULL)
 8456: 		tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
 8457: 	    else {
 8458: 		tmp = xmlBuildQName(l, p, NULL, 0);
 8459: 		xmlFree((char *)l);
 8460: 	    }
 8461: 	    p = xmlDictLookup(ctxt->dict, tmp, -1);
 8462: 	    if (tmp != NULL) xmlFree(tmp);
 8463: 	    *prefix = NULL;
 8464: 	    return(p);
 8465: 	}
 8466: 	if (CUR == ':') {
 8467: 	    xmlChar *tmp;
 8468: 
 8469:             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
 8470: 	             "Failed to parse QName '%s:%s:'\n", p, l, NULL);
 8471: 	    NEXT;
 8472: 	    tmp = (xmlChar *) xmlParseName(ctxt);
 8473: 	    if (tmp != NULL) {
 8474: 	        tmp = xmlBuildQName(tmp, l, NULL, 0);
 8475: 		l = xmlDictLookup(ctxt->dict, tmp, -1);
 8476: 		if (tmp != NULL) xmlFree(tmp);
 8477: 		*prefix = p;
 8478: 		return(l);
 8479: 	    }
 8480: 	    tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
 8481: 	    l = xmlDictLookup(ctxt->dict, tmp, -1);
 8482: 	    if (tmp != NULL) xmlFree(tmp);
 8483: 	    *prefix = p;
 8484: 	    return(l);
 8485: 	}
 8486: 	*prefix = p;
 8487:     } else
 8488:         *prefix = NULL;
 8489:     return(l);
 8490: }
 8491: 
 8492: /**
 8493:  * xmlParseQNameAndCompare:
 8494:  * @ctxt:  an XML parser context
 8495:  * @name:  the localname
 8496:  * @prefix:  the prefix, if any.
 8497:  *
 8498:  * parse an XML name and compares for match
 8499:  * (specialized for endtag parsing)
 8500:  *
 8501:  * Returns NULL for an illegal name, (xmlChar*) 1 for success
 8502:  * and the name for mismatch
 8503:  */
 8504: 
 8505: static const xmlChar *
 8506: xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
 8507:                         xmlChar const *prefix) {
 8508:     const xmlChar *cmp;
 8509:     const xmlChar *in;
 8510:     const xmlChar *ret;
 8511:     const xmlChar *prefix2;
 8512: 
 8513:     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
 8514: 
 8515:     GROW;
 8516:     in = ctxt->input->cur;
 8517: 
 8518:     cmp = prefix;
 8519:     while (*in != 0 && *in == *cmp) {
 8520:     	++in;
 8521: 	++cmp;
 8522:     }
 8523:     if ((*cmp == 0) && (*in == ':')) {
 8524:         in++;
 8525: 	cmp = name;
 8526: 	while (*in != 0 && *in == *cmp) {
 8527: 	    ++in;
 8528: 	    ++cmp;
 8529: 	}
 8530: 	if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
 8531: 	    /* success */
 8532: 	    ctxt->input->cur = in;
 8533: 	    return((const xmlChar*) 1);
 8534: 	}
 8535:     }
 8536:     /*
 8537:      * all strings coms from the dictionary, equality can be done directly
 8538:      */
 8539:     ret = xmlParseQName (ctxt, &prefix2);
 8540:     if ((ret == name) && (prefix == prefix2))
 8541: 	return((const xmlChar*) 1);
 8542:     return ret;
 8543: }
 8544: 
 8545: /**
 8546:  * xmlParseAttValueInternal:
 8547:  * @ctxt:  an XML parser context
 8548:  * @len:  attribute len result
 8549:  * @alloc:  whether the attribute was reallocated as a new string
 8550:  * @normalize:  if 1 then further non-CDATA normalization must be done
 8551:  *
 8552:  * parse a value for an attribute.
 8553:  * NOTE: if no normalization is needed, the routine will return pointers
 8554:  *       directly from the data buffer.
 8555:  *
 8556:  * 3.3.3 Attribute-Value Normalization:
 8557:  * Before the value of an attribute is passed to the application or
 8558:  * checked for validity, the XML processor must normalize it as follows: 
 8559:  * - a character reference is processed by appending the referenced
 8560:  *   character to the attribute value
 8561:  * - an entity reference is processed by recursively processing the
 8562:  *   replacement text of the entity 
 8563:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
 8564:  *   appending #x20 to the normalized value, except that only a single
 8565:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
 8566:  *   parsed entity or the literal entity value of an internal parsed entity 
 8567:  * - other characters are processed by appending them to the normalized value 
 8568:  * If the declared value is not CDATA, then the XML processor must further
 8569:  * process the normalized attribute value by discarding any leading and
 8570:  * trailing space (#x20) characters, and by replacing sequences of space
 8571:  * (#x20) characters by a single space (#x20) character.  
 8572:  * All attributes for which no declaration has been read should be treated
 8573:  * by a non-validating parser as if declared CDATA.
 8574:  *
 8575:  * Returns the AttValue parsed or NULL. The value has to be freed by the
 8576:  *     caller if it was copied, this can be detected by val[*len] == 0.
 8577:  */
 8578: 
 8579: static xmlChar *
 8580: xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
 8581:                          int normalize)
 8582: {
 8583:     xmlChar limit = 0;
 8584:     const xmlChar *in = NULL, *start, *end, *last;
 8585:     xmlChar *ret = NULL;
 8586: 
 8587:     GROW;
 8588:     in = (xmlChar *) CUR_PTR;
 8589:     if (*in != '"' && *in != '\'') {
 8590:         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
 8591:         return (NULL);
 8592:     }
 8593:     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
 8594: 
 8595:     /*
 8596:      * try to handle in this routine the most common case where no
 8597:      * allocation of a new string is required and where content is
 8598:      * pure ASCII.
 8599:      */
 8600:     limit = *in++;
 8601:     end = ctxt->input->end;
 8602:     start = in;
 8603:     if (in >= end) {
 8604:         const xmlChar *oldbase = ctxt->input->base;
 8605: 	GROW;
 8606: 	if (oldbase != ctxt->input->base) {
 8607: 	    long delta = ctxt->input->base - oldbase;
 8608: 	    start = start + delta;
 8609: 	    in = in + delta;
 8610: 	}
 8611: 	end = ctxt->input->end;
 8612:     }
 8613:     if (normalize) {
 8614:         /*
 8615: 	 * Skip any leading spaces
 8616: 	 */
 8617: 	while ((in < end) && (*in != limit) && 
 8618: 	       ((*in == 0x20) || (*in == 0x9) ||
 8619: 	        (*in == 0xA) || (*in == 0xD))) {
 8620: 	    in++;
 8621: 	    start = in;
 8622: 	    if (in >= end) {
 8623: 		const xmlChar *oldbase = ctxt->input->base;
 8624: 		GROW;
 8625: 		if (oldbase != ctxt->input->base) {
 8626: 		    long delta = ctxt->input->base - oldbase;
 8627: 		    start = start + delta;
 8628: 		    in = in + delta;
 8629: 		}
 8630: 		end = ctxt->input->end;
 8631: 	    }
 8632: 	}
 8633: 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
 8634: 	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
 8635: 	    if ((*in++ == 0x20) && (*in == 0x20)) break;
 8636: 	    if (in >= end) {
 8637: 		const xmlChar *oldbase = ctxt->input->base;
 8638: 		GROW;
 8639: 		if (oldbase != ctxt->input->base) {
 8640: 		    long delta = ctxt->input->base - oldbase;
 8641: 		    start = start + delta;
 8642: 		    in = in + delta;
 8643: 		}
 8644: 		end = ctxt->input->end;
 8645: 	    }
 8646: 	}
 8647: 	last = in;
 8648: 	/*
 8649: 	 * skip the trailing blanks
 8650: 	 */
 8651: 	while ((last[-1] == 0x20) && (last > start)) last--;
 8652: 	while ((in < end) && (*in != limit) && 
 8653: 	       ((*in == 0x20) || (*in == 0x9) ||
 8654: 	        (*in == 0xA) || (*in == 0xD))) {
 8655: 	    in++;
 8656: 	    if (in >= end) {
 8657: 		const xmlChar *oldbase = ctxt->input->base;
 8658: 		GROW;
 8659: 		if (oldbase != ctxt->input->base) {
 8660: 		    long delta = ctxt->input->base - oldbase;
 8661: 		    start = start + delta;
 8662: 		    in = in + delta;
 8663: 		    last = last + delta;
 8664: 		}
 8665: 		end = ctxt->input->end;
 8666: 	    }
 8667: 	}
 8668: 	if (*in != limit) goto need_complex;
 8669:     } else {
 8670: 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
 8671: 	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
 8672: 	    in++;
 8673: 	    if (in >= end) {
 8674: 		const xmlChar *oldbase = ctxt->input->base;
 8675: 		GROW;
 8676: 		if (oldbase != ctxt->input->base) {
 8677: 		    long delta = ctxt->input->base - oldbase;
 8678: 		    start = start + delta;
 8679: 		    in = in + delta;
 8680: 		}
 8681: 		end = ctxt->input->end;
 8682: 	    }
 8683: 	}
 8684: 	last = in;
 8685: 	if (*in != limit) goto need_complex;
 8686:     }
 8687:     in++;
 8688:     if (len != NULL) {
 8689:         *len = last - start;
 8690:         ret = (xmlChar *) start;
 8691:     } else {
 8692:         if (alloc) *alloc = 1;
 8693:         ret = xmlStrndup(start, last - start);
 8694:     }
 8695:     CUR_PTR = in;
 8696:     if (alloc) *alloc = 0;
 8697:     return ret;
 8698: need_complex:
 8699:     if (alloc) *alloc = 1;
 8700:     return xmlParseAttValueComplex(ctxt, len, normalize);
 8701: }
 8702: 
 8703: /**
 8704:  * xmlParseAttribute2:
 8705:  * @ctxt:  an XML parser context
 8706:  * @pref:  the element prefix
 8707:  * @elem:  the element name
 8708:  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
 8709:  * @value:  a xmlChar ** used to store the value of the attribute
 8710:  * @len:  an int * to save the length of the attribute
 8711:  * @alloc:  an int * to indicate if the attribute was allocated
 8712:  *
 8713:  * parse an attribute in the new SAX2 framework.
 8714:  *
 8715:  * Returns the attribute name, and the value in *value, .
 8716:  */
 8717: 
 8718: static const xmlChar *
 8719: xmlParseAttribute2(xmlParserCtxtPtr ctxt,
 8720:                    const xmlChar * pref, const xmlChar * elem,
 8721:                    const xmlChar ** prefix, xmlChar ** value,
 8722:                    int *len, int *alloc)
 8723: {
 8724:     const xmlChar *name;
 8725:     xmlChar *val, *internal_val = NULL;
 8726:     int normalize = 0;
 8727: 
 8728:     *value = NULL;
 8729:     GROW;
 8730:     name = xmlParseQName(ctxt, prefix);
 8731:     if (name == NULL) {
 8732:         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 8733:                        "error parsing attribute name\n");
 8734:         return (NULL);
 8735:     }
 8736: 
 8737:     /*
 8738:      * get the type if needed
 8739:      */
 8740:     if (ctxt->attsSpecial != NULL) {
 8741:         int type;
 8742: 
 8743:         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
 8744:                                             pref, elem, *prefix, name);
 8745:         if (type != 0)
 8746:             normalize = 1;
 8747:     }
 8748: 
 8749:     /*
 8750:      * read the value
 8751:      */
 8752:     SKIP_BLANKS;
 8753:     if (RAW == '=') {
 8754:         NEXT;
 8755:         SKIP_BLANKS;
 8756:         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
 8757: 	if (normalize) {
 8758: 	    /*
 8759: 	     * Sometimes a second normalisation pass for spaces is needed
 8760: 	     * but that only happens if charrefs or entities refernces
 8761: 	     * have been used in the attribute value, i.e. the attribute
 8762: 	     * value have been extracted in an allocated string already.
 8763: 	     */
 8764: 	    if (*alloc) {
 8765: 	        const xmlChar *val2;
 8766: 
 8767: 	        val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
 8768: 		if ((val2 != NULL) && (val2 != val)) {
 8769: 		    xmlFree(val);
 8770: 		    val = (xmlChar *) val2;
 8771: 		}
 8772: 	    }
 8773: 	}
 8774:         ctxt->instate = XML_PARSER_CONTENT;
 8775:     } else {
 8776:         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
 8777:                           "Specification mandate value for attribute %s\n",
 8778:                           name);
 8779:         return (NULL);
 8780:     }
 8781: 
 8782:     if (*prefix == ctxt->str_xml) {
 8783:         /*
 8784:          * Check that xml:lang conforms to the specification
 8785:          * No more registered as an error, just generate a warning now
 8786:          * since this was deprecated in XML second edition
 8787:          */
 8788:         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
 8789:             internal_val = xmlStrndup(val, *len);
 8790:             if (!xmlCheckLanguageID(internal_val)) {
 8791:                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
 8792:                               "Malformed value for xml:lang : %s\n",
 8793:                               internal_val, NULL);
 8794:             }
 8795:         }
 8796: 
 8797:         /*
 8798:          * Check that xml:space conforms to the specification
 8799:          */
 8800:         if (xmlStrEqual(name, BAD_CAST "space")) {
 8801:             internal_val = xmlStrndup(val, *len);
 8802:             if (xmlStrEqual(internal_val, BAD_CAST "default"))
 8803:                 *(ctxt->space) = 0;
 8804:             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
 8805:                 *(ctxt->space) = 1;
 8806:             else {
 8807:                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
 8808:                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
 8809:                               internal_val, NULL);
 8810:             }
 8811:         }
 8812:         if (internal_val) {
 8813:             xmlFree(internal_val);
 8814:         }
 8815:     }
 8816: 
 8817:     *value = val;
 8818:     return (name);
 8819: }
 8820: /**
 8821:  * xmlParseStartTag2:
 8822:  * @ctxt:  an XML parser context
 8823:  * 
 8824:  * parse a start of tag either for rule element or
 8825:  * EmptyElement. In both case we don't parse the tag closing chars.
 8826:  * This routine is called when running SAX2 parsing
 8827:  *
 8828:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
 8829:  *
 8830:  * [ WFC: Unique Att Spec ]
 8831:  * No attribute name may appear more than once in the same start-tag or
 8832:  * empty-element tag. 
 8833:  *
 8834:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
 8835:  *
 8836:  * [ WFC: Unique Att Spec ]
 8837:  * No attribute name may appear more than once in the same start-tag or
 8838:  * empty-element tag. 
 8839:  *
 8840:  * With namespace:
 8841:  *
 8842:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
 8843:  *
 8844:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
 8845:  *
 8846:  * Returns the element name parsed
 8847:  */
 8848: 
 8849: static const xmlChar *
 8850: xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
 8851:                   const xmlChar **URI, int *tlen) {
 8852:     const xmlChar *localname;
 8853:     const xmlChar *prefix;
 8854:     const xmlChar *attname;
 8855:     const xmlChar *aprefix;
 8856:     const xmlChar *nsname;
 8857:     xmlChar *attvalue;
 8858:     const xmlChar **atts = ctxt->atts;
 8859:     int maxatts = ctxt->maxatts;
 8860:     int nratts, nbatts, nbdef;
 8861:     int i, j, nbNs, attval, oldline, oldcol;
 8862:     const xmlChar *base;
 8863:     unsigned long cur;
 8864:     int nsNr = ctxt->nsNr;
 8865: 
 8866:     if (RAW != '<') return(NULL);
 8867:     NEXT1;
 8868: 
 8869:     /*
 8870:      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
 8871:      *       point since the attribute values may be stored as pointers to
 8872:      *       the buffer and calling SHRINK would destroy them !
 8873:      *       The Shrinking is only possible once the full set of attribute
 8874:      *       callbacks have been done.
 8875:      */
 8876: reparse:
 8877:     SHRINK;
 8878:     base = ctxt->input->base;
 8879:     cur = ctxt->input->cur - ctxt->input->base;
 8880:     oldline = ctxt->input->line;
 8881:     oldcol = ctxt->input->col;
 8882:     nbatts = 0;
 8883:     nratts = 0;
 8884:     nbdef = 0;
 8885:     nbNs = 0;
 8886:     attval = 0;
 8887:     /* Forget any namespaces added during an earlier parse of this element. */
 8888:     ctxt->nsNr = nsNr;
 8889: 
 8890:     localname = xmlParseQName(ctxt, &prefix);
 8891:     if (localname == NULL) {
 8892: 	xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
 8893: 		       "StartTag: invalid element name\n");
 8894:         return(NULL);
 8895:     }
 8896:     *tlen = ctxt->input->cur - ctxt->input->base - cur;
 8897: 
 8898:     /*
 8899:      * Now parse the attributes, it ends up with the ending
 8900:      *
 8901:      * (S Attribute)* S?
 8902:      */
 8903:     SKIP_BLANKS;
 8904:     GROW;
 8905:     if (ctxt->input->base != base) goto base_changed;
 8906: 
 8907:     while ((RAW != '>') && 
 8908: 	   ((RAW != '/') || (NXT(1) != '>')) &&
 8909: 	   (IS_BYTE_CHAR(RAW))) {
 8910: 	const xmlChar *q = CUR_PTR;
 8911: 	unsigned int cons = ctxt->input->consumed;
 8912: 	int len = -1, alloc = 0;
 8913: 
 8914: 	attname = xmlParseAttribute2(ctxt, prefix, localname,
 8915: 	                             &aprefix, &attvalue, &len, &alloc);
 8916: 	if (ctxt->input->base != base) {
 8917: 	    if ((attvalue != NULL) && (alloc != 0))
 8918: 	        xmlFree(attvalue);
 8919: 	    attvalue = NULL;
 8920: 	    goto base_changed;
 8921: 	}
 8922:         if ((attname != NULL) && (attvalue != NULL)) {
 8923: 	    if (len < 0) len = xmlStrlen(attvalue);
 8924:             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
 8925: 	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
 8926: 		xmlURIPtr uri;
 8927: 
 8928:                 if (*URL != 0) {
 8929: 		    uri = xmlParseURI((const char *) URL);
 8930: 		    if (uri == NULL) {
 8931: 			xmlNsErr(ctxt, XML_WAR_NS_URI,
 8932: 			         "xmlns: '%s' is not a valid URI\n",
 8933: 					   URL, NULL, NULL);
 8934: 		    } else {
 8935: 			if (uri->scheme == NULL) {
 8936: 			    xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
 8937: 				      "xmlns: URI %s is not absolute\n",
 8938: 				      URL, NULL, NULL);
 8939: 			}
 8940: 			xmlFreeURI(uri);
 8941: 		    }
 8942: 		    if (URL == ctxt->str_xml_ns) {
 8943: 			if (attname != ctxt->str_xml) {
 8944: 			    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 8945: 			 "xml namespace URI cannot be the default namespace\n",
 8946: 				     NULL, NULL, NULL);
 8947: 			}
 8948: 			goto skip_default_ns;
 8949: 		    }
 8950: 		    if ((len == 29) &&
 8951: 			(xmlStrEqual(URL,
 8952: 				 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
 8953: 			xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 8954: 			     "reuse of the xmlns namespace name is forbidden\n",
 8955: 				 NULL, NULL, NULL);
 8956: 			goto skip_default_ns;
 8957: 		    }
 8958: 		}
 8959: 		/*
 8960: 		 * check that it's not a defined namespace
 8961: 		 */
 8962: 		for (j = 1;j <= nbNs;j++)
 8963: 		    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
 8964: 			break;
 8965: 		if (j <= nbNs)
 8966: 		    xmlErrAttributeDup(ctxt, NULL, attname);
 8967: 		else
 8968: 		    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
 8969: skip_default_ns:
 8970: 		if (alloc != 0) xmlFree(attvalue);
 8971: 		SKIP_BLANKS;
 8972: 		continue;
 8973: 	    }
 8974:             if (aprefix == ctxt->str_xmlns) {
 8975: 	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
 8976: 		xmlURIPtr uri;
 8977: 
 8978:                 if (attname == ctxt->str_xml) {
 8979: 		    if (URL != ctxt->str_xml_ns) {
 8980: 		        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 8981: 			         "xml namespace prefix mapped to wrong URI\n",
 8982: 			         NULL, NULL, NULL);
 8983: 		    }
 8984: 		    /*
 8985: 		     * Do not keep a namespace definition node
 8986: 		     */
 8987: 		    goto skip_ns;
 8988: 		}
 8989:                 if (URL == ctxt->str_xml_ns) {
 8990: 		    if (attname != ctxt->str_xml) {
 8991: 		        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 8992: 			         "xml namespace URI mapped to wrong prefix\n",
 8993: 			         NULL, NULL, NULL);
 8994: 		    }
 8995: 		    goto skip_ns;
 8996: 		}
 8997:                 if (attname == ctxt->str_xmlns) {
 8998: 		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 8999: 			     "redefinition of the xmlns prefix is forbidden\n",
 9000: 			     NULL, NULL, NULL);
 9001: 		    goto skip_ns;
 9002: 		}
 9003: 		if ((len == 29) &&
 9004: 		    (xmlStrEqual(URL,
 9005: 		                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
 9006: 		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 9007: 			     "reuse of the xmlns namespace name is forbidden\n",
 9008: 			     NULL, NULL, NULL);
 9009: 		    goto skip_ns;
 9010: 		}
 9011: 		if ((URL == NULL) || (URL[0] == 0)) {
 9012: 		    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
 9013: 		             "xmlns:%s: Empty XML namespace is not allowed\n",
 9014: 			          attname, NULL, NULL);
 9015: 		    goto skip_ns;
 9016: 		} else {
 9017: 		    uri = xmlParseURI((const char *) URL);
 9018: 		    if (uri == NULL) {
 9019: 			xmlNsErr(ctxt, XML_WAR_NS_URI,
 9020: 			     "xmlns:%s: '%s' is not a valid URI\n",
 9021: 					   attname, URL, NULL);
 9022: 		    } else {
 9023: 			if ((ctxt->pedantic) && (uri->scheme == NULL)) {
 9024: 			    xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
 9025: 				      "xmlns:%s: URI %s is not absolute\n",
 9026: 				      attname, URL, NULL);
 9027: 			}
 9028: 			xmlFreeURI(uri);
 9029: 		    }
 9030: 		}
 9031: 
 9032: 		/*
 9033: 		 * check that it's not a defined namespace
 9034: 		 */
 9035: 		for (j = 1;j <= nbNs;j++)
 9036: 		    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
 9037: 			break;
 9038: 		if (j <= nbNs)
 9039: 		    xmlErrAttributeDup(ctxt, aprefix, attname);
 9040: 		else
 9041: 		    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
 9042: skip_ns:
 9043: 		if (alloc != 0) xmlFree(attvalue);
 9044: 		SKIP_BLANKS;
 9045: 		if (ctxt->input->base != base) goto base_changed;
 9046: 		continue;
 9047: 	    }
 9048: 
 9049: 	    /*
 9050: 	     * Add the pair to atts
 9051: 	     */
 9052: 	    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
 9053: 	        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
 9054: 		    if (attvalue[len] == 0)
 9055: 			xmlFree(attvalue);
 9056: 		    goto failed;
 9057: 		}
 9058: 	        maxatts = ctxt->maxatts;
 9059: 		atts = ctxt->atts;
 9060: 	    }
 9061: 	    ctxt->attallocs[nratts++] = alloc;
 9062: 	    atts[nbatts++] = attname;
 9063: 	    atts[nbatts++] = aprefix;
 9064: 	    atts[nbatts++] = NULL; /* the URI will be fetched later */
 9065: 	    atts[nbatts++] = attvalue;
 9066: 	    attvalue += len;
 9067: 	    atts[nbatts++] = attvalue;
 9068: 	    /*
 9069: 	     * tag if some deallocation is needed
 9070: 	     */
 9071: 	    if (alloc != 0) attval = 1;
 9072: 	} else {
 9073: 	    if ((attvalue != NULL) && (attvalue[len] == 0))
 9074: 		xmlFree(attvalue);
 9075: 	}
 9076: 
 9077: failed:
 9078: 
 9079: 	GROW
 9080: 	if (ctxt->input->base != base) goto base_changed;
 9081: 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
 9082: 	    break;
 9083: 	if (!IS_BLANK_CH(RAW)) {
 9084: 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 9085: 			   "attributes construct error\n");
 9086: 	    break;
 9087: 	}
 9088: 	SKIP_BLANKS;
 9089:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
 9090:             (attname == NULL) && (attvalue == NULL)) {
 9091: 	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 9092: 	         "xmlParseStartTag: problem parsing attributes\n");
 9093: 	    break;
 9094: 	}
 9095:         GROW;
 9096: 	if (ctxt->input->base != base) goto base_changed;
 9097:     }
 9098: 
 9099:     /*
 9100:      * The attributes defaulting
 9101:      */
 9102:     if (ctxt->attsDefault != NULL) {
 9103:         xmlDefAttrsPtr defaults;
 9104: 
 9105: 	defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
 9106: 	if (defaults != NULL) {
 9107: 	    for (i = 0;i < defaults->nbAttrs;i++) {
 9108: 	        attname = defaults->values[5 * i];
 9109: 		aprefix = defaults->values[5 * i + 1];
 9110: 
 9111:                 /*
 9112: 		 * special work for namespaces defaulted defs
 9113: 		 */
 9114: 		if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
 9115: 		    /*
 9116: 		     * check that it's not a defined namespace
 9117: 		     */
 9118: 		    for (j = 1;j <= nbNs;j++)
 9119: 		        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
 9120: 			    break;
 9121: 	            if (j <= nbNs) continue;
 9122: 
 9123: 		    nsname = xmlGetNamespace(ctxt, NULL);
 9124: 		    if (nsname != defaults->values[5 * i + 2]) {
 9125: 			if (nsPush(ctxt, NULL,
 9126: 			           defaults->values[5 * i + 2]) > 0)
 9127: 			    nbNs++;
 9128: 		    }
 9129: 		} else if (aprefix == ctxt->str_xmlns) {
 9130: 		    /*
 9131: 		     * check that it's not a defined namespace
 9132: 		     */
 9133: 		    for (j = 1;j <= nbNs;j++)
 9134: 		        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
 9135: 			    break;
 9136: 	            if (j <= nbNs) continue;
 9137: 
 9138: 		    nsname = xmlGetNamespace(ctxt, attname);
 9139: 		    if (nsname != defaults->values[2]) {
 9140: 			if (nsPush(ctxt, attname,
 9141: 			           defaults->values[5 * i + 2]) > 0)
 9142: 			    nbNs++;
 9143: 		    }
 9144: 		} else {
 9145: 		    /*
 9146: 		     * check that it's not a defined attribute
 9147: 		     */
 9148: 		    for (j = 0;j < nbatts;j+=5) {
 9149: 			if ((attname == atts[j]) && (aprefix == atts[j+1]))
 9150: 			    break;
 9151: 		    }
 9152: 		    if (j < nbatts) continue;
 9153: 
 9154: 		    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
 9155: 			if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
 9156: 			    return(NULL);
 9157: 			}
 9158: 			maxatts = ctxt->maxatts;
 9159: 			atts = ctxt->atts;
 9160: 		    }
 9161: 		    atts[nbatts++] = attname;
 9162: 		    atts[nbatts++] = aprefix;
 9163: 		    if (aprefix == NULL)
 9164: 			atts[nbatts++] = NULL;
 9165: 		    else
 9166: 		        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
 9167: 		    atts[nbatts++] = defaults->values[5 * i + 2];
 9168: 		    atts[nbatts++] = defaults->values[5 * i + 3];
 9169: 		    if ((ctxt->standalone == 1) &&
 9170: 		        (defaults->values[5 * i + 4] != NULL)) {
 9171: 			xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED, 
 9172: 	  "standalone: attribute %s on %s defaulted from external subset\n",
 9173: 	                                 attname, localname);
 9174: 		    }
 9175: 		    nbdef++;
 9176: 		}
 9177: 	    }
 9178: 	}
 9179:     }
 9180: 
 9181:     /*
 9182:      * The attributes checkings
 9183:      */
 9184:     for (i = 0; i < nbatts;i += 5) {
 9185:         /*
 9186: 	* The default namespace does not apply to attribute names.
 9187: 	*/
 9188: 	if (atts[i + 1] != NULL) {
 9189: 	    nsname = xmlGetNamespace(ctxt, atts[i + 1]);
 9190: 	    if (nsname == NULL) {
 9191: 		xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
 9192: 		    "Namespace prefix %s for %s on %s is not defined\n",
 9193: 		    atts[i + 1], atts[i], localname);
 9194: 	    }
 9195: 	    atts[i + 2] = nsname;
 9196: 	} else
 9197: 	    nsname = NULL;
 9198: 	/*
 9199: 	 * [ WFC: Unique Att Spec ]
 9200: 	 * No attribute name may appear more than once in the same
 9201: 	 * start-tag or empty-element tag. 
 9202: 	 * As extended by the Namespace in XML REC.
 9203: 	 */
 9204:         for (j = 0; j < i;j += 5) {
 9205: 	    if (atts[i] == atts[j]) {
 9206: 	        if (atts[i+1] == atts[j+1]) {
 9207: 		    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
 9208: 		    break;
 9209: 		}
 9210: 		if ((nsname != NULL) && (atts[j + 2] == nsname)) {
 9211: 		    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
 9212: 			     "Namespaced Attribute %s in '%s' redefined\n",
 9213: 			     atts[i], nsname, NULL);
 9214: 		    break;
 9215: 		}
 9216: 	    }
 9217: 	}
 9218:     }
 9219: 
 9220:     nsname = xmlGetNamespace(ctxt, prefix);
 9221:     if ((prefix != NULL) && (nsname == NULL)) {
 9222: 	xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
 9223: 	         "Namespace prefix %s on %s is not defined\n",
 9224: 		 prefix, localname, NULL);
 9225:     }
 9226:     *pref = prefix;
 9227:     *URI = nsname;
 9228: 
 9229:     /*
 9230:      * SAX: Start of Element !
 9231:      */
 9232:     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
 9233: 	(!ctxt->disableSAX)) {
 9234: 	if (nbNs > 0)
 9235: 	    ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
 9236: 			  nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
 9237: 			  nbatts / 5, nbdef, atts);
 9238: 	else
 9239: 	    ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
 9240: 	                  nsname, 0, NULL, nbatts / 5, nbdef, atts);
 9241:     }
 9242: 
 9243:     /*
 9244:      * Free up attribute allocated strings if needed
 9245:      */
 9246:     if (attval != 0) {
 9247: 	for (i = 3,j = 0; j < nratts;i += 5,j++)
 9248: 	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
 9249: 	        xmlFree((xmlChar *) atts[i]);
 9250:     }
 9251: 
 9252:     return(localname);
 9253: 
 9254: base_changed:
 9255:     /*
 9256:      * the attribute strings are valid iif the base didn't changed
 9257:      */
 9258:     if (attval != 0) {
 9259: 	for (i = 3,j = 0; j < nratts;i += 5,j++)
 9260: 	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
 9261: 	        xmlFree((xmlChar *) atts[i]);
 9262:     }
 9263:     ctxt->input->cur = ctxt->input->base + cur;
 9264:     ctxt->input->line = oldline;
 9265:     ctxt->input->col = oldcol;
 9266:     if (ctxt->wellFormed == 1) {
 9267: 	goto reparse;
 9268:     }
 9269:     return(NULL);
 9270: }
 9271: 
 9272: /**
 9273:  * xmlParseEndTag2:
 9274:  * @ctxt:  an XML parser context
 9275:  * @line:  line of the start tag
 9276:  * @nsNr:  number of namespaces on the start tag
 9277:  *
 9278:  * parse an end of tag
 9279:  *
 9280:  * [42] ETag ::= '</' Name S? '>'
 9281:  *
 9282:  * With namespace
 9283:  *
 9284:  * [NS 9] ETag ::= '</' QName S? '>'
 9285:  */
 9286: 
 9287: static void
 9288: xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
 9289:                 const xmlChar *URI, int line, int nsNr, int tlen) {
 9290:     const xmlChar *name;
 9291: 
 9292:     GROW;
 9293:     if ((RAW != '<') || (NXT(1) != '/')) {
 9294: 	xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
 9295: 	return;
 9296:     }
 9297:     SKIP(2);
 9298: 
 9299:     if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
 9300:         if (ctxt->input->cur[tlen] == '>') {
 9301: 	    ctxt->input->cur += tlen + 1;
 9302: 	    goto done;
 9303: 	}
 9304: 	ctxt->input->cur += tlen;
 9305: 	name = (xmlChar*)1;
 9306:     } else {
 9307: 	if (prefix == NULL)
 9308: 	    name = xmlParseNameAndCompare(ctxt, ctxt->name);
 9309: 	else
 9310: 	    name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
 9311:     }
 9312: 
 9313:     /*
 9314:      * We should definitely be at the ending "S? '>'" part
 9315:      */
 9316:     GROW;
 9317:     SKIP_BLANKS;
 9318:     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
 9319: 	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
 9320:     } else
 9321: 	NEXT1;
 9322: 
 9323:     /*
 9324:      * [ WFC: Element Type Match ]
 9325:      * The Name in an element's end-tag must match the element type in the
 9326:      * start-tag. 
 9327:      *
 9328:      */
 9329:     if (name != (xmlChar*)1) {
 9330:         if (name == NULL) name = BAD_CAST "unparseable";
 9331:         if ((line == 0) && (ctxt->node != NULL))
 9332:             line = ctxt->node->line;
 9333:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
 9334: 		     "Opening and ending tag mismatch: %s line %d and %s\n",
 9335: 		                ctxt->name, line, name);
 9336:     }
 9337: 
 9338:     /*
 9339:      * SAX: End of Tag
 9340:      */
 9341: done:
 9342:     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
 9343: 	(!ctxt->disableSAX))
 9344: 	ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
 9345: 
 9346:     spacePop(ctxt);
 9347:     if (nsNr != 0)
 9348: 	nsPop(ctxt, nsNr);
 9349:     return;
 9350: }
 9351: 
 9352: /**
 9353:  * xmlParseCDSect:
 9354:  * @ctxt:  an XML parser context
 9355:  * 
 9356:  * Parse escaped pure raw content.
 9357:  *
 9358:  * [18] CDSect ::= CDStart CData CDEnd
 9359:  *
 9360:  * [19] CDStart ::= '<![CDATA['
 9361:  *
 9362:  * [20] Data ::= (Char* - (Char* ']]>' Char*))
 9363:  *
 9364:  * [21] CDEnd ::= ']]>'
 9365:  */
 9366: void
 9367: xmlParseCDSect(xmlParserCtxtPtr ctxt) {
 9368:     xmlChar *buf = NULL;
 9369:     int len = 0;
 9370:     int size = XML_PARSER_BUFFER_SIZE;
 9371:     int r, rl;
 9372:     int	s, sl;
 9373:     int cur, l;
 9374:     int count = 0;
 9375: 
 9376:     /* Check 2.6.0 was NXT(0) not RAW */
 9377:     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
 9378: 	SKIP(9);
 9379:     } else
 9380:         return;
 9381: 
 9382:     ctxt->instate = XML_PARSER_CDATA_SECTION;
 9383:     r = CUR_CHAR(rl);
 9384:     if (!IS_CHAR(r)) {
 9385: 	xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
 9386: 	ctxt->instate = XML_PARSER_CONTENT;
 9387:         return;
 9388:     }
 9389:     NEXTL(rl);
 9390:     s = CUR_CHAR(sl);
 9391:     if (!IS_CHAR(s)) {
 9392: 	xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
 9393: 	ctxt->instate = XML_PARSER_CONTENT;
 9394:         return;
 9395:     }
 9396:     NEXTL(sl);
 9397:     cur = CUR_CHAR(l);
 9398:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 9399:     if (buf == NULL) {
 9400: 	xmlErrMemory(ctxt, NULL);
 9401: 	return;
 9402:     }
 9403:     while (IS_CHAR(cur) &&
 9404:            ((r != ']') || (s != ']') || (cur != '>'))) {
 9405: 	if (len + 5 >= size) {
 9406: 	    xmlChar *tmp;
 9407: 
 9408: 	    size *= 2;
 9409: 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 9410: 	    if (tmp == NULL) {
 9411: 	        xmlFree(buf);
 9412: 		xmlErrMemory(ctxt, NULL);
 9413: 		return;
 9414: 	    }
 9415: 	    buf = tmp;
 9416: 	}
 9417: 	COPY_BUF(rl,buf,len,r);
 9418: 	r = s;
 9419: 	rl = sl;
 9420: 	s = cur;
 9421: 	sl = l;
 9422: 	count++;
 9423: 	if (count > 50) {
 9424: 	    GROW;
 9425: 	    count = 0;
 9426: 	}
 9427: 	NEXTL(l);
 9428: 	cur = CUR_CHAR(l);
 9429:     }
 9430:     buf[len] = 0;
 9431:     ctxt->instate = XML_PARSER_CONTENT;
 9432:     if (cur != '>') {
 9433: 	xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
 9434: 	                     "CData section not finished\n%.50s\n", buf);
 9435: 	xmlFree(buf);
 9436:         return;
 9437:     }
 9438:     NEXTL(l);
 9439: 
 9440:     /*
 9441:      * OK the buffer is to be consumed as cdata.
 9442:      */
 9443:     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
 9444: 	if (ctxt->sax->cdataBlock != NULL)
 9445: 	    ctxt->sax->cdataBlock(ctxt->userData, buf, len);
 9446: 	else if (ctxt->sax->characters != NULL)
 9447: 	    ctxt->sax->characters(ctxt->userData, buf, len);
 9448:     }
 9449:     xmlFree(buf);
 9450: }
 9451: 
 9452: /**
 9453:  * xmlParseContent:
 9454:  * @ctxt:  an XML parser context
 9455:  *
 9456:  * Parse a content:
 9457:  *
 9458:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
 9459:  */
 9460: 
 9461: void
 9462: xmlParseContent(xmlParserCtxtPtr ctxt) {
 9463:     GROW;
 9464:     while ((RAW != 0) &&
 9465: 	   ((RAW != '<') || (NXT(1) != '/')) &&
 9466: 	   (ctxt->instate != XML_PARSER_EOF)) {
 9467: 	const xmlChar *test = CUR_PTR;
 9468: 	unsigned int cons = ctxt->input->consumed;
 9469: 	const xmlChar *cur = ctxt->input->cur;
 9470: 
 9471: 	/*
 9472: 	 * First case : a Processing Instruction.
 9473: 	 */
 9474: 	if ((*cur == '<') && (cur[1] == '?')) {
 9475: 	    xmlParsePI(ctxt);
 9476: 	}
 9477: 
 9478: 	/*
 9479: 	 * Second case : a CDSection
 9480: 	 */
 9481: 	/* 2.6.0 test was *cur not RAW */
 9482: 	else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
 9483: 	    xmlParseCDSect(ctxt);
 9484: 	}
 9485: 
 9486: 	/*
 9487: 	 * Third case :  a comment
 9488: 	 */
 9489: 	else if ((*cur == '<') && (NXT(1) == '!') &&
 9490: 		 (NXT(2) == '-') && (NXT(3) == '-')) {
 9491: 	    xmlParseComment(ctxt);
 9492: 	    ctxt->instate = XML_PARSER_CONTENT;
 9493: 	}
 9494: 
 9495: 	/*
 9496: 	 * Fourth case :  a sub-element.
 9497: 	 */
 9498: 	else if (*cur == '<') {
 9499: 	    xmlParseElement(ctxt);
 9500: 	}
 9501: 
 9502: 	/*
 9503: 	 * Fifth case : a reference. If if has not been resolved,
 9504: 	 *    parsing returns it's Name, create the node 
 9505: 	 */
 9506: 
 9507: 	else if (*cur == '&') {
 9508: 	    xmlParseReference(ctxt);
 9509: 	}
 9510: 
 9511: 	/*
 9512: 	 * Last case, text. Note that References are handled directly.
 9513: 	 */
 9514: 	else {
 9515: 	    xmlParseCharData(ctxt, 0);
 9516: 	}
 9517: 
 9518: 	GROW;
 9519: 	/*
 9520: 	 * Pop-up of finished entities.
 9521: 	 */
 9522: 	while ((RAW == 0) && (ctxt->inputNr > 1))
 9523: 	    xmlPopInput(ctxt);
 9524: 	SHRINK;
 9525: 
 9526: 	if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
 9527: 	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 9528: 	                "detected an error in element content\n");
 9529: 	    ctxt->instate = XML_PARSER_EOF;
 9530:             break;
 9531: 	}
 9532:     }
 9533: }
 9534: 
 9535: /**
 9536:  * xmlParseElement:
 9537:  * @ctxt:  an XML parser context
 9538:  *
 9539:  * parse an XML element, this is highly recursive
 9540:  *
 9541:  * [39] element ::= EmptyElemTag | STag content ETag
 9542:  *
 9543:  * [ WFC: Element Type Match ]
 9544:  * The Name in an element's end-tag must match the element type in the
 9545:  * start-tag. 
 9546:  *
 9547:  */
 9548: 
 9549: void
 9550: xmlParseElement(xmlParserCtxtPtr ctxt) {
 9551:     const xmlChar *name;
 9552:     const xmlChar *prefix = NULL;
 9553:     const xmlChar *URI = NULL;
 9554:     xmlParserNodeInfo node_info;
 9555:     int line, tlen;
 9556:     xmlNodePtr ret;
 9557:     int nsNr = ctxt->nsNr;
 9558: 
 9559:     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
 9560:         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
 9561: 	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
 9562: 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
 9563: 			  xmlParserMaxDepth);
 9564: 	ctxt->instate = XML_PARSER_EOF;
 9565: 	return;
 9566:     }
 9567: 
 9568:     /* Capture start position */
 9569:     if (ctxt->record_info) {
 9570:         node_info.begin_pos = ctxt->input->consumed +
 9571:                           (CUR_PTR - ctxt->input->base);
 9572: 	node_info.begin_line = ctxt->input->line;
 9573:     }
 9574: 
 9575:     if (ctxt->spaceNr == 0)
 9576: 	spacePush(ctxt, -1);
 9577:     else if (*ctxt->space == -2)
 9578: 	spacePush(ctxt, -1);
 9579:     else
 9580: 	spacePush(ctxt, *ctxt->space);
 9581: 
 9582:     line = ctxt->input->line;
 9583: #ifdef LIBXML_SAX1_ENABLED
 9584:     if (ctxt->sax2)
 9585: #endif /* LIBXML_SAX1_ENABLED */
 9586:         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
 9587: #ifdef LIBXML_SAX1_ENABLED
 9588:     else
 9589: 	name = xmlParseStartTag(ctxt);
 9590: #endif /* LIBXML_SAX1_ENABLED */
 9591:     if (name == NULL) {
 9592: 	spacePop(ctxt);
 9593:         return;
 9594:     }
 9595:     namePush(ctxt, name);
 9596:     ret = ctxt->node;
 9597: 
 9598: #ifdef LIBXML_VALID_ENABLED
 9599:     /*
 9600:      * [ VC: Root Element Type ]
 9601:      * The Name in the document type declaration must match the element
 9602:      * type of the root element. 
 9603:      */
 9604:     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
 9605:         ctxt->node && (ctxt->node == ctxt->myDoc->children))
 9606:         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
 9607: #endif /* LIBXML_VALID_ENABLED */
 9608: 
 9609:     /*
 9610:      * Check for an Empty Element.
 9611:      */
 9612:     if ((RAW == '/') && (NXT(1) == '>')) {
 9613:         SKIP(2);
 9614: 	if (ctxt->sax2) {
 9615: 	    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
 9616: 		(!ctxt->disableSAX))
 9617: 		ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
 9618: #ifdef LIBXML_SAX1_ENABLED
 9619: 	} else {
 9620: 	    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
 9621: 		(!ctxt->disableSAX))
 9622: 		ctxt->sax->endElement(ctxt->userData, name);
 9623: #endif /* LIBXML_SAX1_ENABLED */
 9624: 	}
 9625: 	namePop(ctxt);
 9626: 	spacePop(ctxt);
 9627: 	if (nsNr != ctxt->nsNr)
 9628: 	    nsPop(ctxt, ctxt->nsNr - nsNr);
 9629: 	if ( ret != NULL && ctxt->record_info ) {
 9630: 	   node_info.end_pos = ctxt->input->consumed +
 9631: 			      (CUR_PTR - ctxt->input->base);
 9632: 	   node_info.end_line = ctxt->input->line;
 9633: 	   node_info.node = ret;
 9634: 	   xmlParserAddNodeInfo(ctxt, &node_info);
 9635: 	}
 9636: 	return;
 9637:     }
 9638:     if (RAW == '>') {
 9639:         NEXT1;
 9640:     } else {
 9641:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
 9642: 		     "Couldn't find end of Start Tag %s line %d\n",
 9643: 		                name, line, NULL);
 9644: 
 9645: 	/*
 9646: 	 * end of parsing of this node.
 9647: 	 */
 9648: 	nodePop(ctxt);
 9649: 	namePop(ctxt);
 9650: 	spacePop(ctxt);
 9651: 	if (nsNr != ctxt->nsNr)
 9652: 	    nsPop(ctxt, ctxt->nsNr - nsNr);
 9653: 
 9654: 	/*
 9655: 	 * Capture end position and add node
 9656: 	 */
 9657: 	if ( ret != NULL && ctxt->record_info ) {
 9658: 	   node_info.end_pos = ctxt->input->consumed +
 9659: 			      (CUR_PTR - ctxt->input->base);
 9660: 	   node_info.end_line = ctxt->input->line;
 9661: 	   node_info.node = ret;
 9662: 	   xmlParserAddNodeInfo(ctxt, &node_info);
 9663: 	}
 9664: 	return;
 9665:     }
 9666: 
 9667:     /*
 9668:      * Parse the content of the element:
 9669:      */
 9670:     xmlParseContent(ctxt);
 9671:     if (!IS_BYTE_CHAR(RAW)) {
 9672:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
 9673: 	 "Premature end of data in tag %s line %d\n",
 9674: 		                name, line, NULL);
 9675: 
 9676: 	/*
 9677: 	 * end of parsing of this node.
 9678: 	 */
 9679: 	nodePop(ctxt);
 9680: 	namePop(ctxt);
 9681: 	spacePop(ctxt);
 9682: 	if (nsNr != ctxt->nsNr)
 9683: 	    nsPop(ctxt, ctxt->nsNr - nsNr);
 9684: 	return;
 9685:     }
 9686: 
 9687:     /*
 9688:      * parse the end of tag: '</' should be here.
 9689:      */
 9690:     if (ctxt->sax2) {
 9691: 	xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
 9692: 	namePop(ctxt);
 9693:     }
 9694: #ifdef LIBXML_SAX1_ENABLED
 9695:       else
 9696: 	xmlParseEndTag1(ctxt, line);
 9697: #endif /* LIBXML_SAX1_ENABLED */
 9698: 
 9699:     /*
 9700:      * Capture end position and add node
 9701:      */
 9702:     if ( ret != NULL && ctxt->record_info ) {
 9703:        node_info.end_pos = ctxt->input->consumed +
 9704:                           (CUR_PTR - ctxt->input->base);
 9705:        node_info.end_line = ctxt->input->line;
 9706:        node_info.node = ret;
 9707:        xmlParserAddNodeInfo(ctxt, &node_info);
 9708:     }
 9709: }
 9710: 
 9711: /**
 9712:  * xmlParseVersionNum:
 9713:  * @ctxt:  an XML parser context
 9714:  *
 9715:  * parse the XML version value.
 9716:  *
 9717:  * [26] VersionNum ::= '1.' [0-9]+
 9718:  *
 9719:  * In practice allow [0-9].[0-9]+ at that level
 9720:  *
 9721:  * Returns the string giving the XML version number, or NULL
 9722:  */
 9723: xmlChar *
 9724: xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
 9725:     xmlChar *buf = NULL;
 9726:     int len = 0;
 9727:     int size = 10;
 9728:     xmlChar cur;
 9729: 
 9730:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 9731:     if (buf == NULL) {
 9732: 	xmlErrMemory(ctxt, NULL);
 9733: 	return(NULL);
 9734:     }
 9735:     cur = CUR;
 9736:     if (!((cur >= '0') && (cur <= '9'))) {
 9737: 	xmlFree(buf);
 9738: 	return(NULL);
 9739:     }
 9740:     buf[len++] = cur;
 9741:     NEXT;
 9742:     cur=CUR;
 9743:     if (cur != '.') {
 9744: 	xmlFree(buf);
 9745: 	return(NULL);
 9746:     }
 9747:     buf[len++] = cur;
 9748:     NEXT;
 9749:     cur=CUR;
 9750:     while ((cur >= '0') && (cur <= '9')) {
 9751: 	if (len + 1 >= size) {
 9752: 	    xmlChar *tmp;
 9753: 
 9754: 	    size *= 2;
 9755: 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 9756: 	    if (tmp == NULL) {
 9757: 	        xmlFree(buf);
 9758: 		xmlErrMemory(ctxt, NULL);
 9759: 		return(NULL);
 9760: 	    }
 9761: 	    buf = tmp;
 9762: 	}
 9763: 	buf[len++] = cur;
 9764: 	NEXT;
 9765: 	cur=CUR;
 9766:     }
 9767:     buf[len] = 0;
 9768:     return(buf);
 9769: }
 9770: 
 9771: /**
 9772:  * xmlParseVersionInfo:
 9773:  * @ctxt:  an XML parser context
 9774:  *
 9775:  * parse the XML version.
 9776:  *
 9777:  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
 9778:  *
 9779:  * [25] Eq ::= S? '=' S?
 9780:  *
 9781:  * Returns the version string, e.g. "1.0"
 9782:  */
 9783: 
 9784: xmlChar *
 9785: xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
 9786:     xmlChar *version = NULL;
 9787: 
 9788:     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
 9789: 	SKIP(7);
 9790: 	SKIP_BLANKS;
 9791: 	if (RAW != '=') {
 9792: 	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
 9793: 	    return(NULL);
 9794:         }
 9795: 	NEXT;
 9796: 	SKIP_BLANKS;
 9797: 	if (RAW == '"') {
 9798: 	    NEXT;
 9799: 	    version = xmlParseVersionNum(ctxt);
 9800: 	    if (RAW != '"') {
 9801: 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
 9802: 	    } else
 9803: 	        NEXT;
 9804: 	} else if (RAW == '\''){
 9805: 	    NEXT;
 9806: 	    version = xmlParseVersionNum(ctxt);
 9807: 	    if (RAW != '\'') {
 9808: 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
 9809: 	    } else
 9810: 	        NEXT;
 9811: 	} else {
 9812: 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
 9813: 	}
 9814:     }
 9815:     return(version);
 9816: }
 9817: 
 9818: /**
 9819:  * xmlParseEncName:
 9820:  * @ctxt:  an XML parser context
 9821:  *
 9822:  * parse the XML encoding name
 9823:  *
 9824:  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
 9825:  *
 9826:  * Returns the encoding name value or NULL
 9827:  */
 9828: xmlChar *
 9829: xmlParseEncName(xmlParserCtxtPtr ctxt) {
 9830:     xmlChar *buf = NULL;
 9831:     int len = 0;
 9832:     int size = 10;
 9833:     xmlChar cur;
 9834: 
 9835:     cur = CUR;
 9836:     if (((cur >= 'a') && (cur <= 'z')) ||
 9837:         ((cur >= 'A') && (cur <= 'Z'))) {
 9838: 	buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
 9839: 	if (buf == NULL) {
 9840: 	    xmlErrMemory(ctxt, NULL);
 9841: 	    return(NULL);
 9842: 	}
 9843: 
 9844: 	buf[len++] = cur;
 9845: 	NEXT;
 9846: 	cur = CUR;
 9847: 	while (((cur >= 'a') && (cur <= 'z')) ||
 9848: 	       ((cur >= 'A') && (cur <= 'Z')) ||
 9849: 	       ((cur >= '0') && (cur <= '9')) ||
 9850: 	       (cur == '.') || (cur == '_') ||
 9851: 	       (cur == '-')) {
 9852: 	    if (len + 1 >= size) {
 9853: 	        xmlChar *tmp;
 9854: 
 9855: 		size *= 2;
 9856: 		tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
 9857: 		if (tmp == NULL) {
 9858: 		    xmlErrMemory(ctxt, NULL);
 9859: 		    xmlFree(buf);
 9860: 		    return(NULL);
 9861: 		}
 9862: 		buf = tmp;
 9863: 	    }
 9864: 	    buf[len++] = cur;
 9865: 	    NEXT;
 9866: 	    cur = CUR;
 9867: 	    if (cur == 0) {
 9868: 	        SHRINK;
 9869: 		GROW;
 9870: 		cur = CUR;
 9871: 	    }
 9872:         }
 9873: 	buf[len] = 0;
 9874:     } else {
 9875: 	xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
 9876:     }
 9877:     return(buf);
 9878: }
 9879: 
 9880: /**
 9881:  * xmlParseEncodingDecl:
 9882:  * @ctxt:  an XML parser context
 9883:  * 
 9884:  * parse the XML encoding declaration
 9885:  *
 9886:  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
 9887:  *
 9888:  * this setups the conversion filters.
 9889:  *
 9890:  * Returns the encoding value or NULL
 9891:  */
 9892: 
 9893: const xmlChar *
 9894: xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
 9895:     xmlChar *encoding = NULL;
 9896: 
 9897:     SKIP_BLANKS;
 9898:     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
 9899: 	SKIP(8);
 9900: 	SKIP_BLANKS;
 9901: 	if (RAW != '=') {
 9902: 	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
 9903: 	    return(NULL);
 9904:         }
 9905: 	NEXT;
 9906: 	SKIP_BLANKS;
 9907: 	if (RAW == '"') {
 9908: 	    NEXT;
 9909: 	    encoding = xmlParseEncName(ctxt);
 9910: 	    if (RAW != '"') {
 9911: 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
 9912: 	    } else
 9913: 	        NEXT;
 9914: 	} else if (RAW == '\''){
 9915: 	    NEXT;
 9916: 	    encoding = xmlParseEncName(ctxt);
 9917: 	    if (RAW != '\'') {
 9918: 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
 9919: 	    } else
 9920: 	        NEXT;
 9921: 	} else {
 9922: 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
 9923: 	}
 9924: 	/*
 9925: 	 * UTF-16 encoding stwich has already taken place at this stage,
 9926: 	 * more over the little-endian/big-endian selection is already done
 9927: 	 */
 9928:         if ((encoding != NULL) &&
 9929: 	    ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
 9930: 	     (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
 9931: 	    /*
 9932: 	     * If no encoding was passed to the parser, that we are
 9933: 	     * using UTF-16 and no decoder is present i.e. the 
 9934: 	     * document is apparently UTF-8 compatible, then raise an
 9935: 	     * encoding mismatch fatal error
 9936: 	     */
 9937: 	    if ((ctxt->encoding == NULL) &&
 9938: 	        (ctxt->input->buf != NULL) &&
 9939: 	        (ctxt->input->buf->encoder == NULL)) {
 9940: 		xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
 9941: 		  "Document labelled UTF-16 but has UTF-8 content\n");
 9942: 	    }
 9943: 	    if (ctxt->encoding != NULL)
 9944: 		xmlFree((xmlChar *) ctxt->encoding);
 9945: 	    ctxt->encoding = encoding;
 9946: 	}
 9947: 	/*
 9948: 	 * UTF-8 encoding is handled natively
 9949: 	 */
 9950:         else if ((encoding != NULL) &&
 9951: 	    ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
 9952: 	     (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
 9953: 	    if (ctxt->encoding != NULL)
 9954: 		xmlFree((xmlChar *) ctxt->encoding);
 9955: 	    ctxt->encoding = encoding;
 9956: 	}
 9957: 	else if (encoding != NULL) {
 9958: 	    xmlCharEncodingHandlerPtr handler;
 9959: 
 9960: 	    if (ctxt->input->encoding != NULL)
 9961: 		xmlFree((xmlChar *) ctxt->input->encoding);
 9962: 	    ctxt->input->encoding = encoding;
 9963: 
 9964:             handler = xmlFindCharEncodingHandler((const char *) encoding);
 9965: 	    if (handler != NULL) {
 9966: 		xmlSwitchToEncoding(ctxt, handler);
 9967: 	    } else {
 9968: 		xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
 9969: 			"Unsupported encoding %s\n", encoding);
 9970: 		return(NULL);
 9971: 	    }
 9972: 	}
 9973:     }
 9974:     return(encoding);
 9975: }
 9976: 
 9977: /**
 9978:  * xmlParseSDDecl:
 9979:  * @ctxt:  an XML parser context
 9980:  *
 9981:  * parse the XML standalone declaration
 9982:  *
 9983:  * [32] SDDecl ::= S 'standalone' Eq
 9984:  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
 9985:  *
 9986:  * [ VC: Standalone Document Declaration ]
 9987:  * TODO The standalone document declaration must have the value "no"
 9988:  * if any external markup declarations contain declarations of:
 9989:  *  - attributes with default values, if elements to which these
 9990:  *    attributes apply appear in the document without specifications
 9991:  *    of values for these attributes, or
 9992:  *  - entities (other than amp, lt, gt, apos, quot), if references
 9993:  *    to those entities appear in the document, or
 9994:  *  - attributes with values subject to normalization, where the
 9995:  *    attribute appears in the document with a value which will change
 9996:  *    as a result of normalization, or
 9997:  *  - element types with element content, if white space occurs directly
 9998:  *    within any instance of those types.
 9999:  *
10000:  * Returns:
10001:  *   1 if standalone="yes"
10002:  *   0 if standalone="no"
10003:  *  -2 if standalone attribute is missing or invalid
10004:  *	  (A standalone value of -2 means that the XML declaration was found,
10005:  *	   but no value was specified for the standalone attribute).
10006:  */
10007: 
10008: int
10009: xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10010:     int standalone = -2;
10011: 
10012:     SKIP_BLANKS;
10013:     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10014: 	SKIP(10);
10015:         SKIP_BLANKS;
10016: 	if (RAW != '=') {
10017: 	    xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10018: 	    return(standalone);
10019:         }
10020: 	NEXT;
10021: 	SKIP_BLANKS;
10022:         if (RAW == '\''){
10023: 	    NEXT;
10024: 	    if ((RAW == 'n') && (NXT(1) == 'o')) {
10025: 	        standalone = 0;
10026:                 SKIP(2);
10027: 	    } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10028: 	               (NXT(2) == 's')) {
10029: 	        standalone = 1;
10030: 		SKIP(3);
10031:             } else {
10032: 		xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10033: 	    }
10034: 	    if (RAW != '\'') {
10035: 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10036: 	    } else
10037: 	        NEXT;
10038: 	} else if (RAW == '"'){
10039: 	    NEXT;
10040: 	    if ((RAW == 'n') && (NXT(1) == 'o')) {
10041: 	        standalone = 0;
10042: 		SKIP(2);
10043: 	    } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10044: 	               (NXT(2) == 's')) {
10045: 	        standalone = 1;
10046:                 SKIP(3);
10047:             } else {
10048: 		xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10049: 	    }
10050: 	    if (RAW != '"') {
10051: 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10052: 	    } else
10053: 	        NEXT;
10054: 	} else {
10055: 	    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10056:         }
10057:     }
10058:     return(standalone);
10059: }
10060: 
10061: /**
10062:  * xmlParseXMLDecl:
10063:  * @ctxt:  an XML parser context
10064:  * 
10065:  * parse an XML declaration header
10066:  *
10067:  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10068:  */
10069: 
10070: void
10071: xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10072:     xmlChar *version;
10073: 
10074:     /*
10075:      * This value for standalone indicates that the document has an
10076:      * XML declaration but it does not have a standalone attribute.
10077:      * It will be overwritten later if a standalone attribute is found.
10078:      */
10079:     ctxt->input->standalone = -2;
10080: 
10081:     /*
10082:      * We know that '<?xml' is here.
10083:      */
10084:     SKIP(5);
10085: 
10086:     if (!IS_BLANK_CH(RAW)) {
10087: 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10088: 	               "Blank needed after '<?xml'\n");
10089:     }
10090:     SKIP_BLANKS;
10091: 
10092:     /*
10093:      * We must have the VersionInfo here.
10094:      */
10095:     version = xmlParseVersionInfo(ctxt);
10096:     if (version == NULL) {
10097: 	xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10098:     } else {
10099: 	if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10100: 	    /*
10101: 	     * Changed here for XML-1.0 5th edition
10102: 	     */
10103: 	    if (ctxt->options & XML_PARSE_OLD10) {
10104: 		xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10105: 			          "Unsupported version '%s'\n",
10106: 			          version);
10107: 	    } else {
10108: 	        if ((version[0] == '1') && ((version[1] == '.'))) {
10109: 		    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10110: 		                  "Unsupported version '%s'\n",
10111: 				  version, NULL);
10112: 		} else {
10113: 		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10114: 				      "Unsupported version '%s'\n",
10115: 				      version);
10116: 		}
10117: 	    }
10118: 	}
10119: 	if (ctxt->version != NULL)
10120: 	    xmlFree((void *) ctxt->version);
10121: 	ctxt->version = version;
10122:     }
10123: 
10124:     /*
10125:      * We may have the encoding declaration
10126:      */
10127:     if (!IS_BLANK_CH(RAW)) {
10128:         if ((RAW == '?') && (NXT(1) == '>')) {
10129: 	    SKIP(2);
10130: 	    return;
10131: 	}
10132: 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10133:     }
10134:     xmlParseEncodingDecl(ctxt);
10135:     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10136: 	/*
10137: 	 * The XML REC instructs us to stop parsing right here
10138: 	 */
10139:         return;
10140:     }
10141: 
10142:     /*
10143:      * We may have the standalone status.
10144:      */
10145:     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10146:         if ((RAW == '?') && (NXT(1) == '>')) {
10147: 	    SKIP(2);
10148: 	    return;
10149: 	}
10150: 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10151:     }
10152: 
10153:     /*
10154:      * We can grow the input buffer freely at that point
10155:      */
10156:     GROW;
10157: 
10158:     SKIP_BLANKS;
10159:     ctxt->input->standalone = xmlParseSDDecl(ctxt);
10160: 
10161:     SKIP_BLANKS;
10162:     if ((RAW == '?') && (NXT(1) == '>')) {
10163:         SKIP(2);
10164:     } else if (RAW == '>') {
10165:         /* Deprecated old WD ... */
10166: 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10167: 	NEXT;
10168:     } else {
10169: 	xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10170: 	MOVETO_ENDTAG(CUR_PTR);
10171: 	NEXT;
10172:     }
10173: }
10174: 
10175: /**
10176:  * xmlParseMisc:
10177:  * @ctxt:  an XML parser context
10178:  * 
10179:  * parse an XML Misc* optional field.
10180:  *
10181:  * [27] Misc ::= Comment | PI |  S
10182:  */
10183: 
10184: void
10185: xmlParseMisc(xmlParserCtxtPtr ctxt) {
10186:     while (((RAW == '<') && (NXT(1) == '?')) ||
10187:            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
10188:            IS_BLANK_CH(CUR)) {
10189:         if ((RAW == '<') && (NXT(1) == '?')) {
10190: 	    xmlParsePI(ctxt);
10191: 	} else if (IS_BLANK_CH(CUR)) {
10192: 	    NEXT;
10193: 	} else
10194: 	    xmlParseComment(ctxt);
10195:     }
10196: }
10197: 
10198: /**
10199:  * xmlParseDocument:
10200:  * @ctxt:  an XML parser context
10201:  * 
10202:  * parse an XML document (and build a tree if using the standard SAX
10203:  * interface).
10204:  *
10205:  * [1] document ::= prolog element Misc*
10206:  *
10207:  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10208:  *
10209:  * Returns 0, -1 in case of error. the parser context is augmented
10210:  *                as a result of the parsing.
10211:  */
10212: 
10213: int
10214: xmlParseDocument(xmlParserCtxtPtr ctxt) {
10215:     xmlChar start[4];
10216:     xmlCharEncoding enc;
10217: 
10218:     xmlInitParser();
10219: 
10220:     if ((ctxt == NULL) || (ctxt->input == NULL))
10221:         return(-1);
10222: 
10223:     GROW;
10224: 
10225:     /*
10226:      * SAX: detecting the level.
10227:      */
10228:     xmlDetectSAX2(ctxt);
10229: 
10230:     /*
10231:      * SAX: beginning of the document processing.
10232:      */
10233:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10234:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10235: 
10236:     if ((ctxt->encoding == NULL) &&
10237:         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10238: 	/* 
10239: 	 * Get the 4 first bytes and decode the charset
10240: 	 * if enc != XML_CHAR_ENCODING_NONE
10241: 	 * plug some encoding conversion routines.
10242: 	 */
10243: 	start[0] = RAW;
10244: 	start[1] = NXT(1);
10245: 	start[2] = NXT(2);
10246: 	start[3] = NXT(3);
10247: 	enc = xmlDetectCharEncoding(&start[0], 4);
10248: 	if (enc != XML_CHAR_ENCODING_NONE) {
10249: 	    xmlSwitchEncoding(ctxt, enc);
10250: 	}
10251:     }
10252: 
10253: 
10254:     if (CUR == 0) {
10255: 	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10256:     }
10257: 
10258:     /*
10259:      * Check for the XMLDecl in the Prolog.
10260:      * do not GROW here to avoid the detected encoder to decode more
10261:      * than just the first line, unless the amount of data is really
10262:      * too small to hold "<?xml version="1.0" encoding="foo"
10263:      */
10264:     if ((ctxt->input->end - ctxt->input->cur) < 35) {
10265:        GROW;
10266:     }
10267:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10268: 
10269: 	/*
10270: 	 * Note that we will switch encoding on the fly.
10271: 	 */
10272: 	xmlParseXMLDecl(ctxt);
10273: 	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10274: 	    /*
10275: 	     * The XML REC instructs us to stop parsing right here
10276: 	     */
10277: 	    return(-1);
10278: 	}
10279: 	ctxt->standalone = ctxt->input->standalone;
10280: 	SKIP_BLANKS;
10281:     } else {
10282: 	ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10283:     }
10284:     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10285:         ctxt->sax->startDocument(ctxt->userData);
10286: 
10287:     /*
10288:      * The Misc part of the Prolog
10289:      */
10290:     GROW;
10291:     xmlParseMisc(ctxt);
10292: 
10293:     /*
10294:      * Then possibly doc type declaration(s) and more Misc
10295:      * (doctypedecl Misc*)?
10296:      */
10297:     GROW;
10298:     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10299: 
10300: 	ctxt->inSubset = 1;
10301: 	xmlParseDocTypeDecl(ctxt);
10302: 	if (RAW == '[') {
10303: 	    ctxt->instate = XML_PARSER_DTD;
10304: 	    xmlParseInternalSubset(ctxt);
10305: 	}
10306: 
10307: 	/*
10308: 	 * Create and update the external subset.
10309: 	 */
10310: 	ctxt->inSubset = 2;
10311: 	if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10312: 	    (!ctxt->disableSAX))
10313: 	    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10314: 	                              ctxt->extSubSystem, ctxt->extSubURI);
10315: 	ctxt->inSubset = 0;
10316: 
10317:         xmlCleanSpecialAttr(ctxt);
10318: 
10319: 	ctxt->instate = XML_PARSER_PROLOG;
10320: 	xmlParseMisc(ctxt);
10321:     }
10322: 
10323:     /*
10324:      * Time to start parsing the tree itself
10325:      */
10326:     GROW;
10327:     if (RAW != '<') {
10328: 	xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10329: 		       "Start tag expected, '<' not found\n");
10330:     } else {
10331: 	ctxt->instate = XML_PARSER_CONTENT;
10332: 	xmlParseElement(ctxt);
10333: 	ctxt->instate = XML_PARSER_EPILOG;
10334: 
10335: 
10336: 	/*
10337: 	 * The Misc part at the end
10338: 	 */
10339: 	xmlParseMisc(ctxt);
10340: 
10341: 	if (RAW != 0) {
10342: 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10343: 	}
10344: 	ctxt->instate = XML_PARSER_EOF;
10345:     }
10346: 
10347:     /*
10348:      * SAX: end of the document processing.
10349:      */
10350:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10351:         ctxt->sax->endDocument(ctxt->userData);
10352: 
10353:     /*
10354:      * Remove locally kept entity definitions if the tree was not built
10355:      */
10356:     if ((ctxt->myDoc != NULL) &&
10357: 	(xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10358: 	xmlFreeDoc(ctxt->myDoc);
10359: 	ctxt->myDoc = NULL;
10360:     }
10361: 
10362:     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10363:         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10364: 	if (ctxt->valid)
10365: 	    ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10366: 	if (ctxt->nsWellFormed)
10367: 	    ctxt->myDoc->properties |= XML_DOC_NSVALID;
10368: 	if (ctxt->options & XML_PARSE_OLD10)
10369: 	    ctxt->myDoc->properties |= XML_DOC_OLD10;
10370:     }
10371:     if (! ctxt->wellFormed) {
10372: 	ctxt->valid = 0;
10373: 	return(-1);
10374:     }
10375:     return(0);
10376: }
10377: 
10378: /**
10379:  * xmlParseExtParsedEnt:
10380:  * @ctxt:  an XML parser context
10381:  * 
10382:  * parse a general parsed entity
10383:  * An external general parsed entity is well-formed if it matches the
10384:  * production labeled extParsedEnt.
10385:  *
10386:  * [78] extParsedEnt ::= TextDecl? content
10387:  *
10388:  * Returns 0, -1 in case of error. the parser context is augmented
10389:  *                as a result of the parsing.
10390:  */
10391: 
10392: int
10393: xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10394:     xmlChar start[4];
10395:     xmlCharEncoding enc;
10396: 
10397:     if ((ctxt == NULL) || (ctxt->input == NULL))
10398:         return(-1);
10399: 
10400:     xmlDefaultSAXHandlerInit();
10401: 
10402:     xmlDetectSAX2(ctxt);
10403: 
10404:     GROW;
10405: 
10406:     /*
10407:      * SAX: beginning of the document processing.
10408:      */
10409:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10410:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10411: 
10412:     /* 
10413:      * Get the 4 first bytes and decode the charset
10414:      * if enc != XML_CHAR_ENCODING_NONE
10415:      * plug some encoding conversion routines.
10416:      */
10417:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10418: 	start[0] = RAW;
10419: 	start[1] = NXT(1);
10420: 	start[2] = NXT(2);
10421: 	start[3] = NXT(3);
10422: 	enc = xmlDetectCharEncoding(start, 4);
10423: 	if (enc != XML_CHAR_ENCODING_NONE) {
10424: 	    xmlSwitchEncoding(ctxt, enc);
10425: 	}
10426:     }
10427: 
10428: 
10429:     if (CUR == 0) {
10430: 	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10431:     }
10432: 
10433:     /*
10434:      * Check for the XMLDecl in the Prolog.
10435:      */
10436:     GROW;
10437:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10438: 
10439: 	/*
10440: 	 * Note that we will switch encoding on the fly.
10441: 	 */
10442: 	xmlParseXMLDecl(ctxt);
10443: 	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10444: 	    /*
10445: 	     * The XML REC instructs us to stop parsing right here
10446: 	     */
10447: 	    return(-1);
10448: 	}
10449: 	SKIP_BLANKS;
10450:     } else {
10451: 	ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10452:     }
10453:     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10454:         ctxt->sax->startDocument(ctxt->userData);
10455: 
10456:     /*
10457:      * Doing validity checking on chunk doesn't make sense
10458:      */
10459:     ctxt->instate = XML_PARSER_CONTENT;
10460:     ctxt->validate = 0;
10461:     ctxt->loadsubset = 0;
10462:     ctxt->depth = 0;
10463: 
10464:     xmlParseContent(ctxt);
10465:    
10466:     if ((RAW == '<') && (NXT(1) == '/')) {
10467: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10468:     } else if (RAW != 0) {
10469: 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10470:     }
10471: 
10472:     /*
10473:      * SAX: end of the document processing.
10474:      */
10475:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10476:         ctxt->sax->endDocument(ctxt->userData);
10477: 
10478:     if (! ctxt->wellFormed) return(-1);
10479:     return(0);
10480: }
10481: 
10482: #ifdef LIBXML_PUSH_ENABLED
10483: /************************************************************************
10484:  *									*
10485:  * 		Progressive parsing interfaces				*
10486:  *									*
10487:  ************************************************************************/
10488: 
10489: /**
10490:  * xmlParseLookupSequence:
10491:  * @ctxt:  an XML parser context
10492:  * @first:  the first char to lookup
10493:  * @next:  the next char to lookup or zero
10494:  * @third:  the next char to lookup or zero
10495:  *
10496:  * Try to find if a sequence (first, next, third) or  just (first next) or
10497:  * (first) is available in the input stream.
10498:  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
10499:  * to avoid rescanning sequences of bytes, it DOES change the state of the
10500:  * parser, do not use liberally.
10501:  *
10502:  * Returns the index to the current parsing point if the full sequence
10503:  *      is available, -1 otherwise.
10504:  */
10505: static int
10506: xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
10507:                        xmlChar next, xmlChar third) {
10508:     int base, len;
10509:     xmlParserInputPtr in;
10510:     const xmlChar *buf;
10511: 
10512:     in = ctxt->input;
10513:     if (in == NULL) return(-1);
10514:     base = in->cur - in->base;
10515:     if (base < 0) return(-1);
10516:     if (ctxt->checkIndex > base)
10517:         base = ctxt->checkIndex;
10518:     if (in->buf == NULL) {
10519: 	buf = in->base;
10520: 	len = in->length;
10521:     } else {
10522: 	buf = in->buf->buffer->content;
10523: 	len = in->buf->buffer->use;
10524:     }
10525:     /* take into account the sequence length */
10526:     if (third) len -= 2;
10527:     else if (next) len --;
10528:     for (;base < len;base++) {
10529:         if (buf[base] == first) {
10530: 	    if (third != 0) {
10531: 		if ((buf[base + 1] != next) ||
10532: 		    (buf[base + 2] != third)) continue;
10533: 	    } else if (next != 0) {
10534: 		if (buf[base + 1] != next) continue;
10535: 	    }
10536: 	    ctxt->checkIndex = 0;
10537: #ifdef DEBUG_PUSH
10538: 	    if (next == 0)
10539: 		xmlGenericError(xmlGenericErrorContext,
10540: 			"PP: lookup '%c' found at %d\n",
10541: 			first, base);
10542: 	    else if (third == 0)
10543: 		xmlGenericError(xmlGenericErrorContext,
10544: 			"PP: lookup '%c%c' found at %d\n",
10545: 			first, next, base);
10546: 	    else 
10547: 		xmlGenericError(xmlGenericErrorContext,
10548: 			"PP: lookup '%c%c%c' found at %d\n",
10549: 			first, next, third, base);
10550: #endif
10551: 	    return(base - (in->cur - in->base));
10552: 	}
10553:     }
10554:     ctxt->checkIndex = base;
10555: #ifdef DEBUG_PUSH
10556:     if (next == 0)
10557: 	xmlGenericError(xmlGenericErrorContext,
10558: 		"PP: lookup '%c' failed\n", first);
10559:     else if (third == 0)
10560: 	xmlGenericError(xmlGenericErrorContext,
10561: 		"PP: lookup '%c%c' failed\n", first, next);
10562:     else	
10563: 	xmlGenericError(xmlGenericErrorContext,
10564: 		"PP: lookup '%c%c%c' failed\n", first, next, third);
10565: #endif
10566:     return(-1);
10567: }
10568: 
10569: /**
10570:  * xmlParseGetLasts:
10571:  * @ctxt:  an XML parser context
10572:  * @lastlt:  pointer to store the last '<' from the input
10573:  * @lastgt:  pointer to store the last '>' from the input
10574:  *
10575:  * Lookup the last < and > in the current chunk
10576:  */
10577: static void
10578: xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
10579:                  const xmlChar **lastgt) {
10580:     const xmlChar *tmp;
10581: 
10582:     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
10583: 	xmlGenericError(xmlGenericErrorContext,
10584: 		    "Internal error: xmlParseGetLasts\n");
10585: 	return;
10586:     }
10587:     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
10588:         tmp = ctxt->input->end;
10589: 	tmp--;
10590: 	while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
10591: 	if (tmp < ctxt->input->base) {
10592: 	    *lastlt = NULL;
10593: 	    *lastgt = NULL;
10594: 	} else {
10595: 	    *lastlt = tmp;
10596: 	    tmp++;
10597: 	    while ((tmp < ctxt->input->end) && (*tmp != '>')) {
10598: 	        if (*tmp == '\'') {
10599: 		    tmp++;
10600: 		    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
10601: 		    if (tmp < ctxt->input->end) tmp++;
10602: 		} else if (*tmp == '"') {
10603: 		    tmp++;
10604: 		    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
10605: 		    if (tmp < ctxt->input->end) tmp++;
10606: 		} else
10607: 		    tmp++;
10608: 	    }
10609: 	    if (tmp < ctxt->input->end)
10610: 	        *lastgt = tmp;
10611: 	    else {
10612: 	        tmp = *lastlt;
10613: 		tmp--;
10614: 		while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
10615: 		if (tmp >= ctxt->input->base)
10616: 		    *lastgt = tmp;
10617: 		else
10618: 		    *lastgt = NULL;
10619: 	    }
10620: 	}
10621:     } else {
10622:         *lastlt = NULL;
10623: 	*lastgt = NULL;
10624:     }
10625: }
10626: /**
10627:  * xmlCheckCdataPush:
10628:  * @cur: pointer to the bock of characters
10629:  * @len: length of the block in bytes
10630:  *
10631:  * Check that the block of characters is okay as SCdata content [20]
10632:  *
10633:  * Returns the number of bytes to pass if okay, a negative index where an
10634:  *         UTF-8 error occured otherwise
10635:  */
10636: static int
10637: xmlCheckCdataPush(const xmlChar *utf, int len) {
10638:     int ix;
10639:     unsigned char c;
10640:     int codepoint;
10641: 
10642:     if ((utf == NULL) || (len <= 0))
10643:         return(0);
10644:     
10645:     for (ix = 0; ix < len;) {      /* string is 0-terminated */
10646:         c = utf[ix];
10647:         if ((c & 0x80) == 0x00) {	/* 1-byte code, starts with 10 */
10648: 	    if (c >= 0x20)
10649: 		ix++;
10650: 	    else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
10651: 	        ix++;
10652: 	    else
10653: 	        return(-ix);
10654: 	} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
10655: 	    if (ix + 2 > len) return(ix);
10656: 	    if ((utf[ix+1] & 0xc0 ) != 0x80)
10657: 	        return(-ix);
10658: 	    codepoint = (utf[ix] & 0x1f) << 6;
10659: 	    codepoint |= utf[ix+1] & 0x3f;
10660: 	    if (!xmlIsCharQ(codepoint))
10661: 	        return(-ix);
10662: 	    ix += 2;
10663: 	} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
10664: 	    if (ix + 3 > len) return(ix);
10665: 	    if (((utf[ix+1] & 0xc0) != 0x80) ||
10666: 	        ((utf[ix+2] & 0xc0) != 0x80))
10667: 		    return(-ix);
10668: 	    codepoint = (utf[ix] & 0xf) << 12;
10669: 	    codepoint |= (utf[ix+1] & 0x3f) << 6;
10670: 	    codepoint |= utf[ix+2] & 0x3f;
10671: 	    if (!xmlIsCharQ(codepoint))
10672: 	        return(-ix);
10673: 	    ix += 3;
10674: 	} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
10675: 	    if (ix + 4 > len) return(ix);
10676: 	    if (((utf[ix+1] & 0xc0) != 0x80) ||
10677: 	        ((utf[ix+2] & 0xc0) != 0x80) ||
10678: 		((utf[ix+3] & 0xc0) != 0x80))
10679: 		    return(-ix);
10680: 	    codepoint = (utf[ix] & 0x7) << 18;
10681: 	    codepoint |= (utf[ix+1] & 0x3f) << 12;
10682: 	    codepoint |= (utf[ix+2] & 0x3f) << 6;
10683: 	    codepoint |= utf[ix+3] & 0x3f;
10684: 	    if (!xmlIsCharQ(codepoint))
10685: 	        return(-ix);
10686: 	    ix += 4;
10687: 	} else				/* unknown encoding */
10688: 	    return(-ix);
10689:       }
10690:       return(ix);
10691: }
10692: 
10693: /**
10694:  * xmlParseTryOrFinish:
10695:  * @ctxt:  an XML parser context
10696:  * @terminate:  last chunk indicator
10697:  *
10698:  * Try to progress on parsing
10699:  *
10700:  * Returns zero if no parsing was possible
10701:  */
10702: static int
10703: xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
10704:     int ret = 0;
10705:     int avail, tlen;
10706:     xmlChar cur, next;
10707:     const xmlChar *lastlt, *lastgt;
10708: 
10709:     if (ctxt->input == NULL)
10710:         return(0);
10711: 
10712: #ifdef DEBUG_PUSH
10713:     switch (ctxt->instate) {
10714: 	case XML_PARSER_EOF:
10715: 	    xmlGenericError(xmlGenericErrorContext,
10716: 		    "PP: try EOF\n"); break;
10717: 	case XML_PARSER_START:
10718: 	    xmlGenericError(xmlGenericErrorContext,
10719: 		    "PP: try START\n"); break;
10720: 	case XML_PARSER_MISC:
10721: 	    xmlGenericError(xmlGenericErrorContext,
10722: 		    "PP: try MISC\n");break;
10723: 	case XML_PARSER_COMMENT:
10724: 	    xmlGenericError(xmlGenericErrorContext,
10725: 		    "PP: try COMMENT\n");break;
10726: 	case XML_PARSER_PROLOG:
10727: 	    xmlGenericError(xmlGenericErrorContext,
10728: 		    "PP: try PROLOG\n");break;
10729: 	case XML_PARSER_START_TAG:
10730: 	    xmlGenericError(xmlGenericErrorContext,
10731: 		    "PP: try START_TAG\n");break;
10732: 	case XML_PARSER_CONTENT:
10733: 	    xmlGenericError(xmlGenericErrorContext,
10734: 		    "PP: try CONTENT\n");break;
10735: 	case XML_PARSER_CDATA_SECTION:
10736: 	    xmlGenericError(xmlGenericErrorContext,
10737: 		    "PP: try CDATA_SECTION\n");break;
10738: 	case XML_PARSER_END_TAG:
10739: 	    xmlGenericError(xmlGenericErrorContext,
10740: 		    "PP: try END_TAG\n");break;
10741: 	case XML_PARSER_ENTITY_DECL:
10742: 	    xmlGenericError(xmlGenericErrorContext,
10743: 		    "PP: try ENTITY_DECL\n");break;
10744: 	case XML_PARSER_ENTITY_VALUE:
10745: 	    xmlGenericError(xmlGenericErrorContext,
10746: 		    "PP: try ENTITY_VALUE\n");break;
10747: 	case XML_PARSER_ATTRIBUTE_VALUE:
10748: 	    xmlGenericError(xmlGenericErrorContext,
10749: 		    "PP: try ATTRIBUTE_VALUE\n");break;
10750: 	case XML_PARSER_DTD:
10751: 	    xmlGenericError(xmlGenericErrorContext,
10752: 		    "PP: try DTD\n");break;
10753: 	case XML_PARSER_EPILOG:
10754: 	    xmlGenericError(xmlGenericErrorContext,
10755: 		    "PP: try EPILOG\n");break;
10756: 	case XML_PARSER_PI:
10757: 	    xmlGenericError(xmlGenericErrorContext,
10758: 		    "PP: try PI\n");break;
10759:         case XML_PARSER_IGNORE:
10760:             xmlGenericError(xmlGenericErrorContext,
10761: 		    "PP: try IGNORE\n");break;
10762:     }
10763: #endif
10764: 
10765:     if ((ctxt->input != NULL) &&
10766:         (ctxt->input->cur - ctxt->input->base > 4096)) {
10767: 	xmlSHRINK(ctxt);
10768: 	ctxt->checkIndex = 0;
10769:     }
10770:     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
10771: 
10772:     while (1) {
10773: 	if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
10774: 	    return(0);
10775: 
10776:         
10777: 	/*
10778: 	 * Pop-up of finished entities.
10779: 	 */
10780: 	while ((RAW == 0) && (ctxt->inputNr > 1))
10781: 	    xmlPopInput(ctxt);
10782: 
10783: 	if (ctxt->input == NULL) break;
10784: 	if (ctxt->input->buf == NULL)
10785: 	    avail = ctxt->input->length -
10786: 	            (ctxt->input->cur - ctxt->input->base);
10787: 	else {
10788: 	    /*
10789: 	     * If we are operating on converted input, try to flush
10790: 	     * remainng chars to avoid them stalling in the non-converted
10791: 	     * buffer.
10792: 	     */
10793: 	    if ((ctxt->input->buf->raw != NULL) &&
10794: 		(ctxt->input->buf->raw->use > 0)) {
10795: 		int base = ctxt->input->base -
10796: 		           ctxt->input->buf->buffer->content;
10797: 		int current = ctxt->input->cur - ctxt->input->base;
10798: 
10799: 		xmlParserInputBufferPush(ctxt->input->buf, 0, "");
10800: 		ctxt->input->base = ctxt->input->buf->buffer->content + base;
10801: 		ctxt->input->cur = ctxt->input->base + current;
10802: 		ctxt->input->end =
10803: 		    &ctxt->input->buf->buffer->content[
10804: 		                       ctxt->input->buf->buffer->use];
10805: 	    }
10806: 	    avail = ctxt->input->buf->buffer->use -
10807: 		    (ctxt->input->cur - ctxt->input->base);
10808: 	}
10809:         if (avail < 1)
10810: 	    goto done;
10811:         switch (ctxt->instate) {
10812:             case XML_PARSER_EOF:
10813: 	        /*
10814: 		 * Document parsing is done !
10815: 		 */
10816: 	        goto done;
10817:             case XML_PARSER_START:
10818: 		if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
10819: 		    xmlChar start[4];
10820: 		    xmlCharEncoding enc;
10821: 
10822: 		    /*
10823: 		     * Very first chars read from the document flow.
10824: 		     */
10825: 		    if (avail < 4)
10826: 			goto done;
10827: 
10828: 		    /* 
10829: 		     * Get the 4 first bytes and decode the charset
10830: 		     * if enc != XML_CHAR_ENCODING_NONE
10831: 		     * plug some encoding conversion routines,
10832: 		     * else xmlSwitchEncoding will set to (default)
10833: 		     * UTF8.
10834: 		     */
10835: 		    start[0] = RAW;
10836: 		    start[1] = NXT(1);
10837: 		    start[2] = NXT(2);
10838: 		    start[3] = NXT(3);
10839: 		    enc = xmlDetectCharEncoding(start, 4);
10840: 		    xmlSwitchEncoding(ctxt, enc);
10841: 		    break;
10842: 		}
10843: 
10844: 		if (avail < 2)
10845: 		    goto done;
10846: 		cur = ctxt->input->cur[0];
10847: 		next = ctxt->input->cur[1];
10848: 		if (cur == 0) {
10849: 		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10850: 			ctxt->sax->setDocumentLocator(ctxt->userData,
10851: 						      &xmlDefaultSAXLocator);
10852: 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10853: 		    ctxt->instate = XML_PARSER_EOF;
10854: #ifdef DEBUG_PUSH
10855: 		    xmlGenericError(xmlGenericErrorContext,
10856: 			    "PP: entering EOF\n");
10857: #endif
10858: 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10859: 			ctxt->sax->endDocument(ctxt->userData);
10860: 		    goto done;
10861: 		}
10862: 	        if ((cur == '<') && (next == '?')) {
10863: 		    /* PI or XML decl */
10864: 		    if (avail < 5) return(ret);
10865: 		    if ((!terminate) &&
10866: 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
10867: 			return(ret);
10868: 		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10869: 			ctxt->sax->setDocumentLocator(ctxt->userData,
10870: 						      &xmlDefaultSAXLocator);
10871: 		    if ((ctxt->input->cur[2] == 'x') &&
10872: 			(ctxt->input->cur[3] == 'm') &&
10873: 			(ctxt->input->cur[4] == 'l') &&
10874: 			(IS_BLANK_CH(ctxt->input->cur[5]))) {
10875: 			ret += 5;
10876: #ifdef DEBUG_PUSH
10877: 			xmlGenericError(xmlGenericErrorContext,
10878: 				"PP: Parsing XML Decl\n");
10879: #endif
10880: 			xmlParseXMLDecl(ctxt);
10881: 			if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10882: 			    /*
10883: 			     * The XML REC instructs us to stop parsing right
10884: 			     * here
10885: 			     */
10886: 			    ctxt->instate = XML_PARSER_EOF;
10887: 			    return(0);
10888: 			}
10889: 			ctxt->standalone = ctxt->input->standalone;
10890: 			if ((ctxt->encoding == NULL) &&
10891: 			    (ctxt->input->encoding != NULL))
10892: 			    ctxt->encoding = xmlStrdup(ctxt->input->encoding);
10893: 			if ((ctxt->sax) && (ctxt->sax->startDocument) &&
10894: 			    (!ctxt->disableSAX))
10895: 			    ctxt->sax->startDocument(ctxt->userData);
10896: 			ctxt->instate = XML_PARSER_MISC;
10897: #ifdef DEBUG_PUSH
10898: 			xmlGenericError(xmlGenericErrorContext,
10899: 				"PP: entering MISC\n");
10900: #endif
10901: 		    } else {
10902: 			ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10903: 			if ((ctxt->sax) && (ctxt->sax->startDocument) &&
10904: 			    (!ctxt->disableSAX))
10905: 			    ctxt->sax->startDocument(ctxt->userData);
10906: 			ctxt->instate = XML_PARSER_MISC;
10907: #ifdef DEBUG_PUSH
10908: 			xmlGenericError(xmlGenericErrorContext,
10909: 				"PP: entering MISC\n");
10910: #endif
10911: 		    }
10912: 		} else {
10913: 		    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10914: 			ctxt->sax->setDocumentLocator(ctxt->userData,
10915: 						      &xmlDefaultSAXLocator);
10916: 		    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10917: 		    if (ctxt->version == NULL) {
10918: 		        xmlErrMemory(ctxt, NULL);
10919: 			break;
10920: 		    }
10921: 		    if ((ctxt->sax) && (ctxt->sax->startDocument) &&
10922: 		        (!ctxt->disableSAX))
10923: 			ctxt->sax->startDocument(ctxt->userData);
10924: 		    ctxt->instate = XML_PARSER_MISC;
10925: #ifdef DEBUG_PUSH
10926: 		    xmlGenericError(xmlGenericErrorContext,
10927: 			    "PP: entering MISC\n");
10928: #endif
10929: 		}
10930: 		break;
10931:             case XML_PARSER_START_TAG: {
10932: 	        const xmlChar *name;
10933: 		const xmlChar *prefix = NULL;
10934: 		const xmlChar *URI = NULL;
10935: 		int nsNr = ctxt->nsNr;
10936: 
10937: 		if ((avail < 2) && (ctxt->inputNr == 1))
10938: 		    goto done;
10939: 		cur = ctxt->input->cur[0];
10940: 	        if (cur != '<') {
10941: 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10942: 		    ctxt->instate = XML_PARSER_EOF;
10943: 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10944: 			ctxt->sax->endDocument(ctxt->userData);
10945: 		    goto done;
10946: 		}
10947: 		if (!terminate) {
10948: 		    if (ctxt->progressive) {
10949: 		        /* > can be found unescaped in attribute values */
10950: 		        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
10951: 			    goto done;
10952: 		    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
10953: 			goto done;
10954: 		    }
10955: 		}
10956: 		if (ctxt->spaceNr == 0)
10957: 		    spacePush(ctxt, -1);
10958: 		else if (*ctxt->space == -2)
10959: 		    spacePush(ctxt, -1);
10960: 		else
10961: 		    spacePush(ctxt, *ctxt->space);
10962: #ifdef LIBXML_SAX1_ENABLED
10963: 		if (ctxt->sax2)
10964: #endif /* LIBXML_SAX1_ENABLED */
10965: 		    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
10966: #ifdef LIBXML_SAX1_ENABLED
10967: 		else
10968: 		    name = xmlParseStartTag(ctxt);
10969: #endif /* LIBXML_SAX1_ENABLED */
10970: 		if (name == NULL) {
10971: 		    spacePop(ctxt);
10972: 		    ctxt->instate = XML_PARSER_EOF;
10973: 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10974: 			ctxt->sax->endDocument(ctxt->userData);
10975: 		    goto done;
10976: 		}
10977: #ifdef LIBXML_VALID_ENABLED
10978: 		/*
10979: 		 * [ VC: Root Element Type ]
10980: 		 * The Name in the document type declaration must match
10981: 		 * the element type of the root element. 
10982: 		 */
10983: 		if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
10984: 		    ctxt->node && (ctxt->node == ctxt->myDoc->children))
10985: 		    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
10986: #endif /* LIBXML_VALID_ENABLED */
10987: 
10988: 		/*
10989: 		 * Check for an Empty Element.
10990: 		 */
10991: 		if ((RAW == '/') && (NXT(1) == '>')) {
10992: 		    SKIP(2);
10993: 
10994: 		    if (ctxt->sax2) {
10995: 			if ((ctxt->sax != NULL) &&
10996: 			    (ctxt->sax->endElementNs != NULL) &&
10997: 			    (!ctxt->disableSAX))
10998: 			    ctxt->sax->endElementNs(ctxt->userData, name,
10999: 			                            prefix, URI);
11000: 			if (ctxt->nsNr - nsNr > 0)
11001: 			    nsPop(ctxt, ctxt->nsNr - nsNr);
11002: #ifdef LIBXML_SAX1_ENABLED
11003: 		    } else {
11004: 			if ((ctxt->sax != NULL) &&
11005: 			    (ctxt->sax->endElement != NULL) &&
11006: 			    (!ctxt->disableSAX))
11007: 			    ctxt->sax->endElement(ctxt->userData, name);
11008: #endif /* LIBXML_SAX1_ENABLED */
11009: 		    }
11010: 		    spacePop(ctxt);
11011: 		    if (ctxt->nameNr == 0) {
11012: 			ctxt->instate = XML_PARSER_EPILOG;
11013: 		    } else {
11014: 			ctxt->instate = XML_PARSER_CONTENT;
11015: 		    }
11016: 		    break;
11017: 		}
11018: 		if (RAW == '>') {
11019: 		    NEXT;
11020: 		} else {
11021: 		    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11022: 					 "Couldn't find end of Start Tag %s\n",
11023: 					 name);
11024: 		    nodePop(ctxt);
11025: 		    spacePop(ctxt);
11026: 		}
11027: 		if (ctxt->sax2)
11028: 		    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
11029: #ifdef LIBXML_SAX1_ENABLED
11030: 		else
11031: 		    namePush(ctxt, name);
11032: #endif /* LIBXML_SAX1_ENABLED */
11033: 
11034: 		ctxt->instate = XML_PARSER_CONTENT;
11035:                 break;
11036: 	    }
11037:             case XML_PARSER_CONTENT: {
11038: 		const xmlChar *test;
11039: 		unsigned int cons;
11040: 		if ((avail < 2) && (ctxt->inputNr == 1))
11041: 		    goto done;
11042: 		cur = ctxt->input->cur[0];
11043: 		next = ctxt->input->cur[1];
11044: 
11045: 		test = CUR_PTR;
11046: 	        cons = ctxt->input->consumed;
11047: 		if ((cur == '<') && (next == '/')) {
11048: 		    ctxt->instate = XML_PARSER_END_TAG;
11049: 		    break;
11050: 	        } else if ((cur == '<') && (next == '?')) {
11051: 		    if ((!terminate) &&
11052: 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11053: 			goto done;
11054: 		    xmlParsePI(ctxt);
11055: 		} else if ((cur == '<') && (next != '!')) {
11056: 		    ctxt->instate = XML_PARSER_START_TAG;
11057: 		    break;
11058: 		} else if ((cur == '<') && (next == '!') &&
11059: 		           (ctxt->input->cur[2] == '-') &&
11060: 			   (ctxt->input->cur[3] == '-')) {
11061: 		    int term;
11062: 
11063: 	            if (avail < 4)
11064: 		        goto done;
11065: 		    ctxt->input->cur += 4;
11066: 		    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11067: 		    ctxt->input->cur -= 4;
11068: 		    if ((!terminate) && (term < 0))
11069: 			goto done;
11070: 		    xmlParseComment(ctxt);
11071: 		    ctxt->instate = XML_PARSER_CONTENT;
11072: 		} else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11073: 		    (ctxt->input->cur[2] == '[') &&
11074: 		    (ctxt->input->cur[3] == 'C') &&
11075: 		    (ctxt->input->cur[4] == 'D') &&
11076: 		    (ctxt->input->cur[5] == 'A') &&
11077: 		    (ctxt->input->cur[6] == 'T') &&
11078: 		    (ctxt->input->cur[7] == 'A') &&
11079: 		    (ctxt->input->cur[8] == '[')) {
11080: 		    SKIP(9);
11081: 		    ctxt->instate = XML_PARSER_CDATA_SECTION;
11082: 		    break;
11083: 		} else if ((cur == '<') && (next == '!') &&
11084: 		           (avail < 9)) {
11085: 		    goto done;
11086: 		} else if (cur == '&') {
11087: 		    if ((!terminate) &&
11088: 		        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11089: 			goto done;
11090: 		    xmlParseReference(ctxt);
11091: 		} else {
11092: 		    /* TODO Avoid the extra copy, handle directly !!! */
11093: 		    /*
11094: 		     * Goal of the following test is:
11095: 		     *  - minimize calls to the SAX 'character' callback
11096: 		     *    when they are mergeable
11097: 		     *  - handle an problem for isBlank when we only parse
11098: 		     *    a sequence of blank chars and the next one is
11099: 		     *    not available to check against '<' presence.
11100: 		     *  - tries to homogenize the differences in SAX
11101: 		     *    callbacks between the push and pull versions
11102: 		     *    of the parser.
11103: 		     */
11104: 		    if ((ctxt->inputNr == 1) &&
11105: 		        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11106: 			if (!terminate) {
11107: 			    if (ctxt->progressive) {
11108: 				if ((lastlt == NULL) ||
11109: 				    (ctxt->input->cur > lastlt))
11110: 				    goto done;
11111: 			    } else if (xmlParseLookupSequence(ctxt,
11112: 			                                      '<', 0, 0) < 0) {
11113: 				goto done;
11114: 			    }
11115: 			}
11116:                     }
11117: 		    ctxt->checkIndex = 0;
11118: 		    xmlParseCharData(ctxt, 0);
11119: 		}
11120: 		/*
11121: 		 * Pop-up of finished entities.
11122: 		 */
11123: 		while ((RAW == 0) && (ctxt->inputNr > 1))
11124: 		    xmlPopInput(ctxt);
11125: 		if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
11126: 		    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11127: 		                "detected an error in element content\n");
11128: 		    ctxt->instate = XML_PARSER_EOF;
11129: 		    break;
11130: 		}
11131: 		break;
11132: 	    }
11133:             case XML_PARSER_END_TAG:
11134: 		if (avail < 2)
11135: 		    goto done;
11136: 		if (!terminate) {
11137: 		    if (ctxt->progressive) {
11138: 		        /* > can be found unescaped in attribute values */
11139: 		        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11140: 			    goto done;
11141: 		    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11142: 			goto done;
11143: 		    }
11144: 		}
11145: 		if (ctxt->sax2) {
11146: 		    xmlParseEndTag2(ctxt,
11147: 		           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
11148: 		           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
11149: 		       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
11150: 		    nameNsPop(ctxt);
11151: 		}
11152: #ifdef LIBXML_SAX1_ENABLED
11153: 		  else
11154: 		    xmlParseEndTag1(ctxt, 0);
11155: #endif /* LIBXML_SAX1_ENABLED */
11156: 		if (ctxt->nameNr == 0) {
11157: 		    ctxt->instate = XML_PARSER_EPILOG;
11158: 		} else {
11159: 		    ctxt->instate = XML_PARSER_CONTENT;
11160: 		}
11161: 		break;
11162:             case XML_PARSER_CDATA_SECTION: {
11163: 	        /*
11164: 		 * The Push mode need to have the SAX callback for 
11165: 		 * cdataBlock merge back contiguous callbacks.
11166: 		 */
11167: 		int base;
11168: 
11169: 		base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11170: 		if (base < 0) {
11171: 		    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11172: 		        int tmp;
11173: 
11174: 			tmp = xmlCheckCdataPush(ctxt->input->cur, 
11175: 			                        XML_PARSER_BIG_BUFFER_SIZE);
11176: 			if (tmp < 0) {
11177: 			    tmp = -tmp;
11178: 			    ctxt->input->cur += tmp;
11179: 			    goto encoding_error;
11180: 			}
11181: 			if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11182: 			    if (ctxt->sax->cdataBlock != NULL)
11183: 				ctxt->sax->cdataBlock(ctxt->userData,
11184: 				                      ctxt->input->cur, tmp);
11185: 			    else if (ctxt->sax->characters != NULL)
11186: 				ctxt->sax->characters(ctxt->userData,
11187: 				                      ctxt->input->cur, tmp);
11188: 			}
11189: 			SKIPL(tmp);
11190: 			ctxt->checkIndex = 0;
11191: 		    }
11192: 		    goto done;
11193: 		} else {
11194: 		    int tmp;
11195: 
11196: 		    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
11197: 		    if ((tmp < 0) || (tmp != base)) {
11198: 			tmp = -tmp;
11199: 			ctxt->input->cur += tmp;
11200: 			goto encoding_error;
11201: 		    }
11202: 		    if ((ctxt->sax != NULL) && (base == 0) &&
11203: 		        (ctxt->sax->cdataBlock != NULL) &&
11204: 		        (!ctxt->disableSAX)) {
11205: 			/*
11206: 			 * Special case to provide identical behaviour
11207: 			 * between pull and push parsers on enpty CDATA
11208: 			 * sections
11209: 			 */
11210: 			 if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11211: 			     (!strncmp((const char *)&ctxt->input->cur[-9],
11212: 			               "<![CDATA[", 9)))
11213: 			     ctxt->sax->cdataBlock(ctxt->userData,
11214: 			                           BAD_CAST "", 0);
11215: 		    } else if ((ctxt->sax != NULL) && (base > 0) &&
11216: 			(!ctxt->disableSAX)) {
11217: 			if (ctxt->sax->cdataBlock != NULL)
11218: 			    ctxt->sax->cdataBlock(ctxt->userData,
11219: 						  ctxt->input->cur, base);
11220: 			else if (ctxt->sax->characters != NULL)
11221: 			    ctxt->sax->characters(ctxt->userData,
11222: 						  ctxt->input->cur, base);
11223: 		    }
11224: 		    SKIPL(base + 3);
11225: 		    ctxt->checkIndex = 0;
11226: 		    ctxt->instate = XML_PARSER_CONTENT;
11227: #ifdef DEBUG_PUSH
11228: 		    xmlGenericError(xmlGenericErrorContext,
11229: 			    "PP: entering CONTENT\n");
11230: #endif
11231: 		}
11232: 		break;
11233: 	    }
11234:             case XML_PARSER_MISC:
11235: 		SKIP_BLANKS;
11236: 		if (ctxt->input->buf == NULL)
11237: 		    avail = ctxt->input->length -
11238: 		            (ctxt->input->cur - ctxt->input->base);
11239: 		else
11240: 		    avail = ctxt->input->buf->buffer->use -
11241: 		            (ctxt->input->cur - ctxt->input->base);
11242: 		if (avail < 2)
11243: 		    goto done;
11244: 		cur = ctxt->input->cur[0];
11245: 		next = ctxt->input->cur[1];
11246: 	        if ((cur == '<') && (next == '?')) {
11247: 		    if ((!terminate) &&
11248: 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11249: 			goto done;
11250: #ifdef DEBUG_PUSH
11251: 		    xmlGenericError(xmlGenericErrorContext,
11252: 			    "PP: Parsing PI\n");
11253: #endif
11254: 		    xmlParsePI(ctxt);
11255: 		    ctxt->checkIndex = 0;
11256: 		} else if ((cur == '<') && (next == '!') &&
11257: 		    (ctxt->input->cur[2] == '-') &&
11258: 		    (ctxt->input->cur[3] == '-')) {
11259: 		    if ((!terminate) &&
11260: 		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
11261: 			goto done;
11262: #ifdef DEBUG_PUSH
11263: 		    xmlGenericError(xmlGenericErrorContext,
11264: 			    "PP: Parsing Comment\n");
11265: #endif
11266: 		    xmlParseComment(ctxt);
11267: 		    ctxt->instate = XML_PARSER_MISC;
11268: 		    ctxt->checkIndex = 0;
11269: 		} else if ((cur == '<') && (next == '!') &&
11270: 		    (ctxt->input->cur[2] == 'D') &&
11271: 		    (ctxt->input->cur[3] == 'O') &&
11272: 		    (ctxt->input->cur[4] == 'C') &&
11273: 		    (ctxt->input->cur[5] == 'T') &&
11274: 		    (ctxt->input->cur[6] == 'Y') &&
11275: 		    (ctxt->input->cur[7] == 'P') &&
11276: 		    (ctxt->input->cur[8] == 'E')) {
11277: 		    if ((!terminate) &&
11278: 		        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
11279: 			goto done;
11280: #ifdef DEBUG_PUSH
11281: 		    xmlGenericError(xmlGenericErrorContext,
11282: 			    "PP: Parsing internal subset\n");
11283: #endif
11284: 		    ctxt->inSubset = 1;
11285: 		    xmlParseDocTypeDecl(ctxt);
11286: 		    if (RAW == '[') {
11287: 			ctxt->instate = XML_PARSER_DTD;
11288: #ifdef DEBUG_PUSH
11289: 			xmlGenericError(xmlGenericErrorContext,
11290: 				"PP: entering DTD\n");
11291: #endif
11292: 		    } else {
11293: 			/*
11294: 			 * Create and update the external subset.
11295: 			 */
11296: 			ctxt->inSubset = 2;
11297: 			if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11298: 			    (ctxt->sax->externalSubset != NULL))
11299: 			    ctxt->sax->externalSubset(ctxt->userData,
11300: 				    ctxt->intSubName, ctxt->extSubSystem,
11301: 				    ctxt->extSubURI);
11302: 			ctxt->inSubset = 0;
11303: 			xmlCleanSpecialAttr(ctxt);
11304: 			ctxt->instate = XML_PARSER_PROLOG;
11305: #ifdef DEBUG_PUSH
11306: 			xmlGenericError(xmlGenericErrorContext,
11307: 				"PP: entering PROLOG\n");
11308: #endif
11309: 		    }
11310: 		} else if ((cur == '<') && (next == '!') &&
11311: 		           (avail < 9)) {
11312: 		    goto done;
11313: 		} else {
11314: 		    ctxt->instate = XML_PARSER_START_TAG;
11315: 		    ctxt->progressive = 1;
11316: 		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11317: #ifdef DEBUG_PUSH
11318: 		    xmlGenericError(xmlGenericErrorContext,
11319: 			    "PP: entering START_TAG\n");
11320: #endif
11321: 		}
11322: 		break;
11323:             case XML_PARSER_PROLOG:
11324: 		SKIP_BLANKS;
11325: 		if (ctxt->input->buf == NULL)
11326: 		    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11327: 		else
11328: 		    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
11329: 		if (avail < 2) 
11330: 		    goto done;
11331: 		cur = ctxt->input->cur[0];
11332: 		next = ctxt->input->cur[1];
11333: 	        if ((cur == '<') && (next == '?')) {
11334: 		    if ((!terminate) &&
11335: 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11336: 			goto done;
11337: #ifdef DEBUG_PUSH
11338: 		    xmlGenericError(xmlGenericErrorContext,
11339: 			    "PP: Parsing PI\n");
11340: #endif
11341: 		    xmlParsePI(ctxt);
11342: 		} else if ((cur == '<') && (next == '!') &&
11343: 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11344: 		    if ((!terminate) &&
11345: 		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
11346: 			goto done;
11347: #ifdef DEBUG_PUSH
11348: 		    xmlGenericError(xmlGenericErrorContext,
11349: 			    "PP: Parsing Comment\n");
11350: #endif
11351: 		    xmlParseComment(ctxt);
11352: 		    ctxt->instate = XML_PARSER_PROLOG;
11353: 		} else if ((cur == '<') && (next == '!') &&
11354: 		           (avail < 4)) {
11355: 		    goto done;
11356: 		} else {
11357: 		    ctxt->instate = XML_PARSER_START_TAG;
11358: 		    if (ctxt->progressive == 0)
11359: 			ctxt->progressive = 1;
11360: 		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11361: #ifdef DEBUG_PUSH
11362: 		    xmlGenericError(xmlGenericErrorContext,
11363: 			    "PP: entering START_TAG\n");
11364: #endif
11365: 		}
11366: 		break;
11367:             case XML_PARSER_EPILOG:
11368: 		SKIP_BLANKS;
11369: 		if (ctxt->input->buf == NULL)
11370: 		    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11371: 		else
11372: 		    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
11373: 		if (avail < 2)
11374: 		    goto done;
11375: 		cur = ctxt->input->cur[0];
11376: 		next = ctxt->input->cur[1];
11377: 	        if ((cur == '<') && (next == '?')) {
11378: 		    if ((!terminate) &&
11379: 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11380: 			goto done;
11381: #ifdef DEBUG_PUSH
11382: 		    xmlGenericError(xmlGenericErrorContext,
11383: 			    "PP: Parsing PI\n");
11384: #endif
11385: 		    xmlParsePI(ctxt);
11386: 		    ctxt->instate = XML_PARSER_EPILOG;
11387: 		} else if ((cur == '<') && (next == '!') &&
11388: 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11389: 		    if ((!terminate) &&
11390: 		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
11391: 			goto done;
11392: #ifdef DEBUG_PUSH
11393: 		    xmlGenericError(xmlGenericErrorContext,
11394: 			    "PP: Parsing Comment\n");
11395: #endif
11396: 		    xmlParseComment(ctxt);
11397: 		    ctxt->instate = XML_PARSER_EPILOG;
11398: 		} else if ((cur == '<') && (next == '!') &&
11399: 		           (avail < 4)) {
11400: 		    goto done;
11401: 		} else {
11402: 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11403: 		    ctxt->instate = XML_PARSER_EOF;
11404: #ifdef DEBUG_PUSH
11405: 		    xmlGenericError(xmlGenericErrorContext,
11406: 			    "PP: entering EOF\n");
11407: #endif
11408: 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11409: 			ctxt->sax->endDocument(ctxt->userData);
11410: 		    goto done;
11411: 		}
11412: 		break;
11413:             case XML_PARSER_DTD: {
11414: 	        /*
11415: 		 * Sorry but progressive parsing of the internal subset
11416: 		 * is not expected to be supported. We first check that
11417: 		 * the full content of the internal subset is available and
11418: 		 * the parsing is launched only at that point.
11419: 		 * Internal subset ends up with "']' S? '>'" in an unescaped
11420: 		 * section and not in a ']]>' sequence which are conditional
11421: 		 * sections (whoever argued to keep that crap in XML deserve
11422: 		 * a place in hell !).
11423: 		 */
11424: 		int base, i;
11425: 		xmlChar *buf;
11426: 	        xmlChar quote = 0;
11427: 
11428: 		base = ctxt->input->cur - ctxt->input->base;
11429: 		if (base < 0) return(0);
11430: 		if (ctxt->checkIndex > base)
11431: 		    base = ctxt->checkIndex;
11432: 		buf = ctxt->input->buf->buffer->content;
11433: 		for (;(unsigned int) base < ctxt->input->buf->buffer->use;
11434: 		     base++) {
11435: 		    if (quote != 0) {
11436: 		        if (buf[base] == quote)
11437: 			    quote = 0;
11438: 			continue;    
11439: 		    }
11440: 		    if ((quote == 0) && (buf[base] == '<')) {
11441: 		        int found  = 0;
11442: 			/* special handling of comments */
11443: 		        if (((unsigned int) base + 4 <
11444: 			     ctxt->input->buf->buffer->use) &&
11445: 			    (buf[base + 1] == '!') &&
11446: 			    (buf[base + 2] == '-') &&
11447: 			    (buf[base + 3] == '-')) {
11448: 			    for (;(unsigned int) base + 3 <
11449: 			          ctxt->input->buf->buffer->use; base++) {
11450: 				if ((buf[base] == '-') &&
11451: 				    (buf[base + 1] == '-') &&
11452: 				    (buf[base + 2] == '>')) {
11453: 				    found = 1;
11454: 				    base += 2;
11455: 				    break;
11456: 				}
11457: 		            }
11458: 			    if (!found) {
11459: #if 0
11460: 			        fprintf(stderr, "unfinished comment\n");
11461: #endif
11462: 			        break; /* for */
11463: 		            }
11464: 		            continue;
11465: 			}
11466: 		    }
11467: 		    if (buf[base] == '"') {
11468: 		        quote = '"';
11469: 			continue;
11470: 		    }
11471: 		    if (buf[base] == '\'') {
11472: 		        quote = '\'';
11473: 			continue;
11474: 		    }
11475: 		    if (buf[base] == ']') {
11476: #if 0
11477: 		        fprintf(stderr, "%c%c%c%c: ", buf[base],
11478: 			        buf[base + 1], buf[base + 2], buf[base + 3]);
11479: #endif
11480: 		        if ((unsigned int) base +1 >=
11481: 		            ctxt->input->buf->buffer->use)
11482: 			    break;
11483: 			if (buf[base + 1] == ']') {
11484: 			    /* conditional crap, skip both ']' ! */
11485: 			    base++;
11486: 			    continue;
11487: 			}
11488: 		        for (i = 1;
11489: 		     (unsigned int) base + i < ctxt->input->buf->buffer->use;
11490: 		             i++) {
11491: 			    if (buf[base + i] == '>') {
11492: #if 0
11493: 			        fprintf(stderr, "found\n");
11494: #endif
11495: 			        goto found_end_int_subset;
11496: 			    }
11497: 			    if (!IS_BLANK_CH(buf[base + i])) {
11498: #if 0
11499: 			        fprintf(stderr, "not found\n");
11500: #endif
11501: 			        goto not_end_of_int_subset;
11502: 			    }
11503: 			}
11504: #if 0
11505: 			fprintf(stderr, "end of stream\n");
11506: #endif
11507: 		        break;
11508:                         
11509: 		    }
11510: not_end_of_int_subset:
11511:                     continue; /* for */
11512: 		}
11513: 		/*
11514: 		 * We didn't found the end of the Internal subset
11515: 		 */
11516: #ifdef DEBUG_PUSH
11517: 		if (next == 0)
11518: 		    xmlGenericError(xmlGenericErrorContext,
11519: 			    "PP: lookup of int subset end filed\n");
11520: #endif
11521: 	        goto done;
11522: 
11523: found_end_int_subset:
11524: 		xmlParseInternalSubset(ctxt);
11525: 		ctxt->inSubset = 2;
11526: 		if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11527: 		    (ctxt->sax->externalSubset != NULL))
11528: 		    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
11529: 			    ctxt->extSubSystem, ctxt->extSubURI);
11530: 		ctxt->inSubset = 0;
11531: 		xmlCleanSpecialAttr(ctxt);
11532: 		ctxt->instate = XML_PARSER_PROLOG;
11533: 		ctxt->checkIndex = 0;
11534: #ifdef DEBUG_PUSH
11535: 		xmlGenericError(xmlGenericErrorContext,
11536: 			"PP: entering PROLOG\n");
11537: #endif
11538:                 break;
11539: 	    }
11540:             case XML_PARSER_COMMENT:
11541: 		xmlGenericError(xmlGenericErrorContext,
11542: 			"PP: internal error, state == COMMENT\n");
11543: 		ctxt->instate = XML_PARSER_CONTENT;
11544: #ifdef DEBUG_PUSH
11545: 		xmlGenericError(xmlGenericErrorContext,
11546: 			"PP: entering CONTENT\n");
11547: #endif
11548: 		break;
11549:             case XML_PARSER_IGNORE:
11550: 		xmlGenericError(xmlGenericErrorContext,
11551: 			"PP: internal error, state == IGNORE");
11552: 	        ctxt->instate = XML_PARSER_DTD;
11553: #ifdef DEBUG_PUSH
11554: 		xmlGenericError(xmlGenericErrorContext,
11555: 			"PP: entering DTD\n");
11556: #endif
11557: 	        break;
11558:             case XML_PARSER_PI:
11559: 		xmlGenericError(xmlGenericErrorContext,
11560: 			"PP: internal error, state == PI\n");
11561: 		ctxt->instate = XML_PARSER_CONTENT;
11562: #ifdef DEBUG_PUSH
11563: 		xmlGenericError(xmlGenericErrorContext,
11564: 			"PP: entering CONTENT\n");
11565: #endif
11566: 		break;
11567:             case XML_PARSER_ENTITY_DECL:
11568: 		xmlGenericError(xmlGenericErrorContext,
11569: 			"PP: internal error, state == ENTITY_DECL\n");
11570: 		ctxt->instate = XML_PARSER_DTD;
11571: #ifdef DEBUG_PUSH
11572: 		xmlGenericError(xmlGenericErrorContext,
11573: 			"PP: entering DTD\n");
11574: #endif
11575: 		break;
11576:             case XML_PARSER_ENTITY_VALUE:
11577: 		xmlGenericError(xmlGenericErrorContext,
11578: 			"PP: internal error, state == ENTITY_VALUE\n");
11579: 		ctxt->instate = XML_PARSER_CONTENT;
11580: #ifdef DEBUG_PUSH
11581: 		xmlGenericError(xmlGenericErrorContext,
11582: 			"PP: entering DTD\n");
11583: #endif
11584: 		break;
11585:             case XML_PARSER_ATTRIBUTE_VALUE:
11586: 		xmlGenericError(xmlGenericErrorContext,
11587: 			"PP: internal error, state == ATTRIBUTE_VALUE\n");
11588: 		ctxt->instate = XML_PARSER_START_TAG;
11589: #ifdef DEBUG_PUSH
11590: 		xmlGenericError(xmlGenericErrorContext,
11591: 			"PP: entering START_TAG\n");
11592: #endif
11593: 		break;
11594:             case XML_PARSER_SYSTEM_LITERAL:
11595: 		xmlGenericError(xmlGenericErrorContext,
11596: 			"PP: internal error, state == SYSTEM_LITERAL\n");
11597: 		ctxt->instate = XML_PARSER_START_TAG;
11598: #ifdef DEBUG_PUSH
11599: 		xmlGenericError(xmlGenericErrorContext,
11600: 			"PP: entering START_TAG\n");
11601: #endif
11602: 		break;
11603:             case XML_PARSER_PUBLIC_LITERAL:
11604: 		xmlGenericError(xmlGenericErrorContext,
11605: 			"PP: internal error, state == PUBLIC_LITERAL\n");
11606: 		ctxt->instate = XML_PARSER_START_TAG;
11607: #ifdef DEBUG_PUSH
11608: 		xmlGenericError(xmlGenericErrorContext,
11609: 			"PP: entering START_TAG\n");
11610: #endif
11611: 		break;
11612: 	}
11613:     }
11614: done:    
11615: #ifdef DEBUG_PUSH
11616:     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
11617: #endif
11618:     return(ret);
11619: encoding_error:
11620:     {
11621:         char buffer[150];
11622: 
11623: 	snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
11624: 			ctxt->input->cur[0], ctxt->input->cur[1],
11625: 			ctxt->input->cur[2], ctxt->input->cur[3]);
11626: 	__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
11627: 		     "Input is not proper UTF-8, indicate encoding !\n%s",
11628: 		     BAD_CAST buffer, NULL);
11629:     }
11630:     return(0);
11631: }
11632: 
11633: /**
11634:  * xmlParseChunk:
11635:  * @ctxt:  an XML parser context
11636:  * @chunk:  an char array
11637:  * @size:  the size in byte of the chunk
11638:  * @terminate:  last chunk indicator
11639:  *
11640:  * Parse a Chunk of memory
11641:  *
11642:  * Returns zero if no error, the xmlParserErrors otherwise.
11643:  */
11644: int
11645: xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
11646:               int terminate) {
11647:     int end_in_lf = 0;
11648:     int remain = 0;
11649: 
11650:     if (ctxt == NULL)
11651:         return(XML_ERR_INTERNAL_ERROR);
11652:     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11653:         return(ctxt->errNo);
11654:     if (ctxt->instate == XML_PARSER_START)
11655:         xmlDetectSAX2(ctxt);
11656:     if ((size > 0) && (chunk != NULL) && (!terminate) &&
11657:         (chunk[size - 1] == '\r')) {
11658: 	end_in_lf = 1;
11659: 	size--;
11660:     }
11661: 
11662: xmldecl_done:
11663: 
11664:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
11665:         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
11666: 	int base = ctxt->input->base - ctxt->input->buf->buffer->content;
11667: 	int cur = ctxt->input->cur - ctxt->input->base;
11668: 	int res;
11669: 
11670:         /*
11671:          * Specific handling if we autodetected an encoding, we should not
11672:          * push more than the first line ... which depend on the encoding
11673:          * And only push the rest once the final encoding was detected
11674:          */
11675:         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
11676:             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
11677:             unsigned int len = 45;
11678: 
11679:             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11680:                                BAD_CAST "UTF-16")) ||
11681:                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11682:                                BAD_CAST "UTF16")))
11683:                 len = 90;
11684:             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11685:                                     BAD_CAST "UCS-4")) ||
11686:                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11687:                                     BAD_CAST "UCS4")))
11688:                 len = 180;
11689: 
11690:             if (ctxt->input->buf->rawconsumed < len)
11691:                 len -= ctxt->input->buf->rawconsumed;
11692: 
11693:             /*
11694:              * Change size for reading the initial declaration only
11695:              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
11696:              * will blindly copy extra bytes from memory.
11697:              */
11698:             if ((unsigned int) size > len) {
11699:                 remain = size - len;
11700:                 size = len;
11701:             } else {
11702:                 remain = 0;
11703:             }
11704:         }
11705: 	res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
11706: 	if (res < 0) {
11707: 	    ctxt->errNo = XML_PARSER_EOF;
11708: 	    ctxt->disableSAX = 1;
11709: 	    return (XML_PARSER_EOF);
11710: 	}
11711: 	ctxt->input->base = ctxt->input->buf->buffer->content + base;
11712: 	ctxt->input->cur = ctxt->input->base + cur;
11713: 	ctxt->input->end =
11714: 	    &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
11715: #ifdef DEBUG_PUSH
11716: 	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
11717: #endif
11718: 
11719:     } else if (ctxt->instate != XML_PARSER_EOF) {
11720: 	if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
11721: 	    xmlParserInputBufferPtr in = ctxt->input->buf;
11722: 	    if ((in->encoder != NULL) && (in->buffer != NULL) &&
11723: 		    (in->raw != NULL)) {
11724: 		int nbchars;
11725: 
11726: 		nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
11727: 		if (nbchars < 0) {
11728: 		    /* TODO 2.6.0 */
11729: 		    xmlGenericError(xmlGenericErrorContext,
11730: 				    "xmlParseChunk: encoder error\n");
11731: 		    return(XML_ERR_INVALID_ENCODING);
11732: 		}
11733: 	    }
11734: 	}
11735:     }
11736:     if (remain != 0)
11737:         xmlParseTryOrFinish(ctxt, 0);
11738:     else
11739:         xmlParseTryOrFinish(ctxt, terminate);
11740:     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11741:         return(ctxt->errNo);
11742: 
11743:     if (remain != 0) {
11744:         chunk += size;
11745:         size = remain;
11746:         remain = 0;
11747:         goto xmldecl_done;
11748:     }
11749:     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
11750:         (ctxt->input->buf != NULL)) {
11751: 	xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
11752:     }
11753:     if (terminate) {
11754: 	/*
11755: 	 * Check for termination
11756: 	 */
11757: 	int avail = 0;
11758: 
11759: 	if (ctxt->input != NULL) {
11760: 	    if (ctxt->input->buf == NULL)
11761: 		avail = ctxt->input->length -
11762: 			(ctxt->input->cur - ctxt->input->base);
11763: 	    else
11764: 		avail = ctxt->input->buf->buffer->use -
11765: 			(ctxt->input->cur - ctxt->input->base);
11766: 	}
11767: 			    
11768: 	if ((ctxt->instate != XML_PARSER_EOF) &&
11769: 	    (ctxt->instate != XML_PARSER_EPILOG)) {
11770: 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11771: 	} 
11772: 	if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
11773: 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11774: 	}
11775: 	if (ctxt->instate != XML_PARSER_EOF) {
11776: 	    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11777: 		ctxt->sax->endDocument(ctxt->userData);
11778: 	}
11779: 	ctxt->instate = XML_PARSER_EOF;
11780:     }
11781:     return((xmlParserErrors) ctxt->errNo);	      
11782: }
11783: 
11784: /************************************************************************
11785:  *									*
11786:  * 		I/O front end functions to the parser			*
11787:  *									*
11788:  ************************************************************************/
11789: 
11790: /**
11791:  * xmlCreatePushParserCtxt:
11792:  * @sax:  a SAX handler
11793:  * @user_data:  The user data returned on SAX callbacks
11794:  * @chunk:  a pointer to an array of chars
11795:  * @size:  number of chars in the array
11796:  * @filename:  an optional file name or URI
11797:  *
11798:  * Create a parser context for using the XML parser in push mode.
11799:  * If @buffer and @size are non-NULL, the data is used to detect
11800:  * the encoding.  The remaining characters will be parsed so they
11801:  * don't need to be fed in again through xmlParseChunk.
11802:  * To allow content encoding detection, @size should be >= 4
11803:  * The value of @filename is used for fetching external entities
11804:  * and error/warning reports.
11805:  *
11806:  * Returns the new parser context or NULL
11807:  */
11808: 
11809: xmlParserCtxtPtr
11810: xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
11811:                         const char *chunk, int size, const char *filename) {
11812:     xmlParserCtxtPtr ctxt;
11813:     xmlParserInputPtr inputStream;
11814:     xmlParserInputBufferPtr buf;
11815:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
11816: 
11817:     /*
11818:      * plug some encoding conversion routines
11819:      */
11820:     if ((chunk != NULL) && (size >= 4))
11821: 	enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
11822: 
11823:     buf = xmlAllocParserInputBuffer(enc);
11824:     if (buf == NULL) return(NULL);
11825: 
11826:     ctxt = xmlNewParserCtxt();
11827:     if (ctxt == NULL) {
11828:         xmlErrMemory(NULL, "creating parser: out of memory\n");
11829: 	xmlFreeParserInputBuffer(buf);
11830: 	return(NULL);
11831:     }
11832:     ctxt->dictNames = 1;
11833:     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
11834:     if (ctxt->pushTab == NULL) {
11835:         xmlErrMemory(ctxt, NULL);
11836: 	xmlFreeParserInputBuffer(buf);
11837: 	xmlFreeParserCtxt(ctxt);
11838: 	return(NULL);
11839:     }
11840:     if (sax != NULL) {
11841: #ifdef LIBXML_SAX1_ENABLED
11842: 	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
11843: #endif /* LIBXML_SAX1_ENABLED */
11844: 	    xmlFree(ctxt->sax);
11845: 	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
11846: 	if (ctxt->sax == NULL) {
11847: 	    xmlErrMemory(ctxt, NULL);
11848: 	    xmlFreeParserInputBuffer(buf);
11849: 	    xmlFreeParserCtxt(ctxt);
11850: 	    return(NULL);
11851: 	}
11852: 	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
11853: 	if (sax->initialized == XML_SAX2_MAGIC)
11854: 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
11855: 	else
11856: 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
11857: 	if (user_data != NULL)
11858: 	    ctxt->userData = user_data;
11859:     }	
11860:     if (filename == NULL) {
11861: 	ctxt->directory = NULL;
11862:     } else {
11863:         ctxt->directory = xmlParserGetDirectory(filename);
11864:     }
11865: 
11866:     inputStream = xmlNewInputStream(ctxt);
11867:     if (inputStream == NULL) {
11868: 	xmlFreeParserCtxt(ctxt);
11869: 	xmlFreeParserInputBuffer(buf);
11870: 	return(NULL);
11871:     }
11872: 
11873:     if (filename == NULL)
11874: 	inputStream->filename = NULL;
11875:     else {
11876: 	inputStream->filename = (char *)
11877: 	    xmlCanonicPath((const xmlChar *) filename);
11878: 	if (inputStream->filename == NULL) {
11879: 	    xmlFreeParserCtxt(ctxt);
11880: 	    xmlFreeParserInputBuffer(buf);
11881: 	    return(NULL);
11882: 	}
11883:     }
11884:     inputStream->buf = buf;
11885:     inputStream->base = inputStream->buf->buffer->content;
11886:     inputStream->cur = inputStream->buf->buffer->content;
11887:     inputStream->end = 
11888: 	&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
11889: 
11890:     inputPush(ctxt, inputStream);
11891: 
11892:     /*
11893:      * If the caller didn't provide an initial 'chunk' for determining
11894:      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
11895:      * that it can be automatically determined later
11896:      */
11897:     if ((size == 0) || (chunk == NULL)) {
11898: 	ctxt->charset = XML_CHAR_ENCODING_NONE;
11899:     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
11900: 	int base = ctxt->input->base - ctxt->input->buf->buffer->content;
11901: 	int cur = ctxt->input->cur - ctxt->input->base;
11902: 
11903: 	xmlParserInputBufferPush(ctxt->input->buf, size, chunk);	      
11904: 
11905: 	ctxt->input->base = ctxt->input->buf->buffer->content + base;
11906: 	ctxt->input->cur = ctxt->input->base + cur;
11907: 	ctxt->input->end =
11908: 	    &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
11909: #ifdef DEBUG_PUSH
11910: 	xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
11911: #endif
11912:     }
11913: 
11914:     if (enc != XML_CHAR_ENCODING_NONE) {
11915:         xmlSwitchEncoding(ctxt, enc);
11916:     }
11917: 
11918:     return(ctxt);
11919: }
11920: #endif /* LIBXML_PUSH_ENABLED */
11921: 
11922: /**
11923:  * xmlStopParser:
11924:  * @ctxt:  an XML parser context
11925:  *
11926:  * Blocks further parser processing
11927:  */
11928: void           
11929: xmlStopParser(xmlParserCtxtPtr ctxt) {
11930:     if (ctxt == NULL)
11931:         return;
11932:     ctxt->instate = XML_PARSER_EOF;
11933:     ctxt->disableSAX = 1;
11934:     if (ctxt->input != NULL) {
11935: 	ctxt->input->cur = BAD_CAST"";
11936: 	ctxt->input->base = ctxt->input->cur;
11937:     }
11938: }
11939: 
11940: /**
11941:  * xmlCreateIOParserCtxt:
11942:  * @sax:  a SAX handler
11943:  * @user_data:  The user data returned on SAX callbacks
11944:  * @ioread:  an I/O read function
11945:  * @ioclose:  an I/O close function
11946:  * @ioctx:  an I/O handler
11947:  * @enc:  the charset encoding if known
11948:  *
11949:  * Create a parser context for using the XML parser with an existing
11950:  * I/O stream
11951:  *
11952:  * Returns the new parser context or NULL
11953:  */
11954: xmlParserCtxtPtr
11955: xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
11956: 	xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
11957: 	void *ioctx, xmlCharEncoding enc) {
11958:     xmlParserCtxtPtr ctxt;
11959:     xmlParserInputPtr inputStream;
11960:     xmlParserInputBufferPtr buf;
11961:     
11962:     if (ioread == NULL) return(NULL);
11963: 
11964:     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
11965:     if (buf == NULL) return(NULL);
11966: 
11967:     ctxt = xmlNewParserCtxt();
11968:     if (ctxt == NULL) {
11969: 	xmlFreeParserInputBuffer(buf);
11970: 	return(NULL);
11971:     }
11972:     if (sax != NULL) {
11973: #ifdef LIBXML_SAX1_ENABLED
11974: 	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
11975: #endif /* LIBXML_SAX1_ENABLED */
11976: 	    xmlFree(ctxt->sax);
11977: 	ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
11978: 	if (ctxt->sax == NULL) {
11979: 	    xmlErrMemory(ctxt, NULL);
11980: 	    xmlFreeParserCtxt(ctxt);
11981: 	    return(NULL);
11982: 	}
11983: 	memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
11984: 	if (sax->initialized == XML_SAX2_MAGIC)
11985: 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
11986: 	else
11987: 	    memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
11988: 	if (user_data != NULL)
11989: 	    ctxt->userData = user_data;
11990:     }	
11991: 
11992:     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
11993:     if (inputStream == NULL) {
11994: 	xmlFreeParserCtxt(ctxt);
11995: 	return(NULL);
11996:     }
11997:     inputPush(ctxt, inputStream);
11998: 
11999:     return(ctxt);
12000: }
12001: 
12002: #ifdef LIBXML_VALID_ENABLED
12003: /************************************************************************
12004:  *									*
12005:  * 		Front ends when parsing a DTD				*
12006:  *									*
12007:  ************************************************************************/
12008: 
12009: /**
12010:  * xmlIOParseDTD:
12011:  * @sax:  the SAX handler block or NULL
12012:  * @input:  an Input Buffer
12013:  * @enc:  the charset encoding if known
12014:  *
12015:  * Load and parse a DTD
12016:  * 
12017:  * Returns the resulting xmlDtdPtr or NULL in case of error.
12018:  * @input will be freed by the function in any case.
12019:  */
12020: 
12021: xmlDtdPtr
12022: xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12023: 	      xmlCharEncoding enc) {
12024:     xmlDtdPtr ret = NULL;
12025:     xmlParserCtxtPtr ctxt;
12026:     xmlParserInputPtr pinput = NULL;
12027:     xmlChar start[4];
12028: 
12029:     if (input == NULL)
12030: 	return(NULL);
12031: 
12032:     ctxt = xmlNewParserCtxt();
12033:     if (ctxt == NULL) {
12034:         xmlFreeParserInputBuffer(input);
12035: 	return(NULL);
12036:     }
12037: 
12038:     /*
12039:      * Set-up the SAX context
12040:      */
12041:     if (sax != NULL) { 
12042: 	if (ctxt->sax != NULL)
12043: 	    xmlFree(ctxt->sax);
12044:         ctxt->sax = sax;
12045:         ctxt->userData = ctxt;
12046:     }
12047:     xmlDetectSAX2(ctxt);
12048: 
12049:     /*
12050:      * generate a parser input from the I/O handler
12051:      */
12052: 
12053:     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12054:     if (pinput == NULL) {
12055:         if (sax != NULL) ctxt->sax = NULL;
12056:         xmlFreeParserInputBuffer(input);
12057: 	xmlFreeParserCtxt(ctxt);
12058: 	return(NULL);
12059:     }
12060: 
12061:     /*
12062:      * plug some encoding conversion routines here.
12063:      */
12064:     if (xmlPushInput(ctxt, pinput) < 0) {
12065:         if (sax != NULL) ctxt->sax = NULL;
12066: 	xmlFreeParserCtxt(ctxt);
12067: 	return(NULL);
12068:     }
12069:     if (enc != XML_CHAR_ENCODING_NONE) {
12070:         xmlSwitchEncoding(ctxt, enc);
12071:     }
12072: 
12073:     pinput->filename = NULL;
12074:     pinput->line = 1;
12075:     pinput->col = 1;
12076:     pinput->base = ctxt->input->cur;
12077:     pinput->cur = ctxt->input->cur;
12078:     pinput->free = NULL;
12079: 
12080:     /*
12081:      * let's parse that entity knowing it's an external subset.
12082:      */
12083:     ctxt->inSubset = 2;
12084:     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12085:     if (ctxt->myDoc == NULL) {
12086: 	xmlErrMemory(ctxt, "New Doc failed");
12087: 	return(NULL);
12088:     }
12089:     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12090:     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12091: 	                               BAD_CAST "none", BAD_CAST "none");
12092: 
12093:     if ((enc == XML_CHAR_ENCODING_NONE) &&
12094:         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12095: 	/* 
12096: 	 * Get the 4 first bytes and decode the charset
12097: 	 * if enc != XML_CHAR_ENCODING_NONE
12098: 	 * plug some encoding conversion routines.
12099: 	 */
12100: 	start[0] = RAW;
12101: 	start[1] = NXT(1);
12102: 	start[2] = NXT(2);
12103: 	start[3] = NXT(3);
12104: 	enc = xmlDetectCharEncoding(start, 4);
12105: 	if (enc != XML_CHAR_ENCODING_NONE) {
12106: 	    xmlSwitchEncoding(ctxt, enc);
12107: 	}
12108:     }
12109: 
12110:     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12111: 
12112:     if (ctxt->myDoc != NULL) {
12113: 	if (ctxt->wellFormed) {
12114: 	    ret = ctxt->myDoc->extSubset;
12115: 	    ctxt->myDoc->extSubset = NULL;
12116: 	    if (ret != NULL) {
12117: 		xmlNodePtr tmp;
12118: 
12119: 		ret->doc = NULL;
12120: 		tmp = ret->children;
12121: 		while (tmp != NULL) {
12122: 		    tmp->doc = NULL;
12123: 		    tmp = tmp->next;
12124: 		}
12125: 	    }
12126: 	} else {
12127: 	    ret = NULL;
12128: 	}
12129:         xmlFreeDoc(ctxt->myDoc);
12130:         ctxt->myDoc = NULL;
12131:     }
12132:     if (sax != NULL) ctxt->sax = NULL;
12133:     xmlFreeParserCtxt(ctxt);
12134:     
12135:     return(ret);
12136: }
12137: 
12138: /**
12139:  * xmlSAXParseDTD:
12140:  * @sax:  the SAX handler block
12141:  * @ExternalID:  a NAME* containing the External ID of the DTD
12142:  * @SystemID:  a NAME* containing the URL to the DTD
12143:  *
12144:  * Load and parse an external subset.
12145:  * 
12146:  * Returns the resulting xmlDtdPtr or NULL in case of error.
12147:  */
12148: 
12149: xmlDtdPtr
12150: xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12151:                           const xmlChar *SystemID) {
12152:     xmlDtdPtr ret = NULL;
12153:     xmlParserCtxtPtr ctxt;
12154:     xmlParserInputPtr input = NULL;
12155:     xmlCharEncoding enc;
12156:     xmlChar* systemIdCanonic;
12157: 
12158:     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12159: 
12160:     ctxt = xmlNewParserCtxt();
12161:     if (ctxt == NULL) {
12162: 	return(NULL);
12163:     }
12164: 
12165:     /*
12166:      * Set-up the SAX context
12167:      */
12168:     if (sax != NULL) { 
12169: 	if (ctxt->sax != NULL)
12170: 	    xmlFree(ctxt->sax);
12171:         ctxt->sax = sax;
12172:         ctxt->userData = ctxt;
12173:     }
12174:     
12175:     /*
12176:      * Canonicalise the system ID
12177:      */
12178:     systemIdCanonic = xmlCanonicPath(SystemID);
12179:     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12180: 	xmlFreeParserCtxt(ctxt);
12181: 	return(NULL);
12182:     }
12183: 
12184:     /*
12185:      * Ask the Entity resolver to load the damn thing
12186:      */
12187: 
12188:     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12189: 	input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12190: 	                                 systemIdCanonic);
12191:     if (input == NULL) {
12192:         if (sax != NULL) ctxt->sax = NULL;
12193: 	xmlFreeParserCtxt(ctxt);
12194: 	if (systemIdCanonic != NULL)
12195: 	    xmlFree(systemIdCanonic);
12196: 	return(NULL);
12197:     }
12198: 
12199:     /*
12200:      * plug some encoding conversion routines here.
12201:      */
12202:     if (xmlPushInput(ctxt, input) < 0) {
12203:         if (sax != NULL) ctxt->sax = NULL;
12204: 	xmlFreeParserCtxt(ctxt);
12205: 	if (systemIdCanonic != NULL)
12206: 	    xmlFree(systemIdCanonic);
12207: 	return(NULL);
12208:     }
12209:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12210: 	enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12211: 	xmlSwitchEncoding(ctxt, enc);
12212:     }
12213: 
12214:     if (input->filename == NULL)
12215: 	input->filename = (char *) systemIdCanonic;
12216:     else
12217: 	xmlFree(systemIdCanonic);
12218:     input->line = 1;
12219:     input->col = 1;
12220:     input->base = ctxt->input->cur;
12221:     input->cur = ctxt->input->cur;
12222:     input->free = NULL;
12223: 
12224:     /*
12225:      * let's parse that entity knowing it's an external subset.
12226:      */
12227:     ctxt->inSubset = 2;
12228:     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12229:     if (ctxt->myDoc == NULL) {
12230: 	xmlErrMemory(ctxt, "New Doc failed");
12231:         if (sax != NULL) ctxt->sax = NULL;
12232: 	xmlFreeParserCtxt(ctxt);
12233: 	return(NULL);
12234:     }
12235:     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12236:     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12237: 	                               ExternalID, SystemID);
12238:     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12239: 
12240:     if (ctxt->myDoc != NULL) {
12241: 	if (ctxt->wellFormed) {
12242: 	    ret = ctxt->myDoc->extSubset;
12243: 	    ctxt->myDoc->extSubset = NULL;
12244: 	    if (ret != NULL) {
12245: 		xmlNodePtr tmp;
12246: 
12247: 		ret->doc = NULL;
12248: 		tmp = ret->children;
12249: 		while (tmp != NULL) {
12250: 		    tmp->doc = NULL;
12251: 		    tmp = tmp->next;
12252: 		}
12253: 	    }
12254: 	} else {
12255: 	    ret = NULL;
12256: 	}
12257:         xmlFreeDoc(ctxt->myDoc);
12258:         ctxt->myDoc = NULL;
12259:     }
12260:     if (sax != NULL) ctxt->sax = NULL;
12261:     xmlFreeParserCtxt(ctxt);
12262: 
12263:     return(ret);
12264: }
12265: 
12266: 
12267: /**
12268:  * xmlParseDTD:
12269:  * @ExternalID:  a NAME* containing the External ID of the DTD
12270:  * @SystemID:  a NAME* containing the URL to the DTD
12271:  *
12272:  * Load and parse an external subset.
12273:  *
12274:  * Returns the resulting xmlDtdPtr or NULL in case of error.
12275:  */
12276: 
12277: xmlDtdPtr
12278: xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12279:     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12280: }
12281: #endif /* LIBXML_VALID_ENABLED */
12282: 
12283: /************************************************************************
12284:  *									*
12285:  * 		Front ends when parsing an Entity			*
12286:  *									*
12287:  ************************************************************************/
12288: 
12289: /**
12290:  * xmlParseCtxtExternalEntity:
12291:  * @ctx:  the existing parsing context
12292:  * @URL:  the URL for the entity to load
12293:  * @ID:  the System ID for the entity to load
12294:  * @lst:  the return value for the set of parsed nodes
12295:  *
12296:  * Parse an external general entity within an existing parsing context
12297:  * An external general parsed entity is well-formed if it matches the
12298:  * production labeled extParsedEnt.
12299:  *
12300:  * [78] extParsedEnt ::= TextDecl? content
12301:  *
12302:  * Returns 0 if the entity is well formed, -1 in case of args problem and
12303:  *    the parser error code otherwise
12304:  */
12305: 
12306: int
12307: xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12308: 	               const xmlChar *ID, xmlNodePtr *lst) {
12309:     xmlParserCtxtPtr ctxt;
12310:     xmlDocPtr newDoc;
12311:     xmlNodePtr newRoot;
12312:     xmlSAXHandlerPtr oldsax = NULL;
12313:     int ret = 0;
12314:     xmlChar start[4];
12315:     xmlCharEncoding enc;
12316: 
12317:     if (ctx == NULL) return(-1);
12318: 
12319:     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
12320:         (ctx->depth > 1024)) {
12321: 	return(XML_ERR_ENTITY_LOOP);
12322:     }
12323: 
12324:     if (lst != NULL)
12325:         *lst = NULL;
12326:     if ((URL == NULL) && (ID == NULL))
12327: 	return(-1);
12328:     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
12329: 	return(-1);
12330: 
12331:     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
12332:     if (ctxt == NULL) {
12333: 	return(-1);
12334:     }
12335: 
12336:     oldsax = ctxt->sax;
12337:     ctxt->sax = ctx->sax;
12338:     xmlDetectSAX2(ctxt);
12339:     newDoc = xmlNewDoc(BAD_CAST "1.0");
12340:     if (newDoc == NULL) {
12341: 	xmlFreeParserCtxt(ctxt);
12342: 	return(-1);
12343:     }
12344:     newDoc->properties = XML_DOC_INTERNAL;
12345:     if (ctx->myDoc->dict) {
12346: 	newDoc->dict = ctx->myDoc->dict;
12347: 	xmlDictReference(newDoc->dict);
12348:     }
12349:     if (ctx->myDoc != NULL) {
12350: 	newDoc->intSubset = ctx->myDoc->intSubset;
12351: 	newDoc->extSubset = ctx->myDoc->extSubset;
12352:     }
12353:     if (ctx->myDoc->URL != NULL) {
12354: 	newDoc->URL = xmlStrdup(ctx->myDoc->URL);
12355:     }
12356:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12357:     if (newRoot == NULL) {
12358: 	ctxt->sax = oldsax;
12359: 	xmlFreeParserCtxt(ctxt);
12360: 	newDoc->intSubset = NULL;
12361: 	newDoc->extSubset = NULL;
12362:         xmlFreeDoc(newDoc);
12363: 	return(-1);
12364:     }
12365:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
12366:     nodePush(ctxt, newDoc->children);
12367:     if (ctx->myDoc == NULL) {
12368: 	ctxt->myDoc = newDoc;
12369:     } else {
12370: 	ctxt->myDoc = ctx->myDoc;
12371: 	newDoc->children->doc = ctx->myDoc;
12372:     }
12373: 
12374:     /*
12375:      * Get the 4 first bytes and decode the charset
12376:      * if enc != XML_CHAR_ENCODING_NONE
12377:      * plug some encoding conversion routines.
12378:      */
12379:     GROW
12380:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12381: 	start[0] = RAW;
12382: 	start[1] = NXT(1);
12383: 	start[2] = NXT(2);
12384: 	start[3] = NXT(3);
12385: 	enc = xmlDetectCharEncoding(start, 4);
12386: 	if (enc != XML_CHAR_ENCODING_NONE) {
12387: 	    xmlSwitchEncoding(ctxt, enc);
12388: 	}
12389:     }
12390: 
12391:     /*
12392:      * Parse a possible text declaration first
12393:      */
12394:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12395: 	xmlParseTextDecl(ctxt);
12396: 	/*
12397: 	 * An XML-1.0 document can't reference an entity not XML-1.0
12398: 	 */
12399: 	if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
12400: 	    (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12401: 	    xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, 
12402: 	                   "Version mismatch between document and entity\n");
12403: 	}
12404:     }
12405: 
12406:     /*
12407:      * Doing validity checking on chunk doesn't make sense
12408:      */
12409:     ctxt->instate = XML_PARSER_CONTENT;
12410:     ctxt->validate = ctx->validate;
12411:     ctxt->valid = ctx->valid;
12412:     ctxt->loadsubset = ctx->loadsubset;
12413:     ctxt->depth = ctx->depth + 1;
12414:     ctxt->replaceEntities = ctx->replaceEntities;
12415:     if (ctxt->validate) {
12416: 	ctxt->vctxt.error = ctx->vctxt.error;
12417: 	ctxt->vctxt.warning = ctx->vctxt.warning;
12418:     } else {
12419: 	ctxt->vctxt.error = NULL;
12420: 	ctxt->vctxt.warning = NULL;
12421:     }
12422:     ctxt->vctxt.nodeTab = NULL;
12423:     ctxt->vctxt.nodeNr = 0;
12424:     ctxt->vctxt.nodeMax = 0;
12425:     ctxt->vctxt.node = NULL;
12426:     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12427:     ctxt->dict = ctx->dict;
12428:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12429:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12430:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12431:     ctxt->dictNames = ctx->dictNames;
12432:     ctxt->attsDefault = ctx->attsDefault;
12433:     ctxt->attsSpecial = ctx->attsSpecial;
12434:     ctxt->linenumbers = ctx->linenumbers;
12435: 
12436:     xmlParseContent(ctxt);
12437: 
12438:     ctx->validate = ctxt->validate;
12439:     ctx->valid = ctxt->valid;
12440:     if ((RAW == '<') && (NXT(1) == '/')) {
12441: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12442:     } else if (RAW != 0) {
12443: 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12444:     }
12445:     if (ctxt->node != newDoc->children) {
12446: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12447:     }
12448: 
12449:     if (!ctxt->wellFormed) {
12450:         if (ctxt->errNo == 0)
12451: 	    ret = 1;
12452: 	else
12453: 	    ret = ctxt->errNo;
12454:     } else {
12455: 	if (lst != NULL) {
12456: 	    xmlNodePtr cur;
12457: 
12458: 	    /*
12459: 	     * Return the newly created nodeset after unlinking it from
12460: 	     * they pseudo parent.
12461: 	     */
12462: 	    cur = newDoc->children->children;
12463: 	    *lst = cur;
12464: 	    while (cur != NULL) {
12465: 		cur->parent = NULL;
12466: 		cur = cur->next;
12467: 	    }
12468:             newDoc->children->children = NULL;
12469: 	}
12470: 	ret = 0;
12471:     }
12472:     ctxt->sax = oldsax;
12473:     ctxt->dict = NULL;
12474:     ctxt->attsDefault = NULL;
12475:     ctxt->attsSpecial = NULL;
12476:     xmlFreeParserCtxt(ctxt);
12477:     newDoc->intSubset = NULL;
12478:     newDoc->extSubset = NULL;
12479:     xmlFreeDoc(newDoc);
12480: 
12481:     return(ret);
12482: }
12483: 
12484: /**
12485:  * xmlParseExternalEntityPrivate:
12486:  * @doc:  the document the chunk pertains to
12487:  * @oldctxt:  the previous parser context if available
12488:  * @sax:  the SAX handler bloc (possibly NULL)
12489:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12490:  * @depth:  Used for loop detection, use 0
12491:  * @URL:  the URL for the entity to load
12492:  * @ID:  the System ID for the entity to load
12493:  * @list:  the return value for the set of parsed nodes
12494:  *
12495:  * Private version of xmlParseExternalEntity()
12496:  *
12497:  * Returns 0 if the entity is well formed, -1 in case of args problem and
12498:  *    the parser error code otherwise
12499:  */
12500: 
12501: static xmlParserErrors
12502: xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
12503: 	              xmlSAXHandlerPtr sax,
12504: 		      void *user_data, int depth, const xmlChar *URL,
12505: 		      const xmlChar *ID, xmlNodePtr *list) {
12506:     xmlParserCtxtPtr ctxt;
12507:     xmlDocPtr newDoc;
12508:     xmlNodePtr newRoot;
12509:     xmlSAXHandlerPtr oldsax = NULL;
12510:     xmlParserErrors ret = XML_ERR_OK;
12511:     xmlChar start[4];
12512:     xmlCharEncoding enc;
12513: 
12514:     if (((depth > 40) &&
12515: 	((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12516: 	(depth > 1024)) {
12517: 	return(XML_ERR_ENTITY_LOOP);
12518:     }
12519: 
12520:     if (list != NULL)
12521:         *list = NULL;
12522:     if ((URL == NULL) && (ID == NULL))
12523: 	return(XML_ERR_INTERNAL_ERROR);
12524:     if (doc == NULL)
12525: 	return(XML_ERR_INTERNAL_ERROR);
12526: 
12527: 
12528:     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
12529:     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
12530:     ctxt->userData = ctxt;
12531:     if (oldctxt != NULL) {
12532: 	ctxt->_private = oldctxt->_private;
12533: 	ctxt->loadsubset = oldctxt->loadsubset;
12534: 	ctxt->validate = oldctxt->validate;
12535: 	ctxt->external = oldctxt->external;
12536: 	ctxt->record_info = oldctxt->record_info;
12537: 	ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
12538: 	ctxt->node_seq.length = oldctxt->node_seq.length;
12539: 	ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
12540:     } else {
12541: 	/*
12542: 	 * Doing validity checking on chunk without context
12543: 	 * doesn't make sense
12544: 	 */
12545: 	ctxt->_private = NULL;
12546: 	ctxt->validate = 0;
12547: 	ctxt->external = 2;
12548: 	ctxt->loadsubset = 0;
12549:     }
12550:     if (sax != NULL) {
12551: 	oldsax = ctxt->sax;
12552:         ctxt->sax = sax;
12553: 	if (user_data != NULL)
12554: 	    ctxt->userData = user_data;
12555:     }
12556:     xmlDetectSAX2(ctxt);
12557:     newDoc = xmlNewDoc(BAD_CAST "1.0");
12558:     if (newDoc == NULL) {
12559: 	ctxt->node_seq.maximum = 0;
12560: 	ctxt->node_seq.length = 0;
12561: 	ctxt->node_seq.buffer = NULL;
12562: 	xmlFreeParserCtxt(ctxt);
12563: 	return(XML_ERR_INTERNAL_ERROR);
12564:     }
12565:     newDoc->properties = XML_DOC_INTERNAL;
12566:     newDoc->intSubset = doc->intSubset;
12567:     newDoc->extSubset = doc->extSubset;
12568:     newDoc->dict = doc->dict;
12569:     xmlDictReference(newDoc->dict);
12570: 
12571:     if (doc->URL != NULL) {
12572: 	newDoc->URL = xmlStrdup(doc->URL);
12573:     }
12574:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12575:     if (newRoot == NULL) {
12576: 	if (sax != NULL)
12577: 	    ctxt->sax = oldsax;
12578: 	ctxt->node_seq.maximum = 0;
12579: 	ctxt->node_seq.length = 0;
12580: 	ctxt->node_seq.buffer = NULL;
12581: 	xmlFreeParserCtxt(ctxt);
12582: 	newDoc->intSubset = NULL;
12583: 	newDoc->extSubset = NULL;
12584:         xmlFreeDoc(newDoc);
12585: 	return(XML_ERR_INTERNAL_ERROR);
12586:     }
12587:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
12588:     nodePush(ctxt, newDoc->children);
12589:     ctxt->myDoc = doc;
12590:     newRoot->doc = doc;
12591: 
12592:     /*
12593:      * Get the 4 first bytes and decode the charset
12594:      * if enc != XML_CHAR_ENCODING_NONE
12595:      * plug some encoding conversion routines.
12596:      */
12597:     GROW;
12598:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12599: 	start[0] = RAW;
12600: 	start[1] = NXT(1);
12601: 	start[2] = NXT(2);
12602: 	start[3] = NXT(3);
12603: 	enc = xmlDetectCharEncoding(start, 4);
12604: 	if (enc != XML_CHAR_ENCODING_NONE) {
12605: 	    xmlSwitchEncoding(ctxt, enc);
12606: 	}
12607:     }
12608: 
12609:     /*
12610:      * Parse a possible text declaration first
12611:      */
12612:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12613: 	xmlParseTextDecl(ctxt);
12614:     }
12615: 
12616:     ctxt->instate = XML_PARSER_CONTENT;
12617:     ctxt->depth = depth;
12618: 
12619:     xmlParseContent(ctxt);
12620: 
12621:     if ((RAW == '<') && (NXT(1) == '/')) {
12622: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12623:     } else if (RAW != 0) {
12624: 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12625:     }
12626:     if (ctxt->node != newDoc->children) {
12627: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12628:     }
12629: 
12630:     if (!ctxt->wellFormed) {
12631:         if (ctxt->errNo == 0)
12632: 	    ret = XML_ERR_INTERNAL_ERROR;
12633: 	else
12634: 	    ret = (xmlParserErrors)ctxt->errNo;
12635:     } else {
12636: 	if (list != NULL) {
12637: 	    xmlNodePtr cur;
12638: 
12639: 	    /*
12640: 	     * Return the newly created nodeset after unlinking it from
12641: 	     * they pseudo parent.
12642: 	     */
12643: 	    cur = newDoc->children->children;
12644: 	    *list = cur;
12645: 	    while (cur != NULL) {
12646: 		cur->parent = NULL;
12647: 		cur = cur->next;
12648: 	    }
12649:             newDoc->children->children = NULL;
12650: 	}
12651: 	ret = XML_ERR_OK;
12652:     }
12653: 
12654:     /*
12655:      * Record in the parent context the number of entities replacement
12656:      * done when parsing that reference.
12657:      */
12658:     if (oldctxt != NULL)
12659:         oldctxt->nbentities += ctxt->nbentities;
12660: 
12661:     /*
12662:      * Also record the size of the entity parsed
12663:      */
12664:     if (ctxt->input != NULL) {
12665: 	oldctxt->sizeentities += ctxt->input->consumed;
12666: 	oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
12667:     }
12668:     /*
12669:      * And record the last error if any
12670:      */
12671:     if (ctxt->lastError.code != XML_ERR_OK)
12672:         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12673: 
12674:     if (sax != NULL) 
12675: 	ctxt->sax = oldsax;
12676:     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
12677:     oldctxt->node_seq.length = ctxt->node_seq.length;
12678:     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
12679:     ctxt->node_seq.maximum = 0;
12680:     ctxt->node_seq.length = 0;
12681:     ctxt->node_seq.buffer = NULL;
12682:     xmlFreeParserCtxt(ctxt);
12683:     newDoc->intSubset = NULL;
12684:     newDoc->extSubset = NULL;
12685:     xmlFreeDoc(newDoc);
12686: 
12687:     return(ret);
12688: }
12689: 
12690: #ifdef LIBXML_SAX1_ENABLED
12691: /**
12692:  * xmlParseExternalEntity:
12693:  * @doc:  the document the chunk pertains to
12694:  * @sax:  the SAX handler bloc (possibly NULL)
12695:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12696:  * @depth:  Used for loop detection, use 0
12697:  * @URL:  the URL for the entity to load
12698:  * @ID:  the System ID for the entity to load
12699:  * @lst:  the return value for the set of parsed nodes
12700:  *
12701:  * Parse an external general entity
12702:  * An external general parsed entity is well-formed if it matches the
12703:  * production labeled extParsedEnt.
12704:  *
12705:  * [78] extParsedEnt ::= TextDecl? content
12706:  *
12707:  * Returns 0 if the entity is well formed, -1 in case of args problem and
12708:  *    the parser error code otherwise
12709:  */
12710: 
12711: int
12712: xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
12713: 	  int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
12714:     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
12715: 		                       ID, lst));
12716: }
12717: 
12718: /**
12719:  * xmlParseBalancedChunkMemory:
12720:  * @doc:  the document the chunk pertains to
12721:  * @sax:  the SAX handler bloc (possibly NULL)
12722:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12723:  * @depth:  Used for loop detection, use 0
12724:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
12725:  * @lst:  the return value for the set of parsed nodes
12726:  *
12727:  * Parse a well-balanced chunk of an XML document
12728:  * called by the parser
12729:  * The allowed sequence for the Well Balanced Chunk is the one defined by
12730:  * the content production in the XML grammar:
12731:  *
12732:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12733:  *
12734:  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
12735:  *    the parser error code otherwise
12736:  */
12737: 
12738: int
12739: xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
12740:      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
12741:     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
12742:                                                 depth, string, lst, 0 );
12743: }
12744: #endif /* LIBXML_SAX1_ENABLED */
12745: 
12746: /**
12747:  * xmlParseBalancedChunkMemoryInternal:
12748:  * @oldctxt:  the existing parsing context
12749:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
12750:  * @user_data:  the user data field for the parser context
12751:  * @lst:  the return value for the set of parsed nodes
12752:  *
12753:  *
12754:  * Parse a well-balanced chunk of an XML document
12755:  * called by the parser
12756:  * The allowed sequence for the Well Balanced Chunk is the one defined by
12757:  * the content production in the XML grammar:
12758:  *
12759:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12760:  *
12761:  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
12762:  * error code otherwise
12763:  *
12764:  * In case recover is set to 1, the nodelist will not be empty even if
12765:  * the parsed chunk is not well balanced.
12766:  */
12767: static xmlParserErrors
12768: xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
12769: 	const xmlChar *string, void *user_data, xmlNodePtr *lst) {
12770:     xmlParserCtxtPtr ctxt;
12771:     xmlDocPtr newDoc = NULL;
12772:     xmlNodePtr newRoot;
12773:     xmlSAXHandlerPtr oldsax = NULL;
12774:     xmlNodePtr content = NULL;
12775:     xmlNodePtr last = NULL;
12776:     int size;
12777:     xmlParserErrors ret = XML_ERR_OK;
12778: #ifdef SAX2
12779:     int i;
12780: #endif
12781: 
12782:     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12783:         (oldctxt->depth >  1024)) {
12784: 	return(XML_ERR_ENTITY_LOOP);
12785:     }
12786: 
12787: 
12788:     if (lst != NULL)
12789:         *lst = NULL;
12790:     if (string == NULL)
12791:         return(XML_ERR_INTERNAL_ERROR);
12792: 
12793:     size = xmlStrlen(string);
12794: 
12795:     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
12796:     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
12797:     if (user_data != NULL)
12798: 	ctxt->userData = user_data;
12799:     else
12800: 	ctxt->userData = ctxt;
12801:     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12802:     ctxt->dict = oldctxt->dict;
12803:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12804:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12805:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12806: 
12807: #ifdef SAX2
12808:     /* propagate namespaces down the entity */
12809:     for (i = 0;i < oldctxt->nsNr;i += 2) {
12810:         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
12811:     }
12812: #endif
12813: 
12814:     oldsax = ctxt->sax;
12815:     ctxt->sax = oldctxt->sax;
12816:     xmlDetectSAX2(ctxt);
12817:     ctxt->replaceEntities = oldctxt->replaceEntities;
12818:     ctxt->options = oldctxt->options;
12819: 
12820:     ctxt->_private = oldctxt->_private;
12821:     if (oldctxt->myDoc == NULL) {
12822: 	newDoc = xmlNewDoc(BAD_CAST "1.0");
12823: 	if (newDoc == NULL) {
12824: 	    ctxt->sax = oldsax;
12825: 	    ctxt->dict = NULL;
12826: 	    xmlFreeParserCtxt(ctxt);
12827: 	    return(XML_ERR_INTERNAL_ERROR);
12828: 	}
12829: 	newDoc->properties = XML_DOC_INTERNAL;
12830: 	newDoc->dict = ctxt->dict;
12831: 	xmlDictReference(newDoc->dict);
12832: 	ctxt->myDoc = newDoc;
12833:     } else {
12834: 	ctxt->myDoc = oldctxt->myDoc;
12835:         content = ctxt->myDoc->children;
12836: 	last = ctxt->myDoc->last;
12837:     }
12838:     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
12839:     if (newRoot == NULL) {
12840: 	ctxt->sax = oldsax;
12841: 	ctxt->dict = NULL;
12842: 	xmlFreeParserCtxt(ctxt);
12843: 	if (newDoc != NULL) {
12844: 	    xmlFreeDoc(newDoc);
12845: 	}
12846: 	return(XML_ERR_INTERNAL_ERROR);
12847:     }
12848:     ctxt->myDoc->children = NULL;
12849:     ctxt->myDoc->last = NULL;
12850:     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
12851:     nodePush(ctxt, ctxt->myDoc->children);
12852:     ctxt->instate = XML_PARSER_CONTENT;
12853:     ctxt->depth = oldctxt->depth + 1;
12854: 
12855:     ctxt->validate = 0;
12856:     ctxt->loadsubset = oldctxt->loadsubset;
12857:     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
12858: 	/*
12859: 	 * ID/IDREF registration will be done in xmlValidateElement below
12860: 	 */
12861: 	ctxt->loadsubset |= XML_SKIP_IDS;
12862:     }
12863:     ctxt->dictNames = oldctxt->dictNames;
12864:     ctxt->attsDefault = oldctxt->attsDefault;
12865:     ctxt->attsSpecial = oldctxt->attsSpecial;
12866: 
12867:     xmlParseContent(ctxt);
12868:     if ((RAW == '<') && (NXT(1) == '/')) {
12869: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12870:     } else if (RAW != 0) {
12871: 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12872:     }
12873:     if (ctxt->node != ctxt->myDoc->children) {
12874: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12875:     }
12876: 
12877:     if (!ctxt->wellFormed) {
12878:         if (ctxt->errNo == 0)
12879: 	    ret = XML_ERR_INTERNAL_ERROR;
12880: 	else
12881: 	    ret = (xmlParserErrors)ctxt->errNo;
12882:     } else {
12883:       ret = XML_ERR_OK;
12884:     }
12885: 
12886:     if ((lst != NULL) && (ret == XML_ERR_OK)) {
12887: 	xmlNodePtr cur;
12888: 
12889: 	/*
12890: 	 * Return the newly created nodeset after unlinking it from
12891: 	 * they pseudo parent.
12892: 	 */
12893: 	cur = ctxt->myDoc->children->children;
12894: 	*lst = cur;
12895: 	while (cur != NULL) {
12896: #ifdef LIBXML_VALID_ENABLED
12897: 	    if ((oldctxt->validate) && (oldctxt->wellFormed) &&
12898: 		(oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
12899: 		(cur->type == XML_ELEMENT_NODE)) {
12900: 		oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
12901: 			oldctxt->myDoc, cur);
12902: 	    }
12903: #endif /* LIBXML_VALID_ENABLED */
12904: 	    cur->parent = NULL;
12905: 	    cur = cur->next;
12906: 	}
12907: 	ctxt->myDoc->children->children = NULL;
12908:     }
12909:     if (ctxt->myDoc != NULL) {
12910: 	xmlFreeNode(ctxt->myDoc->children);
12911:         ctxt->myDoc->children = content;
12912:         ctxt->myDoc->last = last;
12913:     }
12914: 
12915:     /*
12916:      * Record in the parent context the number of entities replacement
12917:      * done when parsing that reference.
12918:      */
12919:     if (oldctxt != NULL)
12920:         oldctxt->nbentities += ctxt->nbentities;
12921: 
12922:     /*
12923:      * Also record the last error if any
12924:      */
12925:     if (ctxt->lastError.code != XML_ERR_OK)
12926:         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12927: 
12928:     ctxt->sax = oldsax;
12929:     ctxt->dict = NULL;
12930:     ctxt->attsDefault = NULL;
12931:     ctxt->attsSpecial = NULL;
12932:     xmlFreeParserCtxt(ctxt);
12933:     if (newDoc != NULL) {
12934: 	xmlFreeDoc(newDoc);
12935:     }
12936: 
12937:     return(ret);
12938: }
12939: 
12940: /**
12941:  * xmlParseInNodeContext:
12942:  * @node:  the context node
12943:  * @data:  the input string
12944:  * @datalen:  the input string length in bytes
12945:  * @options:  a combination of xmlParserOption
12946:  * @lst:  the return value for the set of parsed nodes
12947:  *
12948:  * Parse a well-balanced chunk of an XML document
12949:  * within the context (DTD, namespaces, etc ...) of the given node.
12950:  *
12951:  * The allowed sequence for the data is a Well Balanced Chunk defined by
12952:  * the content production in the XML grammar:
12953:  *
12954:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12955:  *
12956:  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
12957:  * error code otherwise
12958:  */
12959: xmlParserErrors
12960: xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
12961:                       int options, xmlNodePtr *lst) {
12962: #ifdef SAX2
12963:     xmlParserCtxtPtr ctxt;
12964:     xmlDocPtr doc = NULL;
12965:     xmlNodePtr fake, cur;
12966:     int nsnr = 0;
12967: 
12968:     xmlParserErrors ret = XML_ERR_OK;
12969: 
12970:     /*
12971:      * check all input parameters, grab the document
12972:      */
12973:     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
12974:         return(XML_ERR_INTERNAL_ERROR);
12975:     switch (node->type) {
12976:         case XML_ELEMENT_NODE:
12977:         case XML_ATTRIBUTE_NODE:
12978:         case XML_TEXT_NODE:
12979:         case XML_CDATA_SECTION_NODE:
12980:         case XML_ENTITY_REF_NODE:
12981:         case XML_PI_NODE:
12982:         case XML_COMMENT_NODE:
12983:         case XML_DOCUMENT_NODE:
12984:         case XML_HTML_DOCUMENT_NODE:
12985: 	    break;
12986: 	default:
12987: 	    return(XML_ERR_INTERNAL_ERROR);
12988: 
12989:     }
12990:     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
12991:            (node->type != XML_DOCUMENT_NODE) &&
12992: 	   (node->type != XML_HTML_DOCUMENT_NODE))
12993: 	node = node->parent;
12994:     if (node == NULL)
12995: 	return(XML_ERR_INTERNAL_ERROR);
12996:     if (node->type == XML_ELEMENT_NODE)
12997: 	doc = node->doc;
12998:     else
12999:         doc = (xmlDocPtr) node;
13000:     if (doc == NULL)
13001: 	return(XML_ERR_INTERNAL_ERROR);
13002: 
13003:     /*
13004:      * allocate a context and set-up everything not related to the
13005:      * node position in the tree
13006:      */
13007:     if (doc->type == XML_DOCUMENT_NODE)
13008: 	ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13009: #ifdef LIBXML_HTML_ENABLED
13010:     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13011: 	ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13012:         /*
13013:          * When parsing in context, it makes no sense to add implied
13014:          * elements like html/body/etc...
13015:          */
13016:         options |= HTML_PARSE_NOIMPLIED;
13017:     }
13018: #endif
13019:     else
13020:         return(XML_ERR_INTERNAL_ERROR);
13021: 
13022:     if (ctxt == NULL)
13023:         return(XML_ERR_NO_MEMORY);
13024: 
13025:     /*
13026:      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13027:      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13028:      * we must wait until the last moment to free the original one.
13029:      */
13030:     if (doc->dict != NULL) {
13031:         if (ctxt->dict != NULL)
13032: 	    xmlDictFree(ctxt->dict);
13033: 	ctxt->dict = doc->dict;
13034:     } else
13035:         options |= XML_PARSE_NODICT;
13036: 
13037:     if (doc->encoding != NULL) {
13038:         xmlCharEncodingHandlerPtr hdlr;
13039: 
13040:         if (ctxt->encoding != NULL)
13041: 	    xmlFree((xmlChar *) ctxt->encoding);
13042:         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13043: 
13044:         hdlr = xmlFindCharEncodingHandler(doc->encoding);
13045:         if (hdlr != NULL) {
13046:             xmlSwitchToEncoding(ctxt, hdlr);
13047: 	} else {
13048:             return(XML_ERR_UNSUPPORTED_ENCODING);
13049:         }
13050:     }
13051: 
13052:     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13053:     xmlDetectSAX2(ctxt);
13054:     ctxt->myDoc = doc;
13055: 
13056:     fake = xmlNewComment(NULL);
13057:     if (fake == NULL) {
13058:         xmlFreeParserCtxt(ctxt);
13059: 	return(XML_ERR_NO_MEMORY);
13060:     }
13061:     xmlAddChild(node, fake);
13062: 
13063:     if (node->type == XML_ELEMENT_NODE) {
13064: 	nodePush(ctxt, node);
13065: 	/*
13066: 	 * initialize the SAX2 namespaces stack
13067: 	 */
13068: 	cur = node;
13069: 	while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13070: 	    xmlNsPtr ns = cur->nsDef;
13071: 	    const xmlChar *iprefix, *ihref;
13072: 
13073: 	    while (ns != NULL) {
13074: 		if (ctxt->dict) {
13075: 		    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13076: 		    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13077: 		} else {
13078: 		    iprefix = ns->prefix;
13079: 		    ihref = ns->href;
13080: 		}
13081: 
13082: 	        if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13083: 		    nsPush(ctxt, iprefix, ihref);
13084: 		    nsnr++;
13085: 		}
13086: 		ns = ns->next;
13087: 	    }
13088: 	    cur = cur->parent;
13089: 	}
13090: 	ctxt->instate = XML_PARSER_CONTENT;
13091:     }
13092: 
13093:     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13094: 	/*
13095: 	 * ID/IDREF registration will be done in xmlValidateElement below
13096: 	 */
13097: 	ctxt->loadsubset |= XML_SKIP_IDS;
13098:     }
13099: 
13100: #ifdef LIBXML_HTML_ENABLED
13101:     if (doc->type == XML_HTML_DOCUMENT_NODE)
13102:         __htmlParseContent(ctxt);
13103:     else
13104: #endif
13105: 	xmlParseContent(ctxt);
13106: 
13107:     nsPop(ctxt, nsnr);
13108:     if ((RAW == '<') && (NXT(1) == '/')) {
13109: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13110:     } else if (RAW != 0) {
13111: 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13112:     }
13113:     if ((ctxt->node != NULL) && (ctxt->node != node)) {
13114: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13115: 	ctxt->wellFormed = 0;
13116:     }
13117: 
13118:     if (!ctxt->wellFormed) {
13119:         if (ctxt->errNo == 0)
13120: 	    ret = XML_ERR_INTERNAL_ERROR;
13121: 	else
13122: 	    ret = (xmlParserErrors)ctxt->errNo;
13123:     } else {
13124:         ret = XML_ERR_OK;
13125:     }
13126: 
13127:     /*
13128:      * Return the newly created nodeset after unlinking it from
13129:      * the pseudo sibling.
13130:      */
13131: 
13132:     cur = fake->next;
13133:     fake->next = NULL;
13134:     node->last = fake;
13135: 
13136:     if (cur != NULL) {
13137: 	cur->prev = NULL;
13138:     }
13139: 
13140:     *lst = cur;
13141: 
13142:     while (cur != NULL) {
13143: 	cur->parent = NULL;
13144: 	cur = cur->next;
13145:     }
13146: 
13147:     xmlUnlinkNode(fake);
13148:     xmlFreeNode(fake);
13149: 
13150: 
13151:     if (ret != XML_ERR_OK) {
13152:         xmlFreeNodeList(*lst);
13153: 	*lst = NULL;
13154:     }
13155: 
13156:     if (doc->dict != NULL)
13157:         ctxt->dict = NULL;
13158:     xmlFreeParserCtxt(ctxt);
13159: 
13160:     return(ret);
13161: #else /* !SAX2 */
13162:     return(XML_ERR_INTERNAL_ERROR);
13163: #endif
13164: }
13165: 
13166: #ifdef LIBXML_SAX1_ENABLED
13167: /**
13168:  * xmlParseBalancedChunkMemoryRecover:
13169:  * @doc:  the document the chunk pertains to
13170:  * @sax:  the SAX handler bloc (possibly NULL)
13171:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13172:  * @depth:  Used for loop detection, use 0
13173:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13174:  * @lst:  the return value for the set of parsed nodes
13175:  * @recover: return nodes even if the data is broken (use 0)
13176:  *
13177:  *
13178:  * Parse a well-balanced chunk of an XML document
13179:  * called by the parser
13180:  * The allowed sequence for the Well Balanced Chunk is the one defined by
13181:  * the content production in the XML grammar:
13182:  *
13183:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13184:  *
13185:  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13186:  *    the parser error code otherwise
13187:  *
13188:  * In case recover is set to 1, the nodelist will not be empty even if
13189:  * the parsed chunk is not well balanced, assuming the parsing succeeded to
13190:  * some extent.
13191:  */
13192: int
13193: xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13194:      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13195:      int recover) {
13196:     xmlParserCtxtPtr ctxt;
13197:     xmlDocPtr newDoc;
13198:     xmlSAXHandlerPtr oldsax = NULL;
13199:     xmlNodePtr content, newRoot;
13200:     int size;
13201:     int ret = 0;
13202: 
13203:     if (depth > 40) {
13204: 	return(XML_ERR_ENTITY_LOOP);
13205:     }
13206: 
13207: 
13208:     if (lst != NULL)
13209:         *lst = NULL;
13210:     if (string == NULL)
13211:         return(-1);
13212: 
13213:     size = xmlStrlen(string);
13214: 
13215:     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13216:     if (ctxt == NULL) return(-1);
13217:     ctxt->userData = ctxt;
13218:     if (sax != NULL) {
13219: 	oldsax = ctxt->sax;
13220:         ctxt->sax = sax;
13221: 	if (user_data != NULL)
13222: 	    ctxt->userData = user_data;
13223:     }
13224:     newDoc = xmlNewDoc(BAD_CAST "1.0");
13225:     if (newDoc == NULL) {
13226: 	xmlFreeParserCtxt(ctxt);
13227: 	return(-1);
13228:     }
13229:     newDoc->properties = XML_DOC_INTERNAL;
13230:     if ((doc != NULL) && (doc->dict != NULL)) {
13231:         xmlDictFree(ctxt->dict);
13232: 	ctxt->dict = doc->dict;
13233: 	xmlDictReference(ctxt->dict);
13234: 	ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13235: 	ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13236: 	ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13237: 	ctxt->dictNames = 1;
13238:     } else {
13239: 	xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13240:     }
13241:     if (doc != NULL) {
13242: 	newDoc->intSubset = doc->intSubset;
13243: 	newDoc->extSubset = doc->extSubset;
13244:     }
13245:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13246:     if (newRoot == NULL) {
13247: 	if (sax != NULL)
13248: 	    ctxt->sax = oldsax;
13249: 	xmlFreeParserCtxt(ctxt);
13250: 	newDoc->intSubset = NULL;
13251: 	newDoc->extSubset = NULL;
13252:         xmlFreeDoc(newDoc);
13253: 	return(-1);
13254:     }
13255:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
13256:     nodePush(ctxt, newRoot);
13257:     if (doc == NULL) {
13258: 	ctxt->myDoc = newDoc;
13259:     } else {
13260: 	ctxt->myDoc = newDoc;
13261: 	newDoc->children->doc = doc;
13262: 	/* Ensure that doc has XML spec namespace */
13263: 	xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13264: 	newDoc->oldNs = doc->oldNs;
13265:     }
13266:     ctxt->instate = XML_PARSER_CONTENT;
13267:     ctxt->depth = depth;
13268: 
13269:     /*
13270:      * Doing validity checking on chunk doesn't make sense
13271:      */
13272:     ctxt->validate = 0;
13273:     ctxt->loadsubset = 0;
13274:     xmlDetectSAX2(ctxt);
13275: 
13276:     if ( doc != NULL ){
13277:         content = doc->children;
13278:         doc->children = NULL;
13279:         xmlParseContent(ctxt);
13280:         doc->children = content;
13281:     }
13282:     else {
13283:         xmlParseContent(ctxt);
13284:     }
13285:     if ((RAW == '<') && (NXT(1) == '/')) {
13286: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13287:     } else if (RAW != 0) {
13288: 	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13289:     }
13290:     if (ctxt->node != newDoc->children) {
13291: 	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13292:     }
13293: 
13294:     if (!ctxt->wellFormed) {
13295:         if (ctxt->errNo == 0)
13296: 	    ret = 1;
13297: 	else
13298: 	    ret = ctxt->errNo;
13299:     } else {
13300:       ret = 0;
13301:     }
13302: 
13303:     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13304: 	xmlNodePtr cur;
13305: 
13306: 	/*
13307: 	 * Return the newly created nodeset after unlinking it from
13308: 	 * they pseudo parent.
13309: 	 */
13310: 	cur = newDoc->children->children;
13311: 	*lst = cur;
13312: 	while (cur != NULL) {
13313: 	    xmlSetTreeDoc(cur, doc);
13314: 	    cur->parent = NULL;
13315: 	    cur = cur->next;
13316: 	}
13317: 	newDoc->children->children = NULL;
13318:     }
13319: 
13320:     if (sax != NULL)
13321: 	ctxt->sax = oldsax;
13322:     xmlFreeParserCtxt(ctxt);
13323:     newDoc->intSubset = NULL;
13324:     newDoc->extSubset = NULL;
13325:     newDoc->oldNs = NULL;
13326:     xmlFreeDoc(newDoc);
13327: 
13328:     return(ret);
13329: }
13330: 
13331: /**
13332:  * xmlSAXParseEntity:
13333:  * @sax:  the SAX handler block
13334:  * @filename:  the filename
13335:  *
13336:  * parse an XML external entity out of context and build a tree.
13337:  * It use the given SAX function block to handle the parsing callback.
13338:  * If sax is NULL, fallback to the default DOM tree building routines.
13339:  *
13340:  * [78] extParsedEnt ::= TextDecl? content
13341:  *
13342:  * This correspond to a "Well Balanced" chunk
13343:  *
13344:  * Returns the resulting document tree
13345:  */
13346: 
13347: xmlDocPtr
13348: xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13349:     xmlDocPtr ret;
13350:     xmlParserCtxtPtr ctxt;
13351: 
13352:     ctxt = xmlCreateFileParserCtxt(filename);
13353:     if (ctxt == NULL) {
13354: 	return(NULL);
13355:     }
13356:     if (sax != NULL) {
13357: 	if (ctxt->sax != NULL)
13358: 	    xmlFree(ctxt->sax);
13359:         ctxt->sax = sax;
13360:         ctxt->userData = NULL;
13361:     }
13362: 
13363:     xmlParseExtParsedEnt(ctxt);
13364: 
13365:     if (ctxt->wellFormed)
13366: 	ret = ctxt->myDoc;
13367:     else {
13368:         ret = NULL;
13369:         xmlFreeDoc(ctxt->myDoc);
13370:         ctxt->myDoc = NULL;
13371:     }
13372:     if (sax != NULL)
13373:         ctxt->sax = NULL;
13374:     xmlFreeParserCtxt(ctxt);
13375: 
13376:     return(ret);
13377: }
13378: 
13379: /**
13380:  * xmlParseEntity:
13381:  * @filename:  the filename
13382:  *
13383:  * parse an XML external entity out of context and build a tree.
13384:  *
13385:  * [78] extParsedEnt ::= TextDecl? content
13386:  *
13387:  * This correspond to a "Well Balanced" chunk
13388:  *
13389:  * Returns the resulting document tree
13390:  */
13391: 
13392: xmlDocPtr
13393: xmlParseEntity(const char *filename) {
13394:     return(xmlSAXParseEntity(NULL, filename));
13395: }
13396: #endif /* LIBXML_SAX1_ENABLED */
13397: 
13398: /**
13399:  * xmlCreateEntityParserCtxtInternal:
13400:  * @URL:  the entity URL
13401:  * @ID:  the entity PUBLIC ID
13402:  * @base:  a possible base for the target URI
13403:  * @pctx:  parser context used to set options on new context
13404:  *
13405:  * Create a parser context for an external entity
13406:  * Automatic support for ZLIB/Compress compressed document is provided
13407:  * by default if found at compile-time.
13408:  *
13409:  * Returns the new parser context or NULL
13410:  */
13411: static xmlParserCtxtPtr
13412: xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
13413: 	                  const xmlChar *base, xmlParserCtxtPtr pctx) {
13414:     xmlParserCtxtPtr ctxt;
13415:     xmlParserInputPtr inputStream;
13416:     char *directory = NULL;
13417:     xmlChar *uri;
13418: 
13419:     ctxt = xmlNewParserCtxt();
13420:     if (ctxt == NULL) {
13421: 	return(NULL);
13422:     }
13423: 
13424:     if (pctx != NULL) {
13425:         ctxt->options = pctx->options;
13426:         ctxt->_private = pctx->_private;
13427:     }
13428: 
13429:     uri = xmlBuildURI(URL, base);
13430: 
13431:     if (uri == NULL) {
13432: 	inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
13433: 	if (inputStream == NULL) {
13434: 	    xmlFreeParserCtxt(ctxt);
13435: 	    return(NULL);
13436: 	}
13437: 
13438: 	inputPush(ctxt, inputStream);
13439: 
13440: 	if ((ctxt->directory == NULL) && (directory == NULL))
13441: 	    directory = xmlParserGetDirectory((char *)URL);
13442: 	if ((ctxt->directory == NULL) && (directory != NULL))
13443: 	    ctxt->directory = directory;
13444:     } else {
13445: 	inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
13446: 	if (inputStream == NULL) {
13447: 	    xmlFree(uri);
13448: 	    xmlFreeParserCtxt(ctxt);
13449: 	    return(NULL);
13450: 	}
13451: 
13452: 	inputPush(ctxt, inputStream);
13453: 
13454: 	if ((ctxt->directory == NULL) && (directory == NULL))
13455: 	    directory = xmlParserGetDirectory((char *)uri);
13456: 	if ((ctxt->directory == NULL) && (directory != NULL))
13457: 	    ctxt->directory = directory;
13458: 	xmlFree(uri);
13459:     }
13460:     return(ctxt);
13461: }
13462: 
13463: /**
13464:  * xmlCreateEntityParserCtxt:
13465:  * @URL:  the entity URL
13466:  * @ID:  the entity PUBLIC ID
13467:  * @base:  a possible base for the target URI
13468:  *
13469:  * Create a parser context for an external entity
13470:  * Automatic support for ZLIB/Compress compressed document is provided
13471:  * by default if found at compile-time.
13472:  *
13473:  * Returns the new parser context or NULL
13474:  */
13475: xmlParserCtxtPtr
13476: xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
13477: 	                  const xmlChar *base) {
13478:     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
13479: 
13480: }
13481: 
13482: /************************************************************************
13483:  *									*
13484:  *		Front ends when parsing from a file			*
13485:  *									*
13486:  ************************************************************************/
13487: 
13488: /**
13489:  * xmlCreateURLParserCtxt:
13490:  * @filename:  the filename or URL
13491:  * @options:  a combination of xmlParserOption
13492:  *
13493:  * Create a parser context for a file or URL content. 
13494:  * Automatic support for ZLIB/Compress compressed document is provided
13495:  * by default if found at compile-time and for file accesses
13496:  *
13497:  * Returns the new parser context or NULL
13498:  */
13499: xmlParserCtxtPtr
13500: xmlCreateURLParserCtxt(const char *filename, int options)
13501: {
13502:     xmlParserCtxtPtr ctxt;
13503:     xmlParserInputPtr inputStream;
13504:     char *directory = NULL;
13505: 
13506:     ctxt = xmlNewParserCtxt();
13507:     if (ctxt == NULL) {
13508: 	xmlErrMemory(NULL, "cannot allocate parser context");
13509: 	return(NULL);
13510:     }
13511: 
13512:     if (options)
13513: 	xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13514:     ctxt->linenumbers = 1;
13515: 
13516:     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
13517:     if (inputStream == NULL) {
13518: 	xmlFreeParserCtxt(ctxt);
13519: 	return(NULL);
13520:     }
13521: 
13522:     inputPush(ctxt, inputStream);
13523:     if ((ctxt->directory == NULL) && (directory == NULL))
13524:         directory = xmlParserGetDirectory(filename);
13525:     if ((ctxt->directory == NULL) && (directory != NULL))
13526:         ctxt->directory = directory;
13527: 
13528:     return(ctxt);
13529: }
13530: 
13531: /**
13532:  * xmlCreateFileParserCtxt:
13533:  * @filename:  the filename
13534:  *
13535:  * Create a parser context for a file content. 
13536:  * Automatic support for ZLIB/Compress compressed document is provided
13537:  * by default if found at compile-time.
13538:  *
13539:  * Returns the new parser context or NULL
13540:  */
13541: xmlParserCtxtPtr
13542: xmlCreateFileParserCtxt(const char *filename)
13543: {
13544:     return(xmlCreateURLParserCtxt(filename, 0));
13545: }
13546: 
13547: #ifdef LIBXML_SAX1_ENABLED
13548: /**
13549:  * xmlSAXParseFileWithData:
13550:  * @sax:  the SAX handler block
13551:  * @filename:  the filename
13552:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13553:  *             documents
13554:  * @data:  the userdata
13555:  *
13556:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13557:  * compressed document is provided by default if found at compile-time.
13558:  * It use the given SAX function block to handle the parsing callback.
13559:  * If sax is NULL, fallback to the default DOM tree building routines.
13560:  *
13561:  * User data (void *) is stored within the parser context in the
13562:  * context's _private member, so it is available nearly everywhere in libxml
13563:  *
13564:  * Returns the resulting document tree
13565:  */
13566: 
13567: xmlDocPtr
13568: xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
13569:                         int recovery, void *data) {
13570:     xmlDocPtr ret;
13571:     xmlParserCtxtPtr ctxt;
13572: 
13573:     xmlInitParser();
13574: 
13575:     ctxt = xmlCreateFileParserCtxt(filename);
13576:     if (ctxt == NULL) {
13577: 	return(NULL);
13578:     }
13579:     if (sax != NULL) {
13580: 	if (ctxt->sax != NULL)
13581: 	    xmlFree(ctxt->sax);
13582:         ctxt->sax = sax;
13583:     }
13584:     xmlDetectSAX2(ctxt);
13585:     if (data!=NULL) {
13586: 	ctxt->_private = data;
13587:     }
13588: 
13589:     if (ctxt->directory == NULL)
13590:         ctxt->directory = xmlParserGetDirectory(filename);
13591: 
13592:     ctxt->recovery = recovery;
13593: 
13594:     xmlParseDocument(ctxt);
13595: 
13596:     if ((ctxt->wellFormed) || recovery) {
13597:         ret = ctxt->myDoc;
13598: 	if (ret != NULL) {
13599: 	    if (ctxt->input->buf->compressed > 0)
13600: 		ret->compression = 9;
13601: 	    else
13602: 		ret->compression = ctxt->input->buf->compressed;
13603: 	}
13604:     }
13605:     else {
13606:        ret = NULL;
13607:        xmlFreeDoc(ctxt->myDoc);
13608:        ctxt->myDoc = NULL;
13609:     }
13610:     if (sax != NULL)
13611:         ctxt->sax = NULL;
13612:     xmlFreeParserCtxt(ctxt);
13613:     
13614:     return(ret);
13615: }
13616: 
13617: /**
13618:  * xmlSAXParseFile:
13619:  * @sax:  the SAX handler block
13620:  * @filename:  the filename
13621:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13622:  *             documents
13623:  *
13624:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13625:  * compressed document is provided by default if found at compile-time.
13626:  * It use the given SAX function block to handle the parsing callback.
13627:  * If sax is NULL, fallback to the default DOM tree building routines.
13628:  *
13629:  * Returns the resulting document tree
13630:  */
13631: 
13632: xmlDocPtr
13633: xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
13634:                           int recovery) {
13635:     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
13636: }
13637: 
13638: /**
13639:  * xmlRecoverDoc:
13640:  * @cur:  a pointer to an array of xmlChar
13641:  *
13642:  * parse an XML in-memory document and build a tree.
13643:  * In the case the document is not Well Formed, a attempt to build a
13644:  * tree is tried anyway
13645:  *
13646:  * Returns the resulting document tree or NULL in case of failure
13647:  */
13648: 
13649: xmlDocPtr
13650: xmlRecoverDoc(const xmlChar *cur) {
13651:     return(xmlSAXParseDoc(NULL, cur, 1));
13652: }
13653: 
13654: /**
13655:  * xmlParseFile:
13656:  * @filename:  the filename
13657:  *
13658:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13659:  * compressed document is provided by default if found at compile-time.
13660:  *
13661:  * Returns the resulting document tree if the file was wellformed,
13662:  * NULL otherwise.
13663:  */
13664: 
13665: xmlDocPtr
13666: xmlParseFile(const char *filename) {
13667:     return(xmlSAXParseFile(NULL, filename, 0));
13668: }
13669: 
13670: /**
13671:  * xmlRecoverFile:
13672:  * @filename:  the filename
13673:  *
13674:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13675:  * compressed document is provided by default if found at compile-time.
13676:  * In the case the document is not Well Formed, it attempts to build
13677:  * a tree anyway
13678:  *
13679:  * Returns the resulting document tree or NULL in case of failure
13680:  */
13681: 
13682: xmlDocPtr
13683: xmlRecoverFile(const char *filename) {
13684:     return(xmlSAXParseFile(NULL, filename, 1));
13685: }
13686: 
13687: 
13688: /**
13689:  * xmlSetupParserForBuffer:
13690:  * @ctxt:  an XML parser context
13691:  * @buffer:  a xmlChar * buffer
13692:  * @filename:  a file name
13693:  *
13694:  * Setup the parser context to parse a new buffer; Clears any prior
13695:  * contents from the parser context. The buffer parameter must not be
13696:  * NULL, but the filename parameter can be
13697:  */
13698: void
13699: xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
13700:                              const char* filename)
13701: {
13702:     xmlParserInputPtr input;
13703: 
13704:     if ((ctxt == NULL) || (buffer == NULL))
13705:         return;
13706: 
13707:     input = xmlNewInputStream(ctxt);
13708:     if (input == NULL) {
13709:         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
13710:         xmlClearParserCtxt(ctxt);
13711:         return;
13712:     }
13713:   
13714:     xmlClearParserCtxt(ctxt);
13715:     if (filename != NULL)
13716:         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
13717:     input->base = buffer;
13718:     input->cur = buffer;
13719:     input->end = &buffer[xmlStrlen(buffer)];
13720:     inputPush(ctxt, input);
13721: }
13722: 
13723: /**
13724:  * xmlSAXUserParseFile:
13725:  * @sax:  a SAX handler
13726:  * @user_data:  The user data returned on SAX callbacks
13727:  * @filename:  a file name
13728:  *
13729:  * parse an XML file and call the given SAX handler routines.
13730:  * Automatic support for ZLIB/Compress compressed document is provided
13731:  * 
13732:  * Returns 0 in case of success or a error number otherwise
13733:  */
13734: int
13735: xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
13736:                     const char *filename) {
13737:     int ret = 0;
13738:     xmlParserCtxtPtr ctxt;
13739:     
13740:     ctxt = xmlCreateFileParserCtxt(filename);
13741:     if (ctxt == NULL) return -1;
13742:     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
13743: 	xmlFree(ctxt->sax);
13744:     ctxt->sax = sax;
13745:     xmlDetectSAX2(ctxt);
13746: 
13747:     if (user_data != NULL)
13748: 	ctxt->userData = user_data;
13749:     
13750:     xmlParseDocument(ctxt);
13751:     
13752:     if (ctxt->wellFormed)
13753: 	ret = 0;
13754:     else {
13755:         if (ctxt->errNo != 0)
13756: 	    ret = ctxt->errNo;
13757: 	else
13758: 	    ret = -1;
13759:     }
13760:     if (sax != NULL)
13761: 	ctxt->sax = NULL;
13762:     if (ctxt->myDoc != NULL) {
13763:         xmlFreeDoc(ctxt->myDoc);
13764: 	ctxt->myDoc = NULL;
13765:     }
13766:     xmlFreeParserCtxt(ctxt);
13767:     
13768:     return ret;
13769: }
13770: #endif /* LIBXML_SAX1_ENABLED */
13771: 
13772: /************************************************************************
13773:  *									*
13774:  * 		Front ends when parsing from memory			*
13775:  *									*
13776:  ************************************************************************/
13777: 
13778: /**
13779:  * xmlCreateMemoryParserCtxt:
13780:  * @buffer:  a pointer to a char array
13781:  * @size:  the size of the array
13782:  *
13783:  * Create a parser context for an XML in-memory document.
13784:  *
13785:  * Returns the new parser context or NULL
13786:  */
13787: xmlParserCtxtPtr
13788: xmlCreateMemoryParserCtxt(const char *buffer, int size) {
13789:     xmlParserCtxtPtr ctxt;
13790:     xmlParserInputPtr input;
13791:     xmlParserInputBufferPtr buf;
13792: 
13793:     if (buffer == NULL)
13794: 	return(NULL);
13795:     if (size <= 0)
13796: 	return(NULL);
13797: 
13798:     ctxt = xmlNewParserCtxt();
13799:     if (ctxt == NULL)
13800: 	return(NULL);
13801: 
13802:     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
13803:     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
13804:     if (buf == NULL) {
13805: 	xmlFreeParserCtxt(ctxt);
13806: 	return(NULL);
13807:     }
13808: 
13809:     input = xmlNewInputStream(ctxt);
13810:     if (input == NULL) {
13811: 	xmlFreeParserInputBuffer(buf);
13812: 	xmlFreeParserCtxt(ctxt);
13813: 	return(NULL);
13814:     }
13815: 
13816:     input->filename = NULL;
13817:     input->buf = buf;
13818:     input->base = input->buf->buffer->content;
13819:     input->cur = input->buf->buffer->content;
13820:     input->end = &input->buf->buffer->content[input->buf->buffer->use];
13821: 
13822:     inputPush(ctxt, input);
13823:     return(ctxt);
13824: }
13825: 
13826: #ifdef LIBXML_SAX1_ENABLED
13827: /**
13828:  * xmlSAXParseMemoryWithData:
13829:  * @sax:  the SAX handler block
13830:  * @buffer:  an pointer to a char array
13831:  * @size:  the size of the array
13832:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13833:  *             documents
13834:  * @data:  the userdata
13835:  *
13836:  * parse an XML in-memory block and use the given SAX function block
13837:  * to handle the parsing callback. If sax is NULL, fallback to the default
13838:  * DOM tree building routines.
13839:  *
13840:  * User data (void *) is stored within the parser context in the
13841:  * context's _private member, so it is available nearly everywhere in libxml
13842:  *
13843:  * Returns the resulting document tree
13844:  */
13845: 
13846: xmlDocPtr
13847: xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
13848: 	          int size, int recovery, void *data) {
13849:     xmlDocPtr ret;
13850:     xmlParserCtxtPtr ctxt;
13851: 
13852:     xmlInitParser();
13853: 
13854:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13855:     if (ctxt == NULL) return(NULL);
13856:     if (sax != NULL) {
13857: 	if (ctxt->sax != NULL)
13858: 	    xmlFree(ctxt->sax);
13859:         ctxt->sax = sax;
13860:     }
13861:     xmlDetectSAX2(ctxt);
13862:     if (data!=NULL) {
13863: 	ctxt->_private=data;
13864:     }
13865: 
13866:     ctxt->recovery = recovery;
13867: 
13868:     xmlParseDocument(ctxt);
13869: 
13870:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
13871:     else {
13872:        ret = NULL;
13873:        xmlFreeDoc(ctxt->myDoc);
13874:        ctxt->myDoc = NULL;
13875:     }
13876:     if (sax != NULL) 
13877: 	ctxt->sax = NULL;
13878:     xmlFreeParserCtxt(ctxt);
13879: 
13880:     return(ret);
13881: }
13882: 
13883: /**
13884:  * xmlSAXParseMemory:
13885:  * @sax:  the SAX handler block
13886:  * @buffer:  an pointer to a char array
13887:  * @size:  the size of the array
13888:  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
13889:  *             documents
13890:  *
13891:  * parse an XML in-memory block and use the given SAX function block
13892:  * to handle the parsing callback. If sax is NULL, fallback to the default
13893:  * DOM tree building routines.
13894:  * 
13895:  * Returns the resulting document tree
13896:  */
13897: xmlDocPtr
13898: xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
13899: 	          int size, int recovery) {
13900:     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
13901: }
13902: 
13903: /**
13904:  * xmlParseMemory:
13905:  * @buffer:  an pointer to a char array
13906:  * @size:  the size of the array
13907:  *
13908:  * parse an XML in-memory block and build a tree.
13909:  * 
13910:  * Returns the resulting document tree
13911:  */
13912: 
13913: xmlDocPtr xmlParseMemory(const char *buffer, int size) {
13914:    return(xmlSAXParseMemory(NULL, buffer, size, 0));
13915: }
13916: 
13917: /**
13918:  * xmlRecoverMemory:
13919:  * @buffer:  an pointer to a char array
13920:  * @size:  the size of the array
13921:  *
13922:  * parse an XML in-memory block and build a tree.
13923:  * In the case the document is not Well Formed, an attempt to
13924:  * build a tree is tried anyway
13925:  *
13926:  * Returns the resulting document tree or NULL in case of error
13927:  */
13928: 
13929: xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
13930:    return(xmlSAXParseMemory(NULL, buffer, size, 1));
13931: }
13932: 
13933: /**
13934:  * xmlSAXUserParseMemory:
13935:  * @sax:  a SAX handler
13936:  * @user_data:  The user data returned on SAX callbacks
13937:  * @buffer:  an in-memory XML document input
13938:  * @size:  the length of the XML document in bytes
13939:  *
13940:  * A better SAX parsing routine.
13941:  * parse an XML in-memory buffer and call the given SAX handler routines.
13942:  *
13943:  * Returns 0 in case of success or a error number otherwise
13944:  */
13945: int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
13946: 			  const char *buffer, int size) {
13947:     int ret = 0;
13948:     xmlParserCtxtPtr ctxt;
13949: 
13950:     xmlInitParser();
13951: 
13952:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13953:     if (ctxt == NULL) return -1;
13954:     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
13955:         xmlFree(ctxt->sax);
13956:     ctxt->sax = sax;
13957:     xmlDetectSAX2(ctxt);
13958: 
13959:     if (user_data != NULL)
13960: 	ctxt->userData = user_data;
13961: 
13962:     xmlParseDocument(ctxt);
13963:     
13964:     if (ctxt->wellFormed)
13965: 	ret = 0;
13966:     else {
13967:         if (ctxt->errNo != 0)
13968: 	    ret = ctxt->errNo;
13969: 	else
13970: 	    ret = -1;
13971:     }
13972:     if (sax != NULL)
13973:         ctxt->sax = NULL;
13974:     if (ctxt->myDoc != NULL) {
13975:         xmlFreeDoc(ctxt->myDoc);
13976: 	ctxt->myDoc = NULL;
13977:     }
13978:     xmlFreeParserCtxt(ctxt);
13979:     
13980:     return ret;
13981: }
13982: #endif /* LIBXML_SAX1_ENABLED */
13983: 
13984: /**
13985:  * xmlCreateDocParserCtxt:
13986:  * @cur:  a pointer to an array of xmlChar
13987:  *
13988:  * Creates a parser context for an XML in-memory document.
13989:  *
13990:  * Returns the new parser context or NULL
13991:  */
13992: xmlParserCtxtPtr
13993: xmlCreateDocParserCtxt(const xmlChar *cur) {
13994:     int len;
13995: 
13996:     if (cur == NULL)
13997: 	return(NULL);
13998:     len = xmlStrlen(cur);
13999:     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14000: }
14001: 
14002: #ifdef LIBXML_SAX1_ENABLED
14003: /**
14004:  * xmlSAXParseDoc:
14005:  * @sax:  the SAX handler block
14006:  * @cur:  a pointer to an array of xmlChar
14007:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14008:  *             documents
14009:  *
14010:  * parse an XML in-memory document and build a tree.
14011:  * It use the given SAX function block to handle the parsing callback.
14012:  * If sax is NULL, fallback to the default DOM tree building routines.
14013:  * 
14014:  * Returns the resulting document tree
14015:  */
14016: 
14017: xmlDocPtr
14018: xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14019:     xmlDocPtr ret;
14020:     xmlParserCtxtPtr ctxt;
14021:     xmlSAXHandlerPtr oldsax = NULL;
14022: 
14023:     if (cur == NULL) return(NULL);
14024: 
14025: 
14026:     ctxt = xmlCreateDocParserCtxt(cur);
14027:     if (ctxt == NULL) return(NULL);
14028:     if (sax != NULL) { 
14029:         oldsax = ctxt->sax;
14030:         ctxt->sax = sax;
14031:         ctxt->userData = NULL;
14032:     }
14033:     xmlDetectSAX2(ctxt);
14034: 
14035:     xmlParseDocument(ctxt);
14036:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14037:     else {
14038:        ret = NULL;
14039:        xmlFreeDoc(ctxt->myDoc);
14040:        ctxt->myDoc = NULL;
14041:     }
14042:     if (sax != NULL)
14043: 	ctxt->sax = oldsax;
14044:     xmlFreeParserCtxt(ctxt);
14045:     
14046:     return(ret);
14047: }
14048: 
14049: /**
14050:  * xmlParseDoc:
14051:  * @cur:  a pointer to an array of xmlChar
14052:  *
14053:  * parse an XML in-memory document and build a tree.
14054:  * 
14055:  * Returns the resulting document tree
14056:  */
14057: 
14058: xmlDocPtr
14059: xmlParseDoc(const xmlChar *cur) {
14060:     return(xmlSAXParseDoc(NULL, cur, 0));
14061: }
14062: #endif /* LIBXML_SAX1_ENABLED */
14063: 
14064: #ifdef LIBXML_LEGACY_ENABLED
14065: /************************************************************************
14066:  *									*
14067:  * 	Specific function to keep track of entities references		*
14068:  * 	and used by the XSLT debugger					*
14069:  *									*
14070:  ************************************************************************/
14071: 
14072: static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14073: 
14074: /**
14075:  * xmlAddEntityReference:
14076:  * @ent : A valid entity
14077:  * @firstNode : A valid first node for children of entity
14078:  * @lastNode : A valid last node of children entity 
14079:  *
14080:  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14081:  */
14082: static void
14083: xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14084:                       xmlNodePtr lastNode)
14085: {
14086:     if (xmlEntityRefFunc != NULL) {
14087:         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14088:     }
14089: }
14090: 
14091: 
14092: /**
14093:  * xmlSetEntityReferenceFunc:
14094:  * @func: A valid function
14095:  *
14096:  * Set the function to call call back when a xml reference has been made
14097:  */
14098: void
14099: xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14100: {
14101:     xmlEntityRefFunc = func;
14102: }
14103: #endif /* LIBXML_LEGACY_ENABLED */
14104: 
14105: /************************************************************************
14106:  *									*
14107:  * 				Miscellaneous				*
14108:  *									*
14109:  ************************************************************************/
14110: 
14111: #ifdef LIBXML_XPATH_ENABLED
14112: #include <libxml/xpath.h>
14113: #endif
14114: 
14115: extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14116: static int xmlParserInitialized = 0;
14117: 
14118: /**
14119:  * xmlInitParser:
14120:  *
14121:  * Initialization function for the XML parser.
14122:  * This is not reentrant. Call once before processing in case of
14123:  * use in multithreaded programs.
14124:  */
14125: 
14126: void
14127: xmlInitParser(void) {
14128:     if (xmlParserInitialized != 0)
14129: 	return;
14130: 
14131: #ifdef LIBXML_THREAD_ENABLED
14132:     __xmlGlobalInitMutexLock();
14133:     if (xmlParserInitialized == 0) {
14134: #endif
14135: 	xmlInitThreads();
14136: 	xmlInitGlobals();
14137: 	if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14138: 	    (xmlGenericError == NULL))
14139: 	    initGenericErrorDefaultFunc(NULL);
14140: 	xmlInitMemory();
14141: 	xmlInitCharEncodingHandlers();
14142: 	xmlDefaultSAXHandlerInit();
14143: 	xmlRegisterDefaultInputCallbacks();
14144: #ifdef LIBXML_OUTPUT_ENABLED
14145: 	xmlRegisterDefaultOutputCallbacks();
14146: #endif /* LIBXML_OUTPUT_ENABLED */
14147: #ifdef LIBXML_HTML_ENABLED
14148: 	htmlInitAutoClose();
14149: 	htmlDefaultSAXHandlerInit();
14150: #endif
14151: #ifdef LIBXML_XPATH_ENABLED
14152: 	xmlXPathInit();
14153: #endif
14154: 	xmlParserInitialized = 1;
14155: #ifdef LIBXML_THREAD_ENABLED
14156:     }
14157:     __xmlGlobalInitMutexUnlock();
14158: #endif
14159: }
14160: 
14161: /**
14162:  * xmlCleanupParser:
14163:  *
14164:  * This function name is somewhat misleading. It does not clean up
14165:  * parser state, it cleans up memory allocated by the library itself.
14166:  * It is a cleanup function for the XML library. It tries to reclaim all
14167:  * related global memory allocated for the library processing.
14168:  * It doesn't deallocate any document related memory. One should
14169:  * call xmlCleanupParser() only when the process has finished using
14170:  * the library and all XML/HTML documents built with it.
14171:  * See also xmlInitParser() which has the opposite function of preparing
14172:  * the library for operations.
14173:  *
14174:  * WARNING: if your application is multithreaded or has plugin support
14175:  *          calling this may crash the application if another thread or
14176:  *          a plugin is still using libxml2. It's sometimes very hard to
14177:  *          guess if libxml2 is in use in the application, some libraries
14178:  *          or plugins may use it without notice. In case of doubt abstain
14179:  *          from calling this function or do it just before calling exit()
14180:  *          to avoid leak reports from valgrind !
14181:  */
14182: 
14183: void
14184: xmlCleanupParser(void) {
14185:     if (!xmlParserInitialized)
14186: 	return;
14187: 
14188:     xmlCleanupCharEncodingHandlers();
14189: #ifdef LIBXML_CATALOG_ENABLED
14190:     xmlCatalogCleanup();
14191: #endif
14192:     xmlDictCleanup();
14193:     xmlCleanupInputCallbacks();
14194: #ifdef LIBXML_OUTPUT_ENABLED
14195:     xmlCleanupOutputCallbacks();
14196: #endif
14197: #ifdef LIBXML_SCHEMAS_ENABLED
14198:     xmlSchemaCleanupTypes();
14199:     xmlRelaxNGCleanupTypes();
14200: #endif
14201:     xmlCleanupGlobals();
14202:     xmlResetLastError();
14203:     xmlCleanupThreads(); /* must be last if called not from the main thread */
14204:     xmlCleanupMemory();
14205:     xmlParserInitialized = 0;
14206: }
14207: 
14208: /************************************************************************
14209:  *									*
14210:  *	New set (2.6.0) of simpler and more flexible APIs		*
14211:  *									*
14212:  ************************************************************************/
14213: 
14214: /**
14215:  * DICT_FREE:
14216:  * @str:  a string
14217:  *
14218:  * Free a string if it is not owned by the "dict" dictionnary in the
14219:  * current scope
14220:  */
14221: #define DICT_FREE(str)						\
14222: 	if ((str) && ((!dict) || 				\
14223: 	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
14224: 	    xmlFree((char *)(str));
14225: 
14226: /**
14227:  * xmlCtxtReset:
14228:  * @ctxt: an XML parser context
14229:  *
14230:  * Reset a parser context
14231:  */
14232: void
14233: xmlCtxtReset(xmlParserCtxtPtr ctxt)
14234: {
14235:     xmlParserInputPtr input;
14236:     xmlDictPtr dict;
14237:     
14238:     if (ctxt == NULL)
14239:         return;
14240: 
14241:     dict = ctxt->dict;
14242: 
14243:     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14244:         xmlFreeInputStream(input);
14245:     }
14246:     ctxt->inputNr = 0;
14247:     ctxt->input = NULL;
14248: 
14249:     ctxt->spaceNr = 0;
14250:     if (ctxt->spaceTab != NULL) {
14251: 	ctxt->spaceTab[0] = -1;
14252: 	ctxt->space = &ctxt->spaceTab[0];
14253:     } else {
14254:         ctxt->space = NULL;
14255:     }
14256: 
14257: 
14258:     ctxt->nodeNr = 0;
14259:     ctxt->node = NULL;
14260: 
14261:     ctxt->nameNr = 0;
14262:     ctxt->name = NULL;
14263: 
14264:     DICT_FREE(ctxt->version);
14265:     ctxt->version = NULL;
14266:     DICT_FREE(ctxt->encoding);
14267:     ctxt->encoding = NULL;
14268:     DICT_FREE(ctxt->directory);
14269:     ctxt->directory = NULL;
14270:     DICT_FREE(ctxt->extSubURI);
14271:     ctxt->extSubURI = NULL;
14272:     DICT_FREE(ctxt->extSubSystem);
14273:     ctxt->extSubSystem = NULL;
14274:     if (ctxt->myDoc != NULL)
14275:         xmlFreeDoc(ctxt->myDoc);
14276:     ctxt->myDoc = NULL;
14277: 
14278:     ctxt->standalone = -1;
14279:     ctxt->hasExternalSubset = 0;
14280:     ctxt->hasPErefs = 0;
14281:     ctxt->html = 0;
14282:     ctxt->external = 0;
14283:     ctxt->instate = XML_PARSER_START;
14284:     ctxt->token = 0;
14285: 
14286:     ctxt->wellFormed = 1;
14287:     ctxt->nsWellFormed = 1;
14288:     ctxt->disableSAX = 0;
14289:     ctxt->valid = 1;
14290: #if 0
14291:     ctxt->vctxt.userData = ctxt;
14292:     ctxt->vctxt.error = xmlParserValidityError;
14293:     ctxt->vctxt.warning = xmlParserValidityWarning;
14294: #endif
14295:     ctxt->record_info = 0;
14296:     ctxt->nbChars = 0;
14297:     ctxt->checkIndex = 0;
14298:     ctxt->inSubset = 0;
14299:     ctxt->errNo = XML_ERR_OK;
14300:     ctxt->depth = 0;
14301:     ctxt->charset = XML_CHAR_ENCODING_UTF8;
14302:     ctxt->catalogs = NULL;
14303:     ctxt->nbentities = 0;
14304:     ctxt->sizeentities = 0;
14305:     xmlInitNodeInfoSeq(&ctxt->node_seq);
14306: 
14307:     if (ctxt->attsDefault != NULL) {
14308:         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
14309:         ctxt->attsDefault = NULL;
14310:     }
14311:     if (ctxt->attsSpecial != NULL) {
14312:         xmlHashFree(ctxt->attsSpecial, NULL);
14313:         ctxt->attsSpecial = NULL;
14314:     }
14315: 
14316: #ifdef LIBXML_CATALOG_ENABLED
14317:     if (ctxt->catalogs != NULL)
14318: 	xmlCatalogFreeLocal(ctxt->catalogs);
14319: #endif
14320:     if (ctxt->lastError.code != XML_ERR_OK)
14321:         xmlResetError(&ctxt->lastError);
14322: }
14323: 
14324: /**
14325:  * xmlCtxtResetPush:
14326:  * @ctxt: an XML parser context
14327:  * @chunk:  a pointer to an array of chars
14328:  * @size:  number of chars in the array
14329:  * @filename:  an optional file name or URI
14330:  * @encoding:  the document encoding, or NULL
14331:  *
14332:  * Reset a push parser context
14333:  *
14334:  * Returns 0 in case of success and 1 in case of error
14335:  */
14336: int
14337: xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14338:                  int size, const char *filename, const char *encoding)
14339: {
14340:     xmlParserInputPtr inputStream;
14341:     xmlParserInputBufferPtr buf;
14342:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14343: 
14344:     if (ctxt == NULL)
14345:         return(1);
14346: 
14347:     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14348:         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14349: 
14350:     buf = xmlAllocParserInputBuffer(enc);
14351:     if (buf == NULL)
14352:         return(1);
14353: 
14354:     if (ctxt == NULL) {
14355:         xmlFreeParserInputBuffer(buf);
14356:         return(1);
14357:     }
14358: 
14359:     xmlCtxtReset(ctxt);
14360: 
14361:     if (ctxt->pushTab == NULL) {
14362:         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
14363: 	                                    sizeof(xmlChar *));
14364:         if (ctxt->pushTab == NULL) {
14365: 	    xmlErrMemory(ctxt, NULL);
14366:             xmlFreeParserInputBuffer(buf);
14367:             return(1);
14368:         }
14369:     }
14370: 
14371:     if (filename == NULL) {
14372:         ctxt->directory = NULL;
14373:     } else {
14374:         ctxt->directory = xmlParserGetDirectory(filename);
14375:     }
14376: 
14377:     inputStream = xmlNewInputStream(ctxt);
14378:     if (inputStream == NULL) {
14379:         xmlFreeParserInputBuffer(buf);
14380:         return(1);
14381:     }
14382: 
14383:     if (filename == NULL)
14384:         inputStream->filename = NULL;
14385:     else
14386:         inputStream->filename = (char *)
14387:             xmlCanonicPath((const xmlChar *) filename);
14388:     inputStream->buf = buf;
14389:     inputStream->base = inputStream->buf->buffer->content;
14390:     inputStream->cur = inputStream->buf->buffer->content;
14391:     inputStream->end =
14392:         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
14393: 
14394:     inputPush(ctxt, inputStream);
14395: 
14396:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14397:         (ctxt->input->buf != NULL)) {
14398:         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
14399:         int cur = ctxt->input->cur - ctxt->input->base;
14400: 
14401:         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14402: 
14403:         ctxt->input->base = ctxt->input->buf->buffer->content + base;
14404:         ctxt->input->cur = ctxt->input->base + cur;
14405:         ctxt->input->end =
14406:             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
14407:                                                use];
14408: #ifdef DEBUG_PUSH
14409:         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14410: #endif
14411:     }
14412: 
14413:     if (encoding != NULL) {
14414:         xmlCharEncodingHandlerPtr hdlr;
14415: 
14416:         if (ctxt->encoding != NULL)
14417: 	    xmlFree((xmlChar *) ctxt->encoding);
14418:         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14419: 
14420:         hdlr = xmlFindCharEncodingHandler(encoding);
14421:         if (hdlr != NULL) {
14422:             xmlSwitchToEncoding(ctxt, hdlr);
14423: 	} else {
14424: 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
14425: 			      "Unsupported encoding %s\n", BAD_CAST encoding);
14426:         }
14427:     } else if (enc != XML_CHAR_ENCODING_NONE) {
14428:         xmlSwitchEncoding(ctxt, enc);
14429:     }
14430: 
14431:     return(0);
14432: }
14433: 
14434: 
14435: /**
14436:  * xmlCtxtUseOptionsInternal:
14437:  * @ctxt: an XML parser context
14438:  * @options:  a combination of xmlParserOption
14439:  * @encoding:  the user provided encoding to use
14440:  *
14441:  * Applies the options to the parser context
14442:  *
14443:  * Returns 0 in case of success, the set of unknown or unimplemented options
14444:  *         in case of error.
14445:  */
14446: static int
14447: xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
14448: {
14449:     if (ctxt == NULL)
14450:         return(-1);
14451:     if (encoding != NULL) {
14452:         if (ctxt->encoding != NULL)
14453: 	    xmlFree((xmlChar *) ctxt->encoding);
14454:         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14455:     }
14456:     if (options & XML_PARSE_RECOVER) {
14457:         ctxt->recovery = 1;
14458:         options -= XML_PARSE_RECOVER;
14459: 	ctxt->options |= XML_PARSE_RECOVER;
14460:     } else
14461:         ctxt->recovery = 0;
14462:     if (options & XML_PARSE_DTDLOAD) {
14463:         ctxt->loadsubset = XML_DETECT_IDS;
14464:         options -= XML_PARSE_DTDLOAD;
14465: 	ctxt->options |= XML_PARSE_DTDLOAD;
14466:     } else
14467:         ctxt->loadsubset = 0;
14468:     if (options & XML_PARSE_DTDATTR) {
14469:         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
14470:         options -= XML_PARSE_DTDATTR;
14471: 	ctxt->options |= XML_PARSE_DTDATTR;
14472:     }
14473:     if (options & XML_PARSE_NOENT) {
14474:         ctxt->replaceEntities = 1;
14475:         /* ctxt->loadsubset |= XML_DETECT_IDS; */
14476:         options -= XML_PARSE_NOENT;
14477: 	ctxt->options |= XML_PARSE_NOENT;
14478:     } else
14479:         ctxt->replaceEntities = 0;
14480:     if (options & XML_PARSE_PEDANTIC) {
14481:         ctxt->pedantic = 1;
14482:         options -= XML_PARSE_PEDANTIC;
14483: 	ctxt->options |= XML_PARSE_PEDANTIC;
14484:     } else
14485:         ctxt->pedantic = 0;
14486:     if (options & XML_PARSE_NOBLANKS) {
14487:         ctxt->keepBlanks = 0;
14488:         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
14489:         options -= XML_PARSE_NOBLANKS;
14490: 	ctxt->options |= XML_PARSE_NOBLANKS;
14491:     } else
14492:         ctxt->keepBlanks = 1;
14493:     if (options & XML_PARSE_DTDVALID) {
14494:         ctxt->validate = 1;
14495:         if (options & XML_PARSE_NOWARNING)
14496:             ctxt->vctxt.warning = NULL;
14497:         if (options & XML_PARSE_NOERROR)
14498:             ctxt->vctxt.error = NULL;
14499:         options -= XML_PARSE_DTDVALID;
14500: 	ctxt->options |= XML_PARSE_DTDVALID;
14501:     } else
14502:         ctxt->validate = 0;
14503:     if (options & XML_PARSE_NOWARNING) {
14504:         ctxt->sax->warning = NULL;
14505:         options -= XML_PARSE_NOWARNING;
14506:     }
14507:     if (options & XML_PARSE_NOERROR) {
14508:         ctxt->sax->error = NULL;
14509:         ctxt->sax->fatalError = NULL;
14510:         options -= XML_PARSE_NOERROR;
14511:     }
14512: #ifdef LIBXML_SAX1_ENABLED
14513:     if (options & XML_PARSE_SAX1) {
14514:         ctxt->sax->startElement = xmlSAX2StartElement;
14515:         ctxt->sax->endElement = xmlSAX2EndElement;
14516:         ctxt->sax->startElementNs = NULL;
14517:         ctxt->sax->endElementNs = NULL;
14518:         ctxt->sax->initialized = 1;
14519:         options -= XML_PARSE_SAX1;
14520: 	ctxt->options |= XML_PARSE_SAX1;
14521:     }
14522: #endif /* LIBXML_SAX1_ENABLED */
14523:     if (options & XML_PARSE_NODICT) {
14524:         ctxt->dictNames = 0;
14525:         options -= XML_PARSE_NODICT;
14526: 	ctxt->options |= XML_PARSE_NODICT;
14527:     } else {
14528:         ctxt->dictNames = 1;
14529:     }
14530:     if (options & XML_PARSE_NOCDATA) {
14531:         ctxt->sax->cdataBlock = NULL;
14532:         options -= XML_PARSE_NOCDATA;
14533: 	ctxt->options |= XML_PARSE_NOCDATA;
14534:     }
14535:     if (options & XML_PARSE_NSCLEAN) {
14536: 	ctxt->options |= XML_PARSE_NSCLEAN;
14537:         options -= XML_PARSE_NSCLEAN;
14538:     }
14539:     if (options & XML_PARSE_NONET) {
14540: 	ctxt->options |= XML_PARSE_NONET;
14541:         options -= XML_PARSE_NONET;
14542:     }
14543:     if (options & XML_PARSE_COMPACT) {
14544: 	ctxt->options |= XML_PARSE_COMPACT;
14545:         options -= XML_PARSE_COMPACT;
14546:     }
14547:     if (options & XML_PARSE_OLD10) {
14548: 	ctxt->options |= XML_PARSE_OLD10;
14549:         options -= XML_PARSE_OLD10;
14550:     }
14551:     if (options & XML_PARSE_NOBASEFIX) {
14552: 	ctxt->options |= XML_PARSE_NOBASEFIX;
14553:         options -= XML_PARSE_NOBASEFIX;
14554:     }
14555:     if (options & XML_PARSE_HUGE) {
14556: 	ctxt->options |= XML_PARSE_HUGE;
14557:         options -= XML_PARSE_HUGE;
14558:     }
14559:     if (options & XML_PARSE_OLDSAX) {
14560: 	ctxt->options |= XML_PARSE_OLDSAX;
14561:         options -= XML_PARSE_OLDSAX;
14562:     }
14563:     ctxt->linenumbers = 1;
14564:     return (options);
14565: }
14566: 
14567: /**
14568:  * xmlCtxtUseOptions:
14569:  * @ctxt: an XML parser context
14570:  * @options:  a combination of xmlParserOption
14571:  *
14572:  * Applies the options to the parser context
14573:  *
14574:  * Returns 0 in case of success, the set of unknown or unimplemented options
14575:  *         in case of error.
14576:  */
14577: int
14578: xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
14579: {
14580:    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
14581: }
14582: 
14583: /**
14584:  * xmlDoRead:
14585:  * @ctxt:  an XML parser context
14586:  * @URL:  the base URL to use for the document
14587:  * @encoding:  the document encoding, or NULL
14588:  * @options:  a combination of xmlParserOption
14589:  * @reuse:  keep the context for reuse
14590:  *
14591:  * Common front-end for the xmlRead functions
14592:  *
14593:  * Returns the resulting document tree or NULL
14594:  */
14595: static xmlDocPtr
14596: xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
14597:           int options, int reuse)
14598: {
14599:     xmlDocPtr ret;
14600: 
14601:     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
14602:     if (encoding != NULL) {
14603:         xmlCharEncodingHandlerPtr hdlr;
14604: 
14605: 	hdlr = xmlFindCharEncodingHandler(encoding);
14606: 	if (hdlr != NULL)
14607: 	    xmlSwitchToEncoding(ctxt, hdlr);
14608:     }
14609:     if ((URL != NULL) && (ctxt->input != NULL) &&
14610:         (ctxt->input->filename == NULL))
14611:         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
14612:     xmlParseDocument(ctxt);
14613:     if ((ctxt->wellFormed) || ctxt->recovery)
14614:         ret = ctxt->myDoc;
14615:     else {
14616:         ret = NULL;
14617: 	if (ctxt->myDoc != NULL) {
14618: 	    xmlFreeDoc(ctxt->myDoc);
14619: 	}
14620:     }
14621:     ctxt->myDoc = NULL;
14622:     if (!reuse) {
14623: 	xmlFreeParserCtxt(ctxt);
14624:     }
14625: 
14626:     return (ret);
14627: }
14628: 
14629: /**
14630:  * xmlReadDoc:
14631:  * @cur:  a pointer to a zero terminated string
14632:  * @URL:  the base URL to use for the document
14633:  * @encoding:  the document encoding, or NULL
14634:  * @options:  a combination of xmlParserOption
14635:  *
14636:  * parse an XML in-memory document and build a tree.
14637:  * 
14638:  * Returns the resulting document tree
14639:  */
14640: xmlDocPtr
14641: xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
14642: {
14643:     xmlParserCtxtPtr ctxt;
14644: 
14645:     if (cur == NULL)
14646:         return (NULL);
14647: 
14648:     ctxt = xmlCreateDocParserCtxt(cur);
14649:     if (ctxt == NULL)
14650:         return (NULL);
14651:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14652: }
14653: 
14654: /**
14655:  * xmlReadFile:
14656:  * @filename:  a file or URL
14657:  * @encoding:  the document encoding, or NULL
14658:  * @options:  a combination of xmlParserOption
14659:  *
14660:  * parse an XML file from the filesystem or the network.
14661:  * 
14662:  * Returns the resulting document tree
14663:  */
14664: xmlDocPtr
14665: xmlReadFile(const char *filename, const char *encoding, int options)
14666: {
14667:     xmlParserCtxtPtr ctxt;
14668: 
14669:     ctxt = xmlCreateURLParserCtxt(filename, options);
14670:     if (ctxt == NULL)
14671:         return (NULL);
14672:     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
14673: }
14674: 
14675: /**
14676:  * xmlReadMemory:
14677:  * @buffer:  a pointer to a char array
14678:  * @size:  the size of the array
14679:  * @URL:  the base URL to use for the document
14680:  * @encoding:  the document encoding, or NULL
14681:  * @options:  a combination of xmlParserOption
14682:  *
14683:  * parse an XML in-memory document and build a tree.
14684:  * 
14685:  * Returns the resulting document tree
14686:  */
14687: xmlDocPtr
14688: xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
14689: {
14690:     xmlParserCtxtPtr ctxt;
14691: 
14692:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14693:     if (ctxt == NULL)
14694:         return (NULL);
14695:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14696: }
14697: 
14698: /**
14699:  * xmlReadFd:
14700:  * @fd:  an open file descriptor
14701:  * @URL:  the base URL to use for the document
14702:  * @encoding:  the document encoding, or NULL
14703:  * @options:  a combination of xmlParserOption
14704:  *
14705:  * parse an XML from a file descriptor and build a tree.
14706:  * NOTE that the file descriptor will not be closed when the
14707:  *      reader is closed or reset.
14708:  * 
14709:  * Returns the resulting document tree
14710:  */
14711: xmlDocPtr
14712: xmlReadFd(int fd, const char *URL, const char *encoding, int options)
14713: {
14714:     xmlParserCtxtPtr ctxt;
14715:     xmlParserInputBufferPtr input;
14716:     xmlParserInputPtr stream;
14717: 
14718:     if (fd < 0)
14719:         return (NULL);
14720: 
14721:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
14722:     if (input == NULL)
14723:         return (NULL);
14724:     input->closecallback = NULL;
14725:     ctxt = xmlNewParserCtxt();
14726:     if (ctxt == NULL) {
14727:         xmlFreeParserInputBuffer(input);
14728:         return (NULL);
14729:     }
14730:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14731:     if (stream == NULL) {
14732:         xmlFreeParserInputBuffer(input);
14733: 	xmlFreeParserCtxt(ctxt);
14734:         return (NULL);
14735:     }
14736:     inputPush(ctxt, stream);
14737:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14738: }
14739: 
14740: /**
14741:  * xmlReadIO:
14742:  * @ioread:  an I/O read function
14743:  * @ioclose:  an I/O close function
14744:  * @ioctx:  an I/O handler
14745:  * @URL:  the base URL to use for the document
14746:  * @encoding:  the document encoding, or NULL
14747:  * @options:  a combination of xmlParserOption
14748:  *
14749:  * parse an XML document from I/O functions and source and build a tree.
14750:  * 
14751:  * Returns the resulting document tree
14752:  */
14753: xmlDocPtr
14754: xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
14755:           void *ioctx, const char *URL, const char *encoding, int options)
14756: {
14757:     xmlParserCtxtPtr ctxt;
14758:     xmlParserInputBufferPtr input;
14759:     xmlParserInputPtr stream;
14760: 
14761:     if (ioread == NULL)
14762:         return (NULL);
14763: 
14764:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
14765:                                          XML_CHAR_ENCODING_NONE);
14766:     if (input == NULL)
14767:         return (NULL);
14768:     ctxt = xmlNewParserCtxt();
14769:     if (ctxt == NULL) {
14770:         xmlFreeParserInputBuffer(input);
14771:         return (NULL);
14772:     }
14773:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14774:     if (stream == NULL) {
14775:         xmlFreeParserInputBuffer(input);
14776: 	xmlFreeParserCtxt(ctxt);
14777:         return (NULL);
14778:     }
14779:     inputPush(ctxt, stream);
14780:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14781: }
14782: 
14783: /**
14784:  * xmlCtxtReadDoc:
14785:  * @ctxt:  an XML parser context
14786:  * @cur:  a pointer to a zero terminated string
14787:  * @URL:  the base URL to use for the document
14788:  * @encoding:  the document encoding, or NULL
14789:  * @options:  a combination of xmlParserOption
14790:  *
14791:  * parse an XML in-memory document and build a tree.
14792:  * This reuses the existing @ctxt parser context
14793:  * 
14794:  * Returns the resulting document tree
14795:  */
14796: xmlDocPtr
14797: xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
14798:                const char *URL, const char *encoding, int options)
14799: {
14800:     xmlParserInputPtr stream;
14801: 
14802:     if (cur == NULL)
14803:         return (NULL);
14804:     if (ctxt == NULL)
14805:         return (NULL);
14806: 
14807:     xmlCtxtReset(ctxt);
14808: 
14809:     stream = xmlNewStringInputStream(ctxt, cur);
14810:     if (stream == NULL) {
14811:         return (NULL);
14812:     }
14813:     inputPush(ctxt, stream);
14814:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14815: }
14816: 
14817: /**
14818:  * xmlCtxtReadFile:
14819:  * @ctxt:  an XML parser context
14820:  * @filename:  a file or URL
14821:  * @encoding:  the document encoding, or NULL
14822:  * @options:  a combination of xmlParserOption
14823:  *
14824:  * parse an XML file from the filesystem or the network.
14825:  * This reuses the existing @ctxt parser context
14826:  * 
14827:  * Returns the resulting document tree
14828:  */
14829: xmlDocPtr
14830: xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
14831:                 const char *encoding, int options)
14832: {
14833:     xmlParserInputPtr stream;
14834: 
14835:     if (filename == NULL)
14836:         return (NULL);
14837:     if (ctxt == NULL)
14838:         return (NULL);
14839: 
14840:     xmlCtxtReset(ctxt);
14841: 
14842:     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
14843:     if (stream == NULL) {
14844:         return (NULL);
14845:     }
14846:     inputPush(ctxt, stream);
14847:     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
14848: }
14849: 
14850: /**
14851:  * xmlCtxtReadMemory:
14852:  * @ctxt:  an XML parser context
14853:  * @buffer:  a pointer to a char array
14854:  * @size:  the size of the array
14855:  * @URL:  the base URL to use for the document
14856:  * @encoding:  the document encoding, or NULL
14857:  * @options:  a combination of xmlParserOption
14858:  *
14859:  * parse an XML in-memory document and build a tree.
14860:  * This reuses the existing @ctxt parser context
14861:  * 
14862:  * Returns the resulting document tree
14863:  */
14864: xmlDocPtr
14865: xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
14866:                   const char *URL, const char *encoding, int options)
14867: {
14868:     xmlParserInputBufferPtr input;
14869:     xmlParserInputPtr stream;
14870: 
14871:     if (ctxt == NULL)
14872:         return (NULL);
14873:     if (buffer == NULL)
14874:         return (NULL);
14875: 
14876:     xmlCtxtReset(ctxt);
14877: 
14878:     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14879:     if (input == NULL) {
14880: 	return(NULL);
14881:     }
14882: 
14883:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14884:     if (stream == NULL) {
14885: 	xmlFreeParserInputBuffer(input);
14886: 	return(NULL);
14887:     }
14888: 
14889:     inputPush(ctxt, stream);
14890:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14891: }
14892: 
14893: /**
14894:  * xmlCtxtReadFd:
14895:  * @ctxt:  an XML parser context
14896:  * @fd:  an open file descriptor
14897:  * @URL:  the base URL to use for the document
14898:  * @encoding:  the document encoding, or NULL
14899:  * @options:  a combination of xmlParserOption
14900:  *
14901:  * parse an XML from a file descriptor and build a tree.
14902:  * This reuses the existing @ctxt parser context
14903:  * NOTE that the file descriptor will not be closed when the
14904:  *      reader is closed or reset.
14905:  * 
14906:  * Returns the resulting document tree
14907:  */
14908: xmlDocPtr
14909: xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
14910:               const char *URL, const char *encoding, int options)
14911: {
14912:     xmlParserInputBufferPtr input;
14913:     xmlParserInputPtr stream;
14914: 
14915:     if (fd < 0)
14916:         return (NULL);
14917:     if (ctxt == NULL)
14918:         return (NULL);
14919: 
14920:     xmlCtxtReset(ctxt);
14921: 
14922: 
14923:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
14924:     if (input == NULL)
14925:         return (NULL);
14926:     input->closecallback = NULL;
14927:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14928:     if (stream == NULL) {
14929:         xmlFreeParserInputBuffer(input);
14930:         return (NULL);
14931:     }
14932:     inputPush(ctxt, stream);
14933:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14934: }
14935: 
14936: /**
14937:  * xmlCtxtReadIO:
14938:  * @ctxt:  an XML parser context
14939:  * @ioread:  an I/O read function
14940:  * @ioclose:  an I/O close function
14941:  * @ioctx:  an I/O handler
14942:  * @URL:  the base URL to use for the document
14943:  * @encoding:  the document encoding, or NULL
14944:  * @options:  a combination of xmlParserOption
14945:  *
14946:  * parse an XML document from I/O functions and source and build a tree.
14947:  * This reuses the existing @ctxt parser context
14948:  * 
14949:  * Returns the resulting document tree
14950:  */
14951: xmlDocPtr
14952: xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
14953:               xmlInputCloseCallback ioclose, void *ioctx,
14954: 	      const char *URL,
14955:               const char *encoding, int options)
14956: {
14957:     xmlParserInputBufferPtr input;
14958:     xmlParserInputPtr stream;
14959: 
14960:     if (ioread == NULL)
14961:         return (NULL);
14962:     if (ctxt == NULL)
14963:         return (NULL);
14964: 
14965:     xmlCtxtReset(ctxt);
14966: 
14967:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
14968:                                          XML_CHAR_ENCODING_NONE);
14969:     if (input == NULL)
14970:         return (NULL);
14971:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14972:     if (stream == NULL) {
14973:         xmlFreeParserInputBuffer(input);
14974:         return (NULL);
14975:     }
14976:     inputPush(ctxt, stream);
14977:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14978: }
14979: 
14980: #define bottom_parser
14981: #include "elfgcchack.h"

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