xml/libxml2libs/src/libxml2/libxml2_parser.c
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /*
       
     2  * libxml2_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 workingdraft
       
    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  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    32  */
       
    33 
       
    34 #pragma warning(disable: 4127 4132)
       
    35 
       
    36 #define IN_LIBXML
       
    37 #include "xmlenglibxml.h"
       
    38 
       
    39 #if (defined(WIN32) || defined(__SYMBIAN32__)) && !defined (__CYGWIN__)
       
    40 #define XML_DIR_SEP '\\'
       
    41 #else
       
    42 #define XML_DIR_SEP '/'
       
    43 #endif
       
    44 
       
    45 #include <stdlib.h>
       
    46 #include <string.h>
       
    47 #include <stdarg.h>
       
    48 
       
    49 #include <stdapis/libxml2/libxml2_globals.h>
       
    50 #include <stdapis/libxml2/libxml2_parserinternals.h>
       
    51 #include "libxml2_errencoding.h"
       
    52 #include "libxml2_xmlerror2.h"
       
    53 #include <stdapis/libxml2/libxml2_uri.h>
       
    54 
       
    55 #ifdef LIBXML_CATALOG_ENABLED
       
    56 #include "libxml2_catalog.h"
       
    57 #endif
       
    58 
       
    59 #ifdef HAVE_CTYPE_H
       
    60 #include <ctype.h>
       
    61 #endif
       
    62 #ifdef HAVE_STDLIB_H
       
    63 #include <stdlib.h>
       
    64 #endif
       
    65 #ifdef HAVE_SYS_STAT_H
       
    66 #include <sys/stat.h>
       
    67 #endif
       
    68 #ifdef HAVE_FCNTL_H
       
    69 #include <fcntl.h>
       
    70 #endif
       
    71 #ifdef HAVE_UNISTD_H
       
    72 #include <unistd.h>
       
    73 #endif
       
    74 #ifdef HAVE_ZLIB_H
       
    75 #include <zlib.h>
       
    76 #endif
       
    77 
       
    78 #define SAX2 1
       
    79 
       
    80 #define XML_PARSER_BIG_BUFFER_SIZE 300
       
    81 #define XML_PARSER_BUFFER_SIZE 100
       
    82 
       
    83 
       
    84 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
       
    85 xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
       
    86                                        const xmlChar **str);
       
    87 
       
    88 static xmlParserErrors
       
    89 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
       
    90                   xmlSAXHandlerPtr sax,
       
    91               void *user_data, int depth, const xmlChar *URL,
       
    92               const xmlChar *ID, xmlNodePtr *list);
       
    93 
       
    94 #ifdef LIBXML_LEGACY_ENABLED
       
    95 static void
       
    96 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
       
    97                       xmlNodePtr lastNode);
       
    98 #endif /* LIBXML_LEGACY_ENABLED */
       
    99 
       
   100 static xmlParserErrors
       
   101 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
       
   102               const xmlChar *string, void *user_data, xmlNodePtr *lst);
       
   103 
       
   104 /************************************************************************
       
   105  *                                                                      *
       
   106  *      Some factorized error routines                                  *
       
   107  *                                                                      *
       
   108  ************************************************************************/
       
   109 
       
   110 /**
       
   111  * xmlErrAttributeDup:
       
   112  * @param ctxt an XML parser context
       
   113  * @param prefix the attribute prefix
       
   114  * @param localname the attribute localname
       
   115  *
       
   116  * Handle a redefinition of attribute error
       
   117  */
       
   118 static void
       
   119 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
       
   120                    const xmlChar * localname)
       
   121 {
       
   122     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   123         (ctxt->instate == XML_PARSER_EOF))
       
   124         return;
       
   125     ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
       
   126     if (prefix == NULL) 
       
   127         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
       
   128                         ctxt->errNo, XML_ERR_FATAL, NULL, 0,
       
   129                         (const char *) localname, NULL, NULL, 0, 0,
       
   130                         EMBED_ERRTXT("Attribute %s redefined\n"), localname);
       
   131     else
       
   132         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
       
   133                         ctxt->errNo, XML_ERR_FATAL, NULL, 0,
       
   134                         (const char *) prefix, (const char *) localname,
       
   135                         NULL, 0, 0, EMBED_ERRTXT("Attribute %s:%s redefined\n"), prefix,
       
   136                         localname);
       
   137     ctxt->wellFormed = 0;
       
   138     if (ctxt->recovery == 0)
       
   139         ctxt->disableSAX = 1;
       
   140 }
       
   141 
       
   142 /**
       
   143  * xmlFatalErr:
       
   144  * @param ctxt an XML parser context
       
   145  * @param error the error number
       
   146  * @param extra extra information string
       
   147  *
       
   148  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
       
   149  */
       
   150 static void
       
   151 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
       
   152 {
       
   153     const char *errmsg;
       
   154 
       
   155     if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF))
       
   156         return;
       
   157 
       
   158 #ifdef XMLENGINE_EXCLUDE_EMBED_MSG
       
   159     errmsg = "Error message is not availabe\n";
       
   160 #else
       
   161     switch (error) { // DONE: Disable this SWITCH if EMBED_ERRTXT returns NULL
       
   162         case XML_ERR_INVALID_HEX_CHARREF:
       
   163             errmsg = EMBED_ERRTXT("CharRef: invalid hexadecimal value\n");
       
   164             break;
       
   165         case XML_ERR_INVALID_DEC_CHARREF:
       
   166             errmsg = EMBED_ERRTXT("CharRef: invalid decimal value\n");
       
   167             break;
       
   168         case XML_ERR_INVALID_CHARREF:
       
   169             errmsg = EMBED_ERRTXT("CharRef: invalid value\n");
       
   170             break;
       
   171         case XML_ERR_INTERNAL_ERROR:
       
   172             errmsg = EMBED_ERRTXT("internal error");
       
   173             break;
       
   174         case XML_ERR_PEREF_AT_EOF:
       
   175             errmsg = EMBED_ERRTXT("PEReference at end of document\n");
       
   176             break;
       
   177         case XML_ERR_PEREF_IN_PROLOG:
       
   178             errmsg = EMBED_ERRTXT("PEReference in prolog\n");
       
   179             break;
       
   180         case XML_ERR_PEREF_IN_EPILOG:
       
   181             errmsg = EMBED_ERRTXT("PEReference in epilog\n");
       
   182             break;
       
   183         case XML_ERR_PEREF_NO_NAME:
       
   184             errmsg = EMBED_ERRTXT("PEReference: no name\n");
       
   185             break;
       
   186         case XML_ERR_PEREF_SEMICOL_MISSING:
       
   187             errmsg = EMBED_ERRTXT("PEReference: expecting ';'\n");
       
   188             break;
       
   189         case XML_ERR_ENTITY_LOOP:
       
   190             errmsg = EMBED_ERRTXT("Detected an entity reference loop\n");
       
   191             break;
       
   192         case XML_ERR_ENTITY_NOT_STARTED:
       
   193             errmsg = EMBED_ERRTXT("EntityValue: \" or ' expected\n");
       
   194             break;
       
   195         case XML_ERR_ENTITY_PE_INTERNAL:
       
   196             errmsg = EMBED_ERRTXT("PEReferences forbidden in internal subset\n");
       
   197             break;
       
   198         case XML_ERR_ENTITY_NOT_FINISHED:
       
   199             errmsg = EMBED_ERRTXT("EntityValue: \" or ' expected\n");
       
   200             break;
       
   201         case XML_ERR_ATTRIBUTE_NOT_STARTED:
       
   202             errmsg = EMBED_ERRTXT("AttValue: \" or ' expected\n");
       
   203             break;
       
   204         case XML_ERR_LT_IN_ATTRIBUTE:
       
   205             errmsg = EMBED_ERRTXT("Unescaped '<' not allowed in attributes values\n");
       
   206             break;
       
   207         case XML_ERR_LITERAL_NOT_STARTED:
       
   208             errmsg = EMBED_ERRTXT("SystemLiteral \" or ' expected\n");
       
   209             break;
       
   210         case XML_ERR_LITERAL_NOT_FINISHED:
       
   211             errmsg = EMBED_ERRTXT("UnfinishedSystem or Public ID \" or ' expected\n");
       
   212             break;
       
   213         case XML_ERR_MISPLACED_CDATA_END:
       
   214             errmsg = EMBED_ERRTXT("Sequence ']]>' not allowed in content\n");
       
   215             break;
       
   216         case XML_ERR_URI_REQUIRED:
       
   217             errmsg = EMBED_ERRTXT("SYSTEM or PUBLIC, the URI is missing\n");
       
   218             break;
       
   219         case XML_ERR_PUBID_REQUIRED:
       
   220             errmsg = EMBED_ERRTXT("PUBLIC, the Public Identifier is missing\n");
       
   221             break;
       
   222         case XML_ERR_HYPHEN_IN_COMMENT:
       
   223             errmsg = EMBED_ERRTXT("Comment must not contain '--' (double-hyphen)\n");
       
   224             break;
       
   225         case XML_ERR_PI_NOT_STARTED:
       
   226             errmsg = EMBED_ERRTXT("xmlParsePI : no target name\n");
       
   227             break;
       
   228         case XML_ERR_RESERVED_XML_NAME:
       
   229             errmsg = EMBED_ERRTXT("Invalid PI name\n");
       
   230             break;
       
   231         case XML_ERR_NOTATION_NOT_STARTED:
       
   232             errmsg = EMBED_ERRTXT("NOTATION: Name expected here\n");
       
   233             break;
       
   234         case XML_ERR_NOTATION_NOT_FINISHED:
       
   235             errmsg = EMBED_ERRTXT("'>' required to close NOTATION declaration\n");
       
   236             break;
       
   237         case XML_ERR_VALUE_REQUIRED:
       
   238             errmsg = EMBED_ERRTXT("Entity value required\n");
       
   239             break;
       
   240         case XML_ERR_URI_FRAGMENT:
       
   241             errmsg = EMBED_ERRTXT("Fragment not allowed");
       
   242             break;
       
   243         case XML_ERR_ATTLIST_NOT_STARTED:
       
   244             errmsg = EMBED_ERRTXT("'(' required to start ATTLIST enumeration\n");
       
   245             break;
       
   246         case XML_ERR_NMTOKEN_REQUIRED:
       
   247             errmsg = EMBED_ERRTXT("NmToken expected in ATTLIST enumeration\n");
       
   248             break;
       
   249         case XML_ERR_ATTLIST_NOT_FINISHED:
       
   250             errmsg = EMBED_ERRTXT("')' required to finish ATTLIST enumeration\n");
       
   251             break;
       
   252         case XML_ERR_MIXED_NOT_STARTED:
       
   253             errmsg = EMBED_ERRTXT("MixedContentDecl : '|' or ')*' expected\n");
       
   254             break;
       
   255         case XML_ERR_PCDATA_REQUIRED:
       
   256             errmsg = EMBED_ERRTXT("MixedContentDecl : '#PCDATA' expected\n");
       
   257             break;
       
   258         case XML_ERR_ELEMCONTENT_NOT_STARTED:
       
   259             errmsg = EMBED_ERRTXT("ContentDecl : Name or '(' expected\n");
       
   260             break;
       
   261         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
       
   262             errmsg = EMBED_ERRTXT("ContentDecl : ',' '|' or ')' expected\n");
       
   263             break;
       
   264         case XML_ERR_PEREF_IN_INT_SUBSET:
       
   265             errmsg =
       
   266                 EMBED_ERRTXT("PEReference: forbidden within markup decl in internal subset\n");
       
   267             break;
       
   268         case XML_ERR_GT_REQUIRED:
       
   269             errmsg =EMBED_ERRTXT("expected '>'\n");
       
   270             break;
       
   271         case XML_ERR_CONDSEC_INVALID:
       
   272             errmsg = EMBED_ERRTXT("XML conditional section '[' expected\n");
       
   273             break;
       
   274         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
       
   275             errmsg = EMBED_ERRTXT("Content error in the external subset\n");
       
   276             break;
       
   277         case XML_ERR_CONDSEC_INVALID_KEYWORD:
       
   278             errmsg =
       
   279                 EMBED_ERRTXT("conditional section INCLUDE or IGNORE keyword expected\n");
       
   280             break;
       
   281         case XML_ERR_CONDSEC_NOT_FINISHED:
       
   282             errmsg = EMBED_ERRTXT("XML conditional section not closed\n");
       
   283             break;
       
   284         case XML_ERR_XMLDECL_NOT_STARTED:
       
   285             errmsg = EMBED_ERRTXT("Text declaration '<?xml' required\n");
       
   286             break;
       
   287         case XML_ERR_XMLDECL_NOT_FINISHED:
       
   288             errmsg = EMBED_ERRTXT("parsing XML declaration: '?>' expected\n");
       
   289             break;
       
   290         case XML_ERR_EXT_ENTITY_STANDALONE:
       
   291             errmsg = EMBED_ERRTXT("external parsed entities cannot be standalone\n");
       
   292             break;
       
   293         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
       
   294             errmsg = EMBED_ERRTXT("EntityRef: expecting ';'\n");
       
   295             break;
       
   296         case XML_ERR_DOCTYPE_NOT_FINISHED:
       
   297             errmsg = EMBED_ERRTXT("DOCTYPE improperly terminated\n");
       
   298             break;
       
   299         case XML_ERR_LTSLASH_REQUIRED:
       
   300             errmsg = EMBED_ERRTXT("EndTag: '</' not found\n");
       
   301             break;
       
   302         case XML_ERR_EQUAL_REQUIRED:
       
   303             errmsg = EMBED_ERRTXT("expected '='\n");
       
   304             break;
       
   305         case XML_ERR_STRING_NOT_CLOSED:
       
   306             errmsg = EMBED_ERRTXT("String not closed expecting \" or '\n");
       
   307             break;
       
   308         case XML_ERR_STRING_NOT_STARTED:
       
   309             errmsg = EMBED_ERRTXT("String not started expecting ' or \"\n");
       
   310             break;
       
   311         case XML_ERR_ENCODING_NAME:
       
   312             errmsg = EMBED_ERRTXT("Invalid XML encoding name\n");
       
   313             break;
       
   314         case XML_ERR_STANDALONE_VALUE:
       
   315             errmsg = EMBED_ERRTXT("standalone accepts only 'yes' or 'no'\n");
       
   316             break;
       
   317         case XML_ERR_DOCUMENT_EMPTY:
       
   318             errmsg = EMBED_ERRTXT("Document is empty\n");
       
   319             break;
       
   320         case XML_ERR_DOCUMENT_END:
       
   321             errmsg = EMBED_ERRTXT("Extra content at the end of the document\n");
       
   322             break;
       
   323         case XML_ERR_NOT_WELL_BALANCED:
       
   324             errmsg = EMBED_ERRTXT("chunk is not well balanced\n");
       
   325             break;
       
   326         case XML_ERR_EXTRA_CONTENT:
       
   327             errmsg = EMBED_ERRTXT("extra content at the end of well balanced chunk\n");
       
   328             break;
       
   329         case XML_ERR_VERSION_MISSING:
       
   330             errmsg = EMBED_ERRTXT("Malformed declaration expecting version\n");
       
   331             break;
       
   332         case XML_ERR_STACK_LOW:
       
   333             errmsg = EMBED_ERRTXT("Thread's stack has reached critical level\n");
       
   334             break;            
       
   335 #if 0
       
   336         case:
       
   337             errmsg = "\n";
       
   338             break;
       
   339 #endif
       
   340         default:
       
   341             errmsg = EMBED_ERRTXT("Unregistered error message\n");
       
   342     }
       
   343 #endif /* !XMLENGINE_EXCLUDE_EMBED_MSG */
       
   344 
       
   345     ctxt->errNo = error;
       
   346     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
       
   347                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
       
   348                     info);
       
   349     ctxt->wellFormed = 0;
       
   350     if (ctxt->recovery == 0)
       
   351         ctxt->disableSAX = 1;
       
   352 }
       
   353 
       
   354 /**
       
   355  * xmlFatalErrMsg:
       
   356  * @param ctxt an XML parser context
       
   357  * @param error the error number
       
   358  * @param msg the error message
       
   359  *
       
   360  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
       
   361  */
       
   362 static void
       
   363 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   364                const char *msg)
       
   365 {
       
   366     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   367         (ctxt->instate == XML_PARSER_EOF))
       
   368     return;
       
   369     ctxt->errNo = error;
       
   370     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
       
   371                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
       
   372     ctxt->wellFormed = 0;
       
   373     if (ctxt->recovery == 0)
       
   374         ctxt->disableSAX = 1;
       
   375 }
       
   376 
       
   377 /**
       
   378  * xmlWarningMsg:
       
   379  * @param ctxt an XML parser context
       
   380  * @param error the error number
       
   381  * @param msg the error message
       
   382  * @param str1 extra data
       
   383  * @param str2 extra data
       
   384  *
       
   385  * Handle a warning.
       
   386  */
       
   387 static void
       
   388 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   389               const char *msg, const xmlChar *str1, const xmlChar *str2)
       
   390 {
       
   391     xmlStructuredErrorFunc schannel = NULL;
       
   392 
       
   393     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   394         (ctxt->instate == XML_PARSER_EOF))
       
   395     return;
       
   396     ctxt->errNo = error;
       
   397     if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
       
   398         schannel = ctxt->sax->serror;
       
   399     __xmlRaiseError(schannel,
       
   400                     (ctxt->sax) ? ctxt->sax->warning : NULL,
       
   401                     ctxt->userData,
       
   402                     ctxt, NULL, XML_FROM_PARSER, error,
       
   403                     XML_ERR_WARNING, NULL, 0,
       
   404             (const char *) str1, (const char *) str2, NULL, 0, 0,
       
   405             msg, (const char *) str1, (const char *) str2);
       
   406 }
       
   407 
       
   408 /**
       
   409  * xmlValidityError:
       
   410  * @param ctxt an XML parser context
       
   411  * @param error the error number
       
   412  * @param msg the error message
       
   413  * @param str1 extra data
       
   414  *
       
   415  * Handle a validity error.
       
   416  */
       
   417 static void
       
   418 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   419               const char *msg, const xmlChar *str1)
       
   420 {
       
   421     xmlStructuredErrorFunc schannel = NULL;
       
   422 
       
   423     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   424         (ctxt->instate == XML_PARSER_EOF))
       
   425     return;
       
   426     ctxt->errNo = error;
       
   427     if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
       
   428         schannel = ctxt->sax->serror;
       
   429     __xmlRaiseError(schannel,
       
   430                     ctxt->vctxt.error, ctxt->vctxt.userData,
       
   431                     ctxt, NULL, XML_FROM_DTD, error,
       
   432                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
       
   433             NULL, NULL, 0, 0,
       
   434             msg, (const char *) str1);
       
   435     ctxt->valid = 0;
       
   436 }
       
   437 
       
   438 /**
       
   439  * xmlFatalErrMsgInt:
       
   440  * @param ctxt an XML parser context
       
   441  * @param error the error number
       
   442  * @param msg the error message
       
   443  * @param val an integer value
       
   444  *
       
   445  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
       
   446  */
       
   447 static void
       
   448 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   449                   const char *msg, int val)
       
   450 {
       
   451     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   452         (ctxt->instate == XML_PARSER_EOF))
       
   453     return;
       
   454     ctxt->errNo = error;
       
   455     __xmlRaiseError(NULL, NULL, NULL,
       
   456                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
       
   457                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
       
   458     ctxt->wellFormed = 0;
       
   459     if (ctxt->recovery == 0)
       
   460         ctxt->disableSAX = 1;
       
   461 }
       
   462 
       
   463 /**
       
   464  * xmlFatalErrMsgStrIntStr:
       
   465  * @param ctxt an XML parser context
       
   466  * @param error the error number
       
   467  * @param msg the error message
       
   468  * @param str1 an string info
       
   469  * @param val an integer value
       
   470  * @param str2 an string info
       
   471  *
       
   472  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
       
   473  */
       
   474 static void
       
   475 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   476                   const char *msg, const xmlChar *str1, int val,
       
   477           const xmlChar *str2)
       
   478 {
       
   479     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   480         (ctxt->instate == XML_PARSER_EOF))
       
   481     return;
       
   482     ctxt->errNo = error;
       
   483     __xmlRaiseError(NULL, NULL, NULL,
       
   484                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
       
   485                     NULL, 0, (const char *) str1, (const char *) str2,
       
   486             NULL, val, 0, msg, str1, val, str2);
       
   487     ctxt->wellFormed = 0;
       
   488     if (ctxt->recovery == 0)
       
   489         ctxt->disableSAX = 1;
       
   490 }
       
   491 
       
   492 /**
       
   493  * xmlFatalErrMsgStr:
       
   494  * @param ctxt an XML parser context
       
   495  * @param error the error number
       
   496  * @param msg the error message
       
   497  * @param val a string value
       
   498  *
       
   499  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
       
   500  */
       
   501 static void
       
   502 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   503                   const char *msg, const xmlChar * val)
       
   504 {
       
   505     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   506         (ctxt->instate == XML_PARSER_EOF))
       
   507     return;
       
   508     ctxt->errNo = error;
       
   509     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
       
   510                     XML_FROM_PARSER, error, XML_ERR_FATAL,
       
   511                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
       
   512                     val);
       
   513     ctxt->wellFormed = 0;
       
   514     if (ctxt->recovery == 0)
       
   515         ctxt->disableSAX = 1;
       
   516 }
       
   517 
       
   518 /**
       
   519  * xmlErrMsgStr:
       
   520  * @param ctxt an XML parser context
       
   521  * @param error the error number
       
   522  * @param msg the error message
       
   523  * @param val a string value
       
   524  *
       
   525  * Handle a non fatal parser error
       
   526  */
       
   527 static void
       
   528 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   529                   const char *msg, const xmlChar * val)
       
   530 {
       
   531     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   532         (ctxt->instate == XML_PARSER_EOF))
       
   533     return;
       
   534     ctxt->errNo = error;
       
   535     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
       
   536                     XML_FROM_PARSER, error, XML_ERR_ERROR,
       
   537                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
       
   538                     val);
       
   539 }
       
   540 
       
   541 /**
       
   542  * xmlNsErr:
       
   543  * @param ctxt an XML parser context
       
   544  * @param error the error number
       
   545  * @param msg the message
       
   546  * @param info1 extra information string
       
   547  * @param info2 extra information string
       
   548  *
       
   549  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
       
   550  */
       
   551 static void
       
   552 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
   553          const char *msg,
       
   554          const xmlChar * info1, const xmlChar * info2,
       
   555          const xmlChar * info3)
       
   556 {
       
   557     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
   558         (ctxt->instate == XML_PARSER_EOF))
       
   559     return;
       
   560     ctxt->errNo = error;
       
   561     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
       
   562                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
       
   563                     (const char *) info2, (const char *) info3, 0, 0, msg,
       
   564                     info1, info2, info3);
       
   565     ctxt->nsWellFormed = 0;
       
   566 }
       
   567 
       
   568 // XMLENGINE: New code
       
   569 /**
       
   570  * xmlParserOOMErr:
       
   571  * @param ctxt an XML parser context
       
   572  *
       
   573  * Handle a OOM error during parsing XML;
       
   574  * parser is set into state that prevents further processing
       
   575  */
       
   576 static void
       
   577 xmlParserOOMErr(xmlParserCtxtPtr ctxt)
       
   578 {
       
   579     // Note: this function is mere a simpler (smaller) form to use
       
   580     // it should not change
       
   581     xmlErrMemory(ctxt, NULL);
       
   582 }
       
   583 //
       
   584 
       
   585 /**
       
   586  * xmlCheckCdataPush:
       
   587  * @param cur pointer to the bock of characters
       
   588  * @param len length of the block in bytes
       
   589  *
       
   590  * Check that the block of characters is okay as SCdata content [20]
       
   591  *
       
   592  * Returns the number of bytes to pass if okay, a negative index where an
       
   593  *         UTF-8 error occured otherwise
       
   594  */
       
   595 static int
       
   596 xmlCheckCdataPush(const xmlChar *utf, int len) {
       
   597     int ix;
       
   598     unsigned char c;
       
   599     int codepoint;
       
   600 
       
   601     if ((utf == NULL) || (len <= 0))
       
   602         return(0);
       
   603 
       
   604     for (ix = 0; ix < len;) {      /* string is 0-terminated */
       
   605         c = utf[ix];
       
   606         if ((c & 0x80) == 0x00) {   /* 1-byte code, starts with 10 */
       
   607         if (c >= 0x20)
       
   608         ix++;
       
   609         else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
       
   610             ix++;
       
   611         else
       
   612             return(-ix);
       
   613     } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
       
   614         if (ix + 2 > len) return(ix);
       
   615         if ((utf[ix+1] & 0xc0 ) != 0x80)
       
   616             return(-ix);
       
   617         codepoint = (utf[ix] & 0x1f) << 6;
       
   618         codepoint |= utf[ix+1] & 0x3f;
       
   619         if (!xmlIsCharQ(codepoint))
       
   620             return(-ix);
       
   621         ix += 2;
       
   622     } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
       
   623         if (ix + 3 > len) return(ix);
       
   624         if (((utf[ix+1] & 0xc0) != 0x80) ||
       
   625             ((utf[ix+2] & 0xc0) != 0x80))
       
   626             return(-ix);
       
   627         codepoint = (utf[ix] & 0xf) << 12;
       
   628         codepoint |= (utf[ix+1] & 0x3f) << 6;
       
   629         codepoint |= utf[ix+2] & 0x3f;
       
   630         if (!xmlIsCharQ(codepoint))
       
   631             return(-ix);
       
   632         ix += 3;
       
   633     } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
       
   634         if (ix + 4 > len) return(ix);
       
   635         if (((utf[ix+1] & 0xc0) != 0x80) ||
       
   636             ((utf[ix+2] & 0xc0) != 0x80) ||
       
   637         ((utf[ix+3] & 0xc0) != 0x80))
       
   638             return(-ix);
       
   639         codepoint = (utf[ix] & 0x7) << 18;
       
   640         codepoint |= (utf[ix+1] & 0x3f) << 12;
       
   641         codepoint |= (utf[ix+2] & 0x3f) << 6;
       
   642         codepoint |= utf[ix+3] & 0x3f;
       
   643         if (!xmlIsCharQ(codepoint))
       
   644             return(-ix);
       
   645         ix += 4;
       
   646     } else              /* unknown encoding */
       
   647         return(-ix);
       
   648       }
       
   649       return(ix);
       
   650 }
       
   651 
       
   652 /************************************************************************
       
   653  *                                                                      *
       
   654  *      SAX2 defaulted attributes handling                              *
       
   655  *                                                                      *
       
   656  ************************************************************************/
       
   657 
       
   658 /**
       
   659  * xmlDetectSAX2:
       
   660  * @param ctxt an XML parser context
       
   661  *
       
   662  * Do the SAX2 detection and specific intialization
       
   663  *
       
   664  * OOM: possible --> OOM flag is set
       
   665  */
       
   666 static void
       
   667 xmlDetectSAX2(xmlParserCtxtPtr ctxt)
       
   668 {
       
   669     if (!ctxt)
       
   670         return;
       
   671 #ifdef LIBXML_SAX1_ENABLED
       
   672     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
       
   673         ((ctxt->sax->startElementNs != NULL) ||
       
   674          (ctxt->sax->endElementNs != NULL)))
       
   675     {
       
   676         ctxt->sax2 = 1;
       
   677     }
       
   678 #else
       
   679     ctxt->sax2 = 1;
       
   680 #endif /* LIBXML_SAX1_ENABLED */
       
   681     // Each of these can end with OOM condition
       
   682     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
       
   683     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
       
   684     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
       
   685     if(ctxt->sax && ctxt->sax->startElementNs == xmlSAX2StartElementNs)
       
   686 		{
       
   687 		ctxt->stackLowThreshold = MIN_STACK_THRESHOLD;
       
   688 		}
       
   689 	else
       
   690 		{
       
   691 		ctxt->stackLowThreshold = MAX_STACK_THRESHOLD;
       
   692 		}
       
   693 }
       
   694 
       
   695 typedef struct _xmlDefAttrs xmlDefAttrs;
       
   696 typedef xmlDefAttrs *xmlDefAttrsPtr;
       
   697 struct _xmlDefAttrs {
       
   698     int nbAttrs;    /* number of defaulted attributes on that element */
       
   699     int maxAttrs;       /* the size of the array */
       
   700     const xmlChar *values[4]; /* array of localname/prefix/values */
       
   701 };
       
   702 
       
   703 /**
       
   704  * xmlAddDefAttrs:
       
   705  * @param ctxt an XML parser context
       
   706  * @param fullname the element fullname
       
   707  * @param fullattr the attribute fullname
       
   708  * @param value the attribute value
       
   709  *
       
   710  * Add a defaulted attribute for an element
       
   711  */
       
   712 static void
       
   713 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
       
   714                const xmlChar *fullname,
       
   715                const xmlChar *fullattr,
       
   716                const xmlChar *value)
       
   717 {
       
   718     xmlDefAttrsPtr defaults;
       
   719     int len;
       
   720     const xmlChar* name;
       
   721     const xmlChar* prefix;
       
   722     LOAD_GS_SAFE_CTXT(ctxt)
       
   723 
       
   724     if (ctxt->attsDefault == NULL) {
       
   725         ctxt->attsDefault = xmlHashCreate(10);
       
   726         if (ctxt->attsDefault == NULL)
       
   727             goto mem_error;
       
   728     }
       
   729 
       
   730     /*
       
   731      * split the element name into prefix:localname , the string found
       
   732      * are within the DTD and then not associated to namespace names.
       
   733      */
       
   734     name = xmlSplitQName3(fullname, &len);
       
   735     if (name == NULL) {
       
   736         name = xmlDictLookup(ctxt->dict, fullname, -1);
       
   737         prefix = NULL;
       
   738     } else {
       
   739         name = xmlDictLookup(ctxt->dict, name, -1);
       
   740         prefix = xmlDictLookup(ctxt->dict, fullname, len);
       
   741     }
       
   742 
       
   743     /*
       
   744      * make sure there is some storage
       
   745      */
       
   746     defaults = (xmlDefAttrsPtr)xmlHashLookup2(ctxt->attsDefault, name, prefix);
       
   747     if (defaults == NULL)
       
   748     {
       
   749         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
       
   750                                    12 * sizeof(const xmlChar *));
       
   751         if (defaults == NULL)
       
   752             goto mem_error;
       
   753         defaults->maxAttrs = 4;
       
   754         defaults->nbAttrs = 0;
       
   755         if ( xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL) == -1 ) 
       
   756             {
       
   757             xmlFree( defaults );
       
   758             return ;   
       
   759             }
       
   760         if ( OOM_FLAG )
       
   761             return ;
       
   762     }
       
   763     else if (defaults->nbAttrs >= defaults->maxAttrs)
       
   764     {
       
   765         // DONE: Fix xmlRealloc
       
   766         // NOTE: nothing to fix since 'defaults' is stored in hash table
       
   767         defaults = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
       
   768                    (2 * defaults->maxAttrs * 4) * sizeof(const xmlChar*));
       
   769         if (defaults == NULL)
       
   770             goto mem_error;
       
   771         defaults->maxAttrs *= 2;
       
   772         if ( xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL) == -1 ) 
       
   773             {
       
   774             xmlFree( defaults );
       
   775             return ;   
       
   776             }
       
   777         if ( OOM_FLAG )
       
   778             return ;
       
   779     }
       
   780 
       
   781     /*
       
   782      * split the element name into prefix:localname , the string found
       
   783      * are within the DTD and then not associated to namespace names.
       
   784      */
       
   785     name = xmlSplitQName3(fullattr, &len);
       
   786     if (name == NULL) {
       
   787         name = xmlDictLookup(ctxt->dict, fullattr, -1);
       
   788         prefix = NULL;
       
   789     } else {
       
   790         name = xmlDictLookup(ctxt->dict, name, -1);
       
   791         prefix = xmlDictLookup(ctxt->dict, fullattr, len);
       
   792     }
       
   793 
       
   794     defaults->values[4 * defaults->nbAttrs] = name;
       
   795     defaults->values[4 * defaults->nbAttrs + 1] = prefix;
       
   796     /* intern the string and precompute the end */
       
   797     len = xmlStrlen(value);
       
   798     value = xmlDictLookup(ctxt->dict, value, len);
       
   799     defaults->values[4 * defaults->nbAttrs + 2] = value;
       
   800     defaults->values[4 * defaults->nbAttrs + 3] = value + len;
       
   801     defaults->nbAttrs++;
       
   802 
       
   803     return;
       
   804 
       
   805 mem_error:
       
   806     xmlErrMemory(ctxt, NULL);
       
   807     return;
       
   808 }
       
   809 
       
   810 /**
       
   811  * xmlAddSpecialAttr:
       
   812  * @param ctxt an XML parser context
       
   813  * @param fullname the element fullname
       
   814  * @param fullattr the attribute fullname
       
   815  * @param type the attribute type
       
   816  *
       
   817  * Register that this attribute is not CDATA
       
   818  */
       
   819 static void
       
   820 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
       
   821           const xmlChar *fullname,
       
   822           const xmlChar *fullattr,
       
   823           int type)
       
   824 {
       
   825     if (ctxt->attsSpecial == NULL) {
       
   826         ctxt->attsSpecial = xmlHashCreate(10);
       
   827     if (ctxt->attsSpecial == NULL)
       
   828         goto mem_error;
       
   829     }
       
   830 
       
   831     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
       
   832                      (void *) (long) type);
       
   833     return;
       
   834 
       
   835 mem_error:
       
   836     xmlParserOOMErr(ctxt);
       
   837     return;
       
   838 }
       
   839 
       
   840 /**
       
   841  * xmlCheckLanguageID:
       
   842  * @param lang pointer to the string value
       
   843  *
       
   844  * Checks that the value conforms to the LanguageID production:
       
   845  *
       
   846  * NOTE: this is somewhat deprecated, those productions were removed from
       
   847  *       the XML Second edition.
       
   848  *
       
   849  * [33] LanguageID ::= Langcode ('-' Subcode)*
       
   850  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
       
   851  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
       
   852  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
       
   853  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
       
   854  * [38] Subcode ::= ([a-z] | [A-Z])+
       
   855  *
       
   856  * Returns 1 if correct 0 otherwise
       
   857  **/
       
   858 XMLPUBFUNEXPORT int
       
   859 xmlCheckLanguageID(const xmlChar * lang)
       
   860 {
       
   861     const xmlChar *cur = lang;
       
   862 
       
   863     if (cur == NULL)
       
   864         return (0);
       
   865     if (((cur[0] == 'i') && (cur[1] == '-')) ||
       
   866         ((cur[0] == 'I') && (cur[1] == '-'))) {
       
   867         /*
       
   868          * IANA code
       
   869          */
       
   870         cur += 2;
       
   871         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
       
   872                ((cur[0] >= 'a') && (cur[0] <= 'z')))
       
   873             cur++;
       
   874     } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
       
   875                ((cur[0] == 'X') && (cur[1] == '-'))) {
       
   876         /*
       
   877          * User code
       
   878          */
       
   879         cur += 2;
       
   880         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
       
   881                ((cur[0] >= 'a') && (cur[0] <= 'z')))
       
   882             cur++;
       
   883     } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
       
   884                ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
       
   885         /*
       
   886          * ISO639
       
   887          */
       
   888         cur++;
       
   889         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
       
   890             ((cur[0] >= 'a') && (cur[0] <= 'z')))
       
   891             cur++;
       
   892         else
       
   893             return (0);
       
   894     } else
       
   895         return (0);
       
   896     while (cur[0] != 0) {       /* non input consuming */
       
   897         if (cur[0] != '-')
       
   898             return (0);
       
   899         cur++;
       
   900         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
       
   901             ((cur[0] >= 'a') && (cur[0] <= 'z')))
       
   902             cur++;
       
   903         else
       
   904             return (0);
       
   905         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
       
   906                ((cur[0] >= 'a') && (cur[0] <= 'z')))
       
   907             cur++;
       
   908     }
       
   909     return (1);
       
   910 }
       
   911 
       
   912 /************************************************************************
       
   913  *                                                                      *
       
   914  *      Parser stacks related functions and macros                      *
       
   915  *                                                                      *
       
   916  ************************************************************************/
       
   917 
       
   918 xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
       
   919                                      const xmlChar** str);
       
   920 
       
   921 #ifdef SAX2
       
   922 /**
       
   923  * nsPush:
       
   924  * @param ctxt an XML parser context
       
   925  * @param prefix the namespace prefix or NULL
       
   926  * @param URL the namespace name
       
   927  *
       
   928  * Pushes a new parser namespace on top of the ns stack
       
   929  *
       
   930  * Returns -1 in case of error, -2 if the namespace should be discarded
       
   931  *     and the index in the stack otherwise.
       
   932  */
       
   933 static int
       
   934 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
       
   935 {
       
   936     if (ctxt->options & XML_PARSE_NSCLEAN)
       
   937     {
       
   938         int i;
       
   939         for (i = 0; i < ctxt->nsNr; i += 2)
       
   940         {
       
   941             if (ctxt->nsTab[i] == prefix)
       
   942             {
       
   943                 /* in scope */
       
   944                 if (ctxt->nsTab[i + 1] == URL)
       
   945                     return(-2);
       
   946                 /* out of scope keep it */
       
   947                 break;
       
   948             }
       
   949         }
       
   950     }
       
   951     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
       
   952     ctxt->nsMax = 10; 
       
   953     ctxt->nsNr = 0;
       
   954     
       
   955     ctxt->nsTab = (const xmlChar **)
       
   956                   xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
       
   957     if (ctxt->nsTab == NULL) {
       
   958         xmlParserOOMErr(ctxt);
       
   959         ctxt->nsMax = 0;
       
   960             return (-1);
       
   961     }
       
   962     } else if (ctxt->nsNr >= ctxt->nsMax) {
       
   963         const xmlChar** largerTab;
       
   964 
       
   965         ctxt->nsMax *= 2;
       
   966         // DONE: Fix memory leak here (when realloc returns NULL)
       
   967         largerTab = (const xmlChar **)
       
   968                   xmlRealloc((char *) ctxt->nsTab,
       
   969                  ctxt->nsMax * sizeof(ctxt->nsTab[0]));
       
   970         if (!largerTab) {
       
   971             xmlParserOOMErr(ctxt);
       
   972             ctxt->nsMax /= 2;
       
   973             return (-1);
       
   974         }
       
   975         ctxt->nsTab = largerTab;
       
   976     }
       
   977     ctxt->nsTab[ctxt->nsNr++] = prefix;
       
   978     ctxt->nsTab[ctxt->nsNr++] = URL;
       
   979 // XE: BEGIN NEW CODE
       
   980     /*
       
   981     * SAX: prefix mapping !
       
   982     */
       
   983     if ((ctxt->sax != NULL) &&
       
   984         (ctxt->sax->startPrefixMapping != NULL) &&
       
   985         (!ctxt->disableSAX))
       
   986     {
       
   987         ctxt->sax->startPrefixMapping(ctxt->userData, prefix, URL);
       
   988     }
       
   989 // XE: END NEW CODE
       
   990     return (ctxt->nsNr);
       
   991 }
       
   992 /**
       
   993  * nsPop:
       
   994  * @param ctxt an XML parser context
       
   995  * @param nr the number to pop
       
   996  *
       
   997  * Pops the top nr parser prefix/namespace from the ns stack
       
   998  *
       
   999  * Returns the number of namespaces removed
       
  1000  */
       
  1001 static int
       
  1002 nsPop(xmlParserCtxtPtr ctxt, int nr)
       
  1003 {
       
  1004     int i;
       
  1005 	
       
  1006     if (ctxt->nsTab == NULL) return(0);
       
  1007     if (ctxt->nsNr < nr) {
       
  1008         xmlGenericError(xmlGenericErrorContext, EMBED_ERRTXT("Pbm popping %d NS\n"), nr);
       
  1009         nr = ctxt->nsNr;
       
  1010     }
       
  1011     if (ctxt->nsNr <= 0)
       
  1012         return (0);
       
  1013 
       
  1014 // XE: REPLACED CODE
       
  1015     //for (i = 0;i < nr;i++) {
       
  1016     // nr is even number, because pairs of (URL,prefix) are removed from ctxt->nsTab[] array
       
  1017     // by this moment ctxt->nsNr points to the next free cell after  ...{prefix}{URL}{..}...
       
  1018     //                                                  ctxt->nsTab[ctxt->nsNr]-------^
       
  1019 // XE: REPLACED WITH
       
  1020     for (i = nr/2; i > 0; i--) {
       
  1021          ctxt->nsNr--;
       
  1022          ctxt->nsTab[ctxt->nsNr] = NULL; // clean up URL
       
  1023          ctxt->nsNr--;
       
  1024 // XE: BEGIN NEW CODE
       
  1025         
       
  1026         /*
       
  1027         * SAX: end of prefix mapping !
       
  1028         */
       
  1029         if ((ctxt->sax != NULL) &&
       
  1030             (ctxt->sax->endPrefixMapping != NULL) &&
       
  1031             (!ctxt->disableSAX))
       
  1032         {
       
  1033             ctxt->sax->endPrefixMapping(ctxt->userData, ctxt->nsTab[ctxt->nsNr]);
       
  1034         }
       
  1035 // XE: END NEW CODE
       
  1036          ctxt->nsTab[ctxt->nsNr] = NULL; // clean up prefix name
       
  1037 
       
  1038          
       
  1039     }
       
  1040     return(nr);
       
  1041 }
       
  1042 #endif
       
  1043 
       
  1044 static int
       
  1045 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
       
  1046     const xmlChar **atts;
       
  1047     int *attallocs;
       
  1048     int maxatts;
       
  1049 
       
  1050     if (ctxt->atts == NULL) {
       
  1051     maxatts = 55; /* allow for 10 attrs by default */
       
  1052     atts = (const xmlChar **)
       
  1053            xmlMalloc(maxatts * sizeof(xmlChar *));
       
  1054     if (atts == NULL) goto mem_error;
       
  1055     ctxt->atts = atts;
       
  1056     attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
       
  1057     if (attallocs == NULL) goto mem_error;
       
  1058     ctxt->attallocs = attallocs;
       
  1059     ctxt->maxatts = maxatts;
       
  1060     } else if (nr + 5 > ctxt->maxatts) {
       
  1061     maxatts = (nr + 5) * 2;
       
  1062     atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
       
  1063                      maxatts * sizeof(const xmlChar *));
       
  1064     if (atts == NULL) goto mem_error;
       
  1065     ctxt->atts = atts;
       
  1066     attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
       
  1067                                  (maxatts / 5) * sizeof(int));
       
  1068     if (attallocs == NULL) goto mem_error;
       
  1069     ctxt->attallocs = attallocs;
       
  1070     ctxt->maxatts = maxatts;
       
  1071     }
       
  1072     return(ctxt->maxatts);
       
  1073 mem_error:
       
  1074     xmlParserOOMErr(ctxt);
       
  1075     return(-1);
       
  1076 }
       
  1077 
       
  1078 /**
       
  1079  * inputPush:
       
  1080  * @param ctxt an XML parser context
       
  1081  * @param value the parser input
       
  1082  *
       
  1083  * Pushes a new parser input on top of the input stack
       
  1084  *
       
  1085  * Returns -1 in case of error, the index in the stack otherwise
       
  1086  *
       
  1087  * OOM: possible --> returns -1 and OOM flag is set
       
  1088  */
       
  1089 XMLPUBFUNEXPORT int
       
  1090 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
       
  1091 {
       
  1092     if (ctxt->inputNr >= ctxt->inputMax)
       
  1093     {
       
  1094         // DONE: Fix xmlRealloc
       
  1095         void* tmp;
       
  1096         ctxt->inputMax *= 2;
       
  1097         tmp = xmlRealloc(ctxt->inputTab,
       
  1098                          ctxt->inputMax * sizeof(ctxt->inputTab[0]));
       
  1099         if (!tmp) {
       
  1100             ctxt->inputMax /= 2;
       
  1101             xmlParserOOMErr(ctxt);
       
  1102             return (-1);
       
  1103         }
       
  1104         ctxt->inputTab = (xmlParserInputPtr*) tmp;
       
  1105     }
       
  1106     ctxt->inputTab[ctxt->inputNr] = value;
       
  1107     ctxt->input = value;
       
  1108     return (ctxt->inputNr++);
       
  1109 }
       
  1110 
       
  1111 /**
       
  1112  * inputPop:
       
  1113  * @param ctxt an XML parser context
       
  1114  *
       
  1115  * Pops the top parser input from the input stack
       
  1116  *
       
  1117  * Returns the input just removed
       
  1118  */
       
  1119 XMLPUBFUNEXPORT xmlParserInputPtr
       
  1120 inputPop(xmlParserCtxtPtr ctxt)
       
  1121 {
       
  1122     xmlParserInputPtr ret;
       
  1123 
       
  1124     if (ctxt->inputNr <= 0)
       
  1125         return (0);
       
  1126     ctxt->inputNr--;
       
  1127     if (ctxt->inputNr > 0)
       
  1128         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
       
  1129     else
       
  1130         ctxt->input = NULL;
       
  1131     ret = ctxt->inputTab[ctxt->inputNr];
       
  1132     ctxt->inputTab[ctxt->inputNr] = 0;
       
  1133     return (ret);
       
  1134 }
       
  1135 /**
       
  1136  * nodePush:
       
  1137  * @param ctxt an XML parser context
       
  1138  * @param value the element node
       
  1139  *
       
  1140  * Pushes a new element node on top of the node stack
       
  1141  *
       
  1142  * Returns 0 in case of error, the index in the stack otherwise
       
  1143  */
       
  1144 XMLPUBFUNEXPORT int
       
  1145 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
       
  1146 {
       
  1147 	LOAD_GS_SAFE_CTXT(ctxt)
       
  1148     if (ctxt->nodeNr >= ctxt->nodeMax)
       
  1149     {
       
  1150         // DONE: Fix xmlRealloc
       
  1151         void* tmp;
       
  1152         ctxt->nodeMax *= 2;
       
  1153         tmp = xmlRealloc(ctxt->nodeTab,
       
  1154                          ctxt->nodeMax * sizeof(ctxt->nodeTab[0]));
       
  1155         if (!tmp) {
       
  1156             ctxt->nodeMax /= 2;
       
  1157             xmlParserOOMErr(ctxt);
       
  1158             return (0);
       
  1159         }
       
  1160         ctxt->nodeTab = (xmlNodePtr*) tmp;
       
  1161     }
       
  1162 
       
  1163     if (((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth)
       
  1164     {
       
  1165         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
       
  1166             EMBED_ERRTXT("Excessive depth in document: change xmlParserMaxDepth = %d\n"),
       
  1167             xmlParserMaxDepth);
       
  1168         ctxt->instate = XML_PARSER_EOF;
       
  1169         return(0);
       
  1170     }
       
  1171 
       
  1172     ctxt->nodeTab[ctxt->nodeNr] = value;
       
  1173     ctxt->node = value;
       
  1174     return (ctxt->nodeNr++);
       
  1175 }
       
  1176 
       
  1177 /**
       
  1178  * nodePop:
       
  1179  * @param ctxt an XML parser context
       
  1180  *
       
  1181  * Pops the top element node from the node stack
       
  1182  *
       
  1183  * Returns the node just removed
       
  1184  */
       
  1185 XMLPUBFUNEXPORT xmlNodePtr
       
  1186 nodePop(xmlParserCtxtPtr ctxt)
       
  1187 {
       
  1188     xmlNodePtr ret;
       
  1189 
       
  1190     if (ctxt->nodeNr <= 0)
       
  1191         return (0);
       
  1192     ctxt->nodeNr--;
       
  1193     if (ctxt->nodeNr > 0)
       
  1194         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
       
  1195     else
       
  1196         ctxt->node = NULL;
       
  1197     ret = ctxt->nodeTab[ctxt->nodeNr];
       
  1198     ctxt->nodeTab[ctxt->nodeNr] = 0;
       
  1199     return (ret);
       
  1200 }
       
  1201 /**
       
  1202  * nameNsPush:
       
  1203  * @param ctxt an XML parser context
       
  1204  * @param value the element name
       
  1205  * @param prefix the element prefix
       
  1206  * @param URI the element namespace name
       
  1207  *
       
  1208  * Pushes a new element name/prefix/URL on top of the name stack
       
  1209  *
       
  1210  * Returns -1 in case of error, the index in the stack otherwise
       
  1211  */
       
  1212 static int
       
  1213 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
       
  1214            const xmlChar *prefix, const xmlChar *URI, int nsNr)
       
  1215 {
       
  1216     if (ctxt->nameNr >= ctxt->nameMax) {
       
  1217         const xmlChar * *tmp;
       
  1218         void **tmp2;
       
  1219         ctxt->nameMax *= 2;
       
  1220         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
       
  1221                                     ctxt->nameMax *
       
  1222                                     sizeof(ctxt->nameTab[0]));
       
  1223         if (tmp == NULL) {
       
  1224         ctxt->nameMax /= 2;
       
  1225         goto mem_error;
       
  1226         }
       
  1227     ctxt->nameTab = tmp;
       
  1228         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
       
  1229                                     ctxt->nameMax * 3 *
       
  1230                                     sizeof(ctxt->pushTab[0]));
       
  1231         if (tmp2 == NULL) {
       
  1232         ctxt->nameMax /= 2;
       
  1233         goto mem_error;
       
  1234         }
       
  1235     ctxt->pushTab = tmp2;
       
  1236     }
       
  1237     ctxt->nameTab[ctxt->nameNr] = value;
       
  1238     ctxt->name = value;
       
  1239     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
       
  1240     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
       
  1241     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
       
  1242     return (ctxt->nameNr++);
       
  1243 mem_error:
       
  1244     xmlParserOOMErr(ctxt);
       
  1245     return (-1);
       
  1246 }
       
  1247 /**
       
  1248  * nameNsPop:
       
  1249  * @param ctxt an XML parser context
       
  1250  *
       
  1251  * Pops the top element/prefix/URI name from the name stack
       
  1252  *
       
  1253  * Returns the name just removed
       
  1254  */
       
  1255 static const xmlChar *
       
  1256 nameNsPop(xmlParserCtxtPtr ctxt)
       
  1257 {
       
  1258     const xmlChar *ret;
       
  1259 
       
  1260     if (ctxt->nameNr <= 0)
       
  1261         return (0);
       
  1262     ctxt->nameNr--;
       
  1263     if (ctxt->nameNr > 0)
       
  1264         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
       
  1265     else
       
  1266         ctxt->name = NULL;
       
  1267     ret = ctxt->nameTab[ctxt->nameNr];
       
  1268     ctxt->nameTab[ctxt->nameNr] = NULL;
       
  1269     return (ret);
       
  1270 }
       
  1271 
       
  1272 /**
       
  1273  * namePush:
       
  1274  * @param ctxt an XML parser context
       
  1275  * @param value the element name
       
  1276  *
       
  1277  * Pushes a new element name on top of the name stack
       
  1278  *
       
  1279  * Returns -1 in case of error, the index in the stack otherwise
       
  1280  */
       
  1281 XMLPUBFUNEXPORT extern int
       
  1282 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
       
  1283 {
       
  1284     if (ctxt->nameNr >= ctxt->nameMax) {
       
  1285         const xmlChar** tmp;
       
  1286         ctxt->nameMax *= 2;
       
  1287         tmp = (const xmlChar**) xmlRealloc((xmlChar**)ctxt->nameTab,
       
  1288                                     ctxt->nameMax *
       
  1289                                     sizeof(ctxt->nameTab[0]));
       
  1290         if (!tmp) {
       
  1291             ctxt->nameMax /= 2;
       
  1292             xmlParserOOMErr(ctxt);
       
  1293             return (-1);
       
  1294         }
       
  1295         ctxt->nameTab = tmp;
       
  1296     }
       
  1297     ctxt->nameTab[ctxt->nameNr] = value;
       
  1298     ctxt->name = value;
       
  1299     return (ctxt->nameNr++);
       
  1300 }
       
  1301 
       
  1302 /**
       
  1303  * namePop:
       
  1304  * @param ctxt an XML parser context
       
  1305  *
       
  1306  * Pops the top element name from the name stack
       
  1307  *
       
  1308  * Returns the name just removed
       
  1309  */
       
  1310 XMLPUBFUNEXPORT extern const xmlChar*
       
  1311 namePop(xmlParserCtxtPtr ctxt)
       
  1312 {
       
  1313     const xmlChar *ret;
       
  1314 
       
  1315     if (ctxt->nameNr <= 0)
       
  1316         return (0);
       
  1317     ctxt->nameNr--;
       
  1318     if (ctxt->nameNr > 0)
       
  1319         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
       
  1320     else
       
  1321         ctxt->name = NULL;
       
  1322     ret = ctxt->nameTab[ctxt->nameNr];
       
  1323     ctxt->nameTab[ctxt->nameNr] = 0;
       
  1324     return (ret);
       
  1325 }
       
  1326 
       
  1327 static int spacePush(xmlParserCtxtPtr ctxt, int val)
       
  1328 {
       
  1329     if (ctxt->spaceNr >= ctxt->spaceMax) {
       
  1330         // DONE: Fix xmlRealloc
       
  1331         void* tmp;
       
  1332         ctxt->spaceMax *= 2;
       
  1333         tmp = xmlRealloc(ctxt->spaceTab,
       
  1334                  ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
       
  1335         if (!tmp) {
       
  1336             ctxt->spaceMax /= 2;
       
  1337             xmlParserOOMErr(ctxt);
       
  1338             return(0);
       
  1339         }
       
  1340         ctxt->spaceTab = (int*) tmp;
       
  1341     }
       
  1342     ctxt->spaceTab[ctxt->spaceNr] = val;
       
  1343     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
       
  1344     return(ctxt->spaceNr++);
       
  1345 }
       
  1346 
       
  1347 static int spacePop(xmlParserCtxtPtr ctxt)
       
  1348 {
       
  1349     int ret;
       
  1350     if (ctxt->spaceNr <= 0) return(0);
       
  1351     ctxt->spaceNr--;
       
  1352     if (ctxt->spaceNr > 0)
       
  1353     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
       
  1354     else
       
  1355         ctxt->space = NULL;
       
  1356     ret = ctxt->spaceTab[ctxt->spaceNr];
       
  1357     ctxt->spaceTab[ctxt->spaceNr] = -1;
       
  1358     return(ret);
       
  1359 }
       
  1360 
       
  1361 /*
       
  1362  * Macros for accessing the content. Those should be used only by the parser,
       
  1363  * and not exported.
       
  1364  *
       
  1365  * Dirty macros, i.e. one often need to make assumption on the context to
       
  1366  * use them
       
  1367  *
       
  1368  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
       
  1369  *           To be used with extreme caution since operations consuming
       
  1370  *           characters may move the input buffer to a different location !
       
  1371  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
       
  1372  *           This should be used internally by the parser
       
  1373  *           only to compare to ASCII values otherwise it would break when
       
  1374  *           running with UTF-8 encoding.
       
  1375  *   RAW     same as CUR but in the input buffer, bypass any token
       
  1376  *           extraction that may have been done
       
  1377  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
       
  1378  *           to compare on ASCII based substring.
       
  1379  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
       
  1380  *           strings without newlines within the parser.
       
  1381  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
       
  1382  *           defined char within the parser.
       
  1383  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
       
  1384  *
       
  1385  *   NEXT    Skip to the next character, this does the proper decoding
       
  1386  *           in UTF-8 mode. It also pop-up unfinishedEntities on the fly.
       
  1387  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
       
  1388  *   CUR_CHAR(l) returns the current unicode character (int), set l
       
  1389  *           to the number of xmlChars used for the encoding [0-5].
       
  1390  *   CUR_SCHAR  same but operate on a string instead of the context
       
  1391  *   COPY_BUF  copy the current unicode char to the target buffer, increment
       
  1392  *            the index
       
  1393  *   GROW, SHRINK  handling of input buffers
       
  1394  */
       
  1395 
       
  1396 #define RAW (*ctxt->input->cur)
       
  1397 #define CUR (*ctxt->input->cur)
       
  1398 #define NXT(val) ctxt->input->cur[(val)]
       
  1399 #define CUR_PTR ctxt->input->cur
       
  1400 
       
  1401 #define CMP4( s, c1, c2, c3, c4 ) \
       
  1402   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
       
  1403     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
       
  1404 #define CMP5( s, c1, c2, c3, c4, c5 ) \
       
  1405   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
       
  1406 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
       
  1407   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
       
  1408 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
       
  1409   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
       
  1410 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
       
  1411   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
       
  1412 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
       
  1413   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
       
  1414     ((unsigned char *) s)[ 8 ] == c9 )
       
  1415 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
       
  1416   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
       
  1417     ((unsigned char *) s)[ 9 ] == c10 )
       
  1418 
       
  1419 #define SKIP(val) do {                          \
       
  1420     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);           \
       
  1421     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
       
  1422     if ((*ctxt->input->cur == 0) &&                 \
       
  1423         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))        \
       
  1424         xmlPopInput(ctxt);                      \
       
  1425   } while (0)
       
  1426 
       
  1427 #define SKIPL(val) do {                         \
       
  1428     int skipl;                              \
       
  1429     for(skipl=0; skipl<val; skipl++) {                  \
       
  1430         if (*(ctxt->input->cur) == '\n') {              \
       
  1431     ctxt->input->line++; ctxt->input->col = 1;          \
       
  1432         } else ctxt->input->col++;                  \
       
  1433         ctxt->nbChars++;                        \
       
  1434     ctxt->input->cur++;                     \
       
  1435     }                                   \
       
  1436     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
       
  1437     if ((*ctxt->input->cur == 0) &&                 \
       
  1438         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))        \
       
  1439         xmlPopInput(ctxt);                      \
       
  1440   } while (0)
       
  1441 
       
  1442 #define SHRINK if ((ctxt->progressive == 0) &&              \
       
  1443            (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
       
  1444            (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
       
  1445     xmlSHRINK (ctxt);
       
  1446 
       
  1447 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
       
  1448     xmlParserInputShrink(ctxt->input);
       
  1449     if ((*ctxt->input->cur == 0) &&
       
  1450         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
       
  1451         xmlPopInput(ctxt);
       
  1452   }
       
  1453 
       
  1454 /**
       
  1455 OOM: possible --> OOM flag is set
       
  1456 */
       
  1457 #define GROW if ((ctxt->progressive == 0) &&                \
       
  1458          (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
       
  1459     xmlGROW (ctxt);
       
  1460 
       
  1461 /**
       
  1462 OOM: possible --> OOM flag is set
       
  1463 */
       
  1464 static void xmlGROW (xmlParserCtxtPtr ctxt) {
       
  1465     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
       
  1466     if ((*ctxt->input->cur == 0) &&
       
  1467         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
       
  1468     {   
       
  1469         xmlPopInput(ctxt);
       
  1470     }
       
  1471 }
       
  1472 
       
  1473 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
       
  1474 
       
  1475 /*
       
  1476  * OOM: possible --> check OOM flag
       
  1477  */
       
  1478 #define NEXT xmlNextChar(ctxt)
       
  1479 
       
  1480 #define NEXT1 {                             \
       
  1481     ctxt->input->col++;                     \
       
  1482     ctxt->input->cur++;                     \
       
  1483     ctxt->nbChars++;                        \
       
  1484     if (*ctxt->input->cur == 0)                 \
       
  1485         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);       \
       
  1486     }
       
  1487 
       
  1488 // OOM: not reviewed yet
       
  1489 
       
  1490 
       
  1491 #define NEXTL(l) do {                               \
       
  1492     if (*(ctxt->input->cur) == '\n') {              \
       
  1493         ctxt->input->line++; ctxt->input->col = 1;  \
       
  1494     }else{                                          \
       
  1495         ctxt->input->col++;                         \
       
  1496     }                                               \
       
  1497     ctxt->input->cur += l;                          \
       
  1498     if (*ctxt->input->cur == '%')                   \
       
  1499         xmlParserHandlePEReference(ctxt);           \
       
  1500   } while (0)
       
  1501 
       
  1502 // OOM: possible --> sets flag when returns 0
       
  1503 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
       
  1504 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
       
  1505 
       
  1506 #define COPY_BUF(l,b,i,v)                       \
       
  1507     if (l == 1) b[i++] = (xmlChar) v;                   \
       
  1508     else i += xmlCopyCharMultiByte(&b[i],v)
       
  1509 
       
  1510 /**
       
  1511  * xmlSkipBlankChars:
       
  1512  * @param ctxt the XML parser context
       
  1513  *
       
  1514  * skip all blanks character found at that point in the input streams.
       
  1515  * It pops up finished entities in the process if allowable at that point.
       
  1516  *
       
  1517  * Returns the number of space chars skipped
       
  1518  *
       
  1519  * OOM: possible -->
       
  1520  */
       
  1521 XMLPUBFUNEXPORT int
       
  1522 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
       
  1523     int res = 0;
       
  1524     /*
       
  1525      * It's Okay to use CUR/NEXT here since all the blanks are on
       
  1526      * the ASCII range.
       
  1527      */
       
  1528     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
       
  1529         const xmlChar *cur;
       
  1530         /*
       
  1531         * if we are in the document content, go really fast
       
  1532         */
       
  1533         cur = ctxt->input->cur;
       
  1534         while (IS_BLANK_CH(*cur)) {
       
  1535             if (*cur == '\n') {
       
  1536                 ctxt->input->line++; ctxt->input->col = 1;
       
  1537             }
       
  1538             cur++;
       
  1539             res++;
       
  1540             if (*cur == 0) {
       
  1541                 ctxt->input->cur = cur;
       
  1542                 xmlParserInputGrow(ctxt->input, INPUT_CHUNK); 
       
  1543                 cur = ctxt->input->cur;
       
  1544             }
       
  1545         }
       
  1546         ctxt->input->cur = cur;
       
  1547     } else {
       
  1548         int cur;
       
  1549         do {
       
  1550             cur = CUR;
       
  1551             while (IS_BLANK(cur)) { /* CHECKED tstblanks.xml */
       
  1552                 NEXT;
       
  1553                 cur = CUR;
       
  1554                 res++;
       
  1555             }
       
  1556             while ((cur == 0) && (ctxt->inputNr > 1) &&
       
  1557                    (ctxt->instate != XML_PARSER_COMMENT)) {
       
  1558                 xmlPopInput(ctxt);
       
  1559                 cur = CUR;
       
  1560             }
       
  1561             /*
       
  1562             * Need to handle support of entities branching here
       
  1563             */
       
  1564             if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
       
  1565         } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
       
  1566     }
       
  1567     return(res);
       
  1568 }
       
  1569 
       
  1570 /************************************************************************
       
  1571  *                                                                      *
       
  1572  *      Commodity functions to handle entities                          *
       
  1573  *                                                                      *
       
  1574  ************************************************************************/
       
  1575 
       
  1576 /**
       
  1577  * xmlPopInput:
       
  1578  * @param ctxt an XML parser context
       
  1579  *
       
  1580  * xmlPopInput: the current input pointed by ctxt->input came to an end
       
  1581  *          pop it and return the next char.
       
  1582  *
       
  1583  * Returns the current xmlChar in the parser context
       
  1584  *
       
  1585  * OOM: possible --> check OOM flag!!!
       
  1586  */
       
  1587 XMLPUBFUNEXPORT xmlChar
       
  1588 xmlPopInput(xmlParserCtxtPtr ctxt) {
       
  1589 	
       
  1590 	LOAD_GS_SAFE_CTXT(ctxt)
       
  1591     if (ctxt->inputNr == 1)
       
  1592         return(0); /* End of main Input */
       
  1593     if (xmlParserDebugEntities)
       
  1594         xmlGenericError(xmlGenericErrorContext, EMBED_ERRTXT("Popping input %d\n"), ctxt->inputNr);
       
  1595     xmlFreeInputStream(inputPop(ctxt));
       
  1596     if ((*ctxt->input->cur == 0) &&
       
  1597         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
       
  1598     {
       
  1599         if(OOM_FLAG)
       
  1600             return 0;
       
  1601         return(xmlPopInput(ctxt));
       
  1602     }
       
  1603     return(CUR);
       
  1604 }
       
  1605 
       
  1606 /**
       
  1607  * xmlPushInput:
       
  1608  * @param ctxt an XML parser context
       
  1609  * @param input an XML parser input fragment (entity, XML fragment ...).
       
  1610  *
       
  1611  * xmlPushInput: switch to a new input stream which is stacked on top
       
  1612  *               of the previous one(s).
       
  1613  */
       
  1614 XMLPUBFUNEXPORT void
       
  1615 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
       
  1616 	LOAD_GS_SAFE_CTXT(ctxt)
       
  1617     if (input == NULL) return;
       
  1618 
       
  1619     if (xmlParserDebugEntities) {
       
  1620     if ((ctxt->input != NULL) && (ctxt->input->filename))
       
  1621         xmlGenericError(xmlGenericErrorContext,
       
  1622             EMBED_ERRTXT("%s(%d): "), ctxt->input->filename,
       
  1623             ctxt->input->line);
       
  1624     xmlGenericError(xmlGenericErrorContext,
       
  1625         EMBED_ERRTXT("Pushing input %d : %.30s\n"), ctxt->inputNr+1, input->cur);
       
  1626     }
       
  1627     inputPush(ctxt, input);
       
  1628     GROW;
       
  1629 }
       
  1630 
       
  1631 /**
       
  1632  * xmlParseCharRef:
       
  1633  * @param ctxt an XML parser context
       
  1634  *
       
  1635  * parse Reference declarations
       
  1636  *
       
  1637  * [66] CharRef ::= '&#' [0-9]+ ';' |
       
  1638  *                  '&#x' [0-9a-fA-F]+ ';'
       
  1639  *
       
  1640  * [ WFC: Legal Character ]
       
  1641  * Characters referred to using character references must match the
       
  1642  * production for Char.
       
  1643  *
       
  1644  * Returns the value parsed (as an int), 0 in case of error
       
  1645  */
       
  1646 XMLPUBFUNEXPORT int
       
  1647 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
       
  1648     unsigned int val = 0;
       
  1649     int count = 0;
       
  1650 
       
  1651     /*
       
  1652      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
       
  1653      */
       
  1654     if ((RAW == '&') && (NXT(1) == '#') &&
       
  1655         (NXT(2) == 'x')) {
       
  1656     SKIP(3);
       
  1657     GROW;
       
  1658     while (RAW != ';') { /* loop blocked by count */
       
  1659         if (count++ > 20) {
       
  1660         count = 0;
       
  1661         GROW;
       
  1662         }
       
  1663         if ((RAW >= '0') && (RAW <= '9'))
       
  1664             val = val * 16 + (CUR - '0');
       
  1665         else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
       
  1666             val = val * 16 + (CUR - 'a') + 10;
       
  1667         else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
       
  1668             val = val * 16 + (CUR - 'A') + 10;
       
  1669         else {
       
  1670         xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
       
  1671         val = 0;
       
  1672         break;
       
  1673         }
       
  1674         NEXT;
       
  1675         count++;
       
  1676     }
       
  1677     if (RAW == ';') {
       
  1678         /* on purpose to avoid reentrancy problems with NEXT and SKIP */
       
  1679         ctxt->input->col++;
       
  1680         ctxt->nbChars ++;
       
  1681         ctxt->input->cur++;
       
  1682     }
       
  1683     } else if  ((RAW == '&') && (NXT(1) == '#')) {
       
  1684     SKIP(2);
       
  1685     GROW;
       
  1686     while (RAW != ';') { /* loop blocked by count */
       
  1687         if (count++ > 20) {
       
  1688         count = 0;
       
  1689         GROW;
       
  1690         }
       
  1691         if ((RAW >= '0') && (RAW <= '9'))
       
  1692             val = val * 10 + (CUR - '0');
       
  1693         else {
       
  1694         xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
       
  1695         val = 0;
       
  1696         break;
       
  1697         }
       
  1698         NEXT;
       
  1699         count++;
       
  1700     }
       
  1701     if (RAW == ';') {
       
  1702         /* on purpose to avoid reentrancy problems with NEXT and SKIP */
       
  1703         ctxt->input->col++;
       
  1704         ctxt->nbChars ++;
       
  1705         ctxt->input->cur++;
       
  1706     }
       
  1707     } else {
       
  1708         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
       
  1709     }
       
  1710 
       
  1711     /*
       
  1712      * [ WFC: Legal Character ]
       
  1713      * Characters referred to using character references must match the
       
  1714      * production for Char.
       
  1715      */
       
  1716     if (IS_CHAR(val)) {
       
  1717         return(val);
       
  1718     } else {
       
  1719         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
       
  1720                           EMBED_ERRTXT("xmlParseCharRef: invalid xmlChar value %d\n"),
       
  1721                       val);
       
  1722     }
       
  1723     return(0);
       
  1724 }
       
  1725 
       
  1726 /**
       
  1727  * xmlParseStringCharRef:
       
  1728  * @param ctxt an XML parser context
       
  1729  * @param str a pointer to an index in the string
       
  1730  *
       
  1731  * parse Reference declarations, variant parsing from a string rather
       
  1732  * than an an input flow.
       
  1733  *
       
  1734  * [66] CharRef ::= '&#' [0-9]+ ';' |
       
  1735  *                  '&#x' [0-9a-fA-F]+ ';'
       
  1736  *
       
  1737  * [ WFC: Legal Character ]
       
  1738  * Characters referred to using character references must match the
       
  1739  * production for Char.
       
  1740  *
       
  1741  * Returns the value parsed (as an int), 0 in case of error, str will be
       
  1742  *         updated to the current value of the index
       
  1743  */
       
  1744 static int
       
  1745 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
       
  1746     const xmlChar *ptr;
       
  1747     xmlChar cur;
       
  1748     int val = 0;
       
  1749 
       
  1750     if ((str == NULL) || (*str == NULL)) return(0);
       
  1751     ptr = *str;
       
  1752     cur = *ptr;
       
  1753     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
       
  1754     ptr += 3;
       
  1755     cur = *ptr;
       
  1756     while (cur != ';') { /* Non input consuming loop */
       
  1757         if ((cur >= '0') && (cur <= '9'))
       
  1758             val = val * 16 + (cur - '0');
       
  1759         else if ((cur >= 'a') && (cur <= 'f'))
       
  1760             val = val * 16 + (cur - 'a') + 10;
       
  1761         else if ((cur >= 'A') && (cur <= 'F'))
       
  1762             val = val * 16 + (cur - 'A') + 10;
       
  1763         else {
       
  1764         xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
       
  1765         val = 0;
       
  1766         break;
       
  1767         }
       
  1768         ptr++;
       
  1769         cur = *ptr;
       
  1770     }
       
  1771     if (cur == ';')
       
  1772         ptr++;
       
  1773     } else if  ((cur == '&') && (ptr[1] == '#')){
       
  1774     ptr += 2;
       
  1775     cur = *ptr;
       
  1776     while (cur != ';') { /* Non input consuming loops */
       
  1777         if ((cur >= '0') && (cur <= '9'))
       
  1778             val = val * 10 + (cur - '0');
       
  1779         else {
       
  1780         xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
       
  1781         val = 0;
       
  1782         break;
       
  1783         }
       
  1784         ptr++;
       
  1785         cur = *ptr;
       
  1786     }
       
  1787     if (cur == ';')
       
  1788         ptr++;
       
  1789     } else {
       
  1790     xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
       
  1791     return(0);
       
  1792     }
       
  1793     *str = ptr;
       
  1794 
       
  1795     /*
       
  1796      * [ WFC: Legal Character ]
       
  1797      * Characters referred to using character references must match the
       
  1798      * production for Char.
       
  1799      */
       
  1800     if (IS_CHAR(val)) {
       
  1801         return(val);
       
  1802     } else {
       
  1803         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
       
  1804               EMBED_ERRTXT("xmlParseStringCharRef: invalid xmlChar value %d\n"),
       
  1805               val);
       
  1806     }
       
  1807     return(0);
       
  1808 }
       
  1809 
       
  1810 /**
       
  1811  * xmlNewBlanksWrapperInputStream:
       
  1812  * @param ctxt an XML parser context
       
  1813  * @param entity an Entity pointer
       
  1814  *
       
  1815  * Create a new input stream for wrapping
       
  1816  * blanks around a PEReference
       
  1817  *
       
  1818  * Returns the new input stream or NULL
       
  1819  */
       
  1820 
       
  1821 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
       
  1822 
       
  1823 static xmlParserInputPtr
       
  1824 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
       
  1825 	xmlParserInputPtr input;
       
  1826     xmlChar *buffer;
       
  1827     size_t length;
       
  1828     LOAD_GS_SAFE_CTXT(ctxt)
       
  1829     if (entity == NULL) {
       
  1830         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
       
  1831                 EMBED_ERRTXT("xmlNewBlanksWrapperInputStream entity\n"));
       
  1832         return(NULL);
       
  1833     }
       
  1834     if (xmlParserDebugEntities)
       
  1835     xmlGenericError(xmlGenericErrorContext,
       
  1836         EMBED_ERRTXT("new blanks wrapper for entity: %s\n"), entity->name);
       
  1837     input = xmlNewInputStream(ctxt);
       
  1838     if (input == NULL) {
       
  1839         return(NULL);
       
  1840     }
       
  1841     length = xmlStrlen(entity->name) + 5;
       
  1842     buffer = (xmlChar*)xmlMallocAtomic(length);
       
  1843     if (buffer == NULL) {
       
  1844         xmlParserOOMErr(ctxt);
       
  1845         return(NULL);
       
  1846     }
       
  1847     buffer [0] = ' ';
       
  1848     buffer [1] = '%';
       
  1849     buffer [length-3] = ';';
       
  1850     buffer [length-2] = ' ';
       
  1851     buffer [length-1] = 0;
       
  1852     memcpy(buffer + 2, entity->name, length - 5);
       
  1853     input->free = deallocblankswrapper;
       
  1854     input->base = buffer;
       
  1855     input->cur = buffer;
       
  1856     input->length = length;
       
  1857     input->end = &buffer[length];
       
  1858     return(input);
       
  1859 }
       
  1860 
       
  1861 /**
       
  1862  * xmlParserHandlePEReference:
       
  1863  * @param ctxt the parser context
       
  1864  *
       
  1865  * [69] PEReference ::= '%' Name ';'
       
  1866  *
       
  1867  * [ WFC: No Recursion ]
       
  1868  * A parsed entity must not contain a recursive
       
  1869  * reference to itself, either directly or indirectly.
       
  1870  *
       
  1871  * [ WFC: Entity Declared ]
       
  1872  * In a document without any DTD, a document with only an internal DTD
       
  1873  * subset which contains no parameter entity references, or a document
       
  1874  * with "standalone='yes'", ...  ... The declaration of a parameter
       
  1875  * entity must precede any reference to it...
       
  1876  *
       
  1877  * [ VC: Entity Declared ]
       
  1878  * In a document with an external subset or external parameter entities
       
  1879  * with "standalone='no'", ...  ... The declaration of a parameter entity
       
  1880  * must precede any reference to it...
       
  1881  *
       
  1882  * [ WFC: In DTD ]
       
  1883  * Parameter-entity references may only appear in the DTD.
       
  1884  * NOTE: misleading but this is handled.
       
  1885  *
       
  1886  * A PEReference may have been detected in the current input stream
       
  1887  * the handling is done accordingly to
       
  1888  *      http://www.w3.org/TR/REC-xml#entproc
       
  1889  * i.e.
       
  1890  *   - Included in literal in entity values
       
  1891  *   - Included as Parameter Entity reference within DTDs
       
  1892  *
       
  1893  * OOM: possible ------      review NOT FINISHED YET
       
  1894  */
       
  1895 XMLPUBFUNEXPORT void
       
  1896 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
       
  1897     const xmlChar *name;
       
  1898     xmlEntityPtr entity = NULL;
       
  1899     xmlParserInputPtr input;
       
  1900 	LOAD_GS_SAFE_CTXT(ctxt)
       
  1901 	
       
  1902     if (RAW != '%') return;
       
  1903 
       
  1904     
       
  1905     switch(ctxt->instate) {
       
  1906     case XML_PARSER_CDATA_SECTION:
       
  1907         return;
       
  1908     case XML_PARSER_COMMENT:
       
  1909         return;
       
  1910     case XML_PARSER_START_TAG:
       
  1911         return;
       
  1912     case XML_PARSER_END_TAG:
       
  1913         return;
       
  1914     case XML_PARSER_EOF:
       
  1915         xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
       
  1916         return;
       
  1917     case XML_PARSER_PROLOG:
       
  1918     case XML_PARSER_START:
       
  1919     case XML_PARSER_MISC:
       
  1920         xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
       
  1921         return;
       
  1922     case XML_PARSER_ENTITY_DECL:
       
  1923     case XML_PARSER_CONTENT:
       
  1924     case XML_PARSER_ATTRIBUTE_VALUE:
       
  1925     case XML_PARSER_PI:
       
  1926     case XML_PARSER_SYSTEM_LITERAL:
       
  1927     case XML_PARSER_PUBLIC_LITERAL:
       
  1928         /* we just ignore it there */
       
  1929         return;
       
  1930     case XML_PARSER_EPILOG:
       
  1931         xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
       
  1932         return;
       
  1933     case XML_PARSER_ENTITY_VALUE:
       
  1934         /*
       
  1935          * NOTE: in the case of entity values, we don't do the
       
  1936          *       substitution here since we need the literal
       
  1937          *       entity value to be able to save the internal
       
  1938          *       subset of the document.
       
  1939          *       This will be handled by xmlStringDecodeEntities
       
  1940          */
       
  1941         return;
       
  1942     case XML_PARSER_DTD:
       
  1943         /*
       
  1944          * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
       
  1945          * In the internal DTD subset, parameter-entity references
       
  1946          * can occur only where markup declarations can occur, not
       
  1947          * within markup declarations.
       
  1948          * In that case this is handled in xmlParseMarkupDecl
       
  1949          */
       
  1950         if ((ctxt->external == 0) && (ctxt->inputNr == 1))
       
  1951             return;
       
  1952         if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
       
  1953             return;
       
  1954         break;
       
  1955     case XML_PARSER_IGNORE:
       
  1956         return;
       
  1957     }
       
  1958 
       
  1959     NEXT;
       
  1960     name = xmlParseName(ctxt); // may set OOM flag
       
  1961     if(OOM_FLAG)
       
  1962         return;
       
  1963     
       
  1964     if (xmlParserDebugEntities)
       
  1965         xmlGenericError(xmlGenericErrorContext, EMBED_ERRTXT("PEReference: %s\n"), name);
       
  1966     if (name == NULL) {
       
  1967         xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
       
  1968         return;
       
  1969     }
       
  1970     // XMLENGINE: OK: IF condition branches were exchanged and ELSE bacame main flow
       
  1971     if (RAW != ';')
       
  1972     {
       
  1973         xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
       
  1974         return;
       
  1975     }
       
  1976 
       
  1977     NEXT;
       
  1978     if(OOM_FLAG)
       
  1979         return;
       
  1980 
       
  1981     if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
       
  1982         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
       
  1983     if (entity == NULL)
       
  1984     {
       
  1985         /*
       
  1986         * [ WFC: Entity Declared ]
       
  1987         * In a document without any DTD, a document with only an
       
  1988         * internal DTD subset which contains no parameter entity
       
  1989         * references, or a document with "standalone='yes'", ...
       
  1990         * ... The declaration of a parameter entity must precede
       
  1991         * any reference to it...
       
  1992         */
       
  1993         if ((ctxt->standalone == 1) ||
       
  1994             ((ctxt->hasExternalSubset == 0) &&
       
  1995             (ctxt->hasPErefs == 0)))
       
  1996         {
       
  1997             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
       
  1998                                 EMBED_ERRTXT("PEReference: %%%s; not found\n"), name);
       
  1999         } else {
       
  2000             /*
       
  2001             * [ VC: Entity Declared ]
       
  2002             * In a document with an external subset or external
       
  2003             * parameter entities with "standalone='no'", ...
       
  2004             * ... The declaration of a parameter entity must precede
       
  2005             * any reference to it...
       
  2006             */
       
  2007             if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
       
  2008                 xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  2009                             EMBED_ERRTXT("PEReference: %%%s; not found\n"), name);
       
  2010             }else{
       
  2011                 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  2012                         EMBED_ERRTXT("PEReference: %%%s; not found\n"), name, NULL);
       
  2013             }
       
  2014             ctxt->valid = 0;
       
  2015         }
       
  2016     } // if (entity == NULL)
       
  2017     else if (ctxt->input->free != deallocblankswrapper)
       
  2018     {
       
  2019         input = xmlNewBlanksWrapperInputStream(ctxt, entity);
       
  2020         xmlPushInput(ctxt, input);
       
  2021     }
       
  2022     else if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
       
  2023             (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY))
       
  2024     {
       
  2025         xmlChar start[4];
       
  2026         xmlCharEncoding enc;
       
  2027 
       
  2028         /*
       
  2029         * handle the extra spaces added before and after
       
  2030         * c.f. http://www.w3.org/TR/REC-xml#as-PE
       
  2031         * this is done independently.
       
  2032         */
       
  2033         input = xmlNewEntityInputStream(ctxt, entity); 
       
  2034         xmlPushInput(ctxt, input);
       
  2035 
       
  2036         /*
       
  2037         * Get the 4 first bytes and decode the charset
       
  2038         * if enc != XML_CHAR_ENCODING_NONE
       
  2039         * plug some encoding conversion routines.
       
  2040         * Note that, since we may have some non-UTF8
       
  2041         * encoding (like UTF16, ), the 'length'
       
  2042         * is not known, but we can calculate based upon
       
  2043         * the amount of data in the buffer.
       
  2044         */
       
  2045         GROW
       
  2046         if ((ctxt->input->end - ctxt->input->cur)>=4) {
       
  2047             start[0] = RAW;
       
  2048             start[1] = NXT(1);
       
  2049             start[2] = NXT(2);
       
  2050             start[3] = NXT(3);
       
  2051             enc = xmlDetectCharEncoding(start, 4);
       
  2052             if (enc != XML_CHAR_ENCODING_NONE) {
       
  2053                 xmlSwitchEncoding(ctxt, enc); 
       
  2054             }
       
  2055         }
       
  2056 
       
  2057         if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
       
  2058             (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
       
  2059             (IS_BLANK_CH(NXT(5))))
       
  2060         {
       
  2061             xmlParseTextDecl(ctxt);
       
  2062         }
       
  2063     } else {
       
  2064         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
       
  2065             EMBED_ERRTXT("PEReference: %s is not a parameter entity\n"),
       
  2066                 name);
       
  2067     }
       
  2068 }
       
  2069 
       
  2070 /*
       
  2071  * Macro used to grow the current buffer.
       
  2072  */
       
  2073  
       
  2074  
       
  2075    /** 
       
  2076      *  SYMBIAN : DEFECT FIX : DEF129002 (libxml2 buffer overflow vulnerability)
       
  2077      *             Increase the buffer size by sufficient amount before doubling it.
       
  2078      *             So that, this will help in dealing with the long-entity names.
       
  2079 	 *			   The original defect can be located in debian bug tracking database
       
  2080 	 *			   with defect number 498768.
       
  2081      */
       
  2082 
       
  2083 #define GROW_BUFFER(buffer) {                \
       
  2084     xmlChar *tmp;                           \
       
  2085     buffer##_size += XML_PARSER_BUFFER_SIZE ; \
       
  2086     buffer##_size *= 2;                     \
       
  2087     tmp = (xmlChar *)                       \
       
  2088             xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));    \
       
  2089     if (tmp == NULL) goto mem_error;        \
       
  2090     buffer = tmp;                           \
       
  2091 }
       
  2092 
       
  2093 
       
  2094 /**
       
  2095  * xmlStringLenDecodeEntities:
       
  2096  * @param ctxt the parser context
       
  2097  * @param str the input string
       
  2098  * @param len the string length
       
  2099  * @param what combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
       
  2100  * @param end an end marker xmlChar, 0 if none
       
  2101  * @param end2 an end marker xmlChar, 0 if none
       
  2102  * @param end3 an end marker xmlChar, 0 if none
       
  2103  *
       
  2104  * Takes a entity string content and process to do the adequate substitutions.
       
  2105  *
       
  2106  * [67] Reference ::= EntityRef | CharRef
       
  2107  *
       
  2108  * [69] PEReference ::= '%' Name ';'
       
  2109  *
       
  2110  * Returns A newly allocated string with the substitution done. The caller
       
  2111  *      must deallocate it !
       
  2112  */
       
  2113 XMLPUBFUNEXPORT xmlChar *
       
  2114 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
       
  2115               int what, xmlChar end, xmlChar  end2, xmlChar end3) {
       
  2116     xmlChar *buffer = NULL;
       
  2117     int buffer_size = 0;
       
  2118 
       
  2119     xmlChar *current = NULL;
       
  2120     const xmlChar *last;
       
  2121     xmlEntityPtr ent;
       
  2122     int c,l;
       
  2123     int nbchars = 0;
       
  2124     LOAD_GS_SAFE_CTXT(ctxt)
       
  2125 
       
  2126     if ((str == NULL) || (len < 0))
       
  2127     return(NULL);
       
  2128     last = str + len;
       
  2129 
       
  2130     if (ctxt->depth > 40) {
       
  2131     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
       
  2132     return(NULL);
       
  2133     }
       
  2134 
       
  2135     /*
       
  2136      * allocate a translation buffer.
       
  2137      */
       
  2138     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
       
  2139     buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
       
  2140     if (buffer == NULL) goto mem_error;
       
  2141 
       
  2142     /*
       
  2143      * OK loop until we reach one of the ending char or a size limit.
       
  2144      * we are operating on already parsed values.
       
  2145      */
       
  2146     if (str < last)
       
  2147     c = CUR_SCHAR(str, l);
       
  2148     else
       
  2149         c = 0;
       
  2150     while ((c != 0) && (c != end) && /* non input consuming loop */
       
  2151        (c != end2) && (c != end3)) {
       
  2152 
       
  2153     if (c == 0) break;
       
  2154         if ((c == '&') && (str[1] == '#')) {
       
  2155         int val = xmlParseStringCharRef(ctxt, &str);
       
  2156         if (val != 0) {
       
  2157         COPY_BUF(0,buffer,nbchars,val);
       
  2158         }
       
  2159     } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
       
  2160         if (xmlParserDebugEntities)
       
  2161         xmlGenericError(xmlGenericErrorContext,
       
  2162             EMBED_ERRTXT("String decoding Entity Reference: %.30s\n"),
       
  2163             str);
       
  2164         ent = xmlParseStringEntityRef(ctxt, &str);
       
  2165         if ((ent != NULL) &&
       
  2166         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
       
  2167         if (ent->content != NULL) {
       
  2168             COPY_BUF(0,buffer,nbchars,ent->content[0]);
       
  2169         } else {
       
  2170             xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
       
  2171                 EMBED_ERRTXT("predefined entity has no content\n"));
       
  2172         }
       
  2173         } else if ((ent != NULL) && (ent->content != NULL)) {
       
  2174         xmlChar *rep;
       
  2175 
       
  2176         ctxt->depth++;
       
  2177         rep = xmlStringDecodeEntities(ctxt, ent->content, what,
       
  2178                                   0, 0, 0);
       
  2179         ctxt->depth--;
       
  2180         if (rep != NULL) {
       
  2181             current = rep;
       
  2182             while (*current != 0) { /* non input consuming loop */
       
  2183             buffer[nbchars++] = *current++;
       
  2184             if (nbchars >
       
  2185                     buffer_size - XML_PARSER_BUFFER_SIZE) {
       
  2186                 GROW_BUFFER(buffer);
       
  2187             }
       
  2188             }
       
  2189             xmlFree(rep);
       
  2190         }
       
  2191         } else if (ent != NULL) {
       
  2192         int i = xmlStrlen(ent->name);
       
  2193         const xmlChar *cur = ent->name;
       
  2194 
       
  2195         buffer[nbchars++] = '&';
       
  2196         if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
       
  2197             GROW_BUFFER(buffer);
       
  2198         }
       
  2199         for (;i > 0;i--)
       
  2200             buffer[nbchars++] = *cur++;
       
  2201         buffer[nbchars++] = ';';
       
  2202         }
       
  2203     } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
       
  2204         if (xmlParserDebugEntities)
       
  2205         xmlGenericError(xmlGenericErrorContext,
       
  2206             EMBED_ERRTXT("String decoding PE Reference: %.30s\n"), str);
       
  2207         ent = xmlParseStringPEReference(ctxt, &str);
       
  2208         if (ent != NULL) {
       
  2209         xmlChar *rep;
       
  2210 
       
  2211         ctxt->depth++;
       
  2212         rep = xmlStringDecodeEntities(ctxt, ent->content, what,
       
  2213                                   0, 0, 0);
       
  2214         ctxt->depth--;
       
  2215         if (rep != NULL) {
       
  2216             current = rep;
       
  2217             while (*current != 0) { /* non input consuming loop */
       
  2218             buffer[nbchars++] = *current++;
       
  2219             if (nbchars >
       
  2220                     buffer_size - XML_PARSER_BUFFER_SIZE) {
       
  2221                 GROW_BUFFER(buffer);
       
  2222             }
       
  2223             }
       
  2224             xmlFree(rep);
       
  2225         }
       
  2226         }
       
  2227     } else {
       
  2228         COPY_BUF(l,buffer,nbchars,c);
       
  2229         str += l;
       
  2230         if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
       
  2231           GROW_BUFFER(buffer);
       
  2232         }
       
  2233     }
       
  2234     if (str < last)
       
  2235         c = CUR_SCHAR(str, l);
       
  2236     else
       
  2237         c = 0;
       
  2238     }
       
  2239     buffer[nbchars++] = 0;
       
  2240     return(buffer);
       
  2241 
       
  2242 mem_error:
       
  2243     xmlParserOOMErr(ctxt);
       
  2244     return(NULL);
       
  2245 }
       
  2246 
       
  2247 /**
       
  2248  * xmlStringDecodeEntities:
       
  2249  * @param ctxt the parser context
       
  2250  * @param str the input string
       
  2251  * @param what combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
       
  2252  * @param end an end marker xmlChar, 0 if none
       
  2253  * @param end2 an end marker xmlChar, 0 if none
       
  2254  * @param end3 an end marker xmlChar, 0 if none
       
  2255  *
       
  2256  * Takes a entity string content and process to do the adequate substitutions.
       
  2257  *
       
  2258  * [67] Reference ::= EntityRef | CharRef
       
  2259  *
       
  2260  * [69] PEReference ::= '%' Name ';'
       
  2261  *
       
  2262  * Returns A newly allocated string with the substitution done. The caller
       
  2263  *      must deallocate it !
       
  2264  */
       
  2265 XMLPUBFUNEXPORT xmlChar *
       
  2266 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
       
  2267                 xmlChar end, xmlChar  end2, xmlChar end3) {
       
  2268     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
       
  2269            end, end2, end3));
       
  2270 }
       
  2271 
       
  2272 /************************************************************************
       
  2273  *                                  *
       
  2274  *      Commodity functions, cleanup needed ?           *
       
  2275  *                                  *
       
  2276  ************************************************************************/
       
  2277 
       
  2278 /**
       
  2279  * areBlanks:
       
  2280  * @param ctxt an XML parser context
       
  2281  * @param str a xmlChar *
       
  2282  * @param len the size of str
       
  2283  * @param blank_chars we know the chars are blanks
       
  2284  *
       
  2285  * Is this a sequence of blank chars that one can ignore ?
       
  2286  *
       
  2287  * Returns 1 if ignorable 0 otherwise.
       
  2288  */
       
  2289 
       
  2290 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
       
  2291                      int blank_chars) {
       
  2292     int i, ret;
       
  2293     xmlNodePtr lastChild;
       
  2294 
       
  2295     /*
       
  2296      * Don't spend time trying to differentiate them, the same callback is
       
  2297      * used !
       
  2298      */
       
  2299     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
       
  2300         return(0);
       
  2301 
       
  2302     /*
       
  2303      * Check for xml:space value.
       
  2304      */
       
  2305     if (*(ctxt->space) == 1)
       
  2306         return(0);
       
  2307 
       
  2308     /*
       
  2309      * Check that the string is made of blanks
       
  2310      */
       
  2311     if (blank_chars == 0) {
       
  2312         for (i = 0;i < len;i++)
       
  2313             if (!(IS_BLANK_CH(str[i])))
       
  2314                 return(0);
       
  2315     }
       
  2316 
       
  2317     /*
       
  2318      * Look if the element is mixed content in the DTD if available
       
  2319      */
       
  2320     if (!ctxt->node)
       
  2321         return(0);
       
  2322     if (ctxt->myDoc) {
       
  2323         ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
       
  2324         
       
  2325         if (ret == 0) return(1); // replace with
       
  2326         if (ret == 1) return(0); //     return 1-ret;  OR return !(ret&1)
       
  2327     }
       
  2328 
       
  2329     /*
       
  2330      * Otherwise, heuristic :-\
       
  2331      */
       
  2332     if (RAW != '<')
       
  2333         return(0);
       
  2334     if ((ctxt->node->children == NULL) &&
       
  2335         (RAW == '<') && (NXT(1) == '/'))
       
  2336         return(0);
       
  2337 
       
  2338     
       
  2339     lastChild = xmlGetLastChild(ctxt->node);
       
  2340     if (lastChild == NULL) {
       
  2341         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
       
  2342             (ctxt->node->content != NULL)) return(0);
       
  2343     } else {
       
  2344         if (xmlNodeIsText(lastChild))
       
  2345             return(0);
       
  2346         else
       
  2347             if ((ctxt->node->children != NULL) &&
       
  2348                 (xmlNodeIsText(ctxt->node->children)))
       
  2349                 return(0);
       
  2350     }
       
  2351     return(1);
       
  2352 }
       
  2353 
       
  2354 /************************************************************************
       
  2355  *                                                                      *
       
  2356  *      Extra stuff for namespace support                               *
       
  2357  *  Relates to http://www.w3.org/TR/WD-xml-names                        *
       
  2358  *                                                                      *
       
  2359  ************************************************************************/
       
  2360 
       
  2361 /**
       
  2362  * xmlSplitQName:
       
  2363  * @param ctxt an XML parser context
       
  2364  * @param name an XML parser context
       
  2365  * @param prefix a xmlChar **
       
  2366  *
       
  2367  * parse an UTF8 encoded XML qualified name string
       
  2368  *
       
  2369  * [NS 5] QName ::= (Prefix ':')? LocalPart
       
  2370  *
       
  2371  * [NS 6] Prefix ::= NCName
       
  2372  *
       
  2373  * [NS 7] LocalPart ::= NCName
       
  2374  *
       
  2375  * Returns the local part, and prefix is updated
       
  2376  *   to get the Prefix if any.
       
  2377  *
       
  2378  * OOM: possible --> returns NULL (*prefix is NULL too);
       
  2379  *      always check OOM flag to distinguish OOM and "bad QName"
       
  2380  */
       
  2381 // DONE: Make sure that in OOM (prefix is set to NULL and freed if needed)
       
  2382 XMLPUBFUNEXPORT xmlChar*
       
  2383 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar* name, xmlChar** prefix)
       
  2384 {
       
  2385     xmlChar buf[XML_MAX_NAMELEN + 5];
       
  2386     xmlChar* buffer = NULL; // We use it instead of 'buf' for too long names
       
  2387     int len = 0;
       
  2388     int max = XML_MAX_NAMELEN;
       
  2389     xmlChar* ret = NULL;
       
  2390     const xmlChar* cur = name;
       
  2391     int c;
       
  2392 
       
  2393     *prefix = NULL;
       
  2394 
       
  2395     if (cur == NULL)
       
  2396         return(NULL);
       
  2397 
       
  2398 #ifndef XML_XML_NAMESPACE
       
  2399     /* xml: prefix is not really a namespace */
       
  2400     if ((cur[0] == 'x') && (cur[1] == 'm') &&
       
  2401         (cur[2] == 'l') && (cur[3] == ':'))
       
  2402     {
       
  2403         return(xmlStrdup(name));
       
  2404     }
       
  2405 #endif
       
  2406 
       
  2407     /* nasty but well=formed */
       
  2408     if (cur[0] == ':')
       
  2409         return(xmlStrdup(name));
       
  2410 
       
  2411     c = *cur++;
       
  2412     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
       
  2413         buf[len++] = c;
       
  2414         c = *cur++;
       
  2415     }
       
  2416     if (len >= max)
       
  2417     {
       
  2418         /*
       
  2419          * Okay someone managed to make a huge name, so he's ready to pay
       
  2420          * for the processing speed.
       
  2421          */
       
  2422         max = len * 2;
       
  2423 
       
  2424         buffer = (xmlChar*) xmlMallocAtomic(max * sizeof(xmlChar));
       
  2425         if (!buffer)
       
  2426             goto OOM_exit;
       
  2427 
       
  2428         // NOTE: Now 'buffer' must be returned or freed (in OOM)..
       
  2429         memcpy(buffer, buf, len);
       
  2430         while ((c != 0) && (c != ':'))
       
  2431         { /* tested bigname.xml */
       
  2432             if (len + 10 > max)
       
  2433             {
       
  2434                 void* tmp; // DONE: Fix xmlRealloc
       
  2435                 max *= 2;
       
  2436                 tmp = xmlRealloc(buffer, max * sizeof(xmlChar));
       
  2437                 if (!tmp) {
       
  2438 OOM_free_buffer:
       
  2439                     if(buffer) // Note: must check if jump here from other parts of function
       
  2440                         xmlFree(buffer);
       
  2441 OOM_exit:
       
  2442                     xmlParserOOMErr(ctxt);
       
  2443                     return(NULL);
       
  2444                 }
       
  2445                 buffer = (xmlChar*) tmp;
       
  2446             }
       
  2447             buffer[len++] = c;
       
  2448             c = *cur++;
       
  2449         }
       
  2450         buffer[len] = 0;
       
  2451     }
       
  2452 
       
  2453     /* nasty but well=formed
       
  2454     if ((c == ':') && (*cur == 0)) {
       
  2455     return(xmlStrdup(name));
       
  2456     } */
       
  2457 
       
  2458     if (buffer == NULL)
       
  2459         ret = xmlStrndup(buf, len);
       
  2460     else {
       
  2461         ret = buffer; // NOTE: 'buffer' is to be returned so far
       
  2462         buffer = NULL;
       
  2463         max = XML_MAX_NAMELEN;
       
  2464     }
       
  2465 
       
  2466 
       
  2467     if (c == ':')
       
  2468     {
       
  2469         c = *cur;
       
  2470         *prefix = ret; // NOTE: in 'prefix' we return 'buffer' or a copy from 'buf'
       
  2471         if (c == 0) {
       
  2472             return(xmlStrndup(BAD_CAST "", 0)); 
       
  2473         }
       
  2474         len = 0;
       
  2475 
       
  2476         /*
       
  2477          * Check that the first character is proper to start
       
  2478          * a new name
       
  2479          */
       
  2480         if (!(((c >= 0x61) && (c <= 0x7A)) ||
       
  2481               ((c >= 0x41) && (c <= 0x5A)) ||
       
  2482               (c == '_') || (c == ':')))
       
  2483         {
       
  2484             int l;
       
  2485             int first = CUR_SCHAR(cur, l);
       
  2486 
       
  2487             if (!IS_LETTER(first) && (first != '_')) {
       
  2488                 xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
       
  2489                     EMBED_ERRTXT("Name %s is not XML Namespace compliant\n"),
       
  2490                     name);
       
  2491             }
       
  2492         }
       
  2493         cur++;
       
  2494 
       
  2495         while ((c != 0) && (len < max))
       
  2496         { /* tested bigname2.xml */
       
  2497             buf[len++] = c;
       
  2498             c = *cur++;
       
  2499         }
       
  2500         if (len >= max) {
       
  2501             /*
       
  2502              * Okay someone managed to make a huge name, so he's ready to pay
       
  2503              * for the processing speed.
       
  2504              */
       
  2505             max = len * 2;
       
  2506 
       
  2507             buffer = (xmlChar*) xmlMallocAtomic(max * sizeof(xmlChar));
       
  2508             if (!buffer)
       
  2509                 goto OOM_free_prefix_buffer; // NOTE: it's ok to free NULL buffer here
       
  2510 
       
  2511             memcpy(buffer, buf, len);
       
  2512             while (c != 0)
       
  2513             { /* tested bigname2.xml */
       
  2514                 if (len + 10 > max)
       
  2515                 {
       
  2516                     void* tmp; // DONE: Fix xmlRealloc
       
  2517                     max *= 2;
       
  2518                     tmp = xmlRealloc(buffer, max * sizeof(xmlChar));
       
  2519                     if (!tmp) {
       
  2520 OOM_free_prefix_buffer:
       
  2521                         xmlFree(*prefix);
       
  2522                         *prefix = NULL;
       
  2523                         goto OOM_free_buffer;
       
  2524                     }
       
  2525                     buffer = (xmlChar*) tmp;
       
  2526                 }
       
  2527                 buffer[len++] = c;
       
  2528                 c = *cur++;
       
  2529             }
       
  2530             buffer[len] = 0;
       
  2531         }
       
  2532 
       
  2533         if (!buffer){
       
  2534             ret = xmlStrndup(buf, len); // DONE: Check OOM, free prefix if needed
       
  2535             if(!ret)
       
  2536                 goto OOM_free_prefix_buffer;
       
  2537         } else {
       
  2538             ret = buffer;
       
  2539         }
       
  2540     } // end if (c == ':')
       
  2541 
       
  2542     return(ret);
       
  2543 }
       
  2544 
       
  2545 /************************************************************************
       
  2546  *                                                                      *
       
  2547  *          The parser itself                                           *
       
  2548  *  Relates to http://www.w3.org/TR/REC-xml                             *
       
  2549  *                                                                      *
       
  2550  ************************************************************************/
       
  2551 
       
  2552 static const xmlChar * xmlParseNameComplex(xmlParserCtxtPtr ctxt);
       
  2553 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
       
  2554                                           int *len, int *alloc, int normalize);
       
  2555 
       
  2556 /**
       
  2557  * xmlParseName:
       
  2558  * @param ctxt an XML parser context
       
  2559  *
       
  2560  * parse an XML name.
       
  2561  *
       
  2562  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
       
  2563  *                  CombiningChar | Extender
       
  2564  *
       
  2565  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
       
  2566  *
       
  2567  * [6] Names ::= Name (S Name)*
       
  2568  *
       
  2569  * Returns the Name parsed or NULL
       
  2570  *
       
  2571  * OOM: possible  --- Review is not finished (for xmlParseNameComplex)
       
  2572  *--> OOM flag is set when NULL is returned
       
  2573  */
       
  2574 
       
  2575 XMLPUBFUNEXPORT const xmlChar*
       
  2576 xmlParseName(xmlParserCtxtPtr ctxt) {
       
  2577     const xmlChar *in;
       
  2578     const xmlChar *ret;
       
  2579     int count = 0;
       
  2580     LOAD_GS_SAFE_CTXT(ctxt)
       
  2581 
       
  2582     GROW;
       
  2583     if(OOM_FLAG)
       
  2584         return NULL;
       
  2585     /*
       
  2586      * Accelerator for simple ASCII names
       
  2587      */
       
  2588     in = ctxt->input->cur;
       
  2589     if (((*in >= 0x61) && (*in <= 0x7A)) ||
       
  2590         ((*in >= 0x41) && (*in <= 0x5A)) ||
       
  2591         (*in == '_') || (*in == ':'))
       
  2592     {
       
  2593         in++;
       
  2594         while (((*in >= 0x61) && (*in <= 0x7A)) ||
       
  2595                ((*in >= 0x41) && (*in <= 0x5A)) ||
       
  2596                ((*in >= 0x30) && (*in <= 0x39)) ||
       
  2597                 (*in == '_')  || (*in == '-')   ||
       
  2598                 (*in == ':')  || (*in == '.'))
       
  2599             in++;
       
  2600 
       
  2601         if ((*in > 0) && (*in < 0x80)) {
       
  2602             count = in - ctxt->input->cur;
       
  2603             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
       
  2604             if(OOM_FLAG)
       
  2605                 return NULL;
       
  2606             ctxt->input->cur = in;
       
  2607             ctxt->nbChars += count;
       
  2608             ctxt->input->col += count;
       
  2609             if (ret == NULL)
       
  2610                 xmlParserOOMErr(ctxt);
       
  2611             return(ret);
       
  2612         }
       
  2613     }
       
  2614     return(xmlParseNameComplex(ctxt));
       
  2615 }
       
  2616 
       
  2617 /**
       
  2618  * xmlParseNameAndCompare:
       
  2619  * @param ctxt an XML parser context
       
  2620  *
       
  2621  * parse an XML name and compares for match
       
  2622  * (specialized for endtag parsing)
       
  2623  *
       
  2624  * Returns NULL for an illegal name, (xmlChar*) 1 for success
       
  2625  * and the name for mismatch
       
  2626  */
       
  2627 
       
  2628 static const xmlChar *
       
  2629 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
       
  2630     register const xmlChar *cmp = other;
       
  2631     register const xmlChar *in;
       
  2632     const xmlChar *ret;
       
  2633 
       
  2634     GROW;
       
  2635 
       
  2636     in = ctxt->input->cur;
       
  2637     while (*in != 0 && *in == *cmp) {
       
  2638         ++in;
       
  2639     ++cmp;
       
  2640     }
       
  2641     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
       
  2642         /* success */
       
  2643     ctxt->input->cur = in;
       
  2644     return (const xmlChar*) 1;
       
  2645     }
       
  2646     /* failure (or end of input buffer), check with full function */
       
  2647     ret = xmlParseName (ctxt);
       
  2648     /* strings coming from the dictionnary direct compare possible */
       
  2649     if (ret == other) {
       
  2650     return (const xmlChar*) 1;
       
  2651     }
       
  2652     return ret;
       
  2653 }
       
  2654 
       
  2655 /**
       
  2656 
       
  2657 OOM:
       
  2658 */
       
  2659 static const xmlChar*
       
  2660 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
       
  2661     int len = 0, clen; // DONE:  renamed 'l' --> 'clen'
       
  2662     int c;
       
  2663     int count = 0;
       
  2664 
       
  2665     /*
       
  2666      * Handler for more complex cases
       
  2667      */
       
  2668     GROW;
       
  2669     c = CUR_CHAR(clen);
       
  2670 
       
  2671     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
       
  2672         (!IS_LETTER(c) && (c != '_') && (c != ':')))
       
  2673     {
       
  2674         return(NULL);
       
  2675     }
       
  2676 
       
  2677     while (
       
  2678             (c != ' ') && (c != '>') && (c != '/')  /* test bigname.xml */
       
  2679             &&
       
  2680              ( IS_LETTER(c)   || IS_DIGIT(c)   ||
       
  2681                (c == '.')     || (c == '-')    ||
       
  2682                (c == '_')     || (c == ':')    ||
       
  2683                IS_COMBINING(c)|| IS_EXTENDER(c)
       
  2684              )
       
  2685            )
       
  2686     {
       
  2687         if (count++ > 100) {
       
  2688             count = 0;
       
  2689             GROW;
       
  2690         }
       
  2691         len += clen;
       
  2692         NEXTL(clen);
       
  2693         c = CUR_CHAR(clen); // may set OOM flag
       
  2694     }
       
  2695     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
       
  2696 }
       
  2697 
       
  2698 /**
       
  2699  * xmlParseStringName:
       
  2700  * @param ctxt an XML parser context
       
  2701  * @param str a pointer to the string pointer (IN/OUT)
       
  2702  *
       
  2703  * parse an XML name.
       
  2704  *
       
  2705  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
       
  2706  *                  CombiningChar | Extender
       
  2707  *
       
  2708  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
       
  2709  *
       
  2710  * [6] Names ::= Name (S Name)*
       
  2711  *
       
  2712  * Returns the Name parsed or NULL. The str pointer
       
  2713  * is updated to the current location in the string.
       
  2714  */
       
  2715 static xmlChar*
       
  2716 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str)
       
  2717 {
       
  2718     xmlChar buf[XML_MAX_NAMELEN + 5];
       
  2719     const xmlChar* cur = *str;
       
  2720     int len = 0, l; 
       
  2721     int c;
       
  2722 
       
  2723     c = CUR_SCHAR(cur, l);
       
  2724     if (!IS_LETTER(c) &&
       
  2725         (c != '_')    &&
       
  2726         (c != ':'))
       
  2727     {
       
  2728         return(NULL);
       
  2729     }
       
  2730 
       
  2731     while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
       
  2732           (c == '.') || (c == '-')  ||
       
  2733           (c == '_') || (c == ':')  ||
       
  2734           (IS_COMBINING(c))         ||
       
  2735           (IS_EXTENDER(c)))
       
  2736     {
       
  2737         COPY_BUF(l,buf,len,c);
       
  2738         cur += l;
       
  2739         c = CUR_SCHAR(cur, l);
       
  2740         if (len >= XML_MAX_NAMELEN)
       
  2741         { /* test bigentname.xml */
       
  2742             /*
       
  2743              * Okay someone managed to make a huge name, so he's ready to pay
       
  2744              * for the processing speed.
       
  2745              */
       
  2746             xmlChar* buffer;
       
  2747             int max = len * 2;
       
  2748 
       
  2749             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
       
  2750             if (!buffer)
       
  2751                 goto OOM_exit;
       
  2752 
       
  2753             memcpy(buffer, buf, len);
       
  2754             while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
       
  2755                      /* test bigentname.xml */
       
  2756                (c == '.') || (c == '-') ||
       
  2757                (c == '_') || (c == ':') ||
       
  2758                (IS_COMBINING(c)) ||
       
  2759                (IS_EXTENDER(c)))
       
  2760             {
       
  2761                 if (len + 10 > max)
       
  2762                 {   // DONE: Fix xmlRealloc
       
  2763                     void* tmp;
       
  2764                     max *= 2;
       
  2765                     tmp = xmlRealloc(buffer, max * sizeof(xmlChar));
       
  2766                     if (!tmp) {
       
  2767                         xmlFree(buffer);
       
  2768 OOM_exit:
       
  2769                         xmlParserOOMErr(ctxt);
       
  2770                         return(NULL);
       
  2771                     }
       
  2772                     buffer = (xmlChar*) tmp;
       
  2773                 }
       
  2774                 COPY_BUF(l,buffer,len,c);
       
  2775                 cur += l;
       
  2776                 c = CUR_SCHAR(cur, l);
       
  2777             }
       
  2778             buffer[len] = 0;
       
  2779             *str = cur;
       
  2780             return(buffer);
       
  2781         }
       
  2782     }
       
  2783     *str = cur;
       
  2784     return(xmlStrndup(buf, len));
       
  2785 }
       
  2786 
       
  2787 /**
       
  2788  * xmlParseNmtoken:
       
  2789  * @param ctxt an XML parser context
       
  2790  *
       
  2791  * parse an XML Nmtoken.
       
  2792  *
       
  2793  * [7] Nmtoken ::= (NameChar)+
       
  2794  *
       
  2795  * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
       
  2796  *
       
  2797  * Returns the Nmtoken parsed or NULL
       
  2798  *
       
  2799  * OOM: possible --> for too long names; check OOM flag
       
  2800  */
       
  2801 XMLPUBFUNEXPORT xmlChar*
       
  2802 xmlParseNmtoken(xmlParserCtxtPtr ctxt)
       
  2803 {
       
  2804     xmlChar buf[XML_MAX_NAMELEN + 5];
       
  2805     int len = 0, l;
       
  2806     int c;
       
  2807     int count = 0;
       
  2808 
       
  2809     GROW;
       
  2810     c = CUR_CHAR(l);
       
  2811 
       
  2812     while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
       
  2813        (c == '.') || (c == '-') ||
       
  2814        (c == '_') || (c == ':') ||
       
  2815        (IS_COMBINING(c)) ||
       
  2816        (IS_EXTENDER(c)))
       
  2817    {
       
  2818         if (count++ > 100) {
       
  2819             count = 0;
       
  2820             GROW;
       
  2821         }
       
  2822         COPY_BUF(l,buf,len,c);
       
  2823         NEXTL(l);
       
  2824         c = CUR_CHAR(l);
       
  2825 
       
  2826         if (len >= XML_MAX_NAMELEN)
       
  2827         {
       
  2828             /*
       
  2829              * Okay someone managed to make a huge token, so he's ready to pay
       
  2830              * for the processing speed.
       
  2831              */
       
  2832             xmlChar *buffer;
       
  2833             int max = len * 2;
       
  2834 
       
  2835             buffer = (xmlChar*) xmlMallocAtomic(max * sizeof(xmlChar));
       
  2836             if (!buffer)
       
  2837                 goto OOM_exit;
       
  2838 
       
  2839             memcpy(buffer, buf, len);
       
  2840             while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
       
  2841                 (c == '.') || (c == '-') ||
       
  2842                 (c == '_') || (c == ':') ||
       
  2843                 (IS_COMBINING(c)) ||
       
  2844                 (IS_EXTENDER(c)))
       
  2845            {
       
  2846                 if (count++ > 100) {
       
  2847                     count = 0;
       
  2848                     GROW;
       
  2849                 }
       
  2850                 if (len + 10 > max) {
       
  2851                     // DONE: Fix xmlRealloc
       
  2852                     void* tmp;
       
  2853                     max *= 2;
       
  2854                     tmp = xmlRealloc(buffer, max * sizeof(xmlChar));
       
  2855                     if (!tmp) {
       
  2856                         xmlFree(buffer);
       
  2857 OOM_exit:
       
  2858                         xmlParserOOMErr(ctxt);
       
  2859                         return(NULL);
       
  2860                     }
       
  2861                     buffer = (xmlChar*) tmp;
       
  2862                 }
       
  2863                 COPY_BUF(l,buffer,len,c);
       
  2864                 NEXTL(l);
       
  2865                 c = CUR_CHAR(l);
       
  2866             }
       
  2867             buffer[len] = 0;
       
  2868             return(buffer);
       
  2869         } // if (len >= XML_MAX_NAMELEN)
       
  2870     } // while
       
  2871     if (len == 0)
       
  2872         return(NULL);
       
  2873     return(xmlStrndup(buf, len));
       
  2874 }
       
  2875 
       
  2876 /**
       
  2877  * xmlParseEntityValue:
       
  2878  * @param ctxt an XML parser context
       
  2879  * @param orig if non-NULL store a copy of the original entity value
       
  2880  *
       
  2881  * parse a value for ENTITY declarations
       
  2882  *
       
  2883  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
       
  2884  *                 "'" ([^%&'] | PEReference | Reference)* "'"
       
  2885  *
       
  2886  * Returns the EntityValue parsed with reference substituted or NULL
       
  2887  */
       
  2888 
       
  2889 XMLPUBFUNEXPORT xmlChar *
       
  2890 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
       
  2891     xmlChar *buf = NULL;
       
  2892     int len = 0;
       
  2893     int size = XML_PARSER_BUFFER_SIZE;
       
  2894     int c, l;
       
  2895     xmlChar stop;
       
  2896     xmlChar *ret = NULL;
       
  2897     const xmlChar *cur = NULL;
       
  2898     xmlParserInputPtr input;
       
  2899 
       
  2900     if (RAW == '"') stop = '"';
       
  2901     else if (RAW == '\'') stop = '\'';
       
  2902     else {
       
  2903     xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
       
  2904     return(NULL);
       
  2905     }
       
  2906     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
       
  2907     if (buf == NULL) {
       
  2908         xmlParserOOMErr(ctxt);
       
  2909         return(NULL);
       
  2910     }
       
  2911 
       
  2912     /*
       
  2913      * The content of the entity definition is copied in a buffer.
       
  2914      */
       
  2915 
       
  2916     ctxt->instate = XML_PARSER_ENTITY_VALUE;
       
  2917     input = ctxt->input;
       
  2918     GROW;
       
  2919     NEXT;
       
  2920     c = CUR_CHAR(l);
       
  2921     /*
       
  2922      * NOTE: 4.4.5 Included in Literal
       
  2923      * When a parameter entity reference appears in a literal entity
       
  2924      * value, ... a single or double quote character in the replacement
       
  2925      * text is always treated as a normal data character and will not
       
  2926      * terminate the literal.
       
  2927      * In practice it means we stop the loop only when back at parsing
       
  2928      * the initial entity and the quote is found
       
  2929      */
       
  2930     while ((IS_CHAR(c)) && ((c != stop) || /* checked */
       
  2931        (ctxt->input != input)))
       
  2932     {
       
  2933         if (len + 5 >= size) {
       
  2934             // DONE: Fix xmlRealloc
       
  2935             void* tmp;
       
  2936             size *= 2;
       
  2937             tmp = xmlRealloc(buf, size * sizeof(xmlChar));
       
  2938             if (!tmp) {
       
  2939                 xmlFree(buf);
       
  2940                 xmlParserOOMErr(ctxt);
       
  2941                 return(NULL);
       
  2942             }
       
  2943             buf = (xmlChar*) tmp;
       
  2944         }
       
  2945         COPY_BUF(l,buf,len,c);
       
  2946         NEXTL(l);
       
  2947         /*
       
  2948          * Pop-up of finished entities.
       
  2949          */
       
  2950         while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
       
  2951             xmlPopInput(ctxt);
       
  2952 
       
  2953         GROW;
       
  2954         c = CUR_CHAR(l);
       
  2955         if (c == 0) {
       
  2956             GROW;
       
  2957             c = CUR_CHAR(l);
       
  2958         }
       
  2959     }
       
  2960     buf[len] = 0;
       
  2961 
       
  2962     /*
       
  2963      * Raise problem w.r.t. '&' and '%' being used in non-entities
       
  2964      * reference constructs. Note Charref will be handled in
       
  2965      * xmlStringDecodeEntities()
       
  2966      */
       
  2967     cur = buf;
       
  2968     while (*cur != 0) { /* non input consuming */
       
  2969     if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
       
  2970         xmlChar *name;
       
  2971         xmlChar tmp = *cur;
       
  2972 
       
  2973         cur++;
       
  2974         name = xmlParseStringName(ctxt, &cur);
       
  2975             if ((name == NULL) || (*cur != ';')) {
       
  2976         xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
       
  2977         EMBED_ERRTXT("EntityValue: '%c' forbidden except for entities references\n"),
       
  2978                               tmp);
       
  2979         }
       
  2980         if ((tmp == '%') && (ctxt->inSubset == 1) &&
       
  2981         (ctxt->inputNr == 1)) {
       
  2982         xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
       
  2983         }
       
  2984         if (name != NULL)
       
  2985         xmlFree(name);
       
  2986         if (*cur == 0)
       
  2987             break;
       
  2988     }
       
  2989     cur++;
       
  2990     }
       
  2991 
       
  2992     /*
       
  2993      * Then PEReference entities are substituted.
       
  2994      */
       
  2995     if (c != stop) {
       
  2996     xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
       
  2997     xmlFree(buf);
       
  2998     } else {
       
  2999     NEXT;
       
  3000     /*
       
  3001      * NOTE: 4.4.7 Bypassed
       
  3002      * When a general entity reference appears in the EntityValue in
       
  3003      * an entity declaration, it is bypassed and left as is.
       
  3004      * so XML_SUBSTITUTE_REF is not set here.
       
  3005      */
       
  3006     ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
       
  3007                       0, 0, 0);
       
  3008     if (orig != NULL)
       
  3009         *orig = buf;
       
  3010     else
       
  3011         xmlFree(buf);
       
  3012     }
       
  3013 
       
  3014     return(ret);
       
  3015 }
       
  3016 
       
  3017 /**
       
  3018  * xmlParseAttValueComplex:
       
  3019  * @param ctxt an XML parser context
       
  3020  * @param len the resulting attribute len
       
  3021  * @param normalize wether to apply the inner normalization
       
  3022  *
       
  3023  * parse a value for an attribute, this is the fallback function
       
  3024  * of xmlParseAttValue() when the attribute parsing requires handling
       
  3025  * of non-ASCII characters, or normalization compaction.
       
  3026  *
       
  3027  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
       
  3028  */
       
  3029 static xmlChar *
       
  3030 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
       
  3031     xmlChar limit = 0;
       
  3032     xmlChar *buf = NULL;
       
  3033     int len = 0;
       
  3034     int buf_size = 0;
       
  3035     int c, l, in_space = 0;
       
  3036     xmlChar *current = NULL;
       
  3037     xmlEntityPtr ent;
       
  3038 
       
  3039     if (NXT(0) == '"') {
       
  3040     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
       
  3041     limit = '"';
       
  3042         NEXT;
       
  3043     } else if (NXT(0) == '\'') {
       
  3044     limit = '\'';
       
  3045     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
       
  3046         NEXT;
       
  3047     } else {
       
  3048     xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
       
  3049     return(NULL);
       
  3050     }
       
  3051 
       
  3052     /*
       
  3053      * allocate a translation buffer.
       
  3054      */
       
  3055     buf_size = XML_PARSER_BUFFER_SIZE;
       
  3056     buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
       
  3057     if (buf == NULL) goto mem_error;
       
  3058 
       
  3059     /*
       
  3060      * OK loop until we reach one of the ending char or a size limit.
       
  3061      */
       
  3062     c = CUR_CHAR(l);
       
  3063     while ((NXT(0) != limit) && /* checked */
       
  3064        (c != '<')) {
       
  3065     if (c == 0) break;
       
  3066     if (c == '&') {
       
  3067         in_space = 0;
       
  3068         if (NXT(1) == '#') {
       
  3069         int val = xmlParseCharRef(ctxt);
       
  3070 
       
  3071         if (val == '&') {
       
  3072             if (ctxt->replaceEntities) {
       
  3073             if (len > buf_size - 10) {
       
  3074                 GROW_BUFFER(buf);
       
  3075             }
       
  3076             buf[len++] = '&';
       
  3077             } else {
       
  3078             /*
       
  3079              * The reparsing will be done in xmlStringGetNodeList()
       
  3080              * called by the attribute() function in SAX.c
       
  3081              */
       
  3082             if (len > buf_size - 10) {
       
  3083                 GROW_BUFFER(buf);
       
  3084             }
       
  3085             buf[len++] = '&';
       
  3086             buf[len++] = '#';
       
  3087             buf[len++] = '3';
       
  3088             buf[len++] = '8';
       
  3089             buf[len++] = ';';
       
  3090             }
       
  3091         } else {
       
  3092             if (len > buf_size - 10) {
       
  3093             GROW_BUFFER(buf);
       
  3094             }
       
  3095             len += xmlCopyChar(0, &buf[len], val);
       
  3096         }
       
  3097         } else {
       
  3098         ent = xmlParseEntityRef(ctxt);
       
  3099         // XML ENGINE: TEST CODE: for disabling "Unknown entity reference" error
       
  3100         //if(!ent)return;
       
  3101 
       
  3102         if ((ent != NULL) &&
       
  3103             (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
       
  3104                 if (len > buf_size - 10) {
       
  3105                     GROW_BUFFER(buf);
       
  3106                 }
       
  3107                 if ((ctxt->replaceEntities == 0) &&
       
  3108                     (ent->content[0] == '&'))
       
  3109                 {
       
  3110                     buf[len++] = '&';
       
  3111                     buf[len++] = '#';
       
  3112                     buf[len++] = '3';
       
  3113                     buf[len++] = '8';
       
  3114                     buf[len++] = ';';
       
  3115                 } else {
       
  3116                 buf[len++] = ent->content[0];
       
  3117                 }
       
  3118         } else if ((ent != NULL) &&
       
  3119                    (ctxt->replaceEntities != 0)) {
       
  3120             xmlChar *rep;
       
  3121 
       
  3122             if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
       
  3123             rep = xmlStringDecodeEntities(ctxt, ent->content,
       
  3124                               XML_SUBSTITUTE_REF,
       
  3125                               0, 0, 0);
       
  3126             if (rep != NULL) {
       
  3127                 current = rep;
       
  3128                 while (*current != 0) { /* non input consuming */
       
  3129                 buf[len++] = *current++;
       
  3130                 if (len > buf_size - 10) {
       
  3131                     GROW_BUFFER(buf);
       
  3132                 }
       
  3133                 }
       
  3134                 xmlFree(rep);
       
  3135             }
       
  3136             } else {
       
  3137             if (len > buf_size - 10) {
       
  3138                 GROW_BUFFER(buf);
       
  3139             }
       
  3140             if (ent->content != NULL)
       
  3141                 buf[len++] = ent->content[0];
       
  3142             }
       
  3143         } else if (ent != NULL) {
       
  3144             int i = xmlStrlen(ent->name);
       
  3145             const xmlChar *cur = ent->name;
       
  3146 
       
  3147             /*
       
  3148              * This may look absurd but is needed to detect
       
  3149              * entities problems
       
  3150              */
       
  3151             if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
       
  3152             (ent->content != NULL)) {
       
  3153             xmlChar *rep;
       
  3154             rep = xmlStringDecodeEntities(ctxt, ent->content,
       
  3155                               XML_SUBSTITUTE_REF, 0, 0, 0);
       
  3156             if (rep != NULL)
       
  3157                 xmlFree(rep);
       
  3158             }
       
  3159 
       
  3160             /*
       
  3161              * Just output the reference
       
  3162              */
       
  3163             buf[len++] = '&';
       
  3164             /**
       
  3165              *   SYMBIAN : DEFECT FIX : DEF129002 (libxml2 buffer overflow vulnerability)
       
  3166              *              Make sure that the buffer is grown until it becomes 
       
  3167              *              large enough to avoid buffer overflow in case of long-entity 
       
  3168              *              names.The original defect can be located in debian bug tracking database
       
  3169 			 *				with defect number 498768. 
       
  3170              */      
       
  3171             while (len > buf_size - i - 10)  {
       
  3172             GROW_BUFFER(buf);
       
  3173             }
       
  3174             for (;i > 0;i--)
       
  3175             buf[len++] = *cur++;
       
  3176             buf[len++] = ';';
       
  3177         }
       
  3178         }
       
  3179     } else {
       
  3180         if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
       
  3181             if ((len != 0) || (!normalize)) {
       
  3182             if ((!normalize) || (!in_space)) {
       
  3183             COPY_BUF(l,buf,len,0x20);
       
  3184             if (len > buf_size - 10) {
       
  3185                 GROW_BUFFER(buf);
       
  3186             }
       
  3187             }
       
  3188             in_space = 1;
       
  3189         }
       
  3190         } else {
       
  3191             in_space = 0;
       
  3192         COPY_BUF(l,buf,len,c);
       
  3193         if (len > buf_size - 10) {
       
  3194             GROW_BUFFER(buf);
       
  3195         }
       
  3196         }
       
  3197         NEXTL(l);
       
  3198     }
       
  3199     GROW;
       
  3200     c = CUR_CHAR(l);
       
  3201     }
       
  3202     if ((in_space) && (normalize)) {
       
  3203         while (buf[len - 1] == 0x20) len--;
       
  3204     }
       
  3205     buf[len] = 0;
       
  3206     if (RAW == '<') {
       
  3207     xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
       
  3208     } else if (RAW != limit) {
       
  3209         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
       
  3210                    EMBED_ERRTXT("AttValue: ' expected\n"));
       
  3211     } else
       
  3212     NEXT;
       
  3213     if (attlen != NULL) *attlen = len;
       
  3214     return(buf);
       
  3215 
       
  3216 mem_error:
       
  3217     xmlParserOOMErr(ctxt);
       
  3218     return(NULL);
       
  3219 }
       
  3220 
       
  3221 /**
       
  3222  * xmlParseAttValue:
       
  3223  * @param ctxt an XML parser context
       
  3224  *
       
  3225  * parse a value for an attribute
       
  3226  * Note: the parser won't do substitution of entities here, this
       
  3227  * will be handled later in xmlStringGetNodeList
       
  3228  *
       
  3229  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
       
  3230  *                   "'" ([^<&'] | Reference)* "'"
       
  3231  *
       
  3232  * 3.3.3 Attribute-Value Normalization:
       
  3233  * Before the value of an attribute is passed to the application or
       
  3234  * checked for validity, the XML processor must normalize it as follows:
       
  3235  * - a character reference is processed by appending the referenced
       
  3236  *   character to the attribute value
       
  3237  * - an entity reference is processed by recursively processing the
       
  3238  *   replacement text of the entity
       
  3239  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
       
  3240  *   appending #x20 to the normalized value, except that only a single
       
  3241  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
       
  3242  *   parsed entity or the literal entity value of an internal parsed entity
       
  3243  * - other characters are processed by appending them to the normalized value
       
  3244  * If the declared value is not CDATA, then the XML processor must further
       
  3245  * process the normalized attribute value by discarding any leading and
       
  3246  * trailing space (#x20) characters, and by replacing sequences of space
       
  3247  * (#x20) characters by a single space (#x20) character.
       
  3248  * All attributes for which no declaration has been read should be treated
       
  3249  * by a non-validating parser as if declared CDATA.
       
  3250  *
       
  3251  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
       
  3252  */
       
  3253 
       
  3254 
       
  3255 XMLPUBFUNEXPORT xmlChar *
       
  3256 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
       
  3257     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
       
  3258 }
       
  3259 
       
  3260 /**
       
  3261  * xmlParseSystemLiteral:
       
  3262  * @param ctxt an XML parser context
       
  3263  *
       
  3264  * parse an XML Literal
       
  3265  *
       
  3266  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
       
  3267  *
       
  3268  * Returns the SystemLiteral parsed or NULL
       
  3269  */
       
  3270 
       
  3271 XMLPUBFUNEXPORT xmlChar *
       
  3272 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
       
  3273     xmlChar *buf = NULL;
       
  3274     int len = 0;
       
  3275     int size = XML_PARSER_BUFFER_SIZE;
       
  3276     int cur, l;
       
  3277     xmlChar stop;
       
  3278     int state = ctxt->instate;
       
  3279     int count = 0;
       
  3280 
       
  3281     SHRINK;
       
  3282     if (RAW == '"') {
       
  3283         NEXT;
       
  3284     stop = '"';
       
  3285     } else if (RAW == '\'') {
       
  3286         NEXT;
       
  3287     stop = '\'';
       
  3288     } else {
       
  3289     xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
       
  3290     return(NULL);
       
  3291     }
       
  3292 
       
  3293     buf = (xmlChar*) xmlMallocAtomic(size * sizeof(xmlChar));
       
  3294     if (!buf){
       
  3295         xmlParserOOMErr(ctxt);
       
  3296         return NULL;
       
  3297     }
       
  3298     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
       
  3299     cur = CUR_CHAR(l);
       
  3300     while ((IS_CHAR(cur)) && (cur != stop))
       
  3301     { /* checked */
       
  3302         if (len + 5 >= size) {
       
  3303             // DONE: Fix xmlRealloc
       
  3304             xmlChar* tmp;
       
  3305             size *= 2;
       
  3306             tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  3307             if (!tmp) {
       
  3308                 xmlFree(buf);
       
  3309                 xmlParserOOMErr(ctxt);
       
  3310                 ctxt->instate = (xmlParserInputState) state; 
       
  3311                 return(NULL);
       
  3312             }
       
  3313             buf = tmp;
       
  3314         }
       
  3315         count++;
       
  3316         if (count > 50) {
       
  3317             GROW;
       
  3318             count = 0;
       
  3319         }
       
  3320         COPY_BUF(l,buf,len,cur);
       
  3321         NEXTL(l);
       
  3322         cur = CUR_CHAR(l);
       
  3323         if (cur == 0) {
       
  3324             GROW;
       
  3325             SHRINK;
       
  3326             cur = CUR_CHAR(l);
       
  3327         }
       
  3328     }
       
  3329     buf[len] = 0;
       
  3330     ctxt->instate = (xmlParserInputState) state;
       
  3331     if (!IS_CHAR(cur)) {
       
  3332     xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
       
  3333     } else {
       
  3334     NEXT;
       
  3335     }
       
  3336     return(buf);
       
  3337 }
       
  3338 
       
  3339 /**
       
  3340  * xmlParsePubidLiteral:
       
  3341  * @param ctxt an XML parser context
       
  3342  *
       
  3343  * parse an XML public literal
       
  3344  *
       
  3345  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
       
  3346  *
       
  3347  * Returns the PubidLiteral parsed or NULL.
       
  3348  */
       
  3349 XMLPUBFUNEXPORT xmlChar *
       
  3350 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt)
       
  3351 {
       
  3352     xmlChar* buf = NULL;
       
  3353     int len = 0;
       
  3354     int size = XML_PARSER_BUFFER_SIZE;
       
  3355     xmlChar cur;
       
  3356     xmlChar stop;
       
  3357     int count = 0;
       
  3358     xmlParserInputState oldstate = ctxt->instate;
       
  3359 
       
  3360     SHRINK;
       
  3361     if (RAW == '"') {
       
  3362         NEXT;
       
  3363         stop = '"';
       
  3364     } else if (RAW == '\'') {
       
  3365         NEXT;
       
  3366         stop = '\'';
       
  3367     } else {
       
  3368         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
       
  3369         return(NULL);
       
  3370     }
       
  3371     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
       
  3372     if (!buf)
       
  3373         goto OOM_exit;
       
  3374 
       
  3375     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
       
  3376     cur = CUR;
       
  3377     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop))
       
  3378     { /* checked */
       
  3379         if (len + 1 >= size)
       
  3380         {
       
  3381             // DONE: Fix xmlRealloc
       
  3382             xmlChar* tmp;
       
  3383             size *= 2;
       
  3384             tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  3385             if (!tmp) {
       
  3386                 xmlFree(buf);
       
  3387 OOM_exit:
       
  3388                 xmlParserOOMErr(ctxt);
       
  3389                 return(NULL);
       
  3390             }
       
  3391             buf = tmp;
       
  3392         }
       
  3393         buf[len++] = cur;
       
  3394         count++;
       
  3395         if (count > 50) {
       
  3396             GROW;
       
  3397             count = 0;
       
  3398         }
       
  3399         NEXT;
       
  3400         cur = CUR;
       
  3401         if (cur == 0) {
       
  3402             GROW;
       
  3403             SHRINK;
       
  3404             cur = CUR;
       
  3405         }
       
  3406     } // while PUBID CHARs
       
  3407 
       
  3408     buf[len] = 0;
       
  3409     if (cur != stop) {
       
  3410         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
       
  3411     } else {
       
  3412         NEXT;
       
  3413     }
       
  3414     ctxt->instate = oldstate;
       
  3415     return(buf);
       
  3416 }
       
  3417 
       
  3418 void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
       
  3419 /**
       
  3420  * xmlParseCharData:
       
  3421  * @param ctxt an XML parser context
       
  3422  * @param cdata int indicating whether we are within a CDATA section
       
  3423  *
       
  3424  * parse a CharData section.
       
  3425  * if we are within a CDATA section ']]>' marks an end of section.
       
  3426  *
       
  3427  * The right angle bracket (>) may be represented using the string "&gt;",
       
  3428  * and must, for compatibility, be escaped using "&gt;" or a character
       
  3429  * reference when it appears in the string "]]>" in content, when that
       
  3430  * string is not marking the end of a CDATA section.
       
  3431  *
       
  3432  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
       
  3433  */
       
  3434 
       
  3435 XMLPUBFUNEXPORT void
       
  3436 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
       
  3437     const xmlChar *in;
       
  3438     int nbchar = 0;
       
  3439     int line = ctxt->input->line;
       
  3440     int col = ctxt->input->col;
       
  3441 
       
  3442     SHRINK;
       
  3443     GROW;
       
  3444     /*
       
  3445      * Accelerated common case where input don't need to be
       
  3446      * modified before passing it to the handler.
       
  3447      */
       
  3448     if (cdata)
       
  3449         goto parse_complex;
       
  3450     //--------------------------------------------------------------------
       
  3451     in = ctxt->input->cur;
       
  3452 
       
  3453     do
       
  3454     {
       
  3455 get_more_space:
       
  3456         while (*in == 0x20)
       
  3457             in++;
       
  3458 
       
  3459         if (*in == 0xA) {
       
  3460             ctxt->input->line++;
       
  3461             in++;
       
  3462             while (*in == 0xA) {
       
  3463                 ctxt->input->line++;
       
  3464                 in++;
       
  3465             }
       
  3466             goto get_more_space;
       
  3467         }
       
  3468 
       
  3469         if (*in == '<') {
       
  3470             nbchar = in - ctxt->input->cur;
       
  3471             if (nbchar > 0) {
       
  3472                 const xmlChar* tmp = ctxt->input->cur;
       
  3473                 ctxt->input->cur = in;
       
  3474 
       
  3475                 if (ctxt->sax->ignorableWhitespace != ctxt->sax->characters) {
       
  3476                     if (areBlanks(ctxt, tmp, nbchar, 1)){
       
  3477                         ctxt->sax->ignorableWhitespace(ctxt->userData, tmp, nbchar);
       
  3478                     } else
       
  3479                         if (ctxt->sax->characters)
       
  3480                             ctxt->sax->characters(ctxt->userData, tmp, nbchar);
       
  3481                 } else
       
  3482                     if (ctxt->sax->characters) {
       
  3483                         ctxt->sax->characters(ctxt->userData, tmp, nbchar);
       
  3484                     }
       
  3485             }
       
  3486             return;
       
  3487         }
       
  3488 get_more:
       
  3489         while (((*in > ']')   && (*in <= 0x7F)) ||
       
  3490                ((*in > '&')   && (*in < '<'))   ||
       
  3491                ((*in > '<')   && (*in < ']'))   ||
       
  3492                ((*in >= 0x20) && (*in < '&'))   ||
       
  3493                (*in == 0x09))
       
  3494         {
       
  3495             in++;
       
  3496         }
       
  3497 
       
  3498         if (*in == 0xA) {
       
  3499             ctxt->input->line++;
       
  3500             in++;
       
  3501             while (*in == 0xA) {
       
  3502                 ctxt->input->line++;
       
  3503                 in++;
       
  3504             }
       
  3505             goto get_more;
       
  3506         }
       
  3507         if (*in == ']') {
       
  3508             if ((in[1] == ']') && (in[2] == '>')) {
       
  3509                 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
       
  3510                 ctxt->input->cur = in;
       
  3511                 return;
       
  3512             }
       
  3513             in++;
       
  3514             goto get_more;
       
  3515         }
       
  3516         nbchar = in - ctxt->input->cur;
       
  3517         if (nbchar > 0) {
       
  3518             if (ctxt->sax->ignorableWhitespace != ctxt->sax->characters
       
  3519                 &&
       
  3520                 IS_BLANK_CH(*ctxt->input->cur))
       
  3521             {
       
  3522                 const xmlChar *tmp = ctxt->input->cur;
       
  3523                 ctxt->input->cur = in;
       
  3524 
       
  3525                 if (areBlanks(ctxt, tmp, nbchar, 0))
       
  3526                 {
       
  3527                     ctxt->sax->ignorableWhitespace(ctxt->userData, tmp, nbchar);
       
  3528                 }
       
  3529                 else if (ctxt->sax->characters)
       
  3530                 {
       
  3531                     ctxt->sax->characters(ctxt->userData, tmp, nbchar);
       
  3532                 }
       
  3533             } else {
       
  3534                 if (ctxt->sax->characters)
       
  3535                 {
       
  3536                     ctxt->sax->characters(ctxt->userData, ctxt->input->cur, nbchar);
       
  3537                 }
       
  3538             }
       
  3539             line = ctxt->input->line; // moved from both IF branches above
       
  3540             col = ctxt->input->col;   //
       
  3541         }
       
  3542         ctxt->input->cur = in;
       
  3543         if (*in == 0xD) {
       
  3544             in++;
       
  3545             if (*in == 0xA) {
       
  3546                 ctxt->input->cur = in;
       
  3547                 in++;
       
  3548                 ctxt->input->line++;
       
  3549                 continue; /* do-while loop */
       
  3550             }
       
  3551             in--;
       
  3552         }
       
  3553 
       
  3554         if (*in == '<' || *in == '&') {
       
  3555             return;
       
  3556         }
       
  3557         SHRINK;
       
  3558         GROW;
       
  3559         in = ctxt->input->cur;
       
  3560         // end of DO-WHILE  loop
       
  3561     } while ((*in >= 0x20 && *in <= 0x7F) || (*in == 0x09));
       
  3562 
       
  3563     //nbchar = 0; // NOT needed
       
  3564 
       
  3565 //---------------------------------------------------------------------------------------
       
  3566 parse_complex:
       
  3567     ctxt->input->line = line;
       
  3568     ctxt->input->col = col;
       
  3569     xmlParseCharDataComplex(ctxt, cdata);
       
  3570 }
       
  3571 
       
  3572 /**
       
  3573  * xmlParseCharDataComplex:
       
  3574  * @param ctxt an XML parser context
       
  3575  * @param cdata int indicating whether we are within a CDATA section
       
  3576  *
       
  3577  * parse a CharData section.this is the fallback function
       
  3578  * of xmlParseCharData() when the parsing requires handling
       
  3579  * of non-ASCII characters.
       
  3580  */
       
  3581 void
       
  3582 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
       
  3583     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
       
  3584     int nbchar = 0;
       
  3585     int cur, l;
       
  3586     int count = 0;
       
  3587 
       
  3588     SHRINK;
       
  3589     GROW;
       
  3590     cur = CUR_CHAR(l);
       
  3591     while ((cur != '<') && /* checked */
       
  3592            (cur != '&') &&
       
  3593        (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
       
  3594     if ((cur == ']') && (NXT(1) == ']') &&
       
  3595         (NXT(2) == '>')) {
       
  3596         if (cdata) break;
       
  3597         else {
       
  3598         xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
       
  3599         }
       
  3600     }
       
  3601     COPY_BUF(l,buf,nbchar,cur);
       
  3602     if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
       
  3603         buf[nbchar] = 0;
       
  3604 
       
  3605         /*
       
  3606          * OK the segment is to be consumed as chars.
       
  3607          */
       
  3608         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
       
  3609         if (areBlanks(ctxt, buf, nbchar, 0)) {
       
  3610             if (ctxt->sax->ignorableWhitespace != NULL)
       
  3611             ctxt->sax->ignorableWhitespace(ctxt->userData,
       
  3612                                            buf, nbchar);
       
  3613         } else {
       
  3614             if (ctxt->sax->characters != NULL)
       
  3615             ctxt->sax->characters(ctxt->userData, buf, nbchar);
       
  3616         }
       
  3617         }
       
  3618         nbchar = 0;
       
  3619     }
       
  3620     count++;
       
  3621     if (count > 50) {
       
  3622         GROW;
       
  3623         count = 0;
       
  3624     }
       
  3625     NEXTL(l);
       
  3626     cur = CUR_CHAR(l);
       
  3627     }
       
  3628     if (nbchar != 0) {
       
  3629         buf[nbchar] = 0;
       
  3630     /*
       
  3631      * OK the segment is to be consumed as chars.
       
  3632      */
       
  3633     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
       
  3634         if (areBlanks(ctxt, buf, nbchar, 0)) {
       
  3635         if (ctxt->sax->ignorableWhitespace != NULL)
       
  3636             ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
       
  3637         } else {
       
  3638         if (ctxt->sax->characters != NULL)
       
  3639             ctxt->sax->characters(ctxt->userData, buf, nbchar);
       
  3640         }
       
  3641     }
       
  3642     }
       
  3643 }
       
  3644 
       
  3645 /**
       
  3646  * xmlParseExternalID:
       
  3647  * @param ctxt an XML parser context
       
  3648  * @param publicID a xmlChar** receiving PubidLiteral
       
  3649  * @param strict indicate whether we should restrict parsing to only
       
  3650  *          production [75], see NOTE below
       
  3651  *
       
  3652  * Parse an External ID or a Public ID
       
  3653  *
       
  3654  * NOTE: Productions [75] and [83] interact badly since [75] can generate
       
  3655  *       'PUBLIC' S PubidLiteral S SystemLiteral
       
  3656  *
       
  3657  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
       
  3658  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
       
  3659  *
       
  3660  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
       
  3661  *
       
  3662  * Returns the function returns SystemLiteral and in the second
       
  3663  *                case publicID receives PubidLiteral, is strict is off
       
  3664  *                it is possible to return NULL and have publicID set.
       
  3665  */
       
  3666 
       
  3667 XMLPUBFUNEXPORT xmlChar *
       
  3668 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
       
  3669     xmlChar *URI = NULL;
       
  3670 
       
  3671     SHRINK;
       
  3672 
       
  3673     *publicID = NULL;
       
  3674     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
       
  3675         SKIP(6);
       
  3676     if (!IS_BLANK_CH(CUR)) {
       
  3677         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  3678                        EMBED_ERRTXT("Space required after 'SYSTEM'\n"));
       
  3679     }
       
  3680         SKIP_BLANKS;
       
  3681     URI = xmlParseSystemLiteral(ctxt);
       
  3682     if (URI == NULL) {
       
  3683         xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
       
  3684         }
       
  3685     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
       
  3686         SKIP(6);
       
  3687     if (!IS_BLANK_CH(CUR)) {
       
  3688         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  3689             EMBED_ERRTXT("Space required after 'PUBLIC'\n"));
       
  3690     }
       
  3691         SKIP_BLANKS;
       
  3692     *publicID = xmlParsePubidLiteral(ctxt);
       
  3693     if (*publicID == NULL) {
       
  3694         xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
       
  3695     }
       
  3696     if (strict) {
       
  3697         /*
       
  3698          * We don't handle [83] so "S SystemLiteral" is required.
       
  3699          */
       
  3700         if (!IS_BLANK_CH(CUR)) {
       
  3701         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  3702             EMBED_ERRTXT("Space required after the Public Identifier\n"));
       
  3703         }
       
  3704     } else {
       
  3705         /*
       
  3706          * We handle [83] so we return immediately, if
       
  3707          * "S SystemLiteral" is not detected. From a purely parsing
       
  3708          * point of view that's a nice mess.
       
  3709          */
       
  3710         const xmlChar *ptr;
       
  3711         GROW;
       
  3712 
       
  3713         ptr = CUR_PTR;
       
  3714         if (!IS_BLANK_CH(*ptr)) return(NULL);
       
  3715 
       
  3716         while (IS_BLANK_CH(*ptr)) ptr++; 
       
  3717         if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
       
  3718     }
       
  3719         SKIP_BLANKS;
       
  3720     URI = xmlParseSystemLiteral(ctxt);
       
  3721     if (URI == NULL) {
       
  3722         xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
       
  3723         }
       
  3724     }
       
  3725     return(URI);
       
  3726 }
       
  3727 
       
  3728 /**
       
  3729  * xmlParseComment:
       
  3730  * @param ctxt an XML parser context
       
  3731  *
       
  3732  * Skip an XML (SGML) comment <!-- .... -->
       
  3733  *  The spec says that "For compatibility, the string "--" (double-hyphen)
       
  3734  *  must not occur within comments. "
       
  3735  *
       
  3736  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
       
  3737  */
       
  3738 XMLPUBFUNEXPORT void
       
  3739 xmlParseComment(xmlParserCtxtPtr ctxt) {
       
  3740     xmlChar *buf = NULL;
       
  3741     int len;
       
  3742     int size = XML_PARSER_BUFFER_SIZE;
       
  3743     int q, ql;
       
  3744     int r, rl;
       
  3745     int cur, l;
       
  3746     xmlParserInputState state;
       
  3747     xmlParserInputPtr input = ctxt->input;
       
  3748     int count = 0;
       
  3749 
       
  3750     /*
       
  3751      * Check that there is a comment right here.
       
  3752      */
       
  3753     if ((RAW != '<') || (NXT(1) != '!') ||
       
  3754         (NXT(2) != '-') || (NXT(3) != '-')) return;
       
  3755 
       
  3756     state = ctxt->instate;
       
  3757     ctxt->instate = XML_PARSER_COMMENT;
       
  3758     SHRINK;
       
  3759     SKIP(4);
       
  3760     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
       
  3761     if (buf == NULL)
       
  3762         goto OOM_exit;
       
  3763 
       
  3764     q = CUR_CHAR(ql);
       
  3765     if (q == 0)
       
  3766         goto not_terminated;
       
  3767     NEXTL(ql);
       
  3768     r = CUR_CHAR(rl);
       
  3769     if (r == 0)
       
  3770         goto not_terminated;
       
  3771     NEXTL(rl);
       
  3772     cur = CUR_CHAR(l);
       
  3773     if (cur == 0)
       
  3774         goto not_terminated;
       
  3775     len = 0;
       
  3776     while (IS_CHAR(cur) && /* checked */
       
  3777            ((cur != '>') ||
       
  3778         (r != '-') || (q != '-'))) {
       
  3779     if ((r == '-') && (q == '-')) {
       
  3780         xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
       
  3781     }
       
  3782     if (len + 5 >= size) {
       
  3783         // DONE: Fix xmlRealloc
       
  3784         xmlChar* tmp;
       
  3785         size *= 2;
       
  3786         tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  3787         if (!tmp) {
       
  3788             xmlFree(buf);
       
  3789 OOM_exit:
       
  3790             xmlParserOOMErr(ctxt);
       
  3791             ctxt->instate = state;
       
  3792             return;
       
  3793         }
       
  3794         buf = tmp;
       
  3795     }
       
  3796     COPY_BUF(ql,buf,len,q);
       
  3797     q = r;
       
  3798     ql = rl;
       
  3799     r = cur;
       
  3800     rl = l;
       
  3801 
       
  3802     count++;
       
  3803     if (count > 50) {
       
  3804         GROW;
       
  3805         count = 0;
       
  3806     }
       
  3807     NEXTL(l);
       
  3808     cur = CUR_CHAR(l);
       
  3809     if (cur == 0) {
       
  3810         SHRINK;
       
  3811         GROW;
       
  3812         cur = CUR_CHAR(l);
       
  3813     }
       
  3814     }
       
  3815     buf[len] = 0;
       
  3816     if (!IS_CHAR(cur)) {
       
  3817     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
       
  3818                          EMBED_ERRTXT("Comment not terminated \n<!--%.50s\n"), buf);
       
  3819     xmlFree(buf);
       
  3820     } else {
       
  3821     if (input != ctxt->input) {
       
  3822         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  3823         EMBED_ERRTXT("Comment doesn't start and stop in the same entity\n"));
       
  3824     }
       
  3825         NEXT;
       
  3826     if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
       
  3827         (!ctxt->disableSAX))
       
  3828         ctxt->sax->comment(ctxt->userData, buf);
       
  3829     xmlFree(buf);
       
  3830     }
       
  3831     ctxt->instate = state;
       
  3832     return;
       
  3833 not_terminated:
       
  3834     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
       
  3835              EMBED_ERRTXT("Comment not terminated\n"), NULL);
       
  3836     xmlFree(buf);
       
  3837 }
       
  3838 
       
  3839 /**
       
  3840  * xmlParsePITarget:
       
  3841  * @param ctxt an XML parser context
       
  3842  *
       
  3843  * parse the name of a PI
       
  3844  *
       
  3845  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
       
  3846  *
       
  3847  * Returns the PITarget name or NULL
       
  3848  */
       
  3849 
       
  3850 XMLPUBFUNEXPORT const xmlChar *
       
  3851 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
       
  3852 	
       
  3853     const xmlChar *name;
       
  3854 	LOAD_GS_SAFE_CTXT(ctxt)
       
  3855 	
       
  3856     name = xmlParseName(ctxt);
       
  3857     if ((name != NULL) &&
       
  3858         ((name[0] == 'x') || (name[0] == 'X')) &&
       
  3859         ((name[1] == 'm') || (name[1] == 'M')) &&
       
  3860         ((name[2] == 'l') || (name[2] == 'L'))) {
       
  3861     int i;
       
  3862     if ((name[0] == 'x') && (name[1] == 'm') &&
       
  3863         (name[2] == 'l') && (name[3] == 0)) {
       
  3864         xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
       
  3865         EMBED_ERRTXT("XML declaration allowed only at the start of the document\n"));
       
  3866         return(name);
       
  3867     } else if (name[3] == 0) {
       
  3868         xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
       
  3869         return(name);
       
  3870     }
       
  3871     for (i = 0;;i++) {
       
  3872         if (xmlW3CPIs[i] == NULL) break;
       
  3873         if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
       
  3874             return(name);
       
  3875     }
       
  3876     xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
       
  3877               EMBED_ERRTXT("xmlParsePITarget: invalid name prefix 'xml'\n"),
       
  3878               NULL, NULL);
       
  3879     }
       
  3880     return(name);
       
  3881 }
       
  3882 
       
  3883 #ifdef LIBXML_CATALOG_ENABLED
       
  3884 /**
       
  3885  * xmlParseCatalogPI:
       
  3886  * @param ctxt an XML parser context
       
  3887  * @param catalog the PI value string
       
  3888  *
       
  3889  * parse an XML Catalog Processing Instruction.
       
  3890  *
       
  3891  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
       
  3892  *
       
  3893  * Occurs only if allowed by the user and if happening in the Misc
       
  3894  * part of the document before any doctype informations
       
  3895  * This will add the given catalog to the parsing context in order
       
  3896  * to be used if there is a resolution need further down in the document
       
  3897  */
       
  3898 
       
  3899 static void
       
  3900 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
       
  3901     xmlChar *URL = NULL;
       
  3902     const xmlChar *tmp, *base;
       
  3903     xmlChar marker;
       
  3904 
       
  3905     tmp = catalog;
       
  3906     while (IS_BLANK_CH(*tmp)) tmp++;
       
  3907     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
       
  3908     goto error;
       
  3909     tmp += 7;
       
  3910     while (IS_BLANK_CH(*tmp)) tmp++;
       
  3911     if (*tmp != '=') {
       
  3912     return;
       
  3913     }
       
  3914     tmp++;
       
  3915     while (IS_BLANK_CH(*tmp)) tmp++;
       
  3916     marker = *tmp;
       
  3917     if ((marker != '\'') && (marker != '"'))
       
  3918     goto error;
       
  3919     tmp++;
       
  3920     base = tmp;
       
  3921     while ((*tmp != 0) && (*tmp != marker)) tmp++;
       
  3922     if (*tmp == 0)
       
  3923     goto error;
       
  3924     URL = xmlStrndup(base, tmp - base);
       
  3925     tmp++;
       
  3926     while (IS_BLANK_CH(*tmp)) tmp++;
       
  3927     if (*tmp != 0)
       
  3928     goto error;
       
  3929 
       
  3930     if (URL != NULL) {
       
  3931     ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
       
  3932     xmlFree(URL);
       
  3933     }
       
  3934     return;
       
  3935 
       
  3936 error:
       
  3937     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
       
  3938               "Catalog PI syntax error: %s\n",
       
  3939           catalog, NULL);
       
  3940     if (URL != NULL)
       
  3941     xmlFree(URL);
       
  3942 }
       
  3943 #endif
       
  3944 
       
  3945 /**
       
  3946  * xmlParsePI:
       
  3947  * @param ctxt an XML parser context
       
  3948  *
       
  3949  * parse an XML Processing Instruction.
       
  3950  *
       
  3951  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
       
  3952  *
       
  3953  * The processing is transfered to SAX once parsed.
       
  3954  */
       
  3955 
       
  3956 XMLPUBFUNEXPORT void
       
  3957 xmlParsePI(xmlParserCtxtPtr ctxt) {
       
  3958     xmlChar *buf = NULL;
       
  3959     int len = 0;
       
  3960     int size = XML_PARSER_BUFFER_SIZE;
       
  3961     int cur, l;
       
  3962     const xmlChar *target;
       
  3963     xmlParserInputState state;
       
  3964     int count = 0;
       
  3965 
       
  3966     if ((RAW == '<') && (NXT(1) == '?')) {
       
  3967     xmlParserInputPtr input = ctxt->input;
       
  3968     state = ctxt->instate;
       
  3969         ctxt->instate = XML_PARSER_PI;
       
  3970     /*
       
  3971      * this is a Processing Instruction.
       
  3972      */
       
  3973     SKIP(2);
       
  3974     SHRINK;
       
  3975 
       
  3976     /*
       
  3977      * Parse the target name and check for special support like
       
  3978      * namespace.
       
  3979      */
       
  3980         target = xmlParsePITarget(ctxt);
       
  3981     if (target != NULL) {
       
  3982         if ((RAW == '?') && (NXT(1) == '>')) {
       
  3983         if (input != ctxt->input) {
       
  3984             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  3985         EMBED_ERRTXT("PI declaration doesn't start and stop in the same entity\n"));
       
  3986         }
       
  3987         SKIP(2);
       
  3988 
       
  3989         /*
       
  3990          * SAX: PI detected.
       
  3991          */
       
  3992         if ((ctxt->sax) && (!ctxt->disableSAX) &&
       
  3993             (ctxt->sax->processingInstruction != NULL))
       
  3994             ctxt->sax->processingInstruction(ctxt->userData,
       
  3995                                              target, NULL);
       
  3996         ctxt->instate = state;
       
  3997         return;
       
  3998         }
       
  3999         buf = (xmlChar*) xmlMallocAtomic(size * sizeof(xmlChar));
       
  4000         if (!buf)
       
  4001             goto OOM_exit;
       
  4002 
       
  4003         cur = CUR;
       
  4004         if (!IS_BLANK(cur)) {
       
  4005         xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4006               EMBED_ERRTXT("ParsePI: PI %s space expected\n"), target);
       
  4007         }
       
  4008             SKIP_BLANKS;
       
  4009         cur = CUR_CHAR(l);
       
  4010         while (IS_CHAR(cur) && /* checked */
       
  4011            ((cur != '?') || (NXT(1) != '>'))) {
       
  4012         if (len + 5 >= size) {
       
  4013             // DONE: Fix xmlRealloc
       
  4014             xmlChar* tmp;
       
  4015             size *= 2;
       
  4016             tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  4017             if (!tmp) {
       
  4018                 xmlFree(buf);
       
  4019 OOM_exit:
       
  4020                 xmlParserOOMErr(ctxt);
       
  4021                 ctxt->instate = state;
       
  4022                 return;
       
  4023             }
       
  4024             buf = tmp;
       
  4025         }
       
  4026         count++;
       
  4027         if (count > 50) {
       
  4028             GROW;
       
  4029             count = 0;
       
  4030         }
       
  4031         COPY_BUF(l,buf,len,cur);
       
  4032         NEXTL(l);
       
  4033         cur = CUR_CHAR(l);
       
  4034         if (cur == 0) {
       
  4035             SHRINK;
       
  4036             GROW;
       
  4037             cur = CUR_CHAR(l);
       
  4038         }
       
  4039         }
       
  4040         buf[len] = 0;
       
  4041         if (cur != '?') {
       
  4042         xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
       
  4043               EMBED_ERRTXT("ParsePI: PI %s never end ...\n"), target);
       
  4044         } else {
       
  4045         if (input != ctxt->input) {
       
  4046             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4047         EMBED_ERRTXT("PI declaration doesn't start and stop in the same entity\n"));
       
  4048         }
       
  4049         SKIP(2);
       
  4050 
       
  4051 #ifdef LIBXML_CATALOG_ENABLED
       
  4052         if (((state == XML_PARSER_MISC) ||
       
  4053                  (state == XML_PARSER_START)) &&
       
  4054             (xmlStrEqual(target, XML_CATALOG_PI))) {
       
  4055             xmlCatalogAllow allow = xmlCatalogGetDefaults();
       
  4056             if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
       
  4057             (allow == XML_CATA_ALLOW_ALL))
       
  4058             xmlParseCatalogPI(ctxt, buf);
       
  4059         }
       
  4060 #endif
       
  4061 
       
  4062 
       
  4063         /*
       
  4064          * SAX: PI detected.
       
  4065          */
       
  4066         if ((ctxt->sax) && (!ctxt->disableSAX) &&
       
  4067             (ctxt->sax->processingInstruction != NULL))
       
  4068             ctxt->sax->processingInstruction(ctxt->userData,
       
  4069                                              target, buf);
       
  4070         }
       
  4071         xmlFree(buf);
       
  4072     } else {
       
  4073         xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
       
  4074     }
       
  4075     ctxt->instate = state;
       
  4076     }
       
  4077 }
       
  4078 
       
  4079 /**
       
  4080  * xmlParseNotationDecl:
       
  4081  * @param ctxt an XML parser context
       
  4082  *
       
  4083  * parse a notation declaration
       
  4084  *
       
  4085  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
       
  4086  *
       
  4087  * Hence there is actually 3 choices:
       
  4088  *     'PUBLIC' S PubidLiteral
       
  4089  *     'PUBLIC' S PubidLiteral S SystemLiteral
       
  4090  * and 'SYSTEM' S SystemLiteral
       
  4091  *
       
  4092  * See the NOTE on xmlParseExternalID().
       
  4093  */
       
  4094 
       
  4095 XMLPUBFUNEXPORT void
       
  4096 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
       
  4097     const xmlChar *name;
       
  4098     xmlChar *Pubid;
       
  4099     xmlChar *Systemid;
       
  4100 
       
  4101     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
       
  4102     xmlParserInputPtr input = ctxt->input;
       
  4103     SHRINK;
       
  4104     SKIP(10);
       
  4105     if (!IS_BLANK_CH(CUR)) {
       
  4106         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4107                EMBED_ERRTXT("Space required after '<!NOTATION'\n"));
       
  4108         return;
       
  4109     }
       
  4110     SKIP_BLANKS;
       
  4111 
       
  4112         name = xmlParseName(ctxt);
       
  4113     if (name == NULL) {
       
  4114         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
       
  4115         return;
       
  4116     }
       
  4117     if (!IS_BLANK_CH(CUR)) {
       
  4118         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4119              EMBED_ERRTXT("Space required after the NOTATION name'\n"));
       
  4120         return;
       
  4121     }
       
  4122     SKIP_BLANKS;
       
  4123 
       
  4124     /*
       
  4125      * Parse the IDs.
       
  4126      */
       
  4127     Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
       
  4128     SKIP_BLANKS;
       
  4129 
       
  4130     if (RAW == '>') {
       
  4131         if (input != ctxt->input) {
       
  4132         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4133     EMBED_ERRTXT("Notation declaration doesn't start and stop in the same entity\n"));
       
  4134         }
       
  4135         NEXT;
       
  4136         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
       
  4137         (ctxt->sax->notationDecl != NULL))
       
  4138         ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
       
  4139     } else {
       
  4140         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
       
  4141     }
       
  4142     if (Systemid != NULL) xmlFree(Systemid);
       
  4143     if (Pubid != NULL) xmlFree(Pubid);
       
  4144     }
       
  4145 }
       
  4146 
       
  4147 /**
       
  4148  * xmlParseEntityDecl:
       
  4149  * @param ctxt an XML parser context
       
  4150  *
       
  4151  * parse <!ENTITY declarations
       
  4152  *
       
  4153  * [70] EntityDecl ::= GEDecl | PEDecl
       
  4154  *
       
  4155  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
       
  4156  *
       
  4157  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
       
  4158  *
       
  4159  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
       
  4160  *
       
  4161  * [74] PEDef ::= EntityValue | ExternalID
       
  4162  *
       
  4163  * [76] NDataDecl ::= S 'NDATA' S Name
       
  4164  *
       
  4165  * [ VC: Notation Declared ]
       
  4166  * The Name must match the declared name of a notation.
       
  4167  */
       
  4168 
       
  4169 XMLPUBFUNEXPORT void
       
  4170 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
       
  4171     const xmlChar *name = NULL;
       
  4172     xmlChar *value = NULL;
       
  4173     xmlChar *URI = NULL, *literal = NULL;
       
  4174     const xmlChar *ndata = NULL;
       
  4175     int isParameter = 0;
       
  4176     xmlChar *orig = NULL;
       
  4177     int skipped;
       
  4178 
       
  4179     GROW;
       
  4180     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
       
  4181     xmlParserInputPtr input = ctxt->input;
       
  4182     SHRINK;
       
  4183     SKIP(8);
       
  4184     skipped = SKIP_BLANKS;
       
  4185     if (skipped == 0) {
       
  4186         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4187                EMBED_ERRTXT("Space required after '<!ENTITY'\n"));
       
  4188     }
       
  4189 
       
  4190     if (RAW == '%') {
       
  4191         NEXT;
       
  4192         skipped = SKIP_BLANKS;
       
  4193         if (skipped == 0) {
       
  4194         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4195                    EMBED_ERRTXT("Space required after '%'\n"));
       
  4196         }
       
  4197         isParameter = 1;
       
  4198     }
       
  4199 
       
  4200         name = xmlParseName(ctxt);
       
  4201     if (name == NULL) {
       
  4202         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  4203                        EMBED_ERRTXT("xmlParseEntityDecl: no name\n"));
       
  4204             return;
       
  4205     }
       
  4206         skipped = SKIP_BLANKS;
       
  4207     if (skipped == 0) {
       
  4208         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4209                EMBED_ERRTXT("Space required after the entity name\n"));
       
  4210     }
       
  4211 
       
  4212     ctxt->instate = XML_PARSER_ENTITY_DECL;
       
  4213     /*
       
  4214      * handle the various case of definitions...
       
  4215      */
       
  4216     if (isParameter) {
       
  4217         if ((RAW == '"') || (RAW == '\'')) {
       
  4218             value = xmlParseEntityValue(ctxt, &orig);
       
  4219         if (value) {
       
  4220             if ((ctxt->sax != NULL) &&
       
  4221             (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
       
  4222             ctxt->sax->entityDecl(ctxt->userData, name,
       
  4223                             XML_INTERNAL_PARAMETER_ENTITY,
       
  4224                     NULL, NULL, value);
       
  4225         }
       
  4226         } else {
       
  4227             URI = xmlParseExternalID(ctxt, &literal, 1);
       
  4228         if ((URI == NULL) && (literal == NULL)) {
       
  4229             xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
       
  4230         }
       
  4231         if (URI) {
       
  4232             xmlURIPtr uri;
       
  4233 
       
  4234             uri = xmlParseURI((const char *) URI);
       
  4235             if (uri == NULL) {
       
  4236                 xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
       
  4237                      EMBED_ERRTXT("Invalid URI: %s\n"), URI);
       
  4238             /*
       
  4239              * This really ought to be a well formedness error
       
  4240              * but the XML Core WG decided otherwise c.f. issue
       
  4241              * E26 of the XML erratas.
       
  4242              */
       
  4243             } else {
       
  4244             if (uri->fragment != NULL) {
       
  4245                 /*
       
  4246                  * Okay this is foolish to block those but not
       
  4247                  * invalid URIs.
       
  4248                  */
       
  4249                 xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
       
  4250             } else {
       
  4251                 if ((ctxt->sax != NULL) &&
       
  4252                 (!ctxt->disableSAX) &&
       
  4253                 (ctxt->sax->entityDecl != NULL))
       
  4254                 ctxt->sax->entityDecl(ctxt->userData, name,
       
  4255                         XML_EXTERNAL_PARAMETER_ENTITY,
       
  4256                         literal, URI, NULL);
       
  4257             }
       
  4258             xmlFreeURI(uri);
       
  4259             }
       
  4260         }
       
  4261         }
       
  4262     } else {
       
  4263         if ((RAW == '"') || (RAW == '\''))
       
  4264         {
       
  4265             value = xmlParseEntityValue(ctxt, &orig);
       
  4266             if ((ctxt->sax != NULL) &&
       
  4267                 (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
       
  4268                 ctxt->sax->entityDecl(ctxt->userData, name,
       
  4269                     XML_INTERNAL_GENERAL_ENTITY,
       
  4270                     NULL, NULL, value);
       
  4271             /*
       
  4272              * For expat compatibility in SAX mode.
       
  4273              */
       
  4274             if ((ctxt->myDoc == NULL) ||
       
  4275                 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))
       
  4276             {
       
  4277                 if (ctxt->myDoc == NULL) {
       
  4278                     ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
       
  4279                 }
       
  4280                 if (ctxt->myDoc->intSubset == NULL)
       
  4281                     ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "fake", NULL, NULL);
       
  4282 
       
  4283                 xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY, NULL, NULL, value);
       
  4284             }
       
  4285         } else {
       
  4286             URI = xmlParseExternalID(ctxt, &literal, 1);
       
  4287             if ((URI == NULL) && (literal == NULL)) {
       
  4288                 xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
       
  4289             }
       
  4290             if (URI) {
       
  4291                 xmlURIPtr uri;
       
  4292 
       
  4293                 uri = xmlParseURI((const char *)URI);
       
  4294                 if (uri == NULL)
       
  4295                 {
       
  4296                     xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
       
  4297                          EMBED_ERRTXT("Invalid URI: %s\n"), URI);
       
  4298                 /*
       
  4299                  * This really ought to be a well formedness error
       
  4300                  * but the XML Core WG decided otherwise c.f. issue
       
  4301                  * E26 of the XML erratas.
       
  4302                  */
       
  4303                 } else {
       
  4304                     if (uri->fragment != NULL) {
       
  4305                         /*
       
  4306                          * Okay this is foolish to block those but not
       
  4307                          * invalid URIs.
       
  4308                          */
       
  4309                         xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
       
  4310                     }
       
  4311                     xmlFreeURI(uri);
       
  4312                 }
       
  4313             }
       
  4314             if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
       
  4315                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4316                        EMBED_ERRTXT("Space required before 'NDATA'\n"));
       
  4317             }
       
  4318             SKIP_BLANKS;
       
  4319             if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A'))
       
  4320             {
       
  4321                 SKIP(5);
       
  4322                 if (!IS_BLANK_CH(CUR)) {
       
  4323                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4324                            EMBED_ERRTXT("Space required after 'NDATA'\n"));
       
  4325                 }
       
  4326                 SKIP_BLANKS;
       
  4327                 ndata = xmlParseName(ctxt);
       
  4328                 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
       
  4329                     (ctxt->sax->unparsedEntityDecl != NULL))
       
  4330                 {
       
  4331                     ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
       
  4332                                 literal, URI, ndata);
       
  4333                 }
       
  4334             } else {
       
  4335                 if ((ctxt->sax != NULL) &&
       
  4336                     (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
       
  4337                 {
       
  4338                     ctxt->sax->entityDecl(ctxt->userData, name,
       
  4339                             XML_EXTERNAL_GENERAL_PARSED_ENTITY,
       
  4340                             literal, URI, NULL);
       
  4341                 }
       
  4342                 /*
       
  4343                  * For expat compatibility in SAX mode.
       
  4344                  * assuming the entity repalcement was asked for
       
  4345                  */
       
  4346                 if ((ctxt->replaceEntities != 0) &&
       
  4347                     ((ctxt->myDoc == NULL) ||
       
  4348                     (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))))
       
  4349                 {
       
  4350                     if (ctxt->myDoc == NULL) {
       
  4351                         ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
       
  4352                     }
       
  4353 
       
  4354                     if (ctxt->myDoc->intSubset == NULL)
       
  4355                         ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,                            BAD_CAST "fake", NULL, NULL);
       
  4356                     xmlSAX2EntityDecl(ctxt, name,
       
  4357                                   XML_EXTERNAL_GENERAL_PARSED_ENTITY,
       
  4358                                   literal, URI, NULL);
       
  4359                 }
       
  4360             }
       
  4361         }
       
  4362     }
       
  4363     SKIP_BLANKS;
       
  4364     if (RAW != '>') {
       
  4365         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
       
  4366                 EMBED_ERRTXT("xmlParseEntityDecl: entity %s not terminated\n"), name);
       
  4367     } else {
       
  4368         if (input != ctxt->input) {
       
  4369         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  4370     EMBED_ERRTXT("Entity declaration doesn't start and stop in the same entity\n"));
       
  4371         }
       
  4372         NEXT;
       
  4373     }
       
  4374     if (orig != NULL) {
       
  4375         /*
       
  4376          * Ugly mechanism to save the raw entity value.
       
  4377          */
       
  4378         xmlEntityPtr cur = NULL;
       
  4379 
       
  4380         if (isParameter) {
       
  4381             if ((ctxt->sax != NULL) &&
       
  4382             (ctxt->sax->getParameterEntity != NULL))
       
  4383             cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
       
  4384         } else {
       
  4385             if ((ctxt->sax != NULL) &&
       
  4386             (ctxt->sax->getEntity != NULL))
       
  4387             cur = ctxt->sax->getEntity(ctxt->userData, name);
       
  4388         if ((cur == NULL) && (ctxt->userData==ctxt)) {
       
  4389             cur = xmlSAX2GetEntity(ctxt, name);
       
  4390         }
       
  4391         }
       
  4392             if (cur != NULL) {
       
  4393             if (cur->orig != NULL)
       
  4394             xmlFree(orig);
       
  4395         else
       
  4396             cur->orig = orig;
       
  4397         } else
       
  4398         xmlFree(orig);
       
  4399     }
       
  4400     if (value != NULL) xmlFree(value);
       
  4401     if (URI != NULL) xmlFree(URI);
       
  4402     if (literal != NULL) xmlFree(literal);
       
  4403     }
       
  4404 }
       
  4405 
       
  4406 /**
       
  4407  * xmlParseDefaultDecl:
       
  4408  * @param ctxt an XML parser context
       
  4409  * @param value Receive a possible fixed default value for the attribute
       
  4410  *
       
  4411  * Parse an attribute default declaration
       
  4412  *
       
  4413  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
       
  4414  *
       
  4415  * [ VC: Required Attribute ]
       
  4416  * if the default declaration is the keyword #REQUIRED, then the
       
  4417  * attribute must be specified for all elements of the type in the
       
  4418  * attribute-list declaration.
       
  4419  *
       
  4420  * [ VC: Attribute Default Legal ]
       
  4421  * The declared default value must meet the lexical constraints of
       
  4422  * the declared attribute type c.f. xmlValidateAttributeDecl()
       
  4423  *
       
  4424  * [ VC: Fixed Attribute Default ]
       
  4425  * if an attribute has a default value declared with the #FIXED
       
  4426  * keyword, instances of that attribute must match the default value.
       
  4427  *
       
  4428  * [ WFC: No < in Attribute Values ]
       
  4429  * handled in xmlParseAttValue()
       
  4430  *
       
  4431  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
       
  4432  *          or XML_ATTRIBUTE_FIXED.
       
  4433  */
       
  4434 
       
  4435 XMLPUBFUNEXPORT int
       
  4436 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
       
  4437     int val;
       
  4438     xmlChar *ret;
       
  4439 
       
  4440     *value = NULL;
       
  4441     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
       
  4442     SKIP(9);
       
  4443     return(XML_ATTRIBUTE_REQUIRED);
       
  4444     }
       
  4445     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
       
  4446     SKIP(8);
       
  4447     return(XML_ATTRIBUTE_IMPLIED);
       
  4448     }
       
  4449     val = XML_ATTRIBUTE_NONE;
       
  4450     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
       
  4451     SKIP(6);
       
  4452     val = XML_ATTRIBUTE_FIXED;
       
  4453     if (!IS_BLANK_CH(CUR)) {
       
  4454         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4455                EMBED_ERRTXT("Space required after '#FIXED'\n"));
       
  4456     }
       
  4457     SKIP_BLANKS;
       
  4458     }
       
  4459     ret = xmlParseAttValue(ctxt);
       
  4460     ctxt->instate = XML_PARSER_DTD;
       
  4461     if (ret == NULL) {
       
  4462     xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
       
  4463                EMBED_ERRTXT("Attribute default value declaration error\n"));
       
  4464     } else
       
  4465         *value = ret;
       
  4466     return(val);
       
  4467 }
       
  4468 
       
  4469 /**
       
  4470  * xmlParseNotationType:
       
  4471  * @param ctxt an XML parser context
       
  4472  *
       
  4473  * parse an Notation attribute type.
       
  4474  *
       
  4475  * Note: the leading 'NOTATION' S part has already being parsed...
       
  4476  *
       
  4477  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
       
  4478  *
       
  4479  * [ VC: Notation Attributes ]
       
  4480  * Values of this type must match one of the notation names included
       
  4481  * in the declaration; all notation names in the declaration must be declared.
       
  4482  *
       
  4483  * Returns: the notation attribute tree built while parsing
       
  4484  */
       
  4485 
       
  4486 XMLPUBFUNEXPORT xmlEnumerationPtr
       
  4487 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
       
  4488     const xmlChar *name;
       
  4489     xmlEnumerationPtr ret = NULL, last = NULL, cur;
       
  4490 
       
  4491     if (RAW != '(') {
       
  4492     xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
       
  4493     return(NULL);
       
  4494     }
       
  4495     SHRINK;
       
  4496     do {
       
  4497         NEXT;
       
  4498     SKIP_BLANKS;
       
  4499         name = xmlParseName(ctxt);
       
  4500     if (name == NULL) {
       
  4501         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  4502                EMBED_ERRTXT("Name expected in NOTATION declaration\n"));
       
  4503         return(ret);
       
  4504     }
       
  4505     cur = xmlCreateEnumeration(name);
       
  4506     if (cur == NULL) return(ret);
       
  4507     if (last == NULL) ret = last = cur;
       
  4508     else {
       
  4509         last->next = cur;
       
  4510         last = cur;
       
  4511     }
       
  4512     SKIP_BLANKS;
       
  4513     } while (RAW == '|');
       
  4514     if (RAW != ')') {
       
  4515     xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
       
  4516     if ((last != NULL) && (last != ret))
       
  4517         xmlFreeEnumeration(last);
       
  4518     return(ret);
       
  4519     }
       
  4520     NEXT;
       
  4521     return(ret);
       
  4522 }
       
  4523 
       
  4524 /**
       
  4525  * xmlParseEnumerationType:
       
  4526  * @param ctxt an XML parser context
       
  4527  *
       
  4528  * parse an Enumeration attribute type.
       
  4529  *
       
  4530  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
       
  4531  *
       
  4532  * [ VC: Enumeration ]
       
  4533  * Values of this type must match one of the Nmtoken tokens in
       
  4534  * the declaration
       
  4535  *
       
  4536  * Returns: the enumeration attribute tree built while parsing
       
  4537  */
       
  4538 
       
  4539 XMLPUBFUNEXPORT xmlEnumerationPtr
       
  4540 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
       
  4541     xmlChar *name;
       
  4542     xmlEnumerationPtr ret = NULL, last = NULL, cur;
       
  4543 
       
  4544     if (RAW != '(') {
       
  4545     xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
       
  4546     return(NULL);
       
  4547     }
       
  4548     SHRINK;
       
  4549     do {
       
  4550         NEXT;
       
  4551     SKIP_BLANKS;
       
  4552         name = xmlParseNmtoken(ctxt);
       
  4553     if (name == NULL) {
       
  4554         xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
       
  4555         return(ret);
       
  4556     }
       
  4557     cur = xmlCreateEnumeration(name);
       
  4558     xmlFree(name);
       
  4559     if (cur == NULL) return(ret);
       
  4560     if (last == NULL) ret = last = cur;
       
  4561     else {
       
  4562         last->next = cur;
       
  4563         last = cur;
       
  4564     }
       
  4565     SKIP_BLANKS;
       
  4566     } while (RAW == '|');
       
  4567     if (RAW != ')') {
       
  4568     xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
       
  4569     return(ret);
       
  4570     }
       
  4571     NEXT;
       
  4572     return(ret);
       
  4573 }
       
  4574 
       
  4575 /**
       
  4576  * xmlParseEnumeratedType:
       
  4577  * @param ctxt an XML parser context
       
  4578  * @param tree the enumeration tree built while parsing
       
  4579  *
       
  4580  * parse an Enumerated attribute type.
       
  4581  *
       
  4582  * [57] EnumeratedType ::= NotationType | Enumeration
       
  4583  *
       
  4584  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
       
  4585  *
       
  4586  *
       
  4587  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
       
  4588  */
       
  4589 
       
  4590 XMLPUBFUNEXPORT int
       
  4591 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
       
  4592     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
       
  4593     SKIP(8);
       
  4594     if (!IS_BLANK_CH(CUR)) {
       
  4595         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4596                EMBED_ERRTXT("Space required after 'NOTATION'\n"));
       
  4597         return(0);
       
  4598     }
       
  4599         SKIP_BLANKS;
       
  4600     *tree = xmlParseNotationType(ctxt);
       
  4601     if (*tree == NULL) return(0);
       
  4602     return(XML_ATTRIBUTE_NOTATION);
       
  4603     }
       
  4604     *tree = xmlParseEnumerationType(ctxt);
       
  4605     if (*tree == NULL) return(0);
       
  4606     return(XML_ATTRIBUTE_ENUMERATION);
       
  4607 }
       
  4608 
       
  4609 /**
       
  4610  * xmlParseAttributeType:
       
  4611  * @param ctxt an XML parser context
       
  4612  * @param tree the enumeration tree built while parsing
       
  4613  *
       
  4614  * parse the Attribute list def for an element
       
  4615  *
       
  4616  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
       
  4617  *
       
  4618  * [55] StringType ::= 'CDATA'
       
  4619  *
       
  4620  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
       
  4621  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
       
  4622  *
       
  4623  * Validity constraints for attribute values syntax are checked in
       
  4624  * xmlValidateAttributeValue()
       
  4625  *
       
  4626  * [ VC: ID ]
       
  4627  * Values of type ID must match the Name production. A name must not
       
  4628  * appear more than once in an XML document as a value of this type;
       
  4629  * i.e., ID values must uniquely identify the elements which bear them.
       
  4630  *
       
  4631  * [ VC: One ID per Element Type ]
       
  4632  * No element type may have more than one ID attribute specified.
       
  4633  *
       
  4634  * [ VC: ID Attribute Default ]
       
  4635  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
       
  4636  *
       
  4637  * [ VC: IDREF ]
       
  4638  * Values of type IDREF must match the Name production, and values
       
  4639  * of type IDREFS must match Names; each IDREF Name must match the value
       
  4640  * of an ID attribute on some element in the XML document; i.e. IDREF
       
  4641  * values must match the value of some ID attribute.
       
  4642  *
       
  4643  * [ VC: Entity Name ]
       
  4644  * Values of type ENTITY must match the Name production, values
       
  4645  * of type ENTITIES must match Names; each Entity Name must match the
       
  4646  * name of an unparsed entity declared in the DTD.
       
  4647  *
       
  4648  * [ VC: Name Token ]
       
  4649  * Values of type NMTOKEN must match the Nmtoken production; values
       
  4650  * of type NMTOKENS must match Nmtokens.
       
  4651  *
       
  4652  * Returns the attribute type
       
  4653  */
       
  4654 XMLPUBFUNEXPORT int
       
  4655 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
       
  4656     SHRINK;
       
  4657     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
       
  4658     SKIP(5);
       
  4659     return(XML_ATTRIBUTE_CDATA);
       
  4660      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
       
  4661     SKIP(6);
       
  4662     return(XML_ATTRIBUTE_IDREFS);
       
  4663      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
       
  4664     SKIP(5);
       
  4665     return(XML_ATTRIBUTE_IDREF);
       
  4666      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
       
  4667         SKIP(2);
       
  4668     return(XML_ATTRIBUTE_ID);
       
  4669      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
       
  4670     SKIP(6);
       
  4671     return(XML_ATTRIBUTE_ENTITY);
       
  4672      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
       
  4673     SKIP(8);
       
  4674     return(XML_ATTRIBUTE_ENTITIES);
       
  4675      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
       
  4676     SKIP(8);
       
  4677     return(XML_ATTRIBUTE_NMTOKENS);
       
  4678      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
       
  4679     SKIP(7);
       
  4680     return(XML_ATTRIBUTE_NMTOKEN);
       
  4681      }
       
  4682      return(xmlParseEnumeratedType(ctxt, tree));
       
  4683 }
       
  4684 
       
  4685 /**
       
  4686  * xmlParseAttributeListDecl:
       
  4687  * @param ctxt an XML parser context
       
  4688  *
       
  4689  * : parse the Attribute list def for an element
       
  4690  *
       
  4691  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
       
  4692  *
       
  4693  * [53] AttDef ::= S Name S AttType S DefaultDecl
       
  4694  *
       
  4695  */
       
  4696 XMLPUBFUNEXPORT void
       
  4697 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
       
  4698     const xmlChar *elemName;
       
  4699     const xmlChar *attrName;
       
  4700     xmlEnumerationPtr tree;
       
  4701 
       
  4702     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
       
  4703     xmlParserInputPtr input = ctxt->input;
       
  4704 
       
  4705     SKIP(9);
       
  4706     if (!IS_BLANK_CH(CUR)) {
       
  4707         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4708                          EMBED_ERRTXT("Space required after '<!ATTLIST'\n"));
       
  4709     }
       
  4710         SKIP_BLANKS;
       
  4711         elemName = xmlParseName(ctxt);
       
  4712     if (elemName == NULL) {
       
  4713         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  4714                EMBED_ERRTXT("ATTLIST: no name for Element\n"));
       
  4715         return;
       
  4716     }
       
  4717     SKIP_BLANKS;
       
  4718     GROW;
       
  4719     while (RAW != '>') {
       
  4720         const xmlChar *check = CUR_PTR;
       
  4721         int type;
       
  4722         int def;
       
  4723         xmlChar *defaultValue = NULL;
       
  4724 
       
  4725         GROW;
       
  4726             tree = NULL;
       
  4727         attrName = xmlParseName(ctxt);
       
  4728         if (attrName == NULL) {
       
  4729         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  4730                    EMBED_ERRTXT("ATTLIST: no name for Attribute\n"));
       
  4731         break;
       
  4732         }
       
  4733         GROW;
       
  4734         if (!IS_BLANK_CH(CUR)) {
       
  4735         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4736                 EMBED_ERRTXT("Space required after the attribute name\n"));
       
  4737                 if (defaultValue != NULL)
       
  4738             xmlFree(defaultValue);
       
  4739         break;
       
  4740         }
       
  4741         SKIP_BLANKS;
       
  4742 
       
  4743         type = xmlParseAttributeType(ctxt, &tree);
       
  4744         if (type <= 0) {
       
  4745                 if (defaultValue != NULL)
       
  4746             xmlFree(defaultValue);
       
  4747             break;
       
  4748         }
       
  4749 
       
  4750         GROW;
       
  4751         if (!IS_BLANK_CH(CUR)) {
       
  4752         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4753                    EMBED_ERRTXT("Space required after the attribute type\n"));
       
  4754                 if (defaultValue != NULL)
       
  4755             xmlFree(defaultValue);
       
  4756             if (tree != NULL)
       
  4757             xmlFreeEnumeration(tree);
       
  4758         break;
       
  4759         }
       
  4760         SKIP_BLANKS;
       
  4761 
       
  4762         def = xmlParseDefaultDecl(ctxt, &defaultValue);
       
  4763         if (def <= 0) {
       
  4764                 if (defaultValue != NULL)
       
  4765             xmlFree(defaultValue);
       
  4766             if (tree != NULL)
       
  4767             xmlFreeEnumeration(tree);
       
  4768             break;
       
  4769         }
       
  4770 
       
  4771         GROW;
       
  4772             if (RAW != '>') {
       
  4773         if (!IS_BLANK_CH(CUR)) {
       
  4774             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  4775             EMBED_ERRTXT("Space required after the attribute default value\n"));
       
  4776             if (defaultValue != NULL)
       
  4777             xmlFree(defaultValue);
       
  4778             if (tree != NULL)
       
  4779             xmlFreeEnumeration(tree);
       
  4780             break;
       
  4781         }
       
  4782         SKIP_BLANKS;
       
  4783         }
       
  4784         if (check == CUR_PTR) {
       
  4785         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
       
  4786                     EMBED_ERRTXT("in xmlParseAttributeListDecl\n"));
       
  4787         if (defaultValue != NULL)
       
  4788             xmlFree(defaultValue);
       
  4789             if (tree != NULL)
       
  4790             xmlFreeEnumeration(tree);
       
  4791         break;
       
  4792         }
       
  4793         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
       
  4794         (ctxt->sax->attributeDecl != NULL))
       
  4795         ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
       
  4796                             type, def, defaultValue, tree);
       
  4797         else if (tree != NULL)
       
  4798         xmlFreeEnumeration(tree);
       
  4799 
       
  4800         if ((ctxt->sax2) && (defaultValue != NULL) &&
       
  4801             (def != XML_ATTRIBUTE_IMPLIED) &&
       
  4802         (def != XML_ATTRIBUTE_REQUIRED)) {
       
  4803         xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
       
  4804         }
       
  4805         if ((ctxt->sax2) && (type != XML_ATTRIBUTE_CDATA)) {
       
  4806         xmlAddSpecialAttr(ctxt, elemName, attrName, type);
       
  4807         }
       
  4808         if (defaultValue != NULL)
       
  4809             xmlFree(defaultValue);
       
  4810         GROW;
       
  4811     }
       
  4812     if (RAW == '>') {
       
  4813         if (input != ctxt->input) {
       
  4814         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  4815     EMBED_ERRTXT("Attribute list declaration doesn't start and stop in the same entity\n"));
       
  4816         }
       
  4817         NEXT;
       
  4818     }
       
  4819     }
       
  4820 }
       
  4821 
       
  4822 /**
       
  4823  * xmlParseElementMixedContentDecl:
       
  4824  * @param ctxt an XML parser context
       
  4825  * @param inputchk the input used for the current entity, needed for boundary checks
       
  4826  *
       
  4827  * parse the declaration for a Mixed Element content
       
  4828  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
       
  4829  *
       
  4830  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
       
  4831  *                '(' S? '#PCDATA' S? ')'
       
  4832  *
       
  4833  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
       
  4834  *
       
  4835  * [ VC: No Duplicate Types ]
       
  4836  * The same name must not appear more than once in a single
       
  4837  * mixed-content declaration.
       
  4838  *
       
  4839  * returns: the list of the xmlElementContentPtr describing the element choices
       
  4840  *          or NULL if error
       
  4841  */
       
  4842 XMLPUBFUNEXPORT xmlElementContentPtr
       
  4843 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk)
       
  4844 {
       
  4845     xmlElementContentPtr ret = NULL;
       
  4846     xmlElementContentPtr cur = NULL;
       
  4847     xmlElementContentPtr n;
       
  4848     const xmlChar* elem = NULL;
       
  4849 
       
  4850     GROW;
       
  4851 
       
  4852     if (!CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A'))
       
  4853     {
       
  4854         xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
       
  4855         return NULL;
       
  4856     }
       
  4857 
       
  4858     SKIP(7);
       
  4859     SKIP_BLANKS;
       
  4860     SHRINK;
       
  4861     if (RAW == ')')
       
  4862     {
       
  4863         if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
       
  4864             xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  4865                 EMBED_ERRTXT("Element content declaration doesn't start and stop in the same entity\n"),
       
  4866                 NULL);
       
  4867         }
       
  4868         NEXT;
       
  4869         ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
       
  4870         if(!ret) //  no need to check OOM_FLAG
       
  4871             {
       
  4872             return /* NULL */ ret;
       
  4873             }
       
  4874         if (RAW == '*') {
       
  4875             ret->ocur = XML_ELEMENT_CONTENT_MULT;
       
  4876             NEXT;
       
  4877         }
       
  4878         return(ret);
       
  4879     }
       
  4880 
       
  4881     if ((RAW == '(') || (RAW == '|'))
       
  4882     {
       
  4883         ret = cur = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
       
  4884         if (!ret)
       
  4885             return /* NULL */ ret ;
       
  4886     }
       
  4887 
       
  4888     while (RAW == '|')
       
  4889     {
       
  4890         NEXT;
       
  4891         if (elem == NULL) {
       
  4892             ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
       
  4893             if (!ret)
       
  4894                 return /* NULL */ ret;
       
  4895             ret->c1 = cur;
       
  4896             if (cur)
       
  4897                 cur->parent = ret;
       
  4898             cur = ret;
       
  4899         } else {
       
  4900             n = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
       
  4901             if (!n)
       
  4902                 return /* NULL */ n;
       
  4903             n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
       
  4904             if (n->c1 != NULL) 
       
  4905                 n->c1->parent = n;
       
  4906             cur->c2 = n;
       
  4907             // if (n != NULL) // this check is redundant
       
  4908             n->parent = cur;
       
  4909             cur = n;
       
  4910         }
       
  4911         SKIP_BLANKS;
       
  4912         elem = xmlParseName(ctxt);
       
  4913         if (!elem) {
       
  4914             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  4915                 EMBED_ERRTXT("xmlParseElementMixedContentDecl : Name expected\n"));
       
  4916             xmlFreeElementContent(cur);
       
  4917             return(NULL);
       
  4918         }
       
  4919         SKIP_BLANKS;
       
  4920         GROW;
       
  4921     }
       
  4922 
       
  4923     if ((RAW == ')') && (NXT(1) == '*')) {
       
  4924         if (elem != NULL) {
       
  4925             cur->c2 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
       
  4926             if (cur->c2 != NULL)
       
  4927                 cur->c2->parent = cur;
       
  4928         }
       
  4929         ret->ocur = XML_ELEMENT_CONTENT_MULT;
       
  4930         if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
       
  4931             xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  4932     EMBED_ERRTXT("Element content declaration doesn't start and stop in the same entity\n"),
       
  4933                      NULL);
       
  4934         }
       
  4935         SKIP(2);
       
  4936     } else {
       
  4937         xmlFreeElementContent(ret);
       
  4938         xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
       
  4939         return(NULL);
       
  4940     }
       
  4941 
       
  4942     return(ret);
       
  4943 }
       
  4944 
       
  4945 /**
       
  4946  * xmlParseElementChildrenContentDecl:
       
  4947  * @param ctxt an XML parser context
       
  4948  * @param inputchk the input used for the current entity, needed for boundary checks
       
  4949  *
       
  4950  * parse the declaration for a Mixed Element content
       
  4951  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
       
  4952  *
       
  4953  *
       
  4954  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
       
  4955  *
       
  4956  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
       
  4957  *
       
  4958  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
       
  4959  *
       
  4960  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
       
  4961  *
       
  4962  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
       
  4963  *  Parameter-entity replacement text must be properly nested
       
  4964  *  with parenthesized groups. That is to say, if either of the
       
  4965  *  opening or closing parentheses in a choice, seq, or Mixed
       
  4966  *  construct is contained in the replacement text for a parameter
       
  4967  *  entity, both must be contained in the same replacement text. For
       
  4968  *  interoperability, if a parameter-entity reference appears in a
       
  4969  *  choice, seq, or Mixed construct, its replacement text should not
       
  4970  *  be empty, and neither the first nor last non-blank character of
       
  4971  *  the replacement text should be a connector (| or ,).
       
  4972  *
       
  4973  * Returns the tree of xmlElementContentPtr describing the element
       
  4974  *          hierarchy.
       
  4975  */
       
  4976 XMLPUBFUNEXPORT xmlElementContentPtr
       
  4977 xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk)
       
  4978 {
       
  4979     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
       
  4980     const xmlChar *elem;
       
  4981     xmlChar type = 0;
       
  4982 
       
  4983     SKIP_BLANKS;
       
  4984     GROW;
       
  4985     if (RAW == '(')
       
  4986     {
       
  4987         int inputid = ctxt->input->id;
       
  4988 
       
  4989         /* Recurse on first child */
       
  4990         NEXT;
       
  4991         SKIP_BLANKS;
       
  4992         cur = ret = xmlParseElementChildrenContentDecl(ctxt, inputid);
       
  4993         SKIP_BLANKS;
       
  4994         GROW;
       
  4995     }
       
  4996     else
       
  4997     {
       
  4998         elem = xmlParseName(ctxt);
       
  4999         if (elem == NULL) {
       
  5000             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
       
  5001             return(NULL);
       
  5002         }
       
  5003         cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
       
  5004         if (cur == NULL) {
       
  5005             xmlParserOOMErr(ctxt);
       
  5006             return(NULL);
       
  5007         }
       
  5008         GROW;
       
  5009         if (RAW == '?') {
       
  5010             cur->ocur = XML_ELEMENT_CONTENT_OPT;
       
  5011             NEXT;
       
  5012         } else if (RAW == '*') {
       
  5013             cur->ocur = XML_ELEMENT_CONTENT_MULT;
       
  5014             NEXT;
       
  5015         } else if (RAW == '+') {
       
  5016             cur->ocur = XML_ELEMENT_CONTENT_PLUS;
       
  5017             NEXT;
       
  5018         } else {
       
  5019             cur->ocur = XML_ELEMENT_CONTENT_ONCE;
       
  5020         }
       
  5021         GROW;
       
  5022     }
       
  5023 
       
  5024     SKIP_BLANKS;
       
  5025     SHRINK;
       
  5026 
       
  5027     while (RAW != ')')
       
  5028     {
       
  5029         /*
       
  5030          * Each loop we parse one separator and one element.
       
  5031          */
       
  5032         if (RAW == ',')
       
  5033         {
       
  5034             if (type == 0){
       
  5035                 type = CUR;
       
  5036             }
       
  5037             /*
       
  5038              * Detect "Name | Name , Name" error
       
  5039              */
       
  5040             else if (type != CUR)
       
  5041             {
       
  5042                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
       
  5043                     EMBED_ERRTXT("xmlParseElementChildrenContentDecl : '%c' expected\n"),
       
  5044                                   type);
       
  5045                 if ((last != NULL) && (last != ret))
       
  5046                     xmlFreeElementContent(last);
       
  5047                 if (ret != NULL)
       
  5048                     xmlFreeElementContent(ret);
       
  5049                 return(NULL);
       
  5050             }
       
  5051 
       
  5052             NEXT;
       
  5053 
       
  5054             op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_SEQ);
       
  5055             if (op == NULL) {
       
  5056                 if ((last != NULL) && (last != ret))
       
  5057                     xmlFreeElementContent(last);
       
  5058                 xmlFreeElementContent(ret);
       
  5059                 return(NULL);
       
  5060             }
       
  5061             if (last == NULL) {
       
  5062                 op->c1 = ret;
       
  5063                 if (ret != NULL)
       
  5064                     ret->parent = op;
       
  5065                 ret = cur = op;
       
  5066             } else {
       
  5067                 cur->c2 = op;
       
  5068                 if (op != NULL)
       
  5069                     op->parent = cur;
       
  5070                 op->c1 = last;
       
  5071                 if (last != NULL)
       
  5072                     last->parent = op;
       
  5073                 cur =op;
       
  5074                 last = NULL;
       
  5075             }
       
  5076         }
       
  5077         else if (RAW == '|')
       
  5078         {
       
  5079 
       
  5080             if (type == 0){
       
  5081                 type = CUR;
       
  5082             }
       
  5083             /*
       
  5084              * Detect "Name , Name | Name" error
       
  5085              */
       
  5086             else if (type != CUR) {
       
  5087                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
       
  5088                     EMBED_ERRTXT("xmlParseElementChildrenContentDecl : '%c' expected\n"),
       
  5089                           type);
       
  5090                 if ((last != NULL) && (last != ret))
       
  5091                     xmlFreeElementContent(last);
       
  5092                 if (ret != NULL)
       
  5093                     xmlFreeElementContent(ret);
       
  5094                 return(NULL);
       
  5095             }
       
  5096             NEXT;
       
  5097 
       
  5098             op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
       
  5099             if (op == NULL) {
       
  5100                 if ((last != NULL) && (last != ret))
       
  5101                     xmlFreeElementContent(last);
       
  5102                 if (ret != NULL)
       
  5103                     xmlFreeElementContent(ret);
       
  5104                 return(NULL);
       
  5105             }
       
  5106             if (last == NULL) {
       
  5107                 op->c1 = ret;
       
  5108                 if (ret != NULL)
       
  5109                     ret->parent = op;
       
  5110                 ret = cur = op;
       
  5111             } else {
       
  5112                 cur->c2 = op;
       
  5113                 if (op != NULL)
       
  5114                     op->parent = cur;
       
  5115                 op->c1 = last;
       
  5116                 if (last != NULL)
       
  5117                     last->parent = op;
       
  5118                 cur =op;
       
  5119                 last = NULL;
       
  5120             }
       
  5121         } else {
       
  5122             // RAW is not ',' or '|'
       
  5123             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
       
  5124             if (ret != NULL)
       
  5125                 xmlFreeElementContent(ret);
       
  5126             return(NULL);
       
  5127         }
       
  5128 
       
  5129         GROW;
       
  5130         SKIP_BLANKS;
       
  5131         GROW;
       
  5132         if (RAW == '(')
       
  5133         {
       
  5134             int inputid = ctxt->input->id;
       
  5135             /* Recurse on second child */
       
  5136             NEXT;
       
  5137             SKIP_BLANKS;
       
  5138             last = xmlParseElementChildrenContentDecl(ctxt, inputid);
       
  5139             SKIP_BLANKS;
       
  5140         }
       
  5141         else
       
  5142         {
       
  5143             elem = xmlParseName(ctxt);
       
  5144             if (elem == NULL) {
       
  5145                 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
       
  5146                 if (ret != NULL)
       
  5147                     xmlFreeElementContent(ret);
       
  5148                 return(NULL);
       
  5149             }
       
  5150             last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
       
  5151             if(!last)
       
  5152                 { // OOM
       
  5153                 if (ret != NULL)
       
  5154                     {
       
  5155                     xmlFreeElementContent(ret);
       
  5156                     }
       
  5157                 xmlParserOOMErr(ctxt);
       
  5158                 return(NULL);
       
  5159                 }
       
  5160 
       
  5161             if (RAW == '?') {
       
  5162                 last->ocur = XML_ELEMENT_CONTENT_OPT;
       
  5163                 NEXT;
       
  5164             } else if (RAW == '*') {
       
  5165                 last->ocur = XML_ELEMENT_CONTENT_MULT;
       
  5166                 NEXT;
       
  5167             } else if (RAW == '+') {
       
  5168                 last->ocur = XML_ELEMENT_CONTENT_PLUS;
       
  5169                 NEXT;
       
  5170             } else {
       
  5171                 last->ocur = XML_ELEMENT_CONTENT_ONCE;
       
  5172             }
       
  5173         }
       
  5174         SKIP_BLANKS;
       
  5175         GROW;
       
  5176     } // end of while (RAW != ')')
       
  5177 
       
  5178     //============================================================
       
  5179     if ((cur != NULL) && (last != NULL)) {
       
  5180         cur->c2 = last;
       
  5181         if (last != NULL)
       
  5182             last->parent = cur;
       
  5183     }
       
  5184     if ((ctxt->validate) && (ctxt->input->id != inputchk))
       
  5185     {
       
  5186         xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  5187             EMBED_ERRTXT("Element content declaration doesn't start and stop in the same entity\n"),
       
  5188             NULL);
       
  5189     }
       
  5190     NEXT;
       
  5191 
       
  5192     if (RAW == '?')
       
  5193     {
       
  5194         if (ret != NULL) {
       
  5195             if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
       
  5196                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
       
  5197                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
       
  5198             else
       
  5199                 ret->ocur = XML_ELEMENT_CONTENT_OPT;
       
  5200         }
       
  5201         NEXT;
       
  5202     }
       
  5203     else if (RAW == '*')
       
  5204     {
       
  5205         if (ret != NULL)
       
  5206         {
       
  5207             ret->ocur = XML_ELEMENT_CONTENT_MULT;
       
  5208             cur = ret;
       
  5209             /*
       
  5210              * Some normalization:
       
  5211              * (a | b* | c?)* == (a | b | c)*
       
  5212              */
       
  5213             while (cur->type == XML_ELEMENT_CONTENT_OR)
       
  5214             {
       
  5215                 if ((cur->c1 != NULL) &&
       
  5216                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
       
  5217                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
       
  5218                 {
       
  5219                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
       
  5220                 }
       
  5221                 if((cur->c2 != NULL) &&
       
  5222                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
       
  5223                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
       
  5224                 {
       
  5225                 cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
       
  5226                 }
       
  5227                 cur = cur->c2;
       
  5228             }
       
  5229         }
       
  5230         NEXT;
       
  5231     }
       
  5232     else if (RAW == '+')
       
  5233     {
       
  5234         if (ret != NULL)
       
  5235         {
       
  5236             int found = 0;
       
  5237 
       
  5238             if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
       
  5239                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
       
  5240             {
       
  5241                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
       
  5242             }
       
  5243             else
       
  5244             {
       
  5245                 ret->ocur = XML_ELEMENT_CONTENT_PLUS;
       
  5246             }
       
  5247             /*
       
  5248              * Some normalization:
       
  5249              * (a | b*)+ == (a | b)*
       
  5250              * (a | b?)+ == (a | b)*
       
  5251              */
       
  5252             while (cur->type == XML_ELEMENT_CONTENT_OR)
       
  5253             {
       
  5254                 if ((cur->c1 != NULL) &&
       
  5255                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
       
  5256                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
       
  5257                 {
       
  5258                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
       
  5259                     found = 1;
       
  5260                 }
       
  5261                 if ((cur->c2 != NULL) &&
       
  5262                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
       
  5263                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
       
  5264                 {
       
  5265                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
       
  5266                     found = 1;
       
  5267                 }
       
  5268                 cur = cur->c2;
       
  5269             }
       
  5270             if (found)
       
  5271                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
       
  5272         }
       
  5273         NEXT;
       
  5274     }
       
  5275     return(ret);
       
  5276 }
       
  5277 
       
  5278 /**
       
  5279  * xmlParseElementContentDecl:
       
  5280  * @param ctxt an XML parser context
       
  5281  * @param name the name of the element being defined.
       
  5282  * @param result the Element Content pointer will be stored here if any
       
  5283  *
       
  5284  * parse the declaration for an Element content either Mixed or Children,
       
  5285  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
       
  5286  *
       
  5287  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
       
  5288  *
       
  5289  * returns: the type of element content XML_ELEMENT_TYPE_xxx or -1 if error
       
  5290  */
       
  5291 
       
  5292 XMLPUBFUNEXPORT int
       
  5293 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
       
  5294                            xmlElementContentPtr *result) {
       
  5295 
       
  5296     xmlElementContentPtr tree = NULL;
       
  5297     int inputid = ctxt->input->id;
       
  5298     int res;
       
  5299     LOAD_GS_SAFE_CTXT(ctxt)
       
  5300 
       
  5301     *result = NULL;
       
  5302 
       
  5303     if (RAW != '(') {
       
  5304     xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
       
  5305         EMBED_ERRTXT("xmlParseElementContentDecl : %s '(' expected\n"), name);
       
  5306     return(-1);
       
  5307     }
       
  5308     NEXT;
       
  5309     GROW;
       
  5310     SKIP_BLANKS;
       
  5311     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A'))
       
  5312     {
       
  5313         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
       
  5314         if(OOM_FLAG)
       
  5315             {
       
  5316             return(-1);
       
  5317             }
       
  5318         res = XML_ELEMENT_TYPE_MIXED;
       
  5319     }
       
  5320     else
       
  5321     {
       
  5322         tree = xmlParseElementChildrenContentDecl(ctxt, inputid);
       
  5323         if(OOM_FLAG)
       
  5324             {
       
  5325             return(-1);
       
  5326             }
       
  5327         res = XML_ELEMENT_TYPE_ELEMENT;
       
  5328     }
       
  5329     SKIP_BLANKS;
       
  5330     *result = tree;
       
  5331     return(res);
       
  5332 }
       
  5333 
       
  5334 /**
       
  5335  * xmlParseElementDecl:
       
  5336  * @param ctxt an XML parser context
       
  5337  *
       
  5338  * parse an Element declaration.
       
  5339  *
       
  5340  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
       
  5341  *
       
  5342  * [ VC: Unique Element Type Declaration ]
       
  5343  * No element type may be declared more than once
       
  5344  *
       
  5345  * Returns the type of the element, or -1 in case of error
       
  5346  */
       
  5347 XMLPUBFUNEXPORT int
       
  5348 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
       
  5349     const xmlChar *name;
       
  5350     int ret = -1;
       
  5351     xmlElementContentPtr content  = NULL;
       
  5352 
       
  5353     GROW;
       
  5354     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
       
  5355     xmlParserInputPtr input = ctxt->input;
       
  5356 
       
  5357     SKIP(9);
       
  5358     if (!IS_BLANK_CH(CUR)) {
       
  5359         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  5360                    EMBED_ERRTXT("Space required after 'ELEMENT'\n"));
       
  5361     }
       
  5362         SKIP_BLANKS;
       
  5363         name = xmlParseName(ctxt);
       
  5364     if (name == NULL) {
       
  5365         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  5366                EMBED_ERRTXT("xmlParseElementDecl: no name for Element\n"));
       
  5367         return(-1);
       
  5368     }
       
  5369     while ((RAW == 0) && (ctxt->inputNr > 1))
       
  5370         xmlPopInput(ctxt);
       
  5371     if (!IS_BLANK_CH(CUR)) {
       
  5372         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  5373                EMBED_ERRTXT("Space required after the element name\n"));
       
  5374     }
       
  5375         SKIP_BLANKS;
       
  5376     if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
       
  5377         SKIP(5);
       
  5378         /*
       
  5379          * Element must always be empty.
       
  5380          */
       
  5381         ret = XML_ELEMENT_TYPE_EMPTY;
       
  5382     } else if ((RAW == 'A') && (NXT(1) == 'N') &&
       
  5383                (NXT(2) == 'Y')) {
       
  5384         SKIP(3);
       
  5385         /*
       
  5386          * Element is a generic container.
       
  5387          */
       
  5388         ret = XML_ELEMENT_TYPE_ANY;
       
  5389     } else if (RAW == '(')
       
  5390         {
       
  5391         ret = xmlParseElementContentDecl(ctxt, name, &content);
       
  5392         if(ret == -1)
       
  5393             {
       
  5394             return ret /* -1 */;
       
  5395             }
       
  5396         }
       
  5397     else {
       
  5398         /*
       
  5399          * [ WFC: PEs in Internal Subset ] error handling.
       
  5400          */
       
  5401         if ((RAW == '%') &&
       
  5402             (ctxt->external == 0) &&
       
  5403             (ctxt->inputNr == 1))
       
  5404         {
       
  5405             xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
       
  5406                 EMBED_ERRTXT("PEReference: forbidden within markup decl in internal subset\n"));
       
  5407         } else {
       
  5408         xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
       
  5409               EMBED_ERRTXT("xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n"));
       
  5410             }
       
  5411         return(-1);
       
  5412     }
       
  5413 
       
  5414     SKIP_BLANKS;
       
  5415     /*
       
  5416      * Pop-up of finished entities.
       
  5417      */
       
  5418     while ((RAW == 0) && (ctxt->inputNr > 1))
       
  5419         xmlPopInput(ctxt);
       
  5420     SKIP_BLANKS;
       
  5421 
       
  5422     if (RAW != '>') {
       
  5423         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
       
  5424     } else {
       
  5425         if (input != ctxt->input) {
       
  5426         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
       
  5427     EMBED_ERRTXT("Element declaration doesn't start and stop in the same entity\n"));
       
  5428         }
       
  5429 
       
  5430         NEXT;
       
  5431         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
       
  5432         (ctxt->sax->elementDecl != NULL))
       
  5433             ctxt->sax->elementDecl(ctxt->userData, name, ret,
       
  5434                                content);
       
  5435     }
       
  5436     if (content != NULL) {
       
  5437         xmlFreeElementContent(content);
       
  5438     }
       
  5439     }
       
  5440     return(ret);
       
  5441 }
       
  5442 
       
  5443 /**
       
  5444  * xmlParseConditionalSections
       
  5445  * @param ctxt an XML parser context
       
  5446  *
       
  5447  * [61] conditionalSect ::= includeSect | ignoreSect
       
  5448  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
       
  5449  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
       
  5450  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
       
  5451  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
       
  5452  */
       
  5453 
       
  5454 static void
       
  5455 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
       
  5456 	LOAD_GS_SAFE_CTXT(ctxt)
       
  5457     SKIP(3);
       
  5458     SKIP_BLANKS;
       
  5459     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
       
  5460     SKIP(7);
       
  5461     SKIP_BLANKS;
       
  5462     if (RAW != '[') {
       
  5463         xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
       
  5464     } else {
       
  5465         NEXT;
       
  5466     }
       
  5467     if (xmlParserDebugEntities) {
       
  5468         if ((ctxt->input != NULL) && (ctxt->input->filename))
       
  5469         xmlGenericError(xmlGenericErrorContext,
       
  5470             EMBED_ERRTXT("%s(%d): "), ctxt->input->filename,
       
  5471             ctxt->input->line);
       
  5472         xmlGenericError(xmlGenericErrorContext,
       
  5473             EMBED_ERRTXT("Entering INCLUDE Conditional Section\n"));
       
  5474     }
       
  5475 
       
  5476     while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
       
  5477            (NXT(2) != '>'))) {
       
  5478         const xmlChar *check = CUR_PTR;
       
  5479         unsigned int cons = ctxt->input->consumed;
       
  5480 
       
  5481         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
       
  5482         xmlParseConditionalSections(ctxt);
       
  5483         } else if (IS_BLANK_CH(CUR)) {
       
  5484         NEXT;
       
  5485         } else if (RAW == '%') {
       
  5486         xmlParsePEReference(ctxt);
       
  5487         } else
       
  5488         xmlParseMarkupDecl(ctxt);
       
  5489 
       
  5490         /*
       
  5491          * Pop-up of finished entities.
       
  5492          */
       
  5493         while ((RAW == 0) && (ctxt->inputNr > 1))
       
  5494         xmlPopInput(ctxt);
       
  5495 
       
  5496         if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
       
  5497         xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
       
  5498         break;
       
  5499         }
       
  5500     }
       
  5501     if (xmlParserDebugEntities) {
       
  5502         if ((ctxt->input != NULL) && (ctxt->input->filename))
       
  5503         xmlGenericError(xmlGenericErrorContext,
       
  5504             EMBED_ERRTXT("%s(%d): "), ctxt->input->filename,
       
  5505             ctxt->input->line);
       
  5506         xmlGenericError(xmlGenericErrorContext,
       
  5507             EMBED_ERRTXT("Leaving INCLUDE Conditional Section\n"));
       
  5508     }
       
  5509 
       
  5510     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
       
  5511     int state;
       
  5512     xmlParserInputState instate;
       
  5513     int depth = 0;
       
  5514 
       
  5515     SKIP(6);
       
  5516     SKIP_BLANKS;
       
  5517     if (RAW != '[') {
       
  5518         xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
       
  5519     } else {
       
  5520         NEXT;
       
  5521     }
       
  5522     if (xmlParserDebugEntities) {
       
  5523         if ((ctxt->input != NULL) && (ctxt->input->filename))
       
  5524         xmlGenericError(xmlGenericErrorContext,
       
  5525             EMBED_ERRTXT("%s(%d): "), ctxt->input->filename,
       
  5526             ctxt->input->line);
       
  5527         xmlGenericError(xmlGenericErrorContext,
       
  5528             EMBED_ERRTXT("Entering IGNORE Conditional Section\n"));
       
  5529     }
       
  5530 
       
  5531     /*
       
  5532      * Parse up to the end of the conditional section
       
  5533      * But disable SAX event generating DTD building in the meantime
       
  5534      */
       
  5535     state = ctxt->disableSAX;
       
  5536     instate = ctxt->instate;
       
  5537     if (ctxt->recovery == 0) ctxt->disableSAX = 1;
       
  5538     ctxt->instate = XML_PARSER_IGNORE;
       
  5539 
       
  5540     while ((depth >= 0) && (RAW != 0)) {
       
  5541       if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
       
  5542         depth++;
       
  5543         SKIP(3);
       
  5544         continue;
       
  5545       }
       
  5546       if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
       
  5547         if (--depth >= 0) SKIP(3);
       
  5548         continue;
       
  5549       }
       
  5550       NEXT;
       
  5551       continue;
       
  5552     }
       
  5553 
       
  5554     ctxt->disableSAX = state;
       
  5555     ctxt->instate = instate;
       
  5556 
       
  5557     if (xmlParserDebugEntities) {
       
  5558         if ((ctxt->input != NULL) && (ctxt->input->filename))
       
  5559         xmlGenericError(xmlGenericErrorContext,
       
  5560             EMBED_ERRTXT("%s(%d): "), ctxt->input->filename,
       
  5561             ctxt->input->line);
       
  5562         xmlGenericError(xmlGenericErrorContext,
       
  5563             EMBED_ERRTXT("Leaving IGNORE Conditional Section\n"));
       
  5564     }
       
  5565 
       
  5566     } else {
       
  5567     xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
       
  5568     }
       
  5569 
       
  5570     if (RAW == 0)
       
  5571         SHRINK;
       
  5572 
       
  5573     if (RAW == 0) {
       
  5574     xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
       
  5575     } else {
       
  5576         SKIP(3);
       
  5577     }
       
  5578 }
       
  5579 
       
  5580 /**
       
  5581  * xmlParseMarkupDecl:
       
  5582  * @param ctxt an XML parser context
       
  5583  *
       
  5584  * parse Markup declarations
       
  5585  *
       
  5586  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
       
  5587  *                     NotationDecl | PI | Comment
       
  5588  *
       
  5589  * [ VC: Proper Declaration/PE Nesting ]
       
  5590  * Parameter-entity replacement text must be properly nested with
       
  5591  * markup declarations. That is to say, if either the first character
       
  5592  * or the last character of a markup declaration (markupdecl above) is
       
  5593  * contained in the replacement text for a parameter-entity reference,
       
  5594  * both must be contained in the same replacement text.
       
  5595  *
       
  5596  * [ WFC: PEs in Internal Subset ]
       
  5597  * In the internal DTD subset, parameter-entity references can occur
       
  5598  * only where markup declarations can occur, not within markup declarations.
       
  5599  * (This does not apply to references that occur in external parameter
       
  5600  * entities or to the external subset.)
       
  5601  */
       
  5602 XMLPUBFUNEXPORT void
       
  5603 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
       
  5604 	LOAD_GS_SAFE_CTXT(ctxt)
       
  5605     GROW;
       
  5606     if( (xmlParseElementDecl(ctxt) == -1) && OOM_FLAG)
       
  5607         {
       
  5608         return;
       
  5609         }
       
  5610     xmlParseAttributeListDecl(ctxt);
       
  5611     xmlParseEntityDecl(ctxt);
       
  5612     xmlParseNotationDecl(ctxt);
       
  5613     xmlParsePI(ctxt);
       
  5614     xmlParseComment(ctxt);
       
  5615     /*
       
  5616      * This is only for internal subset. On external entities,
       
  5617      * the replacement is done before parsing stage
       
  5618      */
       
  5619     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
       
  5620     xmlParsePEReference(ctxt);
       
  5621 
       
  5622     /*
       
  5623      * Conditional sections are allowed from entities included
       
  5624      * by PE References in the internal subset.
       
  5625      */
       
  5626     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
       
  5627         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
       
  5628         xmlParseConditionalSections(ctxt);
       
  5629     }
       
  5630     }
       
  5631 
       
  5632     ctxt->instate = XML_PARSER_DTD;
       
  5633 }
       
  5634 
       
  5635 /**
       
  5636  * xmlParseTextDecl:
       
  5637  * @param ctxt an XML parser context
       
  5638  *
       
  5639  * parse an XML declaration header for external entities
       
  5640  *
       
  5641  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
       
  5642  *
       
  5643  * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
       
  5644  */
       
  5645 
       
  5646 XMLPUBFUNEXPORT void
       
  5647 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
       
  5648     xmlChar *version;
       
  5649     const xmlChar *encoding;
       
  5650 
       
  5651     /*
       
  5652      * We know that '<?xml' is here.
       
  5653      */
       
  5654     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
       
  5655     SKIP(5);
       
  5656     } else {
       
  5657     xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
       
  5658     return;
       
  5659     }
       
  5660 
       
  5661     if (!IS_BLANK_CH(CUR)) {
       
  5662     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  5663                EMBED_ERRTXT("Space needed after '<?xml'\n"));
       
  5664     }
       
  5665     SKIP_BLANKS;
       
  5666 
       
  5667     /*
       
  5668      * We may have the VersionInfo here.
       
  5669      */
       
  5670     version = xmlParseVersionInfo(ctxt);
       
  5671     if (version == NULL)
       
  5672     version = xmlCharStrdup(XML_DEFAULT_VERSION);
       
  5673     else {
       
  5674     if (!IS_BLANK_CH(CUR)) {
       
  5675         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  5676                    EMBED_ERRTXT("Space needed here\n"));
       
  5677     }
       
  5678     }
       
  5679     ctxt->input->version = version;
       
  5680 
       
  5681     /*
       
  5682      * We must have the encoding declaration
       
  5683      */
       
  5684     encoding = xmlParseEncodingDecl(ctxt);
       
  5685     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  5686     /*
       
  5687      * The XML REC instructs us to stop parsing right here
       
  5688      */
       
  5689         return;
       
  5690     }
       
  5691     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
       
  5692     xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
       
  5693                EMBED_ERRTXT("Missing encoding in text declaration\n"));
       
  5694     }
       
  5695 
       
  5696     SKIP_BLANKS;
       
  5697     if ((RAW == '?') && (NXT(1) == '>')) {
       
  5698         SKIP(2);
       
  5699     } else if (RAW == '>') {
       
  5700         /* Deprecated old WD ... */
       
  5701     xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
       
  5702     NEXT;
       
  5703     } else {
       
  5704     xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
       
  5705     MOVETO_ENDTAG(CUR_PTR);
       
  5706     NEXT;
       
  5707     }
       
  5708 }
       
  5709 
       
  5710 /**
       
  5711  * xmlParseExternalSubset:
       
  5712  * @param ctxt an XML parser context
       
  5713  * @param ExternalID the external identifier
       
  5714  * @param SystemID the system identifier (or URL)
       
  5715  *
       
  5716  * parse Markup declarations from an external subset
       
  5717  *
       
  5718  * [30] extSubset ::= textDecl? extSubsetDecl
       
  5719  *
       
  5720  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
       
  5721  */
       
  5722 XMLPUBFUNEXPORT void
       
  5723 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
       
  5724                        const xmlChar *SystemID) {
       
  5725     xmlDetectSAX2(ctxt);
       
  5726     GROW;
       
  5727     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
       
  5728     xmlParseTextDecl(ctxt);
       
  5729     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  5730         /*
       
  5731          * The XML REC instructs us to stop parsing right here
       
  5732          */
       
  5733         ctxt->instate = XML_PARSER_EOF;
       
  5734         return;
       
  5735     }
       
  5736     }
       
  5737     if (ctxt->myDoc == NULL) {
       
  5738         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
       
  5739     }
       
  5740     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
       
  5741         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
       
  5742 
       
  5743     ctxt->instate = XML_PARSER_DTD;
       
  5744     ctxt->external = 1;
       
  5745     while (((RAW == '<') && (NXT(1) == '?')) ||
       
  5746            ((RAW == '<') && (NXT(1) == '!')) ||
       
  5747        (RAW == '%') || IS_BLANK_CH(CUR)) {
       
  5748     const xmlChar *check = CUR_PTR;
       
  5749     unsigned int cons = ctxt->input->consumed;
       
  5750 
       
  5751     GROW;
       
  5752         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
       
  5753         xmlParseConditionalSections(ctxt);
       
  5754     } else if (IS_BLANK_CH(CUR)) {
       
  5755         NEXT;
       
  5756     } else if (RAW == '%') {
       
  5757             xmlParsePEReference(ctxt);
       
  5758     } else
       
  5759         xmlParseMarkupDecl(ctxt);
       
  5760 
       
  5761     /*
       
  5762      * Pop-up of finished entities.
       
  5763      */
       
  5764     while ((RAW == 0) && (ctxt->inputNr > 1))
       
  5765         xmlPopInput(ctxt);
       
  5766 
       
  5767     if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
       
  5768         xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
       
  5769         break;
       
  5770     }
       
  5771     }
       
  5772 
       
  5773     if (RAW != 0) {
       
  5774     xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
       
  5775     }
       
  5776 
       
  5777 }
       
  5778 
       
  5779 /**
       
  5780  * xmlParseReference:
       
  5781  * @param ctxt an XML parser context
       
  5782  *
       
  5783  * parse and handle entity references in content, depending on the SAX
       
  5784  * interface, this may end-up in a call to character() if this is a
       
  5785  * CharRef, a predefined entity, if there is no reference() callback.
       
  5786  * or if the parser was asked to switch to that mode.
       
  5787  *
       
  5788  * [67] Reference ::= EntityRef | CharRef
       
  5789  */
       
  5790 XMLPUBFUNEXPORT void
       
  5791 xmlParseReference(xmlParserCtxtPtr ctxt) {
       
  5792     xmlEntityPtr ent;
       
  5793     xmlChar *val;
       
  5794     LOAD_GS_SAFE_CTXT(ctxt)
       
  5795     if (RAW != '&') return;
       
  5796 
       
  5797     if (NXT(1) == '#') {
       
  5798     int i = 0;
       
  5799     xmlChar out[10];
       
  5800     int hex = NXT(2);
       
  5801     int value = xmlParseCharRef(ctxt);
       
  5802 
       
  5803     if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
       
  5804         /*
       
  5805          * So we are using non-UTF-8 buffers
       
  5806          * Check that the char fit on 8bits, if not
       
  5807          * generate a CharRef.
       
  5808          */
       
  5809         if (value <= 0xFF) {
       
  5810         out[0] = value;
       
  5811         out[1] = 0;
       
  5812         if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
       
  5813             (!ctxt->disableSAX))
       
  5814             ctxt->sax->characters(ctxt->userData, out, 1);
       
  5815         } else {
       
  5816         if ((hex == 'x') || (hex == 'X'))
       
  5817             snprintf((char *)out, sizeof(out), "#x%X", value);
       
  5818         else
       
  5819             snprintf((char *)out, sizeof(out), "#%d", value);
       
  5820         if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
       
  5821             (!ctxt->disableSAX))
       
  5822             ctxt->sax->reference(ctxt->userData, out);
       
  5823         }
       
  5824     } else {
       
  5825         /*
       
  5826          * Just encode the value in UTF-8
       
  5827          */
       
  5828         COPY_BUF(0 ,out, i, value);
       
  5829         out[i] = 0;
       
  5830         if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
       
  5831         (!ctxt->disableSAX))
       
  5832         ctxt->sax->characters(ctxt->userData, out, i);
       
  5833     }
       
  5834     } else {
       
  5835     ent = xmlParseEntityRef(ctxt);
       
  5836     if (ent == NULL) return;
       
  5837     if (!ctxt->wellFormed)
       
  5838         return;
       
  5839     if ((ent->name != NULL) &&
       
  5840         (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
       
  5841         xmlNodePtr list = NULL;
       
  5842         xmlParserErrors ret = XML_ERR_OK;
       
  5843 
       
  5844 
       
  5845         /*
       
  5846          * The first reference to the entity trigger a parsing phase
       
  5847          * where the ent->children is filled with the result from
       
  5848          * the parsing.
       
  5849          */
       
  5850         if (ent->children == NULL) {
       
  5851         xmlChar *value;
       
  5852         value = ent->content;
       
  5853 
       
  5854         /*
       
  5855          * Check that this entity is well formed
       
  5856          */
       
  5857         if ((value != NULL) && (value[0] != 0) &&
       
  5858             (value[1] == 0) && (value[0] == '<') &&
       
  5859             (xmlStrEqual(ent->name, BAD_CAST "lt"))) {
       
  5860             /*
       
  5861              * DONE: get definite answer on this !!!
       
  5862              * Lots of entity decls are used to declare a single
       
  5863              * char
       
  5864              *    <!ENTITY lt     "<">
       
  5865              * Which seems to be valid since
       
  5866              * 2.4: The ampersand character (&) and the left angle
       
  5867              * bracket (<) may appear in their literal form only
       
  5868              * when used ... They are also legal within the literal
       
  5869              * entity value of an internal entity declaration;i
       
  5870              * see "4.3.2 Well-Formed Parsed Entities".
       
  5871              * IMHO 2.4 and 4.3.2 are directly in contradiction.
       
  5872              * Looking at the OASIS test suite and James Clark
       
  5873              * tests, this is broken. However the XML REC uses
       
  5874              * it. Is the XML REC not well-formed ????
       
  5875              * 
       
  5876              *
       
  5877              * ANSWER: since lt gt amp .. are already defined,
       
  5878              *   this is a redefinition and hence the fact that the
       
  5879              *   content is not well balanced is not a Wf error, this
       
  5880              *   is lousy but acceptable.
       
  5881              */
       
  5882             list = xmlNewDocText(ctxt->myDoc, value);
       
  5883             if (list != NULL) {
       
  5884             if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
       
  5885                 (ent->children == NULL)) {
       
  5886                 ent->children = list;
       
  5887                 ent->last = list;
       
  5888                 ent->owner = 1;
       
  5889                 list->parent = (xmlNodePtr) ent;
       
  5890             } else {
       
  5891                 xmlFreeNodeList(list);
       
  5892             }
       
  5893             } else if (list != NULL) {
       
  5894             xmlFreeNodeList(list);
       
  5895             }
       
  5896         } else {
       
  5897             /*
       
  5898              * 4.3.2: An internal general parsed entity is well-formed
       
  5899              * if its replacement text matches the production labeled
       
  5900              * content.
       
  5901              */
       
  5902 
       
  5903             void *user_data;
       
  5904             /*
       
  5905              * This is a bit hackish but this seems the best
       
  5906              * way to make sure both SAX and DOM entity support
       
  5907              * behaves okay.
       
  5908              */
       
  5909             if (ctxt->userData == ctxt)
       
  5910             user_data = NULL;
       
  5911             else
       
  5912             user_data = ctxt->userData;
       
  5913 
       
  5914             if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
       
  5915             ctxt->depth++;
       
  5916             ret = xmlParseBalancedChunkMemoryInternal(ctxt,
       
  5917                        value, user_data, &list);
       
  5918             if(OOM_FLAG)
       
  5919                 {
       
  5920                 return;
       
  5921                 }
       
  5922             ctxt->depth--;
       
  5923             } else if (ent->etype ==
       
  5924                    XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
       
  5925             ctxt->depth++;
       
  5926             ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
       
  5927                    ctxt->sax, user_data, ctxt->depth,
       
  5928                    ent->URI, ent->ExternalID, &list);
       
  5929             ctxt->depth--;
       
  5930             } else {
       
  5931             ret = XML_ERR_ENTITY_PE_INTERNAL;
       
  5932             xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
       
  5933                      EMBED_ERRTXT("invalid entity type found\n"), NULL);
       
  5934             }
       
  5935             if (ret == XML_ERR_ENTITY_LOOP) {
       
  5936             xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
       
  5937             return;
       
  5938             } else if ((ret == XML_ERR_OK) && (list != NULL)) {
       
  5939             if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
       
  5940              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
       
  5941                 (ent->children == NULL)) {
       
  5942                 ent->children = list;
       
  5943                 if (ctxt->replaceEntities) {
       
  5944                 /*
       
  5945                  * Prune it directly in the generated document
       
  5946                  * except for single text nodes.
       
  5947                  */
       
  5948                 if ((list->type == XML_TEXT_NODE) &&
       
  5949                     (list->next == NULL)) {
       
  5950                     list->parent = (xmlNodePtr) ent;
       
  5951                     list = NULL;
       
  5952                     ent->owner = 1;
       
  5953                 } else {
       
  5954                     ent->owner = 0;
       
  5955                     while (list != NULL) {
       
  5956                     list->parent = (xmlNodePtr) ctxt->node;
       
  5957                     list->doc = ctxt->myDoc;
       
  5958                     if (list->next == NULL)
       
  5959                         ent->last = list;
       
  5960                     list = list->next;
       
  5961                     }
       
  5962                     list = ent->children;
       
  5963 #ifdef LIBXML_LEGACY_ENABLED
       
  5964                     if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
       
  5965                       xmlAddEntityReference(ent, list, NULL);
       
  5966 #endif /* LIBXML_LEGACY_ENABLED */
       
  5967                 }
       
  5968                 } else {
       
  5969                 ent->owner = 1;
       
  5970                 while (list != NULL) {
       
  5971                     list->parent = (xmlNodePtr) ent;
       
  5972                     if (list->next == NULL)
       
  5973                     ent->last = list;
       
  5974                     list = list->next;
       
  5975                 }
       
  5976                 }
       
  5977             } else {
       
  5978                 xmlFreeNodeList(list);
       
  5979                 list = NULL;
       
  5980             }
       
  5981             } else if ((ret != XML_ERR_OK) &&
       
  5982                        (ret != XML_WAR_UNDECLARED_ENTITY)) {
       
  5983             xmlFatalErr(ctxt, ret, NULL);
       
  5984             } else if (list != NULL) {
       
  5985             xmlFreeNodeList(list);
       
  5986             list = NULL;
       
  5987             }
       
  5988         }
       
  5989         }
       
  5990         if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
       
  5991         (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
       
  5992         /*
       
  5993          * Create a node.
       
  5994          */
       
  5995         ctxt->sax->reference(ctxt->userData, ent->name);
       
  5996         return;
       
  5997         } else if (ctxt->replaceEntities) {
       
  5998         if ((ctxt->node != NULL) && (ent->children != NULL)) {
       
  5999             /*
       
  6000              * Seems we are generating the DOM content, do
       
  6001              * a simple tree copy for all references except the first
       
  6002              * In the first occurrence list contains the replacement
       
  6003              */
       
  6004             if ((list == NULL) && (ent->owner == 0)) {
       
  6005             xmlNodePtr nw = NULL, cur, firstChild = NULL;
       
  6006             cur = ent->children;
       
  6007             while (cur != NULL) {
       
  6008                 nw = xmlCopyNode(cur, 1);
       
  6009                 if (nw != NULL) {
       
  6010                 nw->_private = cur->_private;
       
  6011                 if (firstChild == NULL){
       
  6012                     firstChild = nw;
       
  6013                 }
       
  6014                 xmlAddChild(ctxt->node, nw);
       
  6015                 }
       
  6016                 if (cur == ent->last)
       
  6017                 break;
       
  6018                 cur = cur->next;
       
  6019             }
       
  6020 #ifdef LIBXML_LEGACY_ENABLED
       
  6021             if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
       
  6022               xmlAddEntityReference(ent, firstChild, nw);
       
  6023 #endif /* LIBXML_LEGACY_ENABLED */
       
  6024             } else if (list == NULL) {
       
  6025                 xmlNodePtr nw = NULL, cur, next, last,
       
  6026                 firstChild = NULL;
       
  6027                 /*
       
  6028                  * Copy the entity child list and make it the new
       
  6029                  * entity child list. The goal is to make sure any
       
  6030                  * ID or REF referenced will be the one from the
       
  6031                  * document content and not the entity copy.
       
  6032                  */
       
  6033                 cur = ent->children;
       
  6034                 ent->children = NULL;
       
  6035                 last = ent->last;
       
  6036                 ent->last = NULL;
       
  6037                 while (cur != NULL) {
       
  6038                     next = cur->next;
       
  6039                     cur->next = NULL;
       
  6040                     cur->parent = NULL;
       
  6041                     nw = xmlCopyNode(cur, 1);
       
  6042                     if (nw != NULL) {
       
  6043                         nw->_private = cur->_private;
       
  6044                         if (firstChild == NULL){
       
  6045                             firstChild = cur;
       
  6046                         }
       
  6047                         xmlAddChild((xmlNodePtr) ent, nw);
       
  6048                         xmlAddChild(ctxt->node, cur);
       
  6049                     }
       
  6050                     if (cur == last)
       
  6051                         break;
       
  6052                     cur = next;
       
  6053                 }
       
  6054                 ent->owner = 1;
       
  6055 #ifdef LIBXML_LEGACY_ENABLED
       
  6056             if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
       
  6057                 xmlAddEntityReference(ent, firstChild, nw);
       
  6058 #endif /* LIBXML_LEGACY_ENABLED */
       
  6059             } else {
       
  6060                 /*
       
  6061                  * the name change is to avoid coalescing of the
       
  6062                  * node with a possible previous text one which
       
  6063                  * would make ent->children a dangling pointer
       
  6064                  */
       
  6065                 if (ent->children->type == XML_TEXT_NODE)
       
  6066                     ent->children->name = xmlStrdup(BAD_CAST "nbktext");
       
  6067                 if ((ent->last != ent->children) &&
       
  6068                     (ent->last->type == XML_TEXT_NODE))
       
  6069                     ent->last->name = xmlStrdup(BAD_CAST "nbktext");
       
  6070                 xmlAddChildList(ctxt->node, ent->children);
       
  6071             }
       
  6072 
       
  6073             /*
       
  6074              * This is to avoid a nasty side effect, see
       
  6075              * characters() in SAX.c
       
  6076              */
       
  6077             ctxt->nodemem = 0;
       
  6078             ctxt->nodelen = 0;
       
  6079             return;
       
  6080         } else {
       
  6081             /*
       
  6082              * Probably running in SAX mode
       
  6083              */
       
  6084             xmlParserInputPtr input;
       
  6085 
       
  6086             input = xmlNewEntityInputStream(ctxt, ent);
       
  6087             xmlPushInput(ctxt, input);
       
  6088             if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) &&
       
  6089             (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
       
  6090             (IS_BLANK_CH(NXT(5)))) {
       
  6091             xmlParseTextDecl(ctxt);
       
  6092             if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  6093                 /*
       
  6094                  * The XML REC instructs us to stop parsing right here
       
  6095                  */
       
  6096                 ctxt->instate = XML_PARSER_EOF;
       
  6097                 return;
       
  6098             }
       
  6099             if (input->standalone == 1) {
       
  6100                 xmlFatalErr(ctxt, XML_ERR_EXT_ENTITY_STANDALONE,
       
  6101                             NULL);
       
  6102             }
       
  6103             }
       
  6104             return;
       
  6105         }
       
  6106         }
       
  6107     } else {
       
  6108         val = ent->content;
       
  6109         if (val == NULL) return;
       
  6110         /*
       
  6111          * inline the entity.
       
  6112          */
       
  6113         if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
       
  6114         (!ctxt->disableSAX))
       
  6115         ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
       
  6116     }
       
  6117     }
       
  6118 }
       
  6119 
       
  6120 /**
       
  6121  * xmlParseEntityRef:
       
  6122  * @param ctxt an XML parser context
       
  6123  *
       
  6124  * parse ENTITY references declarations
       
  6125  *
       
  6126  * [68] EntityRef ::= '&' Name ';'
       
  6127  *
       
  6128  * [ WFC: Entity Declared ]
       
  6129  * In a document without any DTD, a document with only an internal DTD
       
  6130  * subset which contains no parameter entity references, or a document
       
  6131  * with "standalone='yes'", the Name given in the entity reference
       
  6132  * must match that in an entity declaration, except that well-formed
       
  6133  * documents need not declare any of the following entities: amp, lt,
       
  6134  * gt, apos, quot.  The declaration of a parameter entity must precede
       
  6135  * any reference to it.  Similarly, the declaration of a general entity
       
  6136  * must precede any reference to it which appears in a default value in an
       
  6137  * attribute-list declaration. Note that if entities are declared in the
       
  6138  * external subset or in external parameter entities, a non-validating
       
  6139  * processor is not obligated to read and process their declarations;
       
  6140  * for such documents, the rule that an entity must be declared is a
       
  6141  * well-formedness constraint only if standalone='yes'.
       
  6142  *
       
  6143  * [ WFC: Parsed Entity ]
       
  6144  * An entity reference must not contain the name of an unparsed entity
       
  6145  *
       
  6146  * Returns the xmlEntityPtr if found, or NULL otherwise.
       
  6147  */
       
  6148 XMLPUBFUNEXPORT xmlEntityPtr
       
  6149 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
       
  6150     const xmlChar *name;
       
  6151     xmlEntityPtr ent = NULL;
       
  6152 
       
  6153     GROW;
       
  6154 
       
  6155     if (RAW == '&') {
       
  6156         NEXT;
       
  6157         name = xmlParseName(ctxt);
       
  6158     if (name == NULL) {
       
  6159         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  6160                EMBED_ERRTXT("xmlParseEntityRef: no name\n"));
       
  6161     } else {
       
  6162         if (RAW == ';') {
       
  6163             NEXT;
       
  6164         /*
       
  6165          * Ask first SAX for entity resolution, otherwise try the
       
  6166          * predefined set.
       
  6167          */
       
  6168         if (ctxt->sax != NULL) {
       
  6169             if (ctxt->sax->getEntity != NULL)
       
  6170             ent = ctxt->sax->getEntity(ctxt->userData, name);
       
  6171             if ((ctxt->wellFormed == 1 ) && (ent == NULL))
       
  6172                 ent = xmlGetPredefinedEntity(name);
       
  6173             if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
       
  6174             (ctxt->userData==ctxt)) {
       
  6175             ent = xmlSAX2GetEntity(ctxt, name);
       
  6176             }
       
  6177         }
       
  6178         /*
       
  6179          * [ WFC: Entity Declared ]
       
  6180          * In a document without any DTD, a document with only an
       
  6181          * internal DTD subset which contains no parameter entity
       
  6182          * references, or a document with "standalone='yes'", the
       
  6183          * Name given in the entity reference must match that in an
       
  6184          * entity declaration, except that well-formed documents
       
  6185          * need not declare any of the following entities: amp, lt,
       
  6186          * gt, apos, quot.
       
  6187          * The declaration of a parameter entity must precede any
       
  6188          * reference to it.
       
  6189          * Similarly, the declaration of a general entity must
       
  6190          * precede any reference to it which appears in a default
       
  6191          * value in an attribute-list declaration. Note that if
       
  6192          * entities are declared in the external subset or in
       
  6193          * external parameter entities, a non-validating processor
       
  6194          * is not obligated to read and process their declarations;
       
  6195          * for such documents, the rule that an entity must be
       
  6196          * declared is a well-formedness constraint only if
       
  6197          * standalone='yes'.
       
  6198          */
       
  6199         if (ent == NULL) {
       
  6200             // XML ENGINE: TEST CODE:  for disabling "Unknown entity reference" error
       
  6201             //return NULL;
       
  6202             //
       
  6203             if ((ctxt->standalone == 1) ||
       
  6204                 ((ctxt->hasExternalSubset == 0) &&
       
  6205              (ctxt->hasPErefs == 0))) {
       
  6206             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
       
  6207                  EMBED_ERRTXT("Entity '%s' not defined\n"), name);
       
  6208             } else {
       
  6209                 xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  6210                  EMBED_ERRTXT("Entity '%s' not defined\n"), name);
       
  6211             }
       
  6212             ctxt->valid = 0;
       
  6213         }
       
  6214 
       
  6215         /*
       
  6216          * [ WFC: Parsed Entity ]
       
  6217          * An entity reference must not contain the name of an
       
  6218          * unparsed entity
       
  6219          */
       
  6220         else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
       
  6221             xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
       
  6222                  EMBED_ERRTXT("Entity reference to unparsed entity %s\n"), name);
       
  6223         }
       
  6224 
       
  6225         /*
       
  6226          * [ WFC: No External Entity References ]
       
  6227          * Attribute values cannot contain direct or indirect
       
  6228          * entity references to external entities.
       
  6229          */
       
  6230         else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
       
  6231                  (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
       
  6232             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
       
  6233              EMBED_ERRTXT("Attribute references external entity '%s'\n"), name);
       
  6234         }
       
  6235         /*
       
  6236          * [ WFC: No < in Attribute Values ]
       
  6237          * The replacement text of any entity referred to directly or
       
  6238          * indirectly in an attribute value (other than "&lt;") must
       
  6239          * not contain a <.
       
  6240          */
       
  6241         else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
       
  6242                  (ent != NULL) &&
       
  6243              (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
       
  6244                  (ent->content != NULL) &&
       
  6245              (xmlStrchr(ent->content, '<'))) {
       
  6246             xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
       
  6247      EMBED_ERRTXT("'<' in entity '%s' is not allowed in attributes values\n"), name);
       
  6248         }
       
  6249 
       
  6250         /*
       
  6251          * Internal check, no parameter entities here ...
       
  6252          */
       
  6253         else {
       
  6254             switch (ent->etype) {
       
  6255             case XML_INTERNAL_PARAMETER_ENTITY:
       
  6256             case XML_EXTERNAL_PARAMETER_ENTITY:
       
  6257             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
       
  6258              EMBED_ERRTXT("Attempt to reference the parameter entity '%s'\n"),
       
  6259                                   name);
       
  6260             break;
       
  6261             default:
       
  6262             break;
       
  6263             }
       
  6264         }
       
  6265 
       
  6266         /*
       
  6267          * [ WFC: No Recursion ]
       
  6268          * A parsed entity must not contain a recursive reference
       
  6269          * to itself, either directly or indirectly.
       
  6270          * Done somewhere else
       
  6271          */
       
  6272 
       
  6273         } else {
       
  6274         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
       
  6275         }
       
  6276     }
       
  6277     }
       
  6278     return(ent);
       
  6279 }
       
  6280 
       
  6281 /**
       
  6282  * xmlParseStringEntityRef:
       
  6283  * @param ctxt an XML parser context
       
  6284  * @param str a pointer to an index in the string
       
  6285  *
       
  6286  * parse ENTITY references declarations, but this version parses it from
       
  6287  * a string value.
       
  6288  *
       
  6289  * [68] EntityRef ::= '&' Name ';'
       
  6290  *
       
  6291  * [ WFC: Entity Declared ]
       
  6292  * In a document without any DTD, a document with only an internal DTD
       
  6293  * subset which contains no parameter entity references, or a document
       
  6294  * with "standalone='yes'", the Name given in the entity reference
       
  6295  * must match that in an entity declaration, except that well-formed
       
  6296  * documents need not declare any of the following entities: amp, lt,
       
  6297  * gt, apos, quot.  The declaration of a parameter entity must precede
       
  6298  * any reference to it.  Similarly, the declaration of a general entity
       
  6299  * must precede any reference to it which appears in a default value in an
       
  6300  * attribute-list declaration. Note that if entities are declared in the
       
  6301  * external subset or in external parameter entities, a non-validating
       
  6302  * processor is not obligated to read and process their declarations;
       
  6303  * for such documents, the rule that an entity must be declared is a
       
  6304  * well-formedness constraint only if standalone='yes'.
       
  6305  *
       
  6306  * [ WFC: Parsed Entity ]
       
  6307  * An entity reference must not contain the name of an unparsed entity
       
  6308  *
       
  6309  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
       
  6310  * is updated to the current location in the string.
       
  6311  */
       
  6312 xmlEntityPtr
       
  6313 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
       
  6314     xmlChar *name;
       
  6315     const xmlChar *ptr;
       
  6316     xmlChar cur;
       
  6317     xmlEntityPtr ent = NULL;
       
  6318 
       
  6319     if ((str == NULL) || (*str == NULL))
       
  6320         return(NULL);
       
  6321     ptr = *str;
       
  6322     cur = *ptr;
       
  6323     if (cur == '&') {
       
  6324         ptr++;
       
  6325     cur = *ptr;
       
  6326     name = xmlParseStringName(ctxt, &ptr);
       
  6327     if (name == NULL) {
       
  6328         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, EMBED_ERRTXT("xmlParseStringEntityRef: no name\n"));
       
  6329     } else {
       
  6330         if (*ptr == ';') {
       
  6331             ptr++;
       
  6332         /*
       
  6333          * Ask first SAX for entity resolution, otherwise try the
       
  6334          * predefined set.
       
  6335          */
       
  6336         if (ctxt->sax != NULL) {
       
  6337             if (ctxt->sax->getEntity != NULL)
       
  6338                 ent = ctxt->sax->getEntity(ctxt->userData, name);
       
  6339             if (ent == NULL)
       
  6340                 ent = xmlGetPredefinedEntity(name);
       
  6341             if ((ent == NULL) && (ctxt->userData==ctxt)) {
       
  6342                 ent = xmlSAX2GetEntity(ctxt, name);
       
  6343             }
       
  6344         }
       
  6345         /*
       
  6346          * [ WFC: Entity Declared ]
       
  6347          * In a document without any DTD, a document with only an
       
  6348          * internal DTD subset which contains no parameter entity
       
  6349          * references, or a document with "standalone='yes'", the
       
  6350          * Name given in the entity reference must match that in an
       
  6351          * entity declaration, except that well-formed documents
       
  6352          * need not declare any of the following entities: amp, lt,
       
  6353          * gt, apos, quot.
       
  6354          * The declaration of a parameter entity must precede any
       
  6355          * reference to it.
       
  6356          * Similarly, the declaration of a general entity must
       
  6357          * precede any reference to it which appears in a default
       
  6358          * value in an attribute-list declaration. Note that if
       
  6359          * entities are declared in the external subset or in
       
  6360          * external parameter entities, a non-validating processor
       
  6361          * is not obligated to read and process their declarations;
       
  6362          * for such documents, the rule that an entity must be
       
  6363          * declared is a well-formedness constraint only if
       
  6364          * standalone='yes'.
       
  6365          */
       
  6366         if (ent == NULL) {
       
  6367             
       
  6368             if ((ctxt->standalone == 1) ||
       
  6369                 ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0)))
       
  6370             {
       
  6371                 xmlFatalErrMsgStr(
       
  6372                         ctxt,
       
  6373                         XML_ERR_UNDECLARED_ENTITY,
       
  6374                         EMBED_ERRTXT("Entity '%s' not defined\n"),
       
  6375                         name);
       
  6376             } else {
       
  6377                 xmlErrMsgStr(
       
  6378                         ctxt,
       
  6379                         XML_WAR_UNDECLARED_ENTITY,
       
  6380                         EMBED_ERRTXT("Entity '%s' not defined\n"),
       
  6381                         name);
       
  6382             }
       
  6383             
       
  6384         }
       
  6385 
       
  6386         /*
       
  6387          * [ WFC: Parsed Entity ]
       
  6388          * An entity reference must not contain the name of an
       
  6389          * unparsed entity
       
  6390          */
       
  6391         else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
       
  6392             xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
       
  6393                  EMBED_ERRTXT("Entity reference to unparsed entity %s\n"), name);
       
  6394         }
       
  6395 
       
  6396         /*
       
  6397          * [ WFC: No External Entity References ]
       
  6398          * Attribute values cannot contain direct or indirect
       
  6399          * entity references to external entities.
       
  6400          */
       
  6401         else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
       
  6402                  (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
       
  6403             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
       
  6404              EMBED_ERRTXT("Attribute references external entity '%s'\n"), name);
       
  6405         }
       
  6406         /*
       
  6407          * [ WFC: No < in Attribute Values ]
       
  6408          * The replacement text of any entity referred to directly or
       
  6409          * indirectly in an attribute value (other than "&lt;") must
       
  6410          * not contain a <.
       
  6411          */
       
  6412         else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
       
  6413                  (ent != NULL) &&
       
  6414              (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
       
  6415                  (ent->content != NULL) &&
       
  6416              (xmlStrchr(ent->content, '<'))) {
       
  6417             xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
       
  6418          EMBED_ERRTXT("'<' in entity '%s' is not allowed in attributes values\n"),
       
  6419                                   name);
       
  6420         }
       
  6421 
       
  6422         /*
       
  6423          * Internal check, no parameter entities here ...
       
  6424          */
       
  6425         else {
       
  6426             switch (ent->etype) {
       
  6427             case XML_INTERNAL_PARAMETER_ENTITY:
       
  6428             case XML_EXTERNAL_PARAMETER_ENTITY:
       
  6429                 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
       
  6430              EMBED_ERRTXT("Attempt to reference the parameter entity '%s'\n"),
       
  6431                                   name);
       
  6432             break;
       
  6433             default:
       
  6434             break;
       
  6435             }
       
  6436         }
       
  6437 
       
  6438         /*
       
  6439          * [ WFC: No Recursion ]
       
  6440          * A parsed entity must not contain a recursive reference
       
  6441          * to itself, either directly or indirectly.
       
  6442          * Done somewhere else
       
  6443          */
       
  6444 
       
  6445         } else {
       
  6446         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
       
  6447         }
       
  6448         xmlFree(name);
       
  6449     }
       
  6450     }
       
  6451     *str = ptr;
       
  6452     return(ent);
       
  6453 }
       
  6454 
       
  6455 /**
       
  6456  * xmlParsePEReference:
       
  6457  * @param ctxt an XML parser context
       
  6458  *
       
  6459  * parse PEReference declarations
       
  6460  * The entity content is handled directly by pushing it's content as
       
  6461  * a new input stream.
       
  6462  *
       
  6463  * [69] PEReference ::= '%' Name ';'
       
  6464  *
       
  6465  * [ WFC: No Recursion ]
       
  6466  * A parsed entity must not contain a recursive
       
  6467  * reference to itself, either directly or indirectly.
       
  6468  *
       
  6469  * [ WFC: Entity Declared ]
       
  6470  * In a document without any DTD, a document with only an internal DTD
       
  6471  * subset which contains no parameter entity references, or a document
       
  6472  * with "standalone='yes'", ...  ... The declaration of a parameter
       
  6473  * entity must precede any reference to it...
       
  6474  *
       
  6475  * [ VC: Entity Declared ]
       
  6476  * In a document with an external subset or external parameter entities
       
  6477  * with "standalone='no'", ...  ... The declaration of a parameter entity
       
  6478  * must precede any reference to it...
       
  6479  *
       
  6480  * [ WFC: In DTD ]
       
  6481  * Parameter-entity references may only appear in the DTD.
       
  6482  * NOTE: misleading but this is handled.
       
  6483  */
       
  6484 XMLPUBFUNEXPORT void
       
  6485 xmlParsePEReference(xmlParserCtxtPtr ctxt)
       
  6486 {
       
  6487     const xmlChar *name;
       
  6488     xmlEntityPtr entity = NULL;
       
  6489     xmlParserInputPtr input;
       
  6490 
       
  6491     if (RAW == '%') {
       
  6492         NEXT;
       
  6493         name = xmlParseName(ctxt);
       
  6494         if (name == NULL) {
       
  6495             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  6496                            EMBED_ERRTXT("xmlParsePEReference: no name\n"));
       
  6497         } else {
       
  6498             if (RAW == ';') {
       
  6499                 NEXT;
       
  6500                 if ((ctxt->sax != NULL) &&
       
  6501                     (ctxt->sax->getParameterEntity != NULL))
       
  6502                     entity = ctxt->sax->getParameterEntity(ctxt->userData,
       
  6503                                                            name);
       
  6504                 if (entity == NULL) {
       
  6505                     /*
       
  6506                      * [ WFC: Entity Declared ]
       
  6507                      * In a document without any DTD, a document with only an
       
  6508                      * internal DTD subset which contains no parameter entity
       
  6509                      * references, or a document with "standalone='yes'", ...
       
  6510                      * ... The declaration of a parameter entity must precede
       
  6511                      * any reference to it...
       
  6512                      */
       
  6513                     if ((ctxt->standalone == 1) ||
       
  6514                         ((ctxt->hasExternalSubset == 0) &&
       
  6515                          (ctxt->hasPErefs == 0))) {
       
  6516                         xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
       
  6517                                           EMBED_ERRTXT("PEReference: %%%s; not found\n"),
       
  6518                                           name);
       
  6519                     } else {
       
  6520                         /*
       
  6521                          * [ VC: Entity Declared ]
       
  6522                          * In a document with an external subset or external
       
  6523                          * parameter entities with "standalone='no'", ...
       
  6524                          * ... The declaration of a parameter entity must
       
  6525              * precede any reference to it...
       
  6526                          */
       
  6527                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  6528                                       EMBED_ERRTXT("PEReference: %%%s; not found\n"),
       
  6529                                       name, NULL);
       
  6530                         ctxt->valid = 0;
       
  6531                     }
       
  6532                 } else {
       
  6533                     /*
       
  6534                      * Internal checking in case the entity quest barfed
       
  6535                      */
       
  6536                     if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
       
  6537                         (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
       
  6538                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  6539                   EMBED_ERRTXT("Internal: %%%s; is not a parameter entity\n"),
       
  6540                                       name, NULL);
       
  6541                     } else if (ctxt->input->free != deallocblankswrapper) {
       
  6542                         input =
       
  6543                             xmlNewBlanksWrapperInputStream(ctxt, entity);
       
  6544                         xmlPushInput(ctxt, input);
       
  6545                     } else {
       
  6546                         /*
       
  6547                          
       
  6548                          * handle the extra spaces added before and after
       
  6549                          * c.f. http://www.w3.org/TR/REC-xml#as-PE
       
  6550                          */
       
  6551                         input = xmlNewEntityInputStream(ctxt, entity);
       
  6552                         xmlPushInput(ctxt, input);
       
  6553                         if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
       
  6554                 (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
       
  6555                 (IS_BLANK_CH(NXT(5)))) {
       
  6556                             xmlParseTextDecl(ctxt);
       
  6557                             if (ctxt->errNo ==
       
  6558                                 XML_ERR_UNSUPPORTED_ENCODING) {
       
  6559                                 /*
       
  6560                                  * The XML REC instructs us to stop parsing
       
  6561                                  * right here
       
  6562                                  */
       
  6563                                 ctxt->instate = XML_PARSER_EOF;
       
  6564                                 return;
       
  6565                             }
       
  6566                         }
       
  6567                     }
       
  6568                 }
       
  6569                 ctxt->hasPErefs = 1;
       
  6570             } else {
       
  6571                 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
       
  6572             }
       
  6573         }
       
  6574     }
       
  6575 }
       
  6576 
       
  6577 /**
       
  6578  * xmlParseStringPEReference:
       
  6579  * @param ctxt an XML parser context
       
  6580  * @param str a pointer to an index in the string
       
  6581  *
       
  6582  * parse PEReference declarations
       
  6583  *
       
  6584  * [69] PEReference ::= '%' Name ';'
       
  6585  *
       
  6586  * [ WFC: No Recursion ]
       
  6587  * A parsed entity must not contain a recursive
       
  6588  * reference to itself, either directly or indirectly.
       
  6589  *
       
  6590  * [ WFC: Entity Declared ]
       
  6591  * In a document without any DTD, a document with only an internal DTD
       
  6592  * subset which contains no parameter entity references, or a document
       
  6593  * with "standalone='yes'", ...  ... The declaration of a parameter
       
  6594  * entity must precede any reference to it...
       
  6595  *
       
  6596  * [ VC: Entity Declared ]
       
  6597  * In a document with an external subset or external parameter entities
       
  6598  * with "standalone='no'", ...  ... The declaration of a parameter entity
       
  6599  * must precede any reference to it...
       
  6600  *
       
  6601  * [ WFC: In DTD ]
       
  6602  * Parameter-entity references may only appear in the DTD.
       
  6603  * NOTE: misleading but this is handled.
       
  6604  *
       
  6605  * Returns the string of the entity content.
       
  6606  *         str is updated to the current value of the index
       
  6607  */
       
  6608 xmlEntityPtr
       
  6609 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
       
  6610     const xmlChar *ptr;
       
  6611     xmlChar cur;
       
  6612     xmlChar *name;
       
  6613     xmlEntityPtr entity = NULL;
       
  6614 
       
  6615     if ((str == NULL) || (*str == NULL)) return(NULL);
       
  6616     ptr = *str;
       
  6617     cur = *ptr;
       
  6618     if (cur == '%') {
       
  6619         ptr++;
       
  6620     cur = *ptr;
       
  6621         name = xmlParseStringName(ctxt, &ptr);
       
  6622     if (name == NULL) {
       
  6623         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  6624                EMBED_ERRTXT("xmlParseStringPEReference: no name\n"));
       
  6625     } else {
       
  6626         cur = *ptr;
       
  6627         if (cur == ';') {
       
  6628         ptr++;
       
  6629         cur = *ptr;
       
  6630         if ((ctxt->sax != NULL) &&
       
  6631             (ctxt->sax->getParameterEntity != NULL))
       
  6632             entity = ctxt->sax->getParameterEntity(ctxt->userData,
       
  6633                                                    name);
       
  6634         if (entity == NULL) {
       
  6635             /*
       
  6636              * [ WFC: Entity Declared ]
       
  6637              * In a document without any DTD, a document with only an
       
  6638              * internal DTD subset which contains no parameter entity
       
  6639              * references, or a document with "standalone='yes'", ...
       
  6640              * ... The declaration of a parameter entity must precede
       
  6641              * any reference to it...
       
  6642              */
       
  6643             if ((ctxt->standalone == 1) ||
       
  6644             ((ctxt->hasExternalSubset == 0) &&
       
  6645              (ctxt->hasPErefs == 0))) {
       
  6646             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
       
  6647                  EMBED_ERRTXT("PEReference: %%%s; not found\n"), name);
       
  6648             } else {
       
  6649             /*
       
  6650              * [ VC: Entity Declared ]
       
  6651              * In a document with an external subset or external
       
  6652              * parameter entities with "standalone='no'", ...
       
  6653              * ... The declaration of a parameter entity must
       
  6654              * precede any reference to it...
       
  6655              */
       
  6656             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  6657                       EMBED_ERRTXT("PEReference: %%%s; not found\n"),
       
  6658                           name, NULL);
       
  6659             ctxt->valid = 0;
       
  6660             }
       
  6661         } else {
       
  6662             /*
       
  6663              * Internal checking in case the entity quest barfed
       
  6664              */
       
  6665             if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
       
  6666                 (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
       
  6667             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
       
  6668                           EMBED_ERRTXT("%%%s; is not a parameter entity\n"),
       
  6669                       name, NULL);
       
  6670             }
       
  6671         }
       
  6672         ctxt->hasPErefs = 1;
       
  6673         } else {
       
  6674         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
       
  6675         }
       
  6676         xmlFree(name);
       
  6677     }
       
  6678     }
       
  6679     *str = ptr;
       
  6680     return(entity);
       
  6681 }
       
  6682 
       
  6683 /**
       
  6684  * xmlParseDocTypeDecl:
       
  6685  * @param ctxt an XML parser context
       
  6686  *
       
  6687  * parse a DOCTYPE declaration
       
  6688  *
       
  6689  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
       
  6690  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
       
  6691  *
       
  6692  * [ VC: Root Element Type ]
       
  6693  * The Name in the document type declaration must match the element
       
  6694  * type of the root element.
       
  6695  */
       
  6696 
       
  6697 XMLPUBFUNEXPORT void
       
  6698 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
       
  6699     const xmlChar *name = NULL;
       
  6700     xmlChar *ExternalID = NULL;
       
  6701     xmlChar *URI = NULL;
       
  6702 
       
  6703     /*
       
  6704      * We know that '<!DOCTYPE' has been detected.
       
  6705      */
       
  6706     SKIP(9);
       
  6707 
       
  6708     SKIP_BLANKS;
       
  6709 
       
  6710     /*
       
  6711      * Parse the DOCTYPE name.
       
  6712      */
       
  6713     name = xmlParseName(ctxt);
       
  6714     if (name == NULL) {
       
  6715     xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  6716                EMBED_ERRTXT("xmlParseDocTypeDecl : no DOCTYPE name !\n"));
       
  6717     }
       
  6718     ctxt->intSubName = name;
       
  6719 
       
  6720     SKIP_BLANKS;
       
  6721 
       
  6722     /*
       
  6723      * Check for SystemID and ExternalID
       
  6724      */
       
  6725     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
       
  6726 
       
  6727     if ((URI != NULL) || (ExternalID != NULL)) {
       
  6728         ctxt->hasExternalSubset = 1;
       
  6729     }
       
  6730     ctxt->extSubURI = URI;
       
  6731     ctxt->extSubSystem = ExternalID;
       
  6732 
       
  6733     SKIP_BLANKS;
       
  6734 
       
  6735     /*
       
  6736      * Create and update the internal subset.
       
  6737      */
       
  6738     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
       
  6739     (!ctxt->disableSAX))
       
  6740     ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
       
  6741 
       
  6742     /*
       
  6743      * Is there any internal subset declarations ?
       
  6744      * they are handled separately in xmlParseInternalSubset()
       
  6745      */
       
  6746     if (RAW == '[')
       
  6747     return;
       
  6748 
       
  6749     /*
       
  6750      * We should be at the end of the DOCTYPE declaration.
       
  6751      */
       
  6752     if (RAW != '>') {
       
  6753     xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
       
  6754     }
       
  6755     NEXT;
       
  6756 }
       
  6757 
       
  6758 /**
       
  6759  * xmlParseInternalSubset:
       
  6760  * @param ctxt an XML parser context
       
  6761  *
       
  6762  * parse the internal subset declaration
       
  6763  *
       
  6764  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
       
  6765  */
       
  6766 
       
  6767 static void
       
  6768 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
       
  6769 	LOAD_GS_SAFE_CTXT(ctxt)
       
  6770     /*
       
  6771      * Is there any DTD definition ?
       
  6772      */
       
  6773     if (RAW == '[') {
       
  6774         ctxt->instate = XML_PARSER_DTD;
       
  6775         NEXT;
       
  6776     /*
       
  6777      * Parse the succession of Markup declarations and
       
  6778      * PEReferences.
       
  6779      * Subsequence (markupdecl | PEReference | S)*
       
  6780      */
       
  6781     while (RAW != ']') {
       
  6782         const xmlChar *check = CUR_PTR;
       
  6783         unsigned int cons = ctxt->input->consumed;
       
  6784 
       
  6785         SKIP_BLANKS;
       
  6786         xmlParseMarkupDecl(ctxt);
       
  6787         if(OOM_FLAG)
       
  6788             {
       
  6789             return;
       
  6790             }
       
  6791         xmlParsePEReference(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_INTERNAL_ERROR,
       
  6801          EMBED_ERRTXT("xmlParseInternalSubset: error detected in Markup declaration\n"));
       
  6802         break;
       
  6803         }
       
  6804     }
       
  6805     if (RAW == ']') {
       
  6806         NEXT;
       
  6807         SKIP_BLANKS;
       
  6808     }
       
  6809     }
       
  6810 
       
  6811     /*
       
  6812      * We should be at the end of the DOCTYPE declaration.
       
  6813      */
       
  6814     if (RAW != '>') {
       
  6815     xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
       
  6816     }
       
  6817     NEXT;
       
  6818 }
       
  6819 
       
  6820 #ifdef LIBXML_SAX1_ENABLED
       
  6821 /**
       
  6822  * xmlParseAttribute:
       
  6823  * @param ctxt an XML parser context
       
  6824  * @param value a xmlChar ** used to store the value of the attribute
       
  6825  *
       
  6826  * parse an attribute
       
  6827  *
       
  6828  * [41] Attribute ::= Name Eq AttValue
       
  6829  *
       
  6830  * [ WFC: No External Entity References ]
       
  6831  * Attribute values cannot contain direct or indirect entity references
       
  6832  * to external entities.
       
  6833  *
       
  6834  * [ WFC: No < in Attribute Values ]
       
  6835  * The replacement text of any entity referred to directly or indirectly in
       
  6836  * an attribute value (other than "&lt;") must not contain a <.
       
  6837  *
       
  6838  * [ VC: Attribute Value Type ]
       
  6839  * The attribute must have been declared; the value must be of the type
       
  6840  * declared for it.
       
  6841  *
       
  6842  * [25] Eq ::= S? '=' S?
       
  6843  *
       
  6844  * With namespace:
       
  6845  *
       
  6846  * [NS 11] Attribute ::= QName Eq AttValue
       
  6847  *
       
  6848  * Also the case QName == xmlns:??? is handled independently as a namespace
       
  6849  * definition.
       
  6850  *
       
  6851  * Returns the attribute name, and the value in *value.
       
  6852  */
       
  6853 
       
  6854 XMLPUBFUNEXPORT const xmlChar *
       
  6855 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
       
  6856     const xmlChar *name;
       
  6857     xmlChar *val;
       
  6858 
       
  6859     *value = NULL;
       
  6860     GROW;
       
  6861     name = xmlParseName(ctxt);
       
  6862     if (name == NULL) {
       
  6863         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, EMBED_ERRTXT("error parsing attribute name\n"));
       
  6864         return(NULL);
       
  6865     }
       
  6866 
       
  6867     /*
       
  6868      * read the value
       
  6869      */
       
  6870     SKIP_BLANKS;
       
  6871     if (RAW == '=') {
       
  6872         NEXT;
       
  6873         SKIP_BLANKS;
       
  6874         val = xmlParseAttValue(ctxt);
       
  6875         ctxt->instate = XML_PARSER_CONTENT;
       
  6876     } else {
       
  6877         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
       
  6878           EMBED_ERRTXT("Specification mandate value for attribute %s\n"), name);
       
  6879         return(NULL);
       
  6880     }
       
  6881 
       
  6882     /*
       
  6883      * Check that xml:lang conforms to the specification
       
  6884      * No more registered as an error, just generate a warning now
       
  6885      * since this was deprecated in XML second edition
       
  6886      */
       
  6887     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
       
  6888         if (!xmlCheckLanguageID(val)) {
       
  6889             xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
       
  6890                         EMBED_ERRTXT("Malformed value for xml:lang : %s\n"),
       
  6891                         val, NULL);
       
  6892         }
       
  6893     }
       
  6894 
       
  6895     /*
       
  6896      * Check that xml:space conforms to the specification
       
  6897      */
       
  6898     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
       
  6899         if (xmlStrEqual(val, BAD_CAST "default"))
       
  6900             *(ctxt->space) = 0;
       
  6901         else if (xmlStrEqual(val, BAD_CAST "preserve"))
       
  6902             *(ctxt->space) = 1;
       
  6903         else {
       
  6904             xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
       
  6905                 EMBED_ERRTXT("Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n"),
       
  6906                 val);
       
  6907         }
       
  6908     }
       
  6909 
       
  6910     *value = val;
       
  6911     return(name);
       
  6912 }
       
  6913 
       
  6914 /**
       
  6915  * xmlParseStartTag:
       
  6916  * @param ctxt an XML parser context
       
  6917  *
       
  6918  * parse a start of tag either for rule element or
       
  6919  * EmptyElement. In both case we don't parse the tag closing chars.
       
  6920  *
       
  6921  * [40] STag ::= '<' Name (S Attribute)* S? '>'
       
  6922  *
       
  6923  * [ WFC: Unique Att Spec ]
       
  6924  * No attribute name may appear more than once in the same start-tag or
       
  6925  * empty-element tag.
       
  6926  *
       
  6927  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
       
  6928  *
       
  6929  * [ WFC: Unique Att Spec ]
       
  6930  * No attribute name may appear more than once in the same start-tag or
       
  6931  * empty-element tag.
       
  6932  *
       
  6933  * With namespace:
       
  6934  *
       
  6935  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
       
  6936  *
       
  6937  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
       
  6938  *
       
  6939  * Returns the element name parsed
       
  6940  */
       
  6941 
       
  6942 XMLPUBFUNEXPORT const xmlChar *
       
  6943 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
       
  6944     const xmlChar *name;
       
  6945     const xmlChar *attname;
       
  6946     xmlChar *attvalue;
       
  6947     const xmlChar **atts = ctxt->atts;
       
  6948     int nbatts = 0;
       
  6949     int maxatts = ctxt->maxatts;
       
  6950     int i;
       
  6951 
       
  6952     if (RAW != '<') return(NULL);
       
  6953     NEXT1;
       
  6954 
       
  6955     name = xmlParseName(ctxt);
       
  6956     if (name == NULL) {
       
  6957     xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
       
  6958          EMBED_ERRTXT("xmlParseStartTag: invalid element name\n"));
       
  6959         return(NULL);
       
  6960     }
       
  6961 
       
  6962     /*
       
  6963      * Now parse the attributes, it ends up with the ending
       
  6964      *
       
  6965      * (S Attribute)* S?
       
  6966      */
       
  6967     SKIP_BLANKS;
       
  6968     GROW;
       
  6969 
       
  6970     while ((RAW != '>') &&
       
  6971        ((RAW != '/') || (NXT(1) != '>')) &&
       
  6972        (IS_BYTE_CHAR(RAW))) {
       
  6973     const xmlChar *q = CUR_PTR;
       
  6974     unsigned int cons = ctxt->input->consumed;
       
  6975 
       
  6976     attname = xmlParseAttribute(ctxt, &attvalue);
       
  6977         if ((attname != NULL) && (attvalue != NULL)) {
       
  6978         /*
       
  6979          * [ WFC: Unique Att Spec ]
       
  6980          * No attribute name may appear more than once in the same
       
  6981          * start-tag or empty-element tag.
       
  6982          */
       
  6983         for (i = 0; i < nbatts;i += 2) {
       
  6984             if (xmlStrEqual(atts[i], attname)) {
       
  6985             xmlErrAttributeDup(ctxt, NULL, attname);
       
  6986             xmlFree(attvalue);
       
  6987             goto failed;
       
  6988         }
       
  6989         }
       
  6990         /*
       
  6991          * Add the pair to atts
       
  6992          */
       
  6993         if (atts == NULL) {
       
  6994             maxatts = 22; /* allow for 10 attrs by default */
       
  6995             atts = (const xmlChar **)
       
  6996                xmlMalloc(maxatts * sizeof(xmlChar *));
       
  6997         if (atts == NULL) {
       
  6998             xmlParserOOMErr(ctxt);
       
  6999             if (attvalue != NULL)
       
  7000                 xmlFree(attvalue);
       
  7001             goto failed;
       
  7002         }
       
  7003         ctxt->atts = atts;
       
  7004         ctxt->maxatts = maxatts;
       
  7005         } else if (nbatts + 4 > maxatts) {
       
  7006             const xmlChar **n;
       
  7007 
       
  7008             maxatts *= 2;
       
  7009             n = (const xmlChar **) xmlRealloc((void *) atts,
       
  7010                          maxatts * sizeof(const xmlChar *));
       
  7011         if (n == NULL) {
       
  7012             xmlParserOOMErr(ctxt);
       
  7013             if (attvalue != NULL)
       
  7014                 xmlFree(attvalue);
       
  7015             goto failed;
       
  7016         }
       
  7017         atts = n;
       
  7018         ctxt->atts = atts;
       
  7019         ctxt->maxatts = maxatts;
       
  7020         }
       
  7021         atts[nbatts++] = attname;
       
  7022         atts[nbatts++] = attvalue;
       
  7023         atts[nbatts] = NULL;
       
  7024         atts[nbatts + 1] = NULL;
       
  7025     } else {
       
  7026         if (attvalue != NULL)
       
  7027         xmlFree(attvalue);
       
  7028     }
       
  7029 
       
  7030 failed:
       
  7031 
       
  7032     GROW
       
  7033     if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
       
  7034         break;
       
  7035     if (!IS_BLANK_CH(RAW)) {
       
  7036         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  7037                EMBED_ERRTXT("attributes construct error\n"));
       
  7038     }
       
  7039     SKIP_BLANKS;
       
  7040         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
       
  7041             (attname == NULL) && (attvalue == NULL)) {
       
  7042         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
       
  7043                EMBED_ERRTXT("xmlParseStartTag: problem parsing attributes\n"));
       
  7044         break;
       
  7045     }
       
  7046     SHRINK;
       
  7047         GROW;
       
  7048     }
       
  7049 
       
  7050     /*
       
  7051      * SAX: Start of Element !
       
  7052      */
       
  7053     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
       
  7054     (!ctxt->disableSAX)) {
       
  7055     if (nbatts > 0)
       
  7056         ctxt->sax->startElement(ctxt->userData, name, atts);
       
  7057     else
       
  7058         ctxt->sax->startElement(ctxt->userData, name, NULL);
       
  7059     }
       
  7060 
       
  7061     if (atts != NULL) {
       
  7062         /* Free only the content strings */
       
  7063         for (i = 1;i < nbatts;i+=2)
       
  7064         if (atts[i] != NULL)
       
  7065            xmlFree((xmlChar *) atts[i]);
       
  7066     }
       
  7067     return(name);
       
  7068 }
       
  7069 
       
  7070 /**
       
  7071  * xmlParseEndTag1:
       
  7072  * @param ctxt an XML parser context
       
  7073  * @param line line of the start tag
       
  7074  * @param nsNr number of namespaces on the start tag
       
  7075  *
       
  7076  * parse an end of tag
       
  7077  *
       
  7078  * [42] ETag ::= '</' Name S? '>'
       
  7079  *
       
  7080  * With namespace
       
  7081  *
       
  7082  * [NS 9] ETag ::= '</' QName S? '>'
       
  7083  */
       
  7084 
       
  7085 static void
       
  7086 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
       
  7087     const xmlChar *name;
       
  7088 
       
  7089     GROW;
       
  7090     if ((RAW != '<') || (NXT(1) != '/')) {
       
  7091     xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
       
  7092                EMBED_ERRTXT("xmlParseEndTag: '</' not found\n"));
       
  7093     return;
       
  7094     }
       
  7095     SKIP(2);
       
  7096 
       
  7097     name = xmlParseNameAndCompare(ctxt,ctxt->name);
       
  7098 
       
  7099     /*
       
  7100      * We should definitely be at the ending "S? '>'" part
       
  7101      */
       
  7102     GROW;
       
  7103     SKIP_BLANKS;
       
  7104     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
       
  7105     xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
       
  7106     } else
       
  7107     NEXT1;
       
  7108 
       
  7109     /*
       
  7110      * [ WFC: Element Type Match ]
       
  7111      * The Name in an element's end-tag must match the element type in the
       
  7112      * start-tag.
       
  7113      *
       
  7114      */
       
  7115     if (name != (xmlChar*)1) {
       
  7116         if (name == NULL) name = BAD_CAST "unparseable";
       
  7117         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
       
  7118              EMBED_ERRTXT("Opening and ending tag mismatch: %s line %d and %s\n"),
       
  7119                         ctxt->name, line, name);
       
  7120     }
       
  7121 
       
  7122     /*
       
  7123      * SAX: End of Tag
       
  7124      */
       
  7125     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
       
  7126     (!ctxt->disableSAX))
       
  7127         ctxt->sax->endElement(ctxt->userData, ctxt->name);
       
  7128 
       
  7129     namePop(ctxt);
       
  7130     spacePop(ctxt);
       
  7131     return;
       
  7132 }
       
  7133 
       
  7134 /**
       
  7135  * xmlParseEndTag:
       
  7136  * @param ctxt an XML parser context
       
  7137  *
       
  7138  * parse an end of tag
       
  7139  *
       
  7140  * [42] ETag ::= '</' Name S? '>'
       
  7141  *
       
  7142  * With namespace
       
  7143  *
       
  7144  * [NS 9] ETag ::= '</' QName S? '>'
       
  7145  */
       
  7146 
       
  7147 XMLPUBFUNEXPORT void
       
  7148 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
       
  7149     xmlParseEndTag1(ctxt, 0);
       
  7150 }
       
  7151 #endif /* LIBXML_SAX1_ENABLED */
       
  7152 
       
  7153 /************************************************************************
       
  7154  *                                                                      *
       
  7155  *            SAX 2 specific operations                                 *
       
  7156  *                                                                      *
       
  7157  ************************************************************************/
       
  7158 
       
  7159 static const xmlChar *
       
  7160 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
       
  7161     int len = 0, l;
       
  7162     int c;
       
  7163     int count = 0;
       
  7164 
       
  7165     /*
       
  7166      * Handler for more complex cases
       
  7167      */
       
  7168     GROW;
       
  7169     c = CUR_CHAR(l);
       
  7170     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
       
  7171     (!IS_LETTER(c) && (c != '_'))) {
       
  7172     return(NULL);
       
  7173     }
       
  7174 
       
  7175     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
       
  7176        ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
       
  7177             (c == '.') || (c == '-') || (c == '_') ||
       
  7178         (IS_COMBINING(c)) ||
       
  7179         (IS_EXTENDER(c)))) {
       
  7180     if (count++ > 100) {
       
  7181         count = 0;
       
  7182         GROW;
       
  7183     }
       
  7184     len += l;
       
  7185     NEXTL(l);
       
  7186     c = CUR_CHAR(l);
       
  7187     }
       
  7188     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
       
  7189 }
       
  7190 
       
  7191 /*
       
  7192  * xmlGetNamespace:
       
  7193  * @param ctxt an XML parser context
       
  7194  * @param prefix the prefix to lookup
       
  7195  *
       
  7196  * Lookup the namespace name for the prefix (which can be NULL)
       
  7197  * The prefix must come from the ctxt->dict dictionary
       
  7198  *
       
  7199  * Returns the namespace name or NULL if not bound
       
  7200  */
       
  7201 static const xmlChar*
       
  7202 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix)
       
  7203 {
       
  7204     int i;
       
  7205 
       
  7206     if (prefix == ctxt->str_xml)
       
  7207         return(ctxt->str_xml_ns);
       
  7208 
       
  7209     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
       
  7210         if (ctxt->nsTab[i] == prefix) {
       
  7211             if (!prefix && (*ctxt->nsTab[i + 1] == 0))
       
  7212                 return(NULL);
       
  7213             return(ctxt->nsTab[i + 1]);
       
  7214         }
       
  7215     return(NULL);
       
  7216 }
       
  7217 
       
  7218 /**
       
  7219  * xmlParseNCName:
       
  7220  * @param ctxt an XML parser context
       
  7221  * @param len lenght of the string parsed
       
  7222  *
       
  7223  * parse an XML name.
       
  7224  *
       
  7225  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
       
  7226  *                      CombiningChar | Extender
       
  7227  *
       
  7228  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
       
  7229  *
       
  7230  * Returns the Name parsed or NULL
       
  7231  */
       
  7232 
       
  7233 static const xmlChar*
       
  7234 xmlParseNCName(xmlParserCtxtPtr ctxt)
       
  7235 {
       
  7236     const xmlChar* in;
       
  7237     const xmlChar* ret;
       
  7238 
       
  7239     /*
       
  7240      * Accelerator for simple ASCII names
       
  7241      */
       
  7242     in = ctxt->input->cur;
       
  7243     if (((*in >= 0x61) && (*in <= 0x7A)) ||
       
  7244         ((*in >= 0x41) && (*in <= 0x5A)) ||
       
  7245         (*in == '_'))
       
  7246     {
       
  7247         in++;
       
  7248         while (((*in >= 0x61) && (*in <= 0x7A)) ||
       
  7249                ((*in >= 0x41) && (*in <= 0x5A)) ||
       
  7250                ((*in >= 0x30) && (*in <= 0x39)) ||
       
  7251                (*in == '_') || (*in == '-') ||
       
  7252                (*in == '.'))
       
  7253         {
       
  7254             in++;
       
  7255         }
       
  7256         if ((*in > 0) && (*in < 0x80))
       
  7257         {
       
  7258             int count = in - ctxt->input->cur;
       
  7259             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
       
  7260             ctxt->input->cur = in;
       
  7261             ctxt->nbChars += count;
       
  7262             ctxt->input->col += count;
       
  7263             if (!ret) {
       
  7264                 xmlParserOOMErr(ctxt);
       
  7265             }
       
  7266             return(ret);
       
  7267         }
       
  7268     }
       
  7269     return(xmlParseNCNameComplex(ctxt));
       
  7270 }
       
  7271 
       
  7272 /**
       
  7273  * xmlParseQName:
       
  7274  * @param ctxt an XML parser context
       
  7275  * @param prefix pointer to store the prefix part
       
  7276  *
       
  7277  * parse an XML Namespace QName
       
  7278  *
       
  7279  * [6]  QName  ::= (Prefix ':')? LocalPart
       
  7280  * [7]  Prefix  ::= NCName
       
  7281  * [8]  LocalPart  ::= NCName
       
  7282  *
       
  7283  * Returns the Name parsed or NULL
       
  7284  */
       
  7285 
       
  7286 static const xmlChar *
       
  7287 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
       
  7288     const xmlChar *l, *p;
       
  7289 
       
  7290     GROW;
       
  7291 
       
  7292     l = xmlParseNCName(ctxt);
       
  7293     if (l == NULL) {
       
  7294         if (CUR == ':') {
       
  7295             l = xmlParseName(ctxt);
       
  7296             if (l != NULL) {
       
  7297                 xmlNsErr(ctxt, XML_NS_ERR_QNAME, EMBED_ERRTXT("Failed to parse QName '%s'\n"), l, NULL, NULL);
       
  7298                 *prefix = NULL;
       
  7299                 return(l);
       
  7300             }
       
  7301         }
       
  7302         return(NULL);
       
  7303     }
       
  7304     if (CUR == ':') {
       
  7305         NEXT;
       
  7306         p = l;
       
  7307         l = xmlParseNCName(ctxt);
       
  7308         if (l == NULL) {
       
  7309             xmlChar *tmp;
       
  7310             xmlNsErr(ctxt, XML_NS_ERR_QNAME, EMBED_ERRTXT("Failed to parse QName '%s:'\n"), p, NULL, NULL);
       
  7311             tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
       
  7312             p = xmlDictLookup(ctxt->dict, tmp, -1);
       
  7313             if (tmp != NULL)
       
  7314                 xmlFree(tmp);
       
  7315             *prefix = NULL;
       
  7316             return(p);
       
  7317         }
       
  7318         if (CUR == ':') {
       
  7319             xmlChar *tmp;
       
  7320             xmlNsErr(ctxt, XML_NS_ERR_QNAME, EMBED_ERRTXT("Failed to parse QName '%s:%s:'\n"), p, l, NULL);
       
  7321             NEXT;
       
  7322             tmp = (xmlChar *) xmlParseName(ctxt);
       
  7323             if (tmp != NULL) {
       
  7324                 tmp = xmlBuildQName(tmp, l, NULL, 0);
       
  7325                 l = xmlDictLookup(ctxt->dict, tmp, -1);
       
  7326                 if (tmp != NULL) xmlFree(tmp);
       
  7327                 *prefix = p;
       
  7328                 return(l);
       
  7329             }
       
  7330             tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
       
  7331             l = xmlDictLookup(ctxt->dict, tmp, -1);
       
  7332             if (tmp != NULL)
       
  7333                 xmlFree(tmp);
       
  7334             *prefix = p;
       
  7335             return(l);
       
  7336         }
       
  7337         *prefix = p;
       
  7338     } else
       
  7339         *prefix = NULL;
       
  7340     return(l);
       
  7341 }
       
  7342 
       
  7343 /**
       
  7344  * xmlParseQNameAndCompare:
       
  7345  * @param ctxt an XML parser context
       
  7346  * @param name the localname
       
  7347  * @param prefix the prefix, if any.
       
  7348  *
       
  7349  * parse an XML name and compares for match
       
  7350  * (specialized for endtag parsing)
       
  7351  *
       
  7352  * Returns NULL for an illegal name, (xmlChar*) 1 for success
       
  7353  * and the name for mismatch
       
  7354  */
       
  7355 
       
  7356 static const xmlChar *
       
  7357 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
       
  7358                         xmlChar const *prefix) {
       
  7359     const xmlChar *cmp = name;
       
  7360     const xmlChar *in;
       
  7361     const xmlChar *ret;
       
  7362     const xmlChar *prefix2;
       
  7363 
       
  7364     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
       
  7365 
       
  7366     GROW;
       
  7367     in = ctxt->input->cur;
       
  7368 
       
  7369     cmp = prefix;
       
  7370     while (*in != 0 && *in == *cmp) {
       
  7371         ++in;
       
  7372     ++cmp;
       
  7373     }
       
  7374     if ((*cmp == 0) && (*in == ':')) {
       
  7375         in++;
       
  7376     cmp = name;
       
  7377     while (*in != 0 && *in == *cmp) {
       
  7378         ++in;
       
  7379         ++cmp;
       
  7380     }
       
  7381     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
       
  7382         /* success */
       
  7383         ctxt->input->cur = in;
       
  7384         return((const xmlChar*) 1);
       
  7385     }
       
  7386     }
       
  7387     /*
       
  7388      * all strings coms from the dictionary, equality can be done directly
       
  7389      */
       
  7390     ret = xmlParseQName (ctxt, &prefix2);
       
  7391     if ((ret == name) && (prefix == prefix2))
       
  7392     return((const xmlChar*) 1);
       
  7393     return ret;
       
  7394 }
       
  7395 
       
  7396 /**
       
  7397  * xmlParseAttValueInternal:
       
  7398  * @param ctxt an XML parser context
       
  7399  * @param len attribute len result
       
  7400  * @param alloc whether the attribute was reallocated as a new string
       
  7401  * @param normalize if 1 then further non-CDATA normalization must be done
       
  7402  *
       
  7403  * parse a value for an attribute.
       
  7404  * NOTE: if no normalization is needed, the routine will return pointers
       
  7405  *       directly from the data buffer.
       
  7406  *
       
  7407  * 3.3.3 Attribute-Value Normalization:
       
  7408  * Before the value of an attribute is passed to the application or
       
  7409  * checked for validity, the XML processor must normalize it as follows:
       
  7410  * - a character reference is processed by appending the referenced
       
  7411  *   character to the attribute value
       
  7412  * - an entity reference is processed by recursively processing the
       
  7413  *   replacement text of the entity
       
  7414  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
       
  7415  *   appending #x20 to the normalized value, except that only a single
       
  7416  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
       
  7417  *   parsed entity or the literal entity value of an internal parsed entity
       
  7418  * - other characters are processed by appending them to the normalized value
       
  7419  * If the declared value is not CDATA, then the XML processor must further
       
  7420  * process the normalized attribute value by discarding any leading and
       
  7421  * trailing space (#x20) characters, and by replacing sequences of space
       
  7422  * (#x20) characters by a single space (#x20) character.
       
  7423  * All attributes for which no declaration has been read should be treated
       
  7424  * by a non-validating parser as if declared CDATA.
       
  7425  *
       
  7426  * Returns the AttValue parsed or NULL. The value has to be freed by the
       
  7427  *     caller if it was copied, this can be detected by val[*len] == 0.
       
  7428  */
       
  7429 
       
  7430 static xmlChar *
       
  7431 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
       
  7432                          int normalize)
       
  7433 {
       
  7434     xmlChar limit = 0;
       
  7435     const xmlChar *in = NULL, *start, *end, *last;
       
  7436     xmlChar *ret = NULL;
       
  7437 
       
  7438     GROW;
       
  7439     in = (xmlChar *) CUR_PTR;
       
  7440     if (*in != '"' && *in != '\'') {
       
  7441         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
       
  7442         return (NULL);
       
  7443     }
       
  7444     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
       
  7445 
       
  7446     /*
       
  7447      * try to handle in this routine the most common case where no
       
  7448      * allocation of a new string is required and where content is
       
  7449      * pure ASCII.
       
  7450      */
       
  7451     limit = *in++;
       
  7452     end = ctxt->input->end;
       
  7453     start = in;
       
  7454     if (in >= end) {
       
  7455         const xmlChar *oldbase = ctxt->input->base;
       
  7456         GROW;
       
  7457         if (oldbase != ctxt->input->base) {
       
  7458             long delta = ctxt->input->base - oldbase;
       
  7459             start = start + delta;
       
  7460             in = in + delta;
       
  7461         }
       
  7462         end = ctxt->input->end;
       
  7463     }
       
  7464     if (normalize) {
       
  7465         /*
       
  7466         * Skip any leading spaces
       
  7467         */
       
  7468         while ((in < end) && (*in != limit) &&
       
  7469                ((*in == 0x20) || (*in == 0x9) ||
       
  7470                 (*in == 0xA)  || (*in == 0xD)))
       
  7471         {
       
  7472             in++;
       
  7473             start = in;
       
  7474             if (in >= end) {
       
  7475                 const xmlChar *oldbase = ctxt->input->base;
       
  7476                 GROW;
       
  7477                 if (oldbase != ctxt->input->base) {
       
  7478                     long delta = ctxt->input->base - oldbase;
       
  7479                     start = start + delta;
       
  7480                     in = in + delta;
       
  7481                 }
       
  7482                 end = ctxt->input->end;
       
  7483             }
       
  7484         }
       
  7485         while (( in < end)   && (*in != limit) &&
       
  7486                (*in >= 0x20) && (*in <= 0x7f) && (*in != '&') && (*in != '<'))
       
  7487         {
       
  7488             if ((*in++ == 0x20) && (*in == 0x20)) break;
       
  7489             if (in >= end) {
       
  7490                 const xmlChar *oldbase = ctxt->input->base;
       
  7491                 GROW;
       
  7492                 if (oldbase != ctxt->input->base) {
       
  7493                     long delta = ctxt->input->base - oldbase;
       
  7494                     start = start + delta;
       
  7495                     in = in + delta;
       
  7496                 }
       
  7497                 end = ctxt->input->end;
       
  7498             }
       
  7499         }
       
  7500         last = in;
       
  7501         /*
       
  7502         * skip the trailing blanks
       
  7503         */
       
  7504         while ((last[-1] == 0x20) && (last > start)) last--;
       
  7505         while ((in < end) && (*in != limit) &&
       
  7506                ((*in == 0x20) || (*in == 0x9) || (*in == 0xA) || (*in == 0xD)))
       
  7507         {
       
  7508             in++;
       
  7509             if (in >= end) {
       
  7510                 const xmlChar *oldbase = ctxt->input->base;
       
  7511                 GROW;
       
  7512                 if (oldbase != ctxt->input->base) {
       
  7513                     long delta = ctxt->input->base - oldbase;
       
  7514                     start = start + delta;
       
  7515                     in = in + delta;
       
  7516                     last = last + delta;
       
  7517                 }
       
  7518                 end = ctxt->input->end;
       
  7519             }
       
  7520         }
       
  7521         if (*in != limit) goto need_complex;
       
  7522     } // if (normalize)
       
  7523     else
       
  7524     { // if (!normalize)
       
  7525         while ((in < end) && (*in != limit) &&
       
  7526                (*in >= 0x20) && (*in <= 0x7f) && (*in != '&') && (*in != '<'))
       
  7527         {
       
  7528             in++;
       
  7529             if (in >= end) {
       
  7530                 const xmlChar *oldbase = ctxt->input->base;
       
  7531                 GROW;
       
  7532                 if (oldbase != ctxt->input->base) {
       
  7533                     long delta = ctxt->input->base - oldbase;
       
  7534                     start = start + delta;
       
  7535                     in = in + delta;
       
  7536                 }
       
  7537                 end = ctxt->input->end;
       
  7538             }
       
  7539         }
       
  7540         last = in;
       
  7541         if (*in != limit) goto need_complex;
       
  7542     } // if (!normalize)
       
  7543 
       
  7544     in++;
       
  7545     if (len != NULL) {
       
  7546         *len = last - start;
       
  7547         ret = (xmlChar *) start;
       
  7548     } else {
       
  7549         if (alloc) *alloc = 1;
       
  7550         ret = xmlStrndup(start, last - start);
       
  7551     }
       
  7552     CUR_PTR = in;
       
  7553     if (alloc) *alloc = 0;
       
  7554     return ret;
       
  7555 
       
  7556 need_complex:
       
  7557     if (alloc) *alloc = 1;
       
  7558     return xmlParseAttValueComplex(ctxt, len, normalize);
       
  7559 }
       
  7560 
       
  7561 /**
       
  7562  * xmlParseAttribute2:
       
  7563  * @param ctxt an XML parser context
       
  7564  * @param pref the element prefix
       
  7565  * @param elem the element name
       
  7566  * @param prefix a xmlChar ** used to store the value of the attribute prefix
       
  7567  * @param value a xmlChar ** used to store the value of the attribute
       
  7568  * @param len an int * to save the length of the attribute
       
  7569  * @param alloc an int * to indicate if the attribute was allocated
       
  7570  *
       
  7571  * parse an attribute in the new SAX2 framework.
       
  7572  *
       
  7573  * Returns the attribute name, and the value in *value, .
       
  7574  */
       
  7575 
       
  7576 static const xmlChar *
       
  7577 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
       
  7578                    const xmlChar *pref, const xmlChar *elem,
       
  7579                    const xmlChar **prefix, xmlChar **value,
       
  7580                    int *len, int *alloc) {
       
  7581     const xmlChar *name;
       
  7582     xmlChar *val;
       
  7583     int normalize = 0;
       
  7584 
       
  7585     *value = NULL;
       
  7586     GROW;
       
  7587     name = xmlParseQName(ctxt, prefix);
       
  7588     if (name == NULL) {
       
  7589         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, EMBED_ERRTXT("error parsing attribute name\n"));
       
  7590         return(NULL);
       
  7591     }
       
  7592 
       
  7593     /*
       
  7594      * get the type if needed
       
  7595      */
       
  7596     if (ctxt->attsSpecial != NULL) {
       
  7597         int type;
       
  7598 
       
  7599         type = (int)(long)xmlHashQLookup2(ctxt->attsSpecial, pref, elem, *prefix, name);
       
  7600         if (type != 0) normalize = 1;
       
  7601     }
       
  7602 
       
  7603     /*
       
  7604      * read the value
       
  7605      */
       
  7606     SKIP_BLANKS;
       
  7607     if (RAW == '=') {
       
  7608         NEXT;
       
  7609         SKIP_BLANKS;
       
  7610         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
       
  7611         ctxt->instate = XML_PARSER_CONTENT;
       
  7612     } else {
       
  7613         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
       
  7614            EMBED_ERRTXT("Specification mandate value for attribute %s\n"), name);
       
  7615         return(NULL);
       
  7616     }
       
  7617 
       
  7618     /*
       
  7619      * Check that xml:lang conforms to the specification
       
  7620      * No more registered as an error, just generate a warning now
       
  7621      * since this was deprecated in XML second edition
       
  7622      */
       
  7623     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
       
  7624         if (!xmlCheckLanguageID(val)) {
       
  7625             xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
       
  7626                   EMBED_ERRTXT("Malformed value for xml:lang : %s\n"),
       
  7627                     val, NULL);
       
  7628         }
       
  7629     }
       
  7630 
       
  7631     /*
       
  7632      * Check that xml:space conforms to the specification
       
  7633      */
       
  7634     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
       
  7635         if (xmlStrEqual(val, BAD_CAST "default"))
       
  7636             *(ctxt->space) = 0;
       
  7637         else if (xmlStrEqual(val, BAD_CAST "preserve"))
       
  7638             *(ctxt->space) = 1;
       
  7639         else {
       
  7640             xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
       
  7641                     EMBED_ERRTXT("Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n"),
       
  7642                     val);
       
  7643         }
       
  7644     }
       
  7645 
       
  7646     *value = val;
       
  7647     return(name);
       
  7648 }
       
  7649 
       
  7650 /**
       
  7651  * xmlParseStartTag2:
       
  7652  * @param ctxt an XML parser context
       
  7653  *
       
  7654  * parse a start of tag either for rule element or
       
  7655  * EmptyElement. In both case we don't parse the tag closing chars.
       
  7656  * This routine is called when running SAX2 parsing
       
  7657  *
       
  7658  * [40] STag ::= '<' Name (S Attribute)* S? '>'
       
  7659  *
       
  7660  * [ WFC: Unique Att Spec ]
       
  7661  * No attribute name may appear more than once in the same start-tag or
       
  7662  * empty-element tag.
       
  7663  *
       
  7664  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
       
  7665  *
       
  7666  * [ WFC: Unique Att Spec ]
       
  7667  * No attribute name may appear more than once in the same start-tag or
       
  7668  * empty-element tag.
       
  7669  *
       
  7670  * With namespace:
       
  7671  *
       
  7672  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
       
  7673  *
       
  7674  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
       
  7675  *
       
  7676  * Returns the element name parsed
       
  7677  *
       
  7678  * OOM: possible --> check OOM flag / NULL is returned too
       
  7679  */
       
  7680 
       
  7681 static const xmlChar *
       
  7682 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
       
  7683                   const xmlChar **URI, int *tlen)
       
  7684 {
       
  7685     const xmlChar *localname;
       
  7686     const xmlChar *prefix;
       
  7687     const xmlChar *attname;
       
  7688     const xmlChar *aprefix;
       
  7689     const xmlChar *nsname;
       
  7690     xmlChar *attvalue; // = NULL : unneeded initialization -- done by xmlParseAttribute2
       
  7691     const xmlChar **atts = ctxt->atts;
       
  7692     int maxatts = ctxt->maxatts;
       
  7693     int nratts, nbatts, nbdef;
       
  7694     int i, j, nbNs, attval;
       
  7695     const xmlChar *base;
       
  7696     unsigned long cur;
       
  7697     LOAD_GS_SAFE_CTXT(ctxt)
       
  7698 
       
  7699     if (RAW != '<')
       
  7700         return(NULL);
       
  7701     NEXT1;
       
  7702 
       
  7703     /*
       
  7704      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
       
  7705      *       point since the attribute values may be stored as pointers to
       
  7706      *       the buffer and calling SHRINK would destroy them !
       
  7707      *       The Shrinking is only possible once the full set of attribute
       
  7708      *       callbacks have been done.
       
  7709      */
       
  7710 reparse:
       
  7711     SHRINK;
       
  7712     base = ctxt->input->base;
       
  7713     cur = ctxt->input->cur - ctxt->input->base;
       
  7714     nbatts = 0;
       
  7715     nratts = 0;
       
  7716     nbdef = 0;
       
  7717     nbNs = 0;
       
  7718     attval = 0;
       
  7719 
       
  7720     localname = xmlParseQName(ctxt, &prefix);
       
  7721     if (localname == NULL) {
       
  7722         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, EMBED_ERRTXT("StartTag: invalid element name\n"));
       
  7723         return(NULL);
       
  7724     }
       
  7725 
       
  7726     *tlen = ctxt->input->cur - ctxt->input->base - cur;
       
  7727 
       
  7728     /*
       
  7729      * Now parse the attributes, it ends up with the ending
       
  7730      *
       
  7731      * (S Attribute)* S?
       
  7732      */
       
  7733 
       
  7734     SKIP_BLANKS;
       
  7735     GROW;
       
  7736 
       
  7737     if (ctxt->input->base != base)
       
  7738         goto base_changed;
       
  7739 
       
  7740     while ((RAW != '>') &&
       
  7741            ((RAW != '/') || (NXT(1) != '>')) &&
       
  7742            (IS_BYTE_CHAR(RAW)))
       
  7743     {
       
  7744         // Parse one attribute
       
  7745 
       
  7746         const xmlChar *q = CUR_PTR;
       
  7747         unsigned int cons = ctxt->input->consumed;
       
  7748         int len = -1, alloc = 0;
       
  7749 
       
  7750         attname = xmlParseAttribute2(ctxt, prefix, localname, &aprefix, &attvalue, &len, &alloc);
       
  7751         if ((attname != NULL) && (attvalue != NULL))
       
  7752         {
       
  7753             // if 'len' has not changed, then there was memory allocation
       
  7754             // (because of complex, expanded attribute value)
       
  7755             if (len < 0)
       
  7756                 len = xmlStrlen(attvalue);
       
  7757 
       
  7758             if ((attname == ctxt->str_xmlns) && (aprefix == NULL))
       
  7759             {
       
  7760                 // we have [ xmlns="uri" ] - a default namespace definition
       
  7761                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
       
  7762                 xmlURIPtr uri;
       
  7763 
       
  7764                 if(!URL)
       
  7765                     goto OOM;
       
  7766 
       
  7767                 if (*URL != 0) {
       
  7768                     uri = xmlParseURI((const char *) URL);
       
  7769                     if (uri == NULL) {
       
  7770                         if(OOM_FLAG)goto OOM;
       
  7771                         xmlWarningMsg(ctxt, XML_WAR_NS_URI,
       
  7772                             EMBED_ERRTXT("xmlns: %s not a valid URI\n"), URL, NULL);
       
  7773                     } else {
       
  7774                         if (uri->scheme == NULL) {
       
  7775                             xmlWarningMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
       
  7776                                 EMBED_ERRTXT("xmlns: URI %s is not absolute\n"), URL, NULL);
       
  7777                         }
       
  7778                         xmlFreeURI(uri);
       
  7779                     }
       
  7780                 }
       
  7781                 /*
       
  7782                 * check that it's not a defined namespace
       
  7783                 */
       
  7784                 for (j = 1;j <= nbNs;j++)
       
  7785                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
       
  7786                         break;
       
  7787 
       
  7788                 if (j <= nbNs){
       
  7789                     xmlErrAttributeDup(ctxt, NULL, attname);
       
  7790                 }else{
       
  7791                     // SAX2 startPrefixMapping callback is invoked in nsPush
       
  7792                     if (nsPush(ctxt, NULL, URL) > 0)
       
  7793                         nbNs++;
       
  7794                 }
       
  7795                 if (alloc != 0)
       
  7796                     xmlFree(attvalue);
       
  7797 
       
  7798                 SKIP_BLANKS;
       
  7799                 continue;
       
  7800             }
       
  7801 
       
  7802             if (aprefix == ctxt->str_xmlns)
       
  7803             {
       
  7804                 // we have [ xmlns:prefix="uri" ] - a prefix mapping definition
       
  7805                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
       
  7806                 xmlURIPtr uri;
       
  7807 
       
  7808                 if (attname == ctxt->str_xml) {
       
  7809                     if (URL != ctxt->str_xml_ns) {
       
  7810                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
       
  7811                                 EMBED_ERRTXT("xml namespace prefix mapped to wrong URI\n"),
       
  7812                                 NULL, NULL, NULL);
       
  7813                     }
       
  7814                     /*
       
  7815                     * Do not keep a namespace definition node
       
  7816                     */
       
  7817                     if (alloc != 0) xmlFree(attvalue);
       
  7818                     SKIP_BLANKS;
       
  7819                     continue;
       
  7820                 } // attname == ctxt->str_xml
       
  7821 
       
  7822                 uri = xmlParseURI((const char *) URL);
       
  7823                 if (uri == NULL) {
       
  7824                     xmlWarningMsg(ctxt, XML_WAR_NS_URI,
       
  7825                         EMBED_ERRTXT("xmlns:%s: '%s' is not a valid URI\n"), attname, URL);
       
  7826                 } else {
       
  7827                     if ((ctxt->pedantic) && (uri->scheme == NULL)) {
       
  7828                         xmlWarningMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
       
  7829                             EMBED_ERRTXT("xmlns:%s: URI %s is not absolute\n"), attname, URL);
       
  7830                     }
       
  7831                     xmlFreeURI(uri);
       
  7832                 } // uri == NULL
       
  7833 
       
  7834                 /*
       
  7835                 * check that it's not a defined namespace
       
  7836                 */
       
  7837                 for (j = 1;j <= nbNs;j++)
       
  7838                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
       
  7839                         break;
       
  7840                 if (j <= nbNs){
       
  7841                     xmlErrAttributeDup(ctxt, aprefix, attname);
       
  7842                 }else{
       
  7843                     // SAX2 startPrefixMapping callback is invoked in nsPush
       
  7844                     if (nsPush(ctxt, attname, URL) > 0)
       
  7845                         nbNs++;
       
  7846                 }
       
  7847                 if (alloc != 0)
       
  7848                     xmlFree(attvalue);
       
  7849 
       
  7850                 SKIP_BLANKS;
       
  7851                 if (ctxt->input->base != base) {
       
  7852                     if (alloc != 0)
       
  7853                         xmlFree(attvalue);
       
  7854                     goto base_changed;
       
  7855                 }
       
  7856                 continue;
       
  7857             } // if (aprefix == ctxt->str_xmlns)
       
  7858 
       
  7859 
       
  7860             // If we are here, then we have parsed usual [ attribute="value" ] pair
       
  7861 
       
  7862             /*
       
  7863             * Add the pair to atts
       
  7864             */
       
  7865             if ((atts == NULL) || (nbatts + 5 > maxatts)) {
       
  7866                 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
       
  7867                     if (attvalue[len] == 0)
       
  7868                         xmlFree(attvalue);
       
  7869                     goto failed;
       
  7870                 }
       
  7871                 maxatts = ctxt->maxatts;
       
  7872                 atts = ctxt->atts;
       
  7873             }
       
  7874 
       
  7875             ctxt->attallocs[nratts++] = alloc;
       
  7876             atts[nbatts++] = attname;
       
  7877             atts[nbatts++] = aprefix;
       
  7878             atts[nbatts++] = NULL; /* the URI will be fetched later */
       
  7879             atts[nbatts++] = attvalue;
       
  7880             attvalue += len;
       
  7881             atts[nbatts++] = attvalue; // the pointer after the end of attribute is stored instead of length
       
  7882             /*
       
  7883             * tag if some deallocation is needed
       
  7884             */
       
  7885             if (alloc != 0)
       
  7886                 attval = 1;
       
  7887 
       
  7888 
       
  7889         } // if ((attname != NULL) && (attvalue != NULL))
       
  7890         else {
       
  7891             if ((attvalue != NULL) && (attvalue[len] == 0))
       
  7892                 xmlFree(attvalue);
       
  7893         }
       
  7894 
       
  7895 failed:
       
  7896 
       
  7897         GROW;
       
  7898 
       
  7899         if (ctxt->input->base != base)
       
  7900             goto base_changed;
       
  7901 
       
  7902         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
       
  7903         {
       
  7904             break; // while
       
  7905         }
       
  7906 
       
  7907         if (!IS_BLANK_CH(RAW)) {
       
  7908             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, EMBED_ERRTXT("attributes construct error\n"));
       
  7909         }
       
  7910 
       
  7911         SKIP_BLANKS;
       
  7912 
       
  7913         if ((    cons == ctxt->input->consumed  ) &&
       
  7914             (       q == CUR_PTR                ) &&
       
  7915             ( attname == NULL                   ) &&
       
  7916             (attvalue == NULL                   ))
       
  7917         {
       
  7918             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, EMBED_ERRTXT("xmlParseStartTag: problem parsing attributes\n"));
       
  7919             break; // while
       
  7920         }
       
  7921 
       
  7922         GROW;
       
  7923 
       
  7924         if (ctxt->input->base != base)
       
  7925             goto base_changed;
       
  7926 
       
  7927     } // end of while (...) //Parse one attribute
       
  7928 
       
  7929 
       
  7930     /*
       
  7931      * The attributes defaulting
       
  7932      */
       
  7933     if (ctxt->attsDefault != NULL)
       
  7934     {
       
  7935         xmlDefAttrsPtr defaults;
       
  7936         defaults = (xmlDefAttrsPtr)xmlHashLookup2(ctxt->attsDefault, localname, prefix);
       
  7937         if (defaults != NULL)
       
  7938         {
       
  7939             for (i = 0;i < defaults->nbAttrs;i++)
       
  7940             {
       
  7941                 attname = defaults->values[4 * i];
       
  7942                 aprefix = defaults->values[4 * i + 1];
       
  7943 
       
  7944                 /*
       
  7945                  * special work for namespaces defaulted defs
       
  7946                  */
       
  7947                 
       
  7948                 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
       
  7949                     /*
       
  7950                     * check that it's not a defined namespace
       
  7951                     */
       
  7952                     for (j = 1;j <= nbNs;j++)
       
  7953                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
       
  7954                             break;
       
  7955                     if (j <= nbNs)
       
  7956                         continue; // for (i = 0;i < defaults->nbAttrs;i++)
       
  7957 
       
  7958                     nsname = xmlGetNamespace(ctxt, NULL);
       
  7959 
       
  7960                     // DONE: make defaulted namespace mappings added to attributes for XmlInterface support
       
  7961                     if (nsname != defaults->values[4 * i + 2]) {
       
  7962                         // SAX2 startPrefixMapping callback is invoked in nsPush
       
  7963                         if (nsPush(ctxt, NULL, defaults->values[4 * i + 2]) > 0)
       
  7964                             nbNs++;
       
  7965                     }
       
  7966 
       
  7967                 } // (attname == ctxt->str_xmlns) && (aprefix == NULL)
       
  7968                 else
       
  7969                 if (aprefix == ctxt->str_xmlns) {
       
  7970                     /*
       
  7971                     * check that it's not a defined namespace
       
  7972                     */
       
  7973                     for (j = 1;j <= nbNs;j++)
       
  7974                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
       
  7975                             break;
       
  7976                     if (j <= nbNs)
       
  7977                         continue; // for (i = 0;i < defaults->nbAttrs;i++)
       
  7978 
       
  7979                     // DONE: make prefix-to-namespace mappings added to attributes for complete SAX2
       
  7980                     nsname = xmlGetNamespace(ctxt, attname);
       
  7981                     if (nsname != defaults->values[2]) {
       
  7982                         // SAX2 startPrefixMapping callback is invoked in nsPush
       
  7983                         if (nsPush(ctxt, attname, defaults->values[4 * i + 2]) > 0)
       
  7984                             nbNs++;
       
  7985                     }
       
  7986 
       
  7987                 } //(aprefix == ctxt->str_xmlns)
       
  7988                 else {
       
  7989                     /*
       
  7990                     * check that it's not a defined attribute
       
  7991                     */
       
  7992                     for (j = 0;j < nbatts;j+=5) {
       
  7993                         if ((attname == atts[j]) && (aprefix == atts[j+1]))
       
  7994                             break;
       
  7995                     }
       
  7996 
       
  7997                     if (j < nbatts)
       
  7998                         continue; // for (i = 0;i < defaults->nbAttrs;i++)
       
  7999 
       
  8000                     if ((atts == NULL) || (nbatts + 5 > maxatts)) {
       
  8001                         if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0)
       
  8002                             { // OOM
       
  8003                             if(attvalue)
       
  8004                                 {
       
  8005                                 xmlFree(attvalue);
       
  8006                                 }
       
  8007                            return(NULL);
       
  8008                            }
       
  8009                         maxatts = ctxt->maxatts;
       
  8010                         atts = ctxt->atts;
       
  8011                     }
       
  8012 
       
  8013                     atts[nbatts++] = attname;
       
  8014                     atts[nbatts++] = aprefix;
       
  8015                     atts[nbatts++] = aprefix ? xmlGetNamespace(ctxt, aprefix)
       
  8016                                              : aprefix /* it's NULL here */;
       
  8017                     atts[nbatts++] = defaults->values[4 * i + 2];
       
  8018                     atts[nbatts++] = defaults->values[4 * i + 3];
       
  8019                     nbdef++;
       
  8020                 }
       
  8021             } // for (i = 0;i < defaults->nbAttrs;i++)
       
  8022         } // if (defaults != NULL)
       
  8023     } // if (ctxt->attsDefault != NULL)
       
  8024 
       
  8025     /*
       
  8026      * The attributes checkings
       
  8027      */
       
  8028     for (i = 0; i < nbatts;i += 5)
       
  8029     {
       
  8030         if (atts[i + 1] != NULL) {
       
  8031 	        nsname = xmlGetNamespace(ctxt, atts[i + 1]);
       
  8032 	        if (nsname == NULL) {
       
  8033 		        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
       
  8034 		            "Namespace prefix %s for %s on %s is not defined\n",
       
  8035 		            atts[i + 1], atts[i], localname);
       
  8036     	    }
       
  8037 	        atts[i + 2] = nsname;
       
  8038 	    } else
       
  8039     	    nsname = NULL;
       
  8040 
       
  8041         /*
       
  8042         * [ WFC: Unique Att Spec ]
       
  8043         * No attribute name may appear more than once in the same
       
  8044         * start-tag or empty-element tag.
       
  8045         * As extended by the Namespace in XML REC.
       
  8046         */
       
  8047         for (j = 0; j < i;j += 5)
       
  8048         {
       
  8049             if (atts[i] == atts[j])
       
  8050             {
       
  8051                 if (atts[i+1] == atts[j+1])
       
  8052                 {
       
  8053                     xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
       
  8054                     break;
       
  8055                 }
       
  8056                 if ((nsname != NULL) && (atts[j + 2] == nsname))
       
  8057                 {
       
  8058                     xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
       
  8059                         EMBED_ERRTXT("Namespaced Attribute %s in '%s' redefined\n"),
       
  8060                         atts[i], nsname, NULL);
       
  8061                     break;
       
  8062                 }
       
  8063             }
       
  8064         } // for (i = 0; j < i; j += 5)
       
  8065     } // for (i = 0; i < nbatts; i += 5)
       
  8066 
       
  8067     // check element's namespace: if there is, then should be defined already
       
  8068     nsname = xmlGetNamespace(ctxt, prefix);
       
  8069     if ((prefix != NULL) && (nsname == NULL))
       
  8070     {
       
  8071         xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
       
  8072             EMBED_ERRTXT("Namespace prefix %s on %s is not defined\n"),
       
  8073             prefix, localname, NULL);
       
  8074     }
       
  8075 
       
  8076     *pref = prefix;
       
  8077     *URI = nsname;
       
  8078 
       
  8079     /*
       
  8080      * SAX: Start of Element !
       
  8081      */
       
  8082     if ((ctxt->sax != NULL) &&
       
  8083         (ctxt->sax->startElementNs != NULL) &&
       
  8084         (!ctxt->disableSAX))
       
  8085     {
       
  8086         
       
  8087         if (nbNs > 0)
       
  8088             {
       
  8089             ctxt->sax->startElementNs(ctxt->userData,
       
  8090                localname, prefix,
       
  8091                nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
       
  8092                nbatts / 5, nbdef, atts);
       
  8093             }
       
  8094         else
       
  8095             {
       
  8096             ctxt->sax->startElementNs(ctxt->userData,
       
  8097                 localname, prefix,
       
  8098                 nsname, 0, NULL,
       
  8099                 nbatts / 5, nbdef, atts);
       
  8100             }
       
  8101     }
       
  8102 
       
  8103     /*
       
  8104      * Free up attribute allocated strings if needed
       
  8105      */
       
  8106     if (attval != 0) {
       
  8107         for (i = 3,j = 0; j < nratts;i += 5,j++)
       
  8108             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
       
  8109                 xmlFree((xmlChar *) atts[i]);
       
  8110 		}
       
  8111     // check OOM after calling callback
       
  8112     if(OOM_FLAG)
       
  8113         {
       
  8114         goto OOM;
       
  8115         }
       
  8116 // XE: BEGIN NEW CODE - save number of newly defined (and pushed to stack) namespaces
       
  8117     ctxt->lastNsNr = nbNs;
       
  8118 // XE: END NEW CODE
       
  8119 
       
  8120     return(localname);
       
  8121 
       
  8122 base_changed:
       
  8123     /*
       
  8124      * the attribute strings are valid iif the base didn't changed
       
  8125      */
       
  8126     if (attval != 0) {
       
  8127         for (i = 3,j = 0; j < nratts;i += 5,j++)
       
  8128             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
       
  8129                 xmlFree((xmlChar *) atts[i]);
       
  8130     }
       
  8131     ctxt->input->cur = ctxt->input->base + cur;
       
  8132 
       
  8133     if (ctxt->wellFormed == 1) {
       
  8134         goto reparse;
       
  8135     }
       
  8136     return(NULL);
       
  8137 //---------------------------------
       
  8138 OOM:
       
  8139     xmlParserOOMErr(ctxt);
       
  8140     return NULL;
       
  8141 }
       
  8142 
       
  8143 /**
       
  8144  * xmlParseEndTag2:
       
  8145  * @param ctxt an XML parser context
       
  8146  * @param line line of the start tag
       
  8147  * @param nsNr number of namespaces on the start tag
       
  8148  *
       
  8149  * parse an end of tag
       
  8150  *
       
  8151  * [42] ETag ::= '</' Name S? '>'
       
  8152  *
       
  8153  * With namespace
       
  8154  *
       
  8155  * [NS 9] ETag ::= '</' QName S? '>'
       
  8156  */
       
  8157 
       
  8158 static void
       
  8159 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
       
  8160                 const xmlChar *URI, int line, int nsNr, int tlen) {
       
  8161     const xmlChar *name;
       
  8162 
       
  8163     GROW;
       
  8164     if ((RAW != '<') || (NXT(1) != '/')) {
       
  8165     xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
       
  8166     return;
       
  8167     }
       
  8168     SKIP(2);
       
  8169 
       
  8170     if ((tlen > 0) && (strncmp((char*) ctxt->input->cur, (char*) ctxt->name, tlen) == 0)) {
       
  8171         if (ctxt->input->cur[tlen] == '>') {
       
  8172         ctxt->input->cur += tlen + 1;
       
  8173         goto done;
       
  8174     }
       
  8175     ctxt->input->cur += tlen;
       
  8176     name = (xmlChar*)1;
       
  8177     } else {
       
  8178     if (prefix == NULL)
       
  8179         name = xmlParseNameAndCompare(ctxt, ctxt->name);
       
  8180     else
       
  8181         name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
       
  8182     }
       
  8183 
       
  8184     /*
       
  8185      * We should definitely be at the ending "S? '>'" part
       
  8186      */
       
  8187     GROW;
       
  8188     SKIP_BLANKS;
       
  8189     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
       
  8190     xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
       
  8191     } else
       
  8192     NEXT1;
       
  8193 
       
  8194     /*
       
  8195      * [ WFC: Element Type Match ]
       
  8196      * The Name in an element's end-tag must match the element type in the
       
  8197      * start-tag.
       
  8198      *
       
  8199      */
       
  8200     if (name != (xmlChar*)1) {
       
  8201         if (name == NULL) name = BAD_CAST "unparseable";
       
  8202         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
       
  8203              EMBED_ERRTXT("Opening and ending tag mismatch: %s line %d and %s\n"),
       
  8204                         ctxt->name, line, name);
       
  8205     }
       
  8206 
       
  8207     /*
       
  8208      * SAX: End of Tag
       
  8209      */
       
  8210 done:
       
  8211     if ((ctxt->sax != NULL) &&
       
  8212         (ctxt->sax->endElementNs != NULL) &&
       
  8213         (!ctxt->disableSAX))
       
  8214     {
       
  8215         ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
       
  8216     }
       
  8217 
       
  8218     spacePop(ctxt);
       
  8219     if (nsNr != 0){
       
  8220         // SAX2 endPrefixMapping callback is invoked in nsPop for every popped prefix
       
  8221         nsPop(ctxt, nsNr);
       
  8222     }
       
  8223     return;
       
  8224 }
       
  8225 
       
  8226 /**
       
  8227  * xmlParseCDSect:
       
  8228  * @param ctxt an XML parser context
       
  8229  *
       
  8230  * Parse escaped pure raw content.
       
  8231  *
       
  8232  * [18] CDSect ::= CDStart CData CDEnd
       
  8233  *
       
  8234  * [19] CDStart ::= '<![CDATA['
       
  8235  *
       
  8236  * [20] Data ::= (Char* - (Char* ']]>' Char*))
       
  8237  *
       
  8238  * [21] CDEnd ::= ']]>'
       
  8239  */
       
  8240 XMLPUBFUNEXPORT void
       
  8241 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
       
  8242     xmlChar *buf = NULL;
       
  8243     int len = 0;
       
  8244     int size = XML_PARSER_BUFFER_SIZE;
       
  8245     int r, rl;
       
  8246     int s, sl;
       
  8247     int cur, l;
       
  8248     int count = 0;
       
  8249 
       
  8250     /* Check 2.6.0 was NXT(0) not RAW */
       
  8251     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
       
  8252     SKIP(9);
       
  8253     } else
       
  8254         return;
       
  8255 
       
  8256     ctxt->instate = XML_PARSER_CDATA_SECTION;
       
  8257     r = CUR_CHAR(rl);
       
  8258     if (!IS_CHAR(r)) {
       
  8259     xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
       
  8260     ctxt->instate = XML_PARSER_CONTENT;
       
  8261         return;
       
  8262     }
       
  8263     NEXTL(rl);
       
  8264     s = CUR_CHAR(sl);
       
  8265     if (!IS_CHAR(s)) {
       
  8266     xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
       
  8267     ctxt->instate = XML_PARSER_CONTENT;
       
  8268         return;
       
  8269     }
       
  8270     NEXTL(sl);
       
  8271     cur = CUR_CHAR(l);
       
  8272     buf = (xmlChar*) xmlMallocAtomic(size * sizeof(xmlChar));
       
  8273     if (!buf)
       
  8274         goto OOM_exit;
       
  8275 
       
  8276     while (IS_CHAR(cur) &&
       
  8277            ((r != ']') || (s != ']') || (cur != '>'))) {
       
  8278     if (len + 5 >= size) {
       
  8279         // DONE: Fix xmlRealloc
       
  8280         xmlChar* tmp;
       
  8281         size *= 2;
       
  8282         tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  8283         if (!tmp) {
       
  8284             xmlFree(buf);
       
  8285 OOM_exit:
       
  8286             xmlParserOOMErr(ctxt);
       
  8287             return;
       
  8288         }
       
  8289         buf = tmp;
       
  8290     }
       
  8291     COPY_BUF(rl,buf,len,r);
       
  8292     r = s;
       
  8293     rl = sl;
       
  8294     s = cur;
       
  8295     sl = l;
       
  8296     count++;
       
  8297     if (count > 50) {
       
  8298         GROW;
       
  8299         count = 0;
       
  8300     }
       
  8301     NEXTL(l);
       
  8302     cur = CUR_CHAR(l);
       
  8303     }
       
  8304     buf[len] = 0;
       
  8305     ctxt->instate = XML_PARSER_CONTENT;
       
  8306     if (cur != '>') {
       
  8307     xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
       
  8308                          EMBED_ERRTXT("CData section not finished\n%.50s\n"), buf);
       
  8309     xmlFree(buf);
       
  8310         return;
       
  8311     }
       
  8312     NEXTL(l);
       
  8313 
       
  8314     /*
       
  8315      * OK the buffer is to be consumed as cdata.
       
  8316      */
       
  8317     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
       
  8318     if (ctxt->sax->cdataBlock != NULL)
       
  8319         ctxt->sax->cdataBlock(ctxt->userData, buf, len);
       
  8320     else if (ctxt->sax->characters != NULL)
       
  8321         ctxt->sax->characters(ctxt->userData, buf, len);
       
  8322     }
       
  8323     xmlFree(buf);
       
  8324 }
       
  8325 
       
  8326 /**
       
  8327  * xmlParseContent:
       
  8328  * @param ctxt an XML parser context
       
  8329  *
       
  8330  * Parse a content:
       
  8331  *
       
  8332  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
       
  8333  */
       
  8334 
       
  8335 XMLPUBFUNEXPORT void
       
  8336 xmlParseContent(xmlParserCtxtPtr ctxt) {
       
  8337 	LOAD_GS_SAFE_CTXT(ctxt)
       
  8338     GROW;
       
  8339     while ((RAW != 0) &&
       
  8340        ((RAW != '<') || (NXT(1) != '/'))) {
       
  8341     const xmlChar *test = CUR_PTR;
       
  8342     unsigned int cons = ctxt->input->consumed;
       
  8343     const xmlChar *cur = ctxt->input->cur;
       
  8344     
       
  8345     /*
       
  8346      * First case : a Processing Instruction.
       
  8347      */
       
  8348     if ((*cur == '<') && (cur[1] == '?')) {
       
  8349         xmlParsePI(ctxt);
       
  8350     }
       
  8351 
       
  8352     /*
       
  8353      * Second case : a CDSection
       
  8354      */
       
  8355     /* 2.6.0 test was *cur not RAW */
       
  8356     else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
       
  8357         xmlParseCDSect(ctxt);
       
  8358     }
       
  8359 
       
  8360     /*
       
  8361      * Third case :  a comment
       
  8362      */
       
  8363     else if ((*cur == '<') && (NXT(1) == '!') &&
       
  8364          (NXT(2) == '-') && (NXT(3) == '-')) {
       
  8365         xmlParseComment(ctxt);
       
  8366         ctxt->instate = XML_PARSER_CONTENT;
       
  8367     }
       
  8368 
       
  8369     /*
       
  8370      * Fourth case :  a sub-element.
       
  8371      */
       
  8372     else if (*cur == '<') 
       
  8373     	{
       
  8374 		if( (((unsigned int)&cur) - ((unsigned int) xeStackLimit)) < ctxt->stackLowThreshold )
       
  8375 			{
       
  8376 			SET_OOM_FLAG;
       
  8377 			xmlFatalErr(ctxt, XML_ERR_STACK_LOW, NULL); 
       
  8378 			return;
       
  8379 			}    	
       
  8380 
       
  8381         xmlParseElement(ctxt);
       
  8382 	    if(OOM_FLAG) 
       
  8383 	    	{
       
  8384 	    	return;
       
  8385 	    	}        
       
  8386     }
       
  8387 
       
  8388     /*
       
  8389      * Fifth case : a reference. If if has not been resolved,
       
  8390      *    parsing returns it's Name, create the node
       
  8391      */
       
  8392 
       
  8393     else if (*cur == '&') {
       
  8394         xmlParseReference(ctxt);
       
  8395     }
       
  8396 
       
  8397     /*
       
  8398      * Last case, text. Note that References are handled directly.
       
  8399      */
       
  8400     else {
       
  8401         xmlParseCharData(ctxt, 0);
       
  8402     }
       
  8403 
       
  8404     GROW;
       
  8405     /*
       
  8406      * Pop-up of finished entities.
       
  8407      */
       
  8408     while ((RAW == 0) && (ctxt->inputNr > 1))
       
  8409         xmlPopInput(ctxt);
       
  8410     SHRINK;
       
  8411 
       
  8412     if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
       
  8413         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
       
  8414                     EMBED_ERRTXT("detected an error in element content\n"));
       
  8415         ctxt->instate = XML_PARSER_EOF;
       
  8416             break;
       
  8417     }
       
  8418     }
       
  8419 }
       
  8420 
       
  8421 /**
       
  8422  * xmlParseElement:
       
  8423  * @param ctxt an XML parser context
       
  8424  *
       
  8425  * parse an XML element, this is highly recursive
       
  8426  *
       
  8427  * [39] element ::= EmptyElemTag | STag content ETag
       
  8428  *
       
  8429  * [ WFC: Element Type Match ]
       
  8430  * The Name in an element's end-tag must match the element type in the
       
  8431  * start-tag.
       
  8432  *
       
  8433  */
       
  8434 
       
  8435 XMLPUBFUNEXPORT void
       
  8436 xmlParseElement(xmlParserCtxtPtr ctxt)
       
  8437 {
       
  8438 	const xmlChar *name;
       
  8439     const xmlChar *prefix;
       
  8440     const xmlChar *URI;
       
  8441 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  8442     xmlParserNodeInfo node_info;
       
  8443     xmlNodePtr ret;
       
  8444 #endif
       
  8445     int line, tlen;
       
  8446     int nsNr = ctxt->nsNr;
       
  8447     LOAD_GS_SAFE_CTXT(ctxt)
       
  8448 
       
  8449 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  8450     /* Capture start position */
       
  8451     
       
  8452     if (ctxt->record_info) {
       
  8453         node_info.begin_pos = ctxt->input->consumed +
       
  8454                           (CUR_PTR - ctxt->input->base);
       
  8455         node_info.begin_line = ctxt->input->line;
       
  8456     }
       
  8457 #endif
       
  8458 
       
  8459     if (ctxt->spaceNr == 0)
       
  8460         spacePush(ctxt, -1);
       
  8461     else
       
  8462         spacePush(ctxt, *ctxt->space);
       
  8463 
       
  8464     line = ctxt->input->line;
       
  8465 #ifdef LIBXML_SAX1_ENABLED
       
  8466     if (ctxt->sax2)
       
  8467 #endif /* LIBXML_SAX1_ENABLED */
       
  8468         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
       
  8469 #ifdef LIBXML_SAX1_ENABLED
       
  8470     else
       
  8471         name = xmlParseStartTag(ctxt);
       
  8472 #endif /* LIBXML_SAX1_ENABLED */
       
  8473     if (name == NULL) {
       
  8474         spacePop(ctxt);
       
  8475         return;
       
  8476     }
       
  8477     namePush(ctxt, name);
       
  8478 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  8479     ret = ctxt->node;
       
  8480 #endif
       
  8481 
       
  8482 #ifdef LIBXML_VALID_ENABLED
       
  8483     /*
       
  8484      * [ VC: Root Element Type ]
       
  8485      * The Name in the document type declaration must match the element
       
  8486      * type of the root element.
       
  8487      */
       
  8488     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
       
  8489         ctxt->node && (ctxt->node == ctxt->myDoc->children))
       
  8490         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
       
  8491 #endif /* LIBXML_VALID_ENABLED */
       
  8492 
       
  8493     /*
       
  8494      * Check for an Empty Element.
       
  8495      */
       
  8496     if ((RAW == '/') && (NXT(1) == '>')) {
       
  8497         SKIP(2);
       
  8498     if (ctxt->sax2) {
       
  8499         if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
       
  8500         (!ctxt->disableSAX))
       
  8501         ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
       
  8502 #ifdef LIBXML_SAX1_ENABLED
       
  8503     } else {
       
  8504         if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
       
  8505         (!ctxt->disableSAX))
       
  8506         ctxt->sax->endElement(ctxt->userData, name);
       
  8507 #endif /* LIBXML_SAX1_ENABLED */
       
  8508     }
       
  8509     namePop(ctxt);
       
  8510     spacePop(ctxt);
       
  8511     if (nsNr != ctxt->nsNr)
       
  8512         nsPop(ctxt, ctxt->nsNr - nsNr);
       
  8513 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  8514     if ( ret != NULL && ctxt->record_info ) {
       
  8515        node_info.end_pos = ctxt->input->consumed +
       
  8516                   (CUR_PTR - ctxt->input->base);
       
  8517        node_info.end_line = ctxt->input->line;
       
  8518        node_info.node = ret;
       
  8519        xmlParserAddNodeInfo(ctxt, &node_info);
       
  8520     }
       
  8521 #endif
       
  8522     return;
       
  8523     }
       
  8524     if (RAW == '>') {
       
  8525         NEXT1;
       
  8526     } else {
       
  8527         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
       
  8528              EMBED_ERRTXT("Couldn't find end of Start Tag %s line %d\n"),
       
  8529                         name, line, NULL);
       
  8530 
       
  8531         /*
       
  8532          * end of parsing of this node.
       
  8533          */
       
  8534         nodePop(ctxt);
       
  8535         namePop(ctxt);
       
  8536         spacePop(ctxt);
       
  8537         if (nsNr != ctxt->nsNr)
       
  8538             nsPop(ctxt, ctxt->nsNr - nsNr);
       
  8539 
       
  8540 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  8541         /*
       
  8542          * Capture end position and add node
       
  8543          */
       
  8544         if ( ret != NULL && ctxt->record_info ) {
       
  8545            node_info.end_pos = ctxt->input->consumed + (CUR_PTR - ctxt->input->base);
       
  8546            node_info.end_line = ctxt->input->line;
       
  8547            node_info.node = ret;
       
  8548            xmlParserAddNodeInfo(ctxt, &node_info);
       
  8549         }
       
  8550 #endif
       
  8551         return;
       
  8552     }
       
  8553 
       
  8554     /*
       
  8555      * Parse the content of the element:
       
  8556      */
       
  8557     xmlParseContent(ctxt);
       
  8558     if(OOM_FLAG) 
       
  8559     	{
       
  8560     	return;
       
  8561     	}    
       
  8562     if (!IS_BYTE_CHAR(RAW)) {
       
  8563         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
       
  8564                         EMBED_ERRTXT("Premature end of data in tag %s line %d\n"),
       
  8565                         name, line, NULL);
       
  8566 
       
  8567         /*
       
  8568          * end of parsing of this node.
       
  8569          */
       
  8570         nodePop(ctxt);
       
  8571         namePop(ctxt);
       
  8572         spacePop(ctxt);
       
  8573         if (nsNr != ctxt->nsNr)
       
  8574             nsPop(ctxt, ctxt->nsNr - nsNr);
       
  8575         return;
       
  8576     }
       
  8577 
       
  8578     /*
       
  8579      * parse the end of tag: '</' should be here.
       
  8580      */
       
  8581     if (ctxt->sax2) {
       
  8582         xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
       
  8583         namePop(ctxt);
       
  8584     }
       
  8585 #ifdef LIBXML_SAX1_ENABLED
       
  8586     else
       
  8587         xmlParseEndTag1(ctxt, line);
       
  8588 #endif /* LIBXML_SAX1_ENABLED */
       
  8589 
       
  8590 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  8591     /*
       
  8592      * Capture end position and add node
       
  8593      */
       
  8594     if ( ret != NULL && ctxt->record_info ) {
       
  8595        node_info.end_pos = ctxt->input->consumed +
       
  8596                           (CUR_PTR - ctxt->input->base);
       
  8597        node_info.end_line = ctxt->input->line;
       
  8598        node_info.node = ret;
       
  8599        xmlParserAddNodeInfo(ctxt, &node_info);
       
  8600     }
       
  8601 #endif
       
  8602 }
       
  8603 
       
  8604 /**
       
  8605  * xmlParseVersionNum:
       
  8606  * @param ctxt an XML parser context
       
  8607  *
       
  8608  * parse the XML version value.
       
  8609  *
       
  8610  * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
       
  8611  *
       
  8612  * Returns the string giving the XML version number, or NULL
       
  8613  *
       
  8614  * OOM: possible --> sets OOM flag when NULL is returned
       
  8615  */
       
  8616 XMLPUBFUNEXPORT xmlChar*
       
  8617 xmlParseVersionNum(xmlParserCtxtPtr ctxt)
       
  8618 {
       
  8619     xmlChar* buf;
       
  8620     int len = 0;
       
  8621     int size = 10;
       
  8622     xmlChar cur;
       
  8623 
       
  8624     buf = (xmlChar*) xmlMallocAtomic(size * sizeof(xmlChar));
       
  8625     if (!buf)
       
  8626         goto OOM_exit;
       
  8627 
       
  8628     cur = CUR;
       
  8629     while (((cur >= 'a') && (cur <= 'z')) ||
       
  8630            ((cur >= 'A') && (cur <= 'Z')) ||
       
  8631            ((cur >= '0') && (cur <= '9')) ||
       
  8632            (cur == '_') || (cur == '.') ||
       
  8633            (cur == ':') || (cur == '-'))
       
  8634     {
       
  8635         if (len + 1 >= size)
       
  8636         {
       
  8637             // DONE: Fix xmlRealloc
       
  8638             xmlChar* tmp;
       
  8639             size *= 2;
       
  8640             tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  8641             if (!tmp) {
       
  8642                 xmlFree(buf);
       
  8643 OOM_exit:
       
  8644                 xmlParserOOMErr(ctxt);
       
  8645                 return(NULL);
       
  8646             }
       
  8647             buf = tmp;
       
  8648         }
       
  8649         buf[len++] = cur;
       
  8650         NEXT; 
       
  8651         cur=CUR;
       
  8652     }
       
  8653     buf[len] = 0;
       
  8654     return(buf);
       
  8655 }
       
  8656 
       
  8657 /**
       
  8658  * xmlParseVersionInfo:
       
  8659  * @param ctxt an XML parser context
       
  8660  *
       
  8661  * parse the XML version.
       
  8662  *
       
  8663  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
       
  8664  * [25] Eq ::= S? '=' S?
       
  8665  *
       
  8666  * Returns the version string, e.g. "1.0"
       
  8667  *
       
  8668  * OOM:
       
  8669  */
       
  8670 XMLPUBFUNEXPORT xmlChar*
       
  8671 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
       
  8672     xmlChar* version;
       
  8673     xmlChar ch;
       
  8674     int errCode;
       
  8675     LOAD_GS_SAFE_CTXT(ctxt)
       
  8676     
       
  8677     
       
  8678     
       
  8679     
       
  8680     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n'))
       
  8681     {
       
  8682         SKIP(7);
       
  8683         SKIP_BLANKS;
       
  8684 //XMLENGINE: BEGIN REPLACE CODE
       
  8685 //XMLENGINE: NEW CODE
       
  8686         if(OOM_FLAG) goto OOM;
       
  8687         if (RAW != '=') {
       
  8688             errCode = XML_ERR_EQUAL_REQUIRED;
       
  8689             goto ERR;
       
  8690         }
       
  8691         NEXT;
       
  8692         if(OOM_FLAG)
       
  8693             goto OOM;
       
  8694         SKIP_BLANKS;
       
  8695         if(OOM_FLAG)
       
  8696             goto OOM;
       
  8697 
       
  8698         ch = RAW;
       
  8699         if (ch == '"' || ch=='\'')
       
  8700         { // DONE: OPTIMIZE: Combine two cases when RAW='\"' or '\''
       
  8701             NEXT;
       
  8702             if(OOM_FLAG)
       
  8703                 goto OOM;
       
  8704             version = xmlParseVersionNum(ctxt);
       
  8705             if (RAW == ch) {
       
  8706                 NEXT;
       
  8707                 if(OOM_FLAG)
       
  8708                     goto OOM; // checks xmlParseVersionNum too
       
  8709                 return version;
       
  8710             } else {
       
  8711                 errCode = XML_ERR_STRING_NOT_CLOSED;
       
  8712                 goto ERR;
       
  8713             }
       
  8714         } else {
       
  8715             errCode = XML_ERR_STRING_NOT_STARTED;
       
  8716             goto ERR;
       
  8717         }
       
  8718 //XMLENGINE: END REPLACE CODE
       
  8719     }
       
  8720 OOM:
       
  8721     return NULL;
       
  8722 ERR:
       
  8723     xmlFatalErr(ctxt, (xmlParserErrors)errCode, NULL);
       
  8724     goto OOM;
       
  8725 }
       
  8726 
       
  8727 /**
       
  8728  * xmlParseEncName:
       
  8729  * @param ctxt an XML parser context
       
  8730  *
       
  8731  * parse the XML encoding name
       
  8732  *
       
  8733  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
       
  8734  *
       
  8735  * Returns the encoding name value or NULL
       
  8736  */
       
  8737 XMLPUBFUNEXPORT xmlChar *
       
  8738 xmlParseEncName(xmlParserCtxtPtr ctxt) {
       
  8739     xmlChar *buf = NULL;
       
  8740     int len = 0;
       
  8741     int size = 10;
       
  8742     xmlChar cur;
       
  8743 
       
  8744     cur = CUR;
       
  8745     if (((cur >= 'a') && (cur <= 'z')) ||
       
  8746         ((cur >= 'A') && (cur <= 'Z'))) {
       
  8747     buf = (xmlChar*) xmlMallocAtomic(size * sizeof(xmlChar));
       
  8748     if (!buf)
       
  8749         goto OOM_exit;
       
  8750 
       
  8751     buf[len++] = cur;
       
  8752     NEXT;
       
  8753     cur = CUR;
       
  8754     while (((cur >= 'a') && (cur <= 'z')) ||
       
  8755            ((cur >= 'A') && (cur <= 'Z')) ||
       
  8756            ((cur >= '0') && (cur <= '9')) ||
       
  8757            (cur == '.') || (cur == '_') ||
       
  8758            (cur == '-')) {
       
  8759         if (len + 1 >= size) {
       
  8760             // DONE: Fix xmlRealloc
       
  8761             xmlChar* tmp;
       
  8762             size *= 2;
       
  8763             tmp = (xmlChar*) xmlRealloc(buf, size * sizeof(xmlChar));
       
  8764             if (!tmp) {
       
  8765                 xmlFree(buf);
       
  8766 OOM_exit:
       
  8767                 xmlParserOOMErr(ctxt);
       
  8768                 return(NULL);
       
  8769             }
       
  8770             buf = tmp;
       
  8771         }
       
  8772         buf[len++] = cur;
       
  8773         NEXT;
       
  8774         cur = CUR;
       
  8775         if (cur == 0) {
       
  8776             SHRINK;
       
  8777         GROW;
       
  8778         cur = CUR;
       
  8779         }
       
  8780         }
       
  8781     buf[len] = 0;
       
  8782     } else {
       
  8783     xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
       
  8784     }
       
  8785     return(buf);
       
  8786 }
       
  8787 
       
  8788 /**
       
  8789  * xmlParseEncodingDecl:
       
  8790  * @param ctxt an XML parser context
       
  8791  *
       
  8792  * parse the XML encoding declaration
       
  8793  *
       
  8794  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
       
  8795  *
       
  8796  * this setups the conversion filters.
       
  8797  *
       
  8798  * Returns the encoding value or NULL
       
  8799  */
       
  8800 
       
  8801 XMLPUBFUNEXPORT const xmlChar *
       
  8802 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
       
  8803     xmlChar *encoding = NULL;
       
  8804 
       
  8805     SKIP_BLANKS;
       
  8806     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
       
  8807     SKIP(8);
       
  8808     SKIP_BLANKS;
       
  8809     if (RAW != '=') {
       
  8810         xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
       
  8811         return(NULL);
       
  8812         }
       
  8813     NEXT;
       
  8814     SKIP_BLANKS;
       
  8815     if (RAW == '"') {
       
  8816         NEXT;
       
  8817         encoding = xmlParseEncName(ctxt);
       
  8818         if (RAW != '"') {
       
  8819         xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
       
  8820         } else
       
  8821             NEXT;
       
  8822     } else if (RAW == '\''){
       
  8823         NEXT;
       
  8824         encoding = xmlParseEncName(ctxt);
       
  8825         if (RAW != '\'') {
       
  8826         xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
       
  8827         } else
       
  8828             NEXT;
       
  8829     } else {
       
  8830         xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
       
  8831     }
       
  8832     /*
       
  8833      * UTF-16 encoding stwich has already taken place at this stage,
       
  8834      * more over the little-endian/big-endian selection is already done
       
  8835      */
       
  8836         if ((encoding != NULL) &&
       
  8837         ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
       
  8838          (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
       
  8839         if (ctxt->encoding != NULL)
       
  8840         xmlFree((xmlChar *) ctxt->encoding);
       
  8841         ctxt->encoding = encoding;
       
  8842     }
       
  8843     /*
       
  8844      * UTF-8 encoding is handled natively
       
  8845      */
       
  8846         else if ((encoding != NULL) &&
       
  8847         ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
       
  8848          (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
       
  8849         if (ctxt->encoding != NULL)
       
  8850         xmlFree((xmlChar *) ctxt->encoding);
       
  8851         ctxt->encoding = encoding;
       
  8852     }
       
  8853     else if (encoding != NULL) {
       
  8854         xmlCharEncodingHandlerPtr handler;
       
  8855 
       
  8856         if (ctxt->input->encoding != NULL)
       
  8857         xmlFree((xmlChar *) ctxt->input->encoding);
       
  8858         ctxt->input->encoding = encoding;
       
  8859 
       
  8860             handler = xmlFindCharEncodingHandler((const char *) encoding);
       
  8861         if (handler != NULL) {
       
  8862         xmlSwitchToEncoding(ctxt, handler);
       
  8863         } else {
       
  8864         xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
       
  8865             EMBED_ERRTXT("Unsupported encoding %s\n"), encoding);
       
  8866         return(NULL);
       
  8867         }
       
  8868     }
       
  8869     }
       
  8870     return(encoding);
       
  8871 }
       
  8872 
       
  8873 /**
       
  8874  * xmlParseSDDecl:
       
  8875  * @param ctxt an XML parser context
       
  8876  *
       
  8877  * parse the XML standalone declaration
       
  8878  *
       
  8879  * [32] SDDecl ::= S 'standalone' Eq
       
  8880  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
       
  8881  *
       
  8882  * [ VC: Standalone Document Declaration ]
       
  8883  *  The standalone document declaration must have the value "no"
       
  8884  * if any external markup declarations contain declarations of:
       
  8885  *  - attributes with default values, if elements to which these
       
  8886  *    attributes apply appear in the document without specifications
       
  8887  *    of values for these attributes, or
       
  8888  *  - entities (other than amp, lt, gt, apos, quot), if references
       
  8889  *    to those entities appear in the document, or
       
  8890  *  - attributes with values subject to normalization, where the
       
  8891  *    attribute appears in the document with a value which will change
       
  8892  *    as a result of normalization, or
       
  8893  *  - element types with element content, if white space occurs directly
       
  8894  *    within any instance of those types.
       
  8895  *
       
  8896  * Returns 1 if standalone, 0 otherwise
       
  8897  */
       
  8898 
       
  8899 XMLPUBFUNEXPORT int
       
  8900 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
       
  8901     int standalone = -1;
       
  8902 
       
  8903     SKIP_BLANKS;
       
  8904     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
       
  8905     SKIP(10);
       
  8906         SKIP_BLANKS;
       
  8907     if (RAW != '=') {
       
  8908         xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
       
  8909         return(standalone);
       
  8910         }
       
  8911     NEXT;
       
  8912     SKIP_BLANKS;
       
  8913         if (RAW == '\''){
       
  8914         NEXT;
       
  8915         if ((RAW == 'n') && (NXT(1) == 'o')) {
       
  8916             standalone = 0;
       
  8917                 SKIP(2);
       
  8918         } else if ((RAW == 'y') && (NXT(1) == 'e') &&
       
  8919                    (NXT(2) == 's')) {
       
  8920             standalone = 1;
       
  8921         SKIP(3);
       
  8922             } else {
       
  8923         xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
       
  8924         }
       
  8925         if (RAW != '\'') {
       
  8926         xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
       
  8927         } else
       
  8928             NEXT;
       
  8929     } else if (RAW == '"'){
       
  8930         NEXT;
       
  8931         if ((RAW == 'n') && (NXT(1) == 'o')) {
       
  8932             standalone = 0;
       
  8933         SKIP(2);
       
  8934         } else if ((RAW == 'y') && (NXT(1) == 'e') &&
       
  8935                    (NXT(2) == 's')) {
       
  8936             standalone = 1;
       
  8937                 SKIP(3);
       
  8938             } else {
       
  8939         xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
       
  8940         }
       
  8941         if (RAW != '"') {
       
  8942         xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
       
  8943         } else
       
  8944             NEXT;
       
  8945     } else {
       
  8946         xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
       
  8947         }
       
  8948     }
       
  8949     return(standalone);
       
  8950 }
       
  8951 
       
  8952 /**
       
  8953  * xmlParseXMLDecl:
       
  8954  * @param ctxt an XML parser context
       
  8955  *
       
  8956  * parse an XML declaration header
       
  8957  *
       
  8958  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
       
  8959  *
       
  8960  * OOM:
       
  8961  */
       
  8962 XMLPUBFUNEXPORT void
       
  8963 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
       
  8964     xmlChar *version;
       
  8965     /*
       
  8966      * We know that '<?xml' is here.
       
  8967      */
       
  8968     SKIP(5);
       
  8969 
       
  8970     if (!IS_BLANK_CH(RAW)) {
       
  8971         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
       
  8972                    EMBED_ERRTXT("Blank needed after '<?xml'\n"));
       
  8973     }
       
  8974     SKIP_BLANKS; 
       
  8975 
       
  8976     /*
       
  8977      * We must have the VersionInfo here.
       
  8978      */
       
  8979     version = xmlParseVersionInfo(ctxt);
       
  8980     if (version == NULL) {
       
  8981         xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
       
  8982     } else {
       
  8983         if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
       
  8984             /*
       
  8985             
       
  8986             */
       
  8987             xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
       
  8988                     EMBED_ERRTXT("Unsupported version '%s'\n"),
       
  8989                 version, NULL);
       
  8990         }
       
  8991         if (ctxt->version != NULL)
       
  8992             xmlFree((void *) ctxt->version);
       
  8993         ctxt->version = version;
       
  8994     }
       
  8995 
       
  8996     /*
       
  8997      * We may have the encoding declaration
       
  8998      */
       
  8999     if (!IS_BLANK_CH(RAW)) {
       
  9000         if ((RAW == '?') && (NXT(1) == '>')) {
       
  9001         SKIP(2);
       
  9002         return;
       
  9003     }
       
  9004     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, EMBED_ERRTXT("Blank needed here\n"));
       
  9005     }
       
  9006     xmlParseEncodingDecl(ctxt);
       
  9007     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  9008     /*
       
  9009      * The XML REC instructs us to stop parsing right here
       
  9010      */
       
  9011         return;
       
  9012     }
       
  9013 
       
  9014     /*
       
  9015      * We may have the standalone status.
       
  9016      */
       
  9017     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
       
  9018         if ((RAW == '?') && (NXT(1) == '>')) {
       
  9019         SKIP(2);
       
  9020         return;
       
  9021     }
       
  9022     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, EMBED_ERRTXT("Blank needed here\n"));
       
  9023     }
       
  9024     SKIP_BLANKS;
       
  9025     ctxt->input->standalone = xmlParseSDDecl(ctxt);
       
  9026 
       
  9027     SKIP_BLANKS;
       
  9028     if ((RAW == '?') && (NXT(1) == '>')) {
       
  9029         SKIP(2);
       
  9030     } else if (RAW == '>') {
       
  9031         /* Deprecated old WD ... */
       
  9032     xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
       
  9033     NEXT;
       
  9034     } else {
       
  9035     xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
       
  9036     MOVETO_ENDTAG(CUR_PTR);
       
  9037     NEXT;
       
  9038     }
       
  9039 }
       
  9040 
       
  9041 /**
       
  9042  * xmlParseMisc:
       
  9043  * @param ctxt an XML parser context
       
  9044  *
       
  9045  * parse an XML Misc* optional field.
       
  9046  *
       
  9047  * [27] Misc ::= Comment | PI |  S
       
  9048  */
       
  9049 
       
  9050 XMLPUBFUNEXPORT void
       
  9051 xmlParseMisc(xmlParserCtxtPtr ctxt) {
       
  9052     while (((RAW == '<') && (NXT(1) == '?')) ||
       
  9053            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
       
  9054            IS_BLANK_CH(CUR)) {
       
  9055         if ((RAW == '<') && (NXT(1) == '?')) {
       
  9056         xmlParsePI(ctxt);
       
  9057     } else if (IS_BLANK_CH(CUR)) {
       
  9058         NEXT;
       
  9059     } else
       
  9060         xmlParseComment(ctxt);
       
  9061     }
       
  9062 }
       
  9063 
       
  9064 /**
       
  9065  * xmlParseDocument:
       
  9066  * @param ctxt an XML parser context
       
  9067  *
       
  9068  * parse an XML document (and build a tree if using the standard SAX
       
  9069  * interface).
       
  9070  *
       
  9071  * [1] document ::= prolog element Misc*
       
  9072  *
       
  9073  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
       
  9074  *
       
  9075  * Returns 0, -1 in case of error. the parser context is augmented
       
  9076  *                as a result of the parsing.
       
  9077  *
       
  9078  * OOM: possible, of course --> check OOM flag [REVIEW NOT FINISHED]
       
  9079  */
       
  9080 
       
  9081 XMLPUBFUNEXPORT int
       
  9082 xmlParseDocument(xmlParserCtxtPtr ctxt) {
       
  9083     xmlChar start[4];
       
  9084     xmlCharEncoding enc;
       
  9085     LOAD_GS_SAFE_CTXT(ctxt)
       
  9086 
       
  9087     xmlInitParser();
       
  9088     if(OOM_FLAG)
       
  9089         return -1;
       
  9090     GROW;
       
  9091     if(OOM_FLAG)
       
  9092         return -1;
       
  9093 
       
  9094     /*
       
  9095      * SAX: detecting the level.
       
  9096      */
       
  9097     xmlDetectSAX2(ctxt);
       
  9098     if(OOM_FLAG)
       
  9099         return (-1);
       
  9100     /*
       
  9101      * SAX: beginning of the document processing.
       
  9102      */
       
  9103     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
       
  9104     {
       
  9105         ctxt->sax->setDocumentLocator(ctxt->userData, (xmlSAXLocatorPtr)&xmlDefaultSAXLocator);
       
  9106         if(OOM_FLAG)
       
  9107             return -1;
       
  9108     }
       
  9109 
       
  9110     if ((ctxt->encoding == (const xmlChar*)XML_CHAR_ENCODING_NONE) &&
       
  9111         ((ctxt->input->end - ctxt->input->cur) >= 4))
       
  9112     {
       
  9113         /*
       
  9114         * Get the 4 first bytes and decode the charset
       
  9115         * if enc != XML_CHAR_ENCODING_NONE
       
  9116         * plug some encoding conversion routines.
       
  9117         */
       
  9118         start[0] = RAW;
       
  9119         start[1] = NXT(1);
       
  9120         start[2] = NXT(2);
       
  9121         start[3] = NXT(3);
       
  9122         enc = xmlDetectCharEncoding(&start[0], 4);
       
  9123         if (enc != XML_CHAR_ENCODING_NONE) {
       
  9124             xmlSwitchEncoding(ctxt, enc);
       
  9125             if(OOM_FLAG)
       
  9126                 return -1;
       
  9127         }
       
  9128     }
       
  9129 
       
  9130 
       
  9131     if (CUR == 0) {
       
  9132         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
       
  9133     }
       
  9134 
       
  9135     /*
       
  9136      * Check for the XMLDecl in the Prolog.
       
  9137      */
       
  9138     GROW; 
       
  9139     if(OOM_FLAG)
       
  9140         return -1;
       
  9141     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5))))
       
  9142     {
       
  9143         /*
       
  9144         * Note that we will switch encoding on the fly.
       
  9145         */
       
  9146         xmlParseXMLDecl(ctxt); 
       
  9147         if(OOM_FLAG)
       
  9148             return -1;
       
  9149         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  9150             /*
       
  9151             * The XML REC instructs us to stop parsing right here
       
  9152             */
       
  9153             return(-1);
       
  9154         }
       
  9155         ctxt->standalone = ctxt->input->standalone;
       
  9156         SKIP_BLANKS; 
       
  9157         if(OOM_FLAG)
       
  9158             return -1;
       
  9159     } else {
       
  9160         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
       
  9161         if(OOM_FLAG)
       
  9162             return -1;
       
  9163     }
       
  9164     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
       
  9165         {
       
  9166         ctxt->sax->startDocument(ctxt->userData);
       
  9167         if(OOM_FLAG)
       
  9168             return -1;
       
  9169         }
       
  9170     /*
       
  9171      * The Misc part of the Prolog
       
  9172      */
       
  9173     GROW;
       
  9174     if(OOM_FLAG)
       
  9175         return -1;
       
  9176     xmlParseMisc(ctxt);
       
  9177     if(OOM_FLAG)
       
  9178         return -1;
       
  9179     /*
       
  9180      * Then possibly doc type declaration(s) and more Misc
       
  9181      * (doctypedecl Misc*)?
       
  9182      */
       
  9183     GROW;
       
  9184     if(OOM_FLAG)
       
  9185         return -1;
       
  9186     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
       
  9187 
       
  9188     ctxt->inSubset = 1;
       
  9189     xmlParseDocTypeDecl(ctxt);
       
  9190     if(OOM_FLAG)
       
  9191         return -1;
       
  9192     if (RAW == '[') {
       
  9193         ctxt->instate = XML_PARSER_DTD;
       
  9194         xmlParseInternalSubset(ctxt);
       
  9195         if(OOM_FLAG)
       
  9196             return -1;
       
  9197     }
       
  9198 
       
  9199     /*
       
  9200      * Create and update the external subset.
       
  9201      */
       
  9202     ctxt->inSubset = 2;
       
  9203     if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
       
  9204         (!ctxt->disableSAX))
       
  9205         {
       
  9206         ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
       
  9207                                   ctxt->extSubSystem, ctxt->extSubURI);
       
  9208         if(OOM_FLAG)
       
  9209             return -1;
       
  9210         }
       
  9211     ctxt->inSubset = 0;
       
  9212 
       
  9213     ctxt->instate = XML_PARSER_PROLOG;
       
  9214     xmlParseMisc(ctxt);
       
  9215     if(OOM_FLAG)
       
  9216         return -1;
       
  9217     }
       
  9218 
       
  9219     /*
       
  9220      * Time to start parsing the tree itself
       
  9221      */
       
  9222     GROW;
       
  9223     if(OOM_FLAG)
       
  9224         return -1;
       
  9225     if (RAW != '<') {
       
  9226         xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
       
  9227                EMBED_ERRTXT("Start tag expected, '<' not found\n"));
       
  9228     } else {
       
  9229         ctxt->instate = XML_PARSER_CONTENT;
       
  9230         xmlParseElement(ctxt);
       
  9231             if(OOM_FLAG) 
       
  9232             	return -1;        
       
  9233         ctxt->instate = XML_PARSER_EPILOG;
       
  9234 
       
  9235 
       
  9236         /*
       
  9237          * The Misc part at the end
       
  9238          */
       
  9239         xmlParseMisc(ctxt);
       
  9240         if(OOM_FLAG)
       
  9241             return -1;
       
  9242         if (RAW != 0) {
       
  9243             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
       
  9244         }
       
  9245         ctxt->instate = XML_PARSER_EOF;
       
  9246     }
       
  9247 
       
  9248     /*
       
  9249      * SAX: end of the document processing.
       
  9250      */
       
  9251     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
       
  9252         {
       
  9253         ctxt->sax->endDocument(ctxt->userData);
       
  9254         if(OOM_FLAG)
       
  9255             return -1;
       
  9256         }
       
  9257 
       
  9258     /*
       
  9259      * Remove locally kept entity definitions if the tree was not built
       
  9260      */
       
  9261     if ((ctxt->myDoc != NULL) &&
       
  9262         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))
       
  9263     {
       
  9264         xmlFreeDoc(ctxt->myDoc);
       
  9265         ctxt->myDoc = NULL;
       
  9266     }
       
  9267 
       
  9268     if (! ctxt->wellFormed) {
       
  9269         ctxt->valid = 0;
       
  9270         return(-1);
       
  9271     }
       
  9272     return(0);
       
  9273 }
       
  9274 
       
  9275 /**
       
  9276  * xmlParseExtParsedEnt:
       
  9277  * @param ctxt an XML parser context
       
  9278  *
       
  9279  * parse a general parsed entity
       
  9280  * An external general parsed entity is well-formed if it matches the
       
  9281  * production labeled extParsedEnt.
       
  9282  *
       
  9283  * [78] extParsedEnt ::= TextDecl? content
       
  9284  *
       
  9285  * Returns 0, -1 in case of error. the parser context is augmented
       
  9286  *                as a result of the parsing.
       
  9287  */
       
  9288 
       
  9289 XMLPUBFUNEXPORT int
       
  9290 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
       
  9291     xmlChar start[4];
       
  9292     xmlCharEncoding enc;
       
  9293     LOAD_GS_SAFE_CTXT(ctxt)
       
  9294 
       
  9295     xmlDefaultSAXHandlerInit();
       
  9296     if(OOM_FLAG)
       
  9297         return -1;
       
  9298 
       
  9299     xmlDetectSAX2(ctxt);
       
  9300     if(OOM_FLAG)
       
  9301         return -1;
       
  9302 
       
  9303     GROW;
       
  9304     if(OOM_FLAG)
       
  9305         return -1;
       
  9306     /*
       
  9307      * SAX: beginning of the document processing.
       
  9308      */
       
  9309     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
       
  9310     {
       
  9311         ctxt->sax->setDocumentLocator(ctxt->userData, (xmlSAXLocatorPtr)&xmlDefaultSAXLocator);
       
  9312     }
       
  9313     /*
       
  9314      * Get the 4 first bytes and decode the charset
       
  9315      * if enc != XML_CHAR_ENCODING_NONE
       
  9316      * plug some encoding conversion routines.
       
  9317      */
       
  9318     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
       
  9319         start[0] = RAW;
       
  9320         start[1] = NXT(1);
       
  9321         start[2] = NXT(2);
       
  9322         start[3] = NXT(3);
       
  9323         enc = xmlDetectCharEncoding(start, 4);
       
  9324         if (enc != XML_CHAR_ENCODING_NONE) {
       
  9325             xmlSwitchEncoding(ctxt, enc);
       
  9326             if(OOM_FLAG)
       
  9327                 return -1;
       
  9328         }
       
  9329     }
       
  9330 
       
  9331     if (CUR == 0) {
       
  9332         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
       
  9333     }
       
  9334 
       
  9335     /*
       
  9336      * Check for the XMLDecl in the Prolog.
       
  9337      */
       
  9338     GROW;
       
  9339     if(OOM_FLAG)
       
  9340         return -1;
       
  9341 
       
  9342     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
       
  9343 
       
  9344     /*
       
  9345      * Note that we will switch encoding on the fly.
       
  9346      */
       
  9347     xmlParseXMLDecl(ctxt);
       
  9348     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  9349         /*
       
  9350          * The XML REC instructs us to stop parsing right here
       
  9351          */
       
  9352         return(-1);
       
  9353     }
       
  9354     SKIP_BLANKS;
       
  9355     } else {
       
  9356     ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
       
  9357     }
       
  9358     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
       
  9359         ctxt->sax->startDocument(ctxt->userData);
       
  9360 
       
  9361     /*
       
  9362      * Doing validity checking on chunk doesn't make sense
       
  9363      */
       
  9364     ctxt->instate = XML_PARSER_CONTENT;
       
  9365     ctxt->validate = 0;
       
  9366     ctxt->loadsubset = 0;
       
  9367     ctxt->depth = 0;
       
  9368 
       
  9369     xmlParseContent(ctxt);
       
  9370 
       
  9371     if ((RAW == '<') && (NXT(1) == '/')) {
       
  9372         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
  9373     } else if (RAW != 0) {
       
  9374         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
       
  9375     }
       
  9376 
       
  9377     /*
       
  9378      * SAX: end of the document processing.
       
  9379      */
       
  9380     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
       
  9381         ctxt->sax->endDocument(ctxt->userData);
       
  9382 
       
  9383     if (! ctxt->wellFormed) return(-1);
       
  9384     return(0);
       
  9385 }
       
  9386 
       
  9387 #ifdef LIBXML_PUSH_ENABLED
       
  9388 /************************************************************************
       
  9389  *                                                                      *
       
  9390  *      Progressive parsing interfaces                                  *
       
  9391  *                                                                      *
       
  9392  ************************************************************************/
       
  9393 
       
  9394 /**
       
  9395  * xmlParseLookupSequence:
       
  9396  * @param ctxt an XML parser context
       
  9397  * @param first the first char to lookup
       
  9398  * @param next the next char to lookup or zero
       
  9399  * @param third the next char to lookup or zero
       
  9400  *
       
  9401  * Try to find if a sequence (first, next, third) or  just (first next) or
       
  9402  * (first) is available in the input stream.
       
  9403  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
       
  9404  * to avoid rescanning sequences of bytes, it DOES change the state of the
       
  9405  * parser, do not use liberally.
       
  9406  *
       
  9407  * Returns the index to the current parsing point if the full sequence
       
  9408  *      is available, -1 otherwise.
       
  9409  */
       
  9410 static int
       
  9411 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
       
  9412                        xmlChar next, xmlChar third) {
       
  9413     int base, len;
       
  9414     xmlParserInputPtr in;
       
  9415     const xmlChar *buf;
       
  9416 
       
  9417     in = ctxt->input;
       
  9418     if (in == NULL) return(-1);
       
  9419     base = in->cur - in->base;
       
  9420     if (base < 0) return(-1);
       
  9421     if (ctxt->checkIndex > base)
       
  9422         base = ctxt->checkIndex;
       
  9423     if (in->buf == NULL) {
       
  9424     buf = in->base;
       
  9425     len = in->length;
       
  9426     } else {
       
  9427     buf = in->buf->buffer->content;
       
  9428     len = in->buf->buffer->use;
       
  9429     }
       
  9430     /* take into account the sequence length */
       
  9431     if (third) len -= 2;
       
  9432     else if (next) len --;
       
  9433     for (;base < len;base++) {
       
  9434         if (buf[base] == first) {
       
  9435         if (third != 0) {
       
  9436         if ((buf[base + 1] != next) ||
       
  9437             (buf[base + 2] != third)) continue;
       
  9438         } else if (next != 0) {
       
  9439         if (buf[base + 1] != next) continue;
       
  9440         }
       
  9441         ctxt->checkIndex = 0;
       
  9442 #ifdef DEBUG_PUSH
       
  9443         if (next == 0)
       
  9444         xmlGenericError(xmlGenericErrorContext,
       
  9445             "PP: lookup '%c' found at %d\n",
       
  9446             first, base);
       
  9447         else if (third == 0)
       
  9448         xmlGenericError(xmlGenericErrorContext,
       
  9449             "PP: lookup '%c%c' found at %d\n",
       
  9450             first, next, base);
       
  9451         else
       
  9452         xmlGenericError(xmlGenericErrorContext,
       
  9453             "PP: lookup '%c%c%c' found at %d\n",
       
  9454             first, next, third, base);
       
  9455 #endif
       
  9456         return(base - (in->cur - in->base));
       
  9457     }
       
  9458     }
       
  9459     ctxt->checkIndex = base;
       
  9460 #ifdef DEBUG_PUSH
       
  9461     if (next == 0)
       
  9462     xmlGenericError(xmlGenericErrorContext,
       
  9463         "PP: lookup '%c' failed\n", first);
       
  9464     else if (third == 0)
       
  9465     xmlGenericError(xmlGenericErrorContext,
       
  9466         "PP: lookup '%c%c' failed\n", first, next);
       
  9467     else
       
  9468     xmlGenericError(xmlGenericErrorContext,
       
  9469         "PP: lookup '%c%c%c' failed\n", first, next, third);
       
  9470 #endif
       
  9471     return(-1);
       
  9472 }
       
  9473 
       
  9474 /**
       
  9475  * xmlParseGetLasts:
       
  9476  * @param ctxt an XML parser context
       
  9477  * @param lastlt pointer to store the last '<' from the input
       
  9478  * @param lastgt pointer to store the last '>' from the input
       
  9479  *
       
  9480  * Lookup the last < and > in the current chunk
       
  9481  */
       
  9482 static void
       
  9483 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
       
  9484                  const xmlChar **lastgt) {
       
  9485     const xmlChar *tmp;
       
  9486 
       
  9487     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
       
  9488         xmlGenericError(xmlGenericErrorContext,
       
  9489             EMBED_ERRTXT("Internal error: xmlParseGetLasts\n"));
       
  9490         return;
       
  9491     }
       
  9492     if ((ctxt->progressive == 1) && (ctxt->inputNr == 1)) {
       
  9493         tmp = ctxt->input->end;
       
  9494     tmp--;
       
  9495     while ((tmp >= ctxt->input->base) && (*tmp != '<') &&
       
  9496            (*tmp != '>')) tmp--;
       
  9497     if (tmp < ctxt->input->base) {
       
  9498         *lastlt = NULL;
       
  9499         *lastgt = NULL;
       
  9500     } else if (*tmp == '<') {
       
  9501         *lastlt = tmp;
       
  9502         tmp--;
       
  9503         while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
       
  9504         if (tmp < ctxt->input->base)
       
  9505             *lastgt = NULL;
       
  9506         else
       
  9507             *lastgt = tmp;
       
  9508     } else {
       
  9509         *lastgt = tmp;
       
  9510         tmp--;
       
  9511         while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
       
  9512         if (tmp < ctxt->input->base)
       
  9513             *lastlt = NULL;
       
  9514         else
       
  9515             *lastlt = tmp;
       
  9516     }
       
  9517 
       
  9518     } else {
       
  9519         *lastlt = NULL;
       
  9520         *lastgt = NULL;
       
  9521     }
       
  9522 }
       
  9523 /**
       
  9524  * xmlParseTryOrFinish:
       
  9525  * @param ctxt an XML parser context
       
  9526  * @param terminate last chunk indicator
       
  9527  *
       
  9528  * Try to progress on parsing
       
  9529  *
       
  9530  * Returns zero if no parsing was possible
       
  9531  */
       
  9532 static int
       
  9533 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
       
  9534     int ret = 0;
       
  9535     int avail, tlen;
       
  9536     xmlChar cur, next;
       
  9537     const xmlChar *lastlt, *lastgt;
       
  9538     LOAD_GS_SAFE_CTXT(ctxt)
       
  9539 
       
  9540     if (ctxt->input == NULL)
       
  9541         return(0);
       
  9542 
       
  9543 #ifdef DEBUG_PUSH
       
  9544     switch (ctxt->instate) {
       
  9545     case XML_PARSER_EOF:
       
  9546         xmlGenericError(xmlGenericErrorContext,
       
  9547             "PP: try EOF\n"); break;
       
  9548     case XML_PARSER_START:
       
  9549         xmlGenericError(xmlGenericErrorContext,
       
  9550             "PP: try START\n"); break;
       
  9551     case XML_PARSER_MISC:
       
  9552         xmlGenericError(xmlGenericErrorContext,
       
  9553             "PP: try MISC\n");break;
       
  9554     case XML_PARSER_COMMENT:
       
  9555         xmlGenericError(xmlGenericErrorContext,
       
  9556             "PP: try COMMENT\n");break;
       
  9557     case XML_PARSER_PROLOG:
       
  9558         xmlGenericError(xmlGenericErrorContext,
       
  9559             "PP: try PROLOG\n");break;
       
  9560     case XML_PARSER_START_TAG:
       
  9561         xmlGenericError(xmlGenericErrorContext,
       
  9562             "PP: try START_TAG\n");break;
       
  9563     case XML_PARSER_CONTENT:
       
  9564         xmlGenericError(xmlGenericErrorContext,
       
  9565             "PP: try CONTENT\n");break;
       
  9566     case XML_PARSER_CDATA_SECTION:
       
  9567         xmlGenericError(xmlGenericErrorContext,
       
  9568             "PP: try CDATA_SECTION\n");break;
       
  9569     case XML_PARSER_END_TAG:
       
  9570         xmlGenericError(xmlGenericErrorContext,
       
  9571             "PP: try END_TAG\n");break;
       
  9572     case XML_PARSER_ENTITY_DECL:
       
  9573         xmlGenericError(xmlGenericErrorContext,
       
  9574             "PP: try ENTITY_DECL\n");break;
       
  9575     case XML_PARSER_ENTITY_VALUE:
       
  9576         xmlGenericError(xmlGenericErrorContext,
       
  9577             "PP: try ENTITY_VALUE\n");break;
       
  9578     case XML_PARSER_ATTRIBUTE_VALUE:
       
  9579         xmlGenericError(xmlGenericErrorContext,
       
  9580             "PP: try ATTRIBUTE_VALUE\n");break;
       
  9581     case XML_PARSER_DTD:
       
  9582         xmlGenericError(xmlGenericErrorContext,
       
  9583             "PP: try DTD\n");break;
       
  9584     case XML_PARSER_EPILOG:
       
  9585         xmlGenericError(xmlGenericErrorContext,
       
  9586             "PP: try EPILOG\n");break;
       
  9587     case XML_PARSER_PI:
       
  9588         xmlGenericError(xmlGenericErrorContext,
       
  9589             "PP: try PI\n");break;
       
  9590         case XML_PARSER_IGNORE:
       
  9591             xmlGenericError(xmlGenericErrorContext,
       
  9592             "PP: try IGNORE\n");break;
       
  9593     }
       
  9594 #endif
       
  9595 
       
  9596     if ((ctxt->input != NULL) && (ctxt->input->cur - ctxt->input->base > 4096)) {
       
  9597         xmlSHRINK(ctxt);
       
  9598         ctxt->checkIndex = 0;
       
  9599     }
       
  9600 
       
  9601     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
       
  9602 
       
  9603 while (1)
       
  9604 {
       
  9605     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
       
  9606         return(0);
       
  9607 
       
  9608     /*
       
  9609      * Pop-up of finished entities.
       
  9610      */
       
  9611     while ((RAW == 0) && (ctxt->inputNr > 1))
       
  9612         xmlPopInput(ctxt);
       
  9613 
       
  9614     if (ctxt->input == NULL) break;
       
  9615     if (ctxt->input->buf == NULL){
       
  9616         avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
       
  9617     }else{
       
  9618         /*
       
  9619          * If we are operating on converted input, try to flush
       
  9620          * remainng chars to avoid them stalling in the non-converted
       
  9621          * buffer.
       
  9622          */
       
  9623         if ((ctxt->input->buf->raw != NULL) && (ctxt->input->buf->raw->use > 0))
       
  9624         {
       
  9625             int base = ctxt->input->base - ctxt->input->buf->buffer->content;
       
  9626             int current = ctxt->input->cur - ctxt->input->base;
       
  9627             xmlParserInputBufferPush(ctxt->input->buf, 0, "");
       
  9628             ctxt->input->base = ctxt->input->buf->buffer->content + base;
       
  9629             ctxt->input->cur = ctxt->input->base + current;
       
  9630             ctxt->input->end = &ctxt->input->buf->buffer->content[ ctxt->input->buf->buffer->use];
       
  9631         }
       
  9632 
       
  9633         avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
       
  9634     }
       
  9635 
       
  9636     if (avail < 1)
       
  9637         goto done;
       
  9638 
       
  9639     switch (ctxt->instate) {
       
  9640 
       
  9641     case XML_PARSER_EOF:
       
  9642         /*
       
  9643          * Document parsing is done !
       
  9644          */
       
  9645             goto done;
       
  9646 
       
  9647     case XML_PARSER_START:
       
  9648         if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
       
  9649             xmlChar start[4];
       
  9650             xmlCharEncoding enc;
       
  9651 
       
  9652             /*
       
  9653              * Very first chars read from the document flow.
       
  9654              */
       
  9655             if (avail < 4)  goto done;
       
  9656             /*
       
  9657              * Get the 4 first bytes and decode the charset
       
  9658              * if enc != XML_CHAR_ENCODING_NONE
       
  9659              * plug some encoding conversion routines.
       
  9660              */
       
  9661             start[0] = RAW;
       
  9662             start[1] = NXT(1);
       
  9663             start[2] = NXT(2);
       
  9664             start[3] = NXT(3);
       
  9665             enc = xmlDetectCharEncoding(start, 4);
       
  9666             if (enc != XML_CHAR_ENCODING_NONE) {
       
  9667                 xmlSwitchEncoding(ctxt, enc);
       
  9668             }
       
  9669             break;
       
  9670         }
       
  9671 
       
  9672         if (avail < 2)
       
  9673                 goto done;
       
  9674 
       
  9675         cur = ctxt->input->cur[0];
       
  9676         next = ctxt->input->cur[1];
       
  9677 
       
  9678         if (cur == 0) {
       
  9679             if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
       
  9680             {
       
  9681                 ctxt->sax->setDocumentLocator(ctxt->userData, (xmlSAXLocatorPtr)&xmlDefaultSAXLocator);
       
  9682             }
       
  9683             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
       
  9684             ctxt->instate = XML_PARSER_EOF;
       
  9685 #ifdef DEBUG_PUSH
       
  9686             xmlGenericError(xmlGenericErrorContext, "PP: entering EOF\n");
       
  9687 #endif
       
  9688             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
       
  9689                 ctxt->sax->endDocument(ctxt->userData);
       
  9690             goto done;
       
  9691         }
       
  9692 
       
  9693         if ((cur == '<') && (next == '?')) {
       
  9694             /* PI or XML decl */
       
  9695             if (avail < 5) return(ret);
       
  9696             if ((!terminate) && (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
       
  9697                 return(ret);
       
  9698             if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
       
  9699             {
       
  9700                 ctxt->sax->setDocumentLocator(ctxt->userData, (xmlSAXLocatorPtr)&xmlDefaultSAXLocator);
       
  9701             }
       
  9702             if ((ctxt->input->cur[2] == 'x') &&
       
  9703                 (ctxt->input->cur[3] == 'm') &&
       
  9704                 (ctxt->input->cur[4] == 'l') &&
       
  9705                 (IS_BLANK_CH(ctxt->input->cur[5])))
       
  9706             {
       
  9707                 ret += 5;
       
  9708 #ifdef DEBUG_PUSH
       
  9709                 xmlGenericError(xmlGenericErrorContext, "PP: Parsing XML Decl\n");
       
  9710 #endif
       
  9711                 xmlParseXMLDecl(ctxt);
       
  9712                 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
       
  9713                     /*
       
  9714                     * The XML REC instructs us to stop parsing right
       
  9715                     * here
       
  9716                     */
       
  9717                     ctxt->instate = XML_PARSER_EOF;
       
  9718                     return(0);
       
  9719                 }
       
  9720 
       
  9721                 ctxt->standalone = ctxt->input->standalone;
       
  9722 
       
  9723                 if ((ctxt->encoding == NULL) && (ctxt->input->encoding != NULL))
       
  9724                     ctxt->encoding = xmlStrdup(ctxt->input->encoding);
       
  9725 
       
  9726                 if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
       
  9727                     ctxt->sax->startDocument(ctxt->userData);
       
  9728 
       
  9729                 ctxt->instate = XML_PARSER_MISC;
       
  9730 #ifdef DEBUG_PUSH
       
  9731                 xmlGenericError(xmlGenericErrorContext, "PP: entering MISC\n");
       
  9732 #endif
       
  9733             }
       
  9734             else
       
  9735             {
       
  9736                 ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
       
  9737                 if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
       
  9738                     ctxt->sax->startDocument(ctxt->userData);
       
  9739 
       
  9740                 ctxt->instate = XML_PARSER_MISC;
       
  9741 #ifdef DEBUG_PUSH
       
  9742                 xmlGenericError(xmlGenericErrorContext, "PP: entering MISC\n");
       
  9743 #endif
       
  9744             }
       
  9745         } // if ((cur == '<') && (next == '?'))
       
  9746         else
       
  9747         {
       
  9748             if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
       
  9749             {
       
  9750                 ctxt->sax->setDocumentLocator(ctxt->userData, (xmlSAXLocatorPtr) &xmlDefaultSAXLocator);
       
  9751             }
       
  9752             ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION); 
       
  9753             if(OOM_FLAG)
       
  9754                 {
       
  9755                 xmlParserOOMErr(ctxt);
       
  9756                 return(0);
       
  9757                 }
       
  9758 
       
  9759             if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
       
  9760             {
       
  9761                 ctxt->sax->startDocument(ctxt->userData);
       
  9762                 if(OOM_FLAG)
       
  9763                     {
       
  9764                     xmlParserOOMErr(ctxt);
       
  9765                     return(0);
       
  9766                     }
       
  9767             }
       
  9768             ctxt->instate = XML_PARSER_MISC;
       
  9769 #ifdef DEBUG_PUSH
       
  9770             xmlGenericError(xmlGenericErrorContext, "PP: entering MISC\n");
       
  9771 #endif
       
  9772         }
       
  9773         break;
       
  9774 
       
  9775     case XML_PARSER_START_TAG: {
       
  9776         const xmlChar *name;
       
  9777         const xmlChar *prefix;
       
  9778         const xmlChar *URI;
       
  9779         int nsNr = ctxt->nsNr;
       
  9780 
       
  9781         if ((avail < 2) && (ctxt->inputNr == 1))
       
  9782             goto done;
       
  9783 
       
  9784         cur = ctxt->input->cur[0];
       
  9785         if (cur != '<') {
       
  9786             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
       
  9787             ctxt->instate = XML_PARSER_EOF;
       
  9788             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
       
  9789                 ctxt->sax->endDocument(ctxt->userData);
       
  9790             goto done;
       
  9791         }
       
  9792 
       
  9793         if (!terminate) {
       
  9794             if (ctxt->progressive) {
       
  9795                 /* > can be found unescaped in attribute values */
       
  9796                 if ((lastlt == NULL) || (ctxt->input->cur >= lastlt))
       
  9797                     goto done;
       
  9798             }
       
  9799             else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
       
  9800                     goto done;
       
  9801             }
       
  9802         }
       
  9803         if (ctxt->spaceNr == 0){
       
  9804             spacePush(ctxt, -1);
       
  9805         }else{
       
  9806             spacePush(ctxt, *ctxt->space);
       
  9807         }
       
  9808 #ifdef LIBXML_SAX1_ENABLED
       
  9809         if (ctxt->sax2)
       
  9810             {
       
  9811 #endif /* LIBXML_SAX1_ENABLED */
       
  9812             name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
       
  9813 #ifdef LIBXML_SAX1_ENABLED
       
  9814             }
       
  9815         else
       
  9816             {
       
  9817             name = xmlParseStartTag(ctxt);
       
  9818             }
       
  9819 #endif /* LIBXML_SAX1_ENABLED */
       
  9820         if(OOM_FLAG) 
       
  9821             {
       
  9822             // Note: xmlParseStartTag2 should have set parser into error state already
       
  9823             xmlParserOOMErr(ctxt);   // just in case
       
  9824             return(0);
       
  9825             }
       
  9826 
       
  9827         if (name == NULL) {
       
  9828             spacePop(ctxt);
       
  9829             ctxt->instate = XML_PARSER_EOF;
       
  9830             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
       
  9831                 ctxt->sax->endDocument(ctxt->userData);
       
  9832             goto done;
       
  9833         }
       
  9834 
       
  9835 #ifdef LIBXML_VALID_ENABLED
       
  9836         /*
       
  9837          * [ VC: Root Element Type ]
       
  9838          * The Name in the document type declaration must match
       
  9839          * the element type of the root element.
       
  9840          */
       
  9841         if (ctxt->validate   &&
       
  9842             ctxt->wellFormed && ctxt->myDoc &&
       
  9843             ctxt->node  && (ctxt->node == ctxt->myDoc->children))
       
  9844         {
       
  9845             ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
       
  9846         }
       
  9847 #endif /* LIBXML_VALID_ENABLED */
       
  9848 
       
  9849         /*
       
  9850          * Check for an Empty Element.
       
  9851          */
       
  9852         if ((RAW == '/') && (NXT(1) == '>')) {
       
  9853             SKIP(2);
       
  9854 
       
  9855             if (ctxt->sax2) {
       
  9856                 if ((ctxt->sax != NULL) &&
       
  9857                     (ctxt->sax->endElementNs != NULL) &&
       
  9858                     (!ctxt->disableSAX))
       
  9859                 {
       
  9860                     ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
       
  9861                 }
       
  9862 #ifdef LIBXML_SAX1_ENABLED
       
  9863             } else {
       
  9864                 if ((ctxt->sax != NULL) &&
       
  9865                     (ctxt->sax->endElement != NULL) &&
       
  9866                     (!ctxt->disableSAX))
       
  9867                 {
       
  9868                     ctxt->sax->endElement(ctxt->userData, name);
       
  9869                 }
       
  9870 #endif /* LIBXML_SAX1_ENABLED */
       
  9871             }
       
  9872             spacePop(ctxt);
       
  9873             if (ctxt->nameNr == 0) {
       
  9874                 ctxt->instate = XML_PARSER_EPILOG;
       
  9875             } else {
       
  9876                 ctxt->instate = XML_PARSER_CONTENT;
       
  9877             }
       
  9878 // XE: BEGIN NEW CODE
       
  9879             // Remove from namsespaces stack all namespaces
       
  9880             // that were declared in this empty element
       
  9881             nsPop(ctxt, ctxt->lastNsNr*2);
       
  9882 // XE: END NEW CODE
       
  9883             break;
       
  9884         } // if ((RAW == '/') && (NXT(1) == '>'))
       
  9885 
       
  9886         if (RAW == '>') {
       
  9887             NEXT;
       
  9888         } else {
       
  9889             xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED, EMBED_ERRTXT("Couldn't find end of Start Tag %s\n"), name);
       
  9890             nodePop(ctxt);
       
  9891             spacePop(ctxt);
       
  9892         }
       
  9893         if (ctxt->sax2){
       
  9894             nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
       
  9895 #ifdef LIBXML_SAX1_ENABLED
       
  9896         }else{
       
  9897             namePush(ctxt, name);
       
  9898 #endif /* LIBXML_SAX1_ENABLED */
       
  9899         }
       
  9900 
       
  9901         ctxt->instate = XML_PARSER_CONTENT;
       
  9902         break;
       
  9903         }
       
  9904 
       
  9905     case XML_PARSER_CONTENT: {
       
  9906         const xmlChar *test;
       
  9907         unsigned int cons;
       
  9908         if ((avail < 2) && (ctxt->inputNr == 1))
       
  9909             goto done;
       
  9910         cur = ctxt->input->cur[0];
       
  9911         next = ctxt->input->cur[1];
       
  9912 
       
  9913         test = CUR_PTR;
       
  9914             cons = ctxt->input->consumed;
       
  9915         if ((cur == '<') && (next == '/')) {
       
  9916             ctxt->instate = XML_PARSER_END_TAG;
       
  9917             break;
       
  9918             } else if ((cur == '<') && (next == '?')) {
       
  9919             if ((!terminate) &&
       
  9920                 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
       
  9921             goto done;
       
  9922             xmlParsePI(ctxt);
       
  9923         } else if ((cur == '<') && (next != '!')) {
       
  9924             ctxt->instate = XML_PARSER_START_TAG;
       
  9925             break;
       
  9926         } else if ((cur == '<') && (next == '!') &&
       
  9927                    (ctxt->input->cur[2] == '-') &&
       
  9928                (ctxt->input->cur[3] == '-')) {
       
  9929             if ((!terminate) &&
       
  9930                 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
       
  9931             goto done;
       
  9932             xmlParseComment(ctxt);
       
  9933             ctxt->instate = XML_PARSER_CONTENT;
       
  9934         } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
       
  9935             (ctxt->input->cur[2] == '[') &&
       
  9936             (ctxt->input->cur[3] == 'C') &&
       
  9937             (ctxt->input->cur[4] == 'D') &&
       
  9938             (ctxt->input->cur[5] == 'A') &&
       
  9939             (ctxt->input->cur[6] == 'T') &&
       
  9940             (ctxt->input->cur[7] == 'A') &&
       
  9941             (ctxt->input->cur[8] == '[')) {
       
  9942             SKIP(9);
       
  9943             ctxt->instate = XML_PARSER_CDATA_SECTION;
       
  9944             break;
       
  9945         } else if ((cur == '<') && (next == '!') &&
       
  9946                    (avail < 9)) {
       
  9947             goto done;
       
  9948         } else if (cur == '&') {
       
  9949             if ((!terminate) &&
       
  9950                 (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
       
  9951             goto done;
       
  9952             xmlParseReference(ctxt);
       
  9953             if(OOM_FLAG)
       
  9954                 {
       
  9955                 return(0);
       
  9956                 }
       
  9957         } else {
       
  9958             
       
  9959             /*
       
  9960              * Goal of the following test is:
       
  9961              *  - minimize calls to the SAX 'character' callback
       
  9962              *    when they are mergeable
       
  9963              *  - handle an problem for isBlank when we only parse
       
  9964              *    a sequence of blank chars and the next one is
       
  9965              *    not available to check against '<' presence.
       
  9966              *  - tries to homogenize the differences in SAX
       
  9967              *    callbacks between the push and pull versions
       
  9968              *    of the parser.
       
  9969              */
       
  9970             if ((ctxt->inputNr == 1) &&
       
  9971                 (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
       
  9972             if (!terminate) {
       
  9973                 if (ctxt->progressive) {
       
  9974                 if ((lastlt == NULL) ||
       
  9975                     (ctxt->input->cur > lastlt))
       
  9976                     goto done;
       
  9977                 } else if (xmlParseLookupSequence(ctxt,
       
  9978                                                   '<', 0, 0) < 0) {
       
  9979                 goto done;
       
  9980                 }
       
  9981             }
       
  9982                     }
       
  9983             ctxt->checkIndex = 0;
       
  9984             xmlParseCharData(ctxt, 0);
       
  9985         }
       
  9986         /*
       
  9987          * Pop-up of finished entities.
       
  9988          */
       
  9989         while ((RAW == 0) && (ctxt->inputNr > 1))
       
  9990             xmlPopInput(ctxt);
       
  9991         if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
       
  9992             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
       
  9993                         EMBED_ERRTXT("detected an error in element content\n"));
       
  9994             ctxt->instate = XML_PARSER_EOF;
       
  9995             break;
       
  9996         }
       
  9997         break;
       
  9998         }
       
  9999 case XML_PARSER_END_TAG:
       
 10000         if (avail < 2)
       
 10001             goto done;
       
 10002         if (!terminate) {
       
 10003             if (ctxt->progressive) {
       
 10004                 if ((lastgt == NULL) || (ctxt->input->cur > lastgt))
       
 10005                 goto done;
       
 10006             } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
       
 10007             goto done;
       
 10008             }
       
 10009         }
       
 10010         if (ctxt->sax2) {
       
 10011             xmlParseEndTag2(ctxt,
       
 10012                    (xmlChar*) ctxt->pushTab[ctxt->nameNr * 3 - 3],
       
 10013                    (xmlChar*) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
       
 10014                (int) (long)   ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
       
 10015             nameNsPop(ctxt);
       
 10016         }
       
 10017 #ifdef LIBXML_SAX1_ENABLED
       
 10018           else
       
 10019             xmlParseEndTag1(ctxt, 0);
       
 10020 #endif /* LIBXML_SAX1_ENABLED */
       
 10021         if (ctxt->nameNr == 0) {
       
 10022             ctxt->instate = XML_PARSER_EPILOG;
       
 10023         } else {
       
 10024             ctxt->instate = XML_PARSER_CONTENT;
       
 10025         }
       
 10026         break;
       
 10027             case XML_PARSER_CDATA_SECTION: {
       
 10028             /*
       
 10029          * The Push mode need to have the SAX callback for
       
 10030          * cdataBlock merge back contiguous callbacks.
       
 10031          */
       
 10032         int base;
       
 10033 
       
 10034         base = xmlParseLookupSequence(ctxt, ']', ']', '>');
       
 10035         if (base < 0) {
       
 10036             if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
       
 10037                 int tmp;
       
 10038 
       
 10039             tmp = xmlCheckCdataPush(ctxt->input->cur,
       
 10040                                     XML_PARSER_BIG_BUFFER_SIZE);
       
 10041             if (tmp < 0) {
       
 10042                 tmp = -tmp;
       
 10043                 ctxt->input->cur += tmp;
       
 10044                 goto encoding_error;
       
 10045             }
       
 10046             if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
       
 10047                 if (ctxt->sax->cdataBlock != NULL)
       
 10048                 ctxt->sax->cdataBlock(ctxt->userData,
       
 10049                                       ctxt->input->cur, tmp);
       
 10050                 else if (ctxt->sax->characters != NULL)
       
 10051                 ctxt->sax->characters(ctxt->userData,
       
 10052                                       ctxt->input->cur, tmp);
       
 10053             }
       
 10054             SKIPL(tmp);
       
 10055             ctxt->checkIndex = 0;
       
 10056             }
       
 10057             goto done;
       
 10058         } else {
       
 10059             int tmp;
       
 10060 
       
 10061             tmp = xmlCheckCdataPush(ctxt->input->cur, base);
       
 10062             if ((tmp < 0) || (tmp != base)) {
       
 10063             tmp = -tmp;
       
 10064             ctxt->input->cur += tmp;
       
 10065             goto encoding_error;
       
 10066             }
       
 10067             if ((ctxt->sax != NULL) && (base > 0) &&
       
 10068             (!ctxt->disableSAX)) {
       
 10069             if (ctxt->sax->cdataBlock != NULL)
       
 10070                 ctxt->sax->cdataBlock(ctxt->userData,
       
 10071                           ctxt->input->cur, base);
       
 10072             else if (ctxt->sax->characters != NULL)
       
 10073                 ctxt->sax->characters(ctxt->userData,
       
 10074                           ctxt->input->cur, base);
       
 10075             }
       
 10076             SKIPL(base + 3);
       
 10077             ctxt->checkIndex = 0;
       
 10078             ctxt->instate = XML_PARSER_CONTENT;
       
 10079 #ifdef DEBUG_PUSH
       
 10080             xmlGenericError(xmlGenericErrorContext,
       
 10081                 "PP: entering CONTENT\n");
       
 10082 #endif
       
 10083         }
       
 10084         break;
       
 10085         }
       
 10086             case XML_PARSER_MISC:
       
 10087         SKIP_BLANKS;
       
 10088         if (ctxt->input->buf == NULL)
       
 10089             avail = ctxt->input->length -
       
 10090                     (ctxt->input->cur - ctxt->input->base);
       
 10091         else
       
 10092             avail = ctxt->input->buf->buffer->use -
       
 10093                     (ctxt->input->cur - ctxt->input->base);
       
 10094         if (avail < 2)
       
 10095             goto done;
       
 10096         cur = ctxt->input->cur[0];
       
 10097         next = ctxt->input->cur[1];
       
 10098             if ((cur == '<') && (next == '?')) {
       
 10099             if ((!terminate) &&
       
 10100                 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
       
 10101             goto done;
       
 10102 #ifdef DEBUG_PUSH
       
 10103             xmlGenericError(xmlGenericErrorContext,
       
 10104                 "PP: Parsing PI\n");
       
 10105 #endif
       
 10106             xmlParsePI(ctxt);
       
 10107         } else if ((cur == '<') && (next == '!') &&
       
 10108             (ctxt->input->cur[2] == '-') &&
       
 10109             (ctxt->input->cur[3] == '-')) {
       
 10110             if ((!terminate) &&
       
 10111                 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
       
 10112             goto done;
       
 10113 #ifdef DEBUG_PUSH
       
 10114             xmlGenericError(xmlGenericErrorContext,
       
 10115                 "PP: Parsing Comment\n");
       
 10116 #endif
       
 10117             xmlParseComment(ctxt);
       
 10118             ctxt->instate = XML_PARSER_MISC;
       
 10119         } else if ((cur == '<') && (next == '!') &&
       
 10120             (ctxt->input->cur[2] == 'D') &&
       
 10121             (ctxt->input->cur[3] == 'O') &&
       
 10122             (ctxt->input->cur[4] == 'C') &&
       
 10123             (ctxt->input->cur[5] == 'T') &&
       
 10124             (ctxt->input->cur[6] == 'Y') &&
       
 10125             (ctxt->input->cur[7] == 'P') &&
       
 10126             (ctxt->input->cur[8] == 'E')) {
       
 10127             if ((!terminate) &&
       
 10128                 (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
       
 10129             goto done;
       
 10130 #ifdef DEBUG_PUSH
       
 10131             xmlGenericError(xmlGenericErrorContext,
       
 10132                 "PP: Parsing internal subset\n");
       
 10133 #endif
       
 10134             ctxt->inSubset = 1;
       
 10135             xmlParseDocTypeDecl(ctxt);
       
 10136             if (RAW == '[') {
       
 10137             ctxt->instate = XML_PARSER_DTD;
       
 10138 #ifdef DEBUG_PUSH
       
 10139             xmlGenericError(xmlGenericErrorContext,
       
 10140                 "PP: entering DTD\n");
       
 10141 #endif
       
 10142             } else {
       
 10143                 /*
       
 10144                  * Create and update the external subset.
       
 10145                  */
       
 10146                 ctxt->inSubset = 2;
       
 10147                 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
       
 10148                     (ctxt->sax->externalSubset != NULL))
       
 10149                 {
       
 10150                     ctxt->sax->externalSubset(ctxt->userData,
       
 10151                         ctxt->intSubName, ctxt->extSubSystem,
       
 10152                         ctxt->extSubURI);
       
 10153                 }
       
 10154                 ctxt->inSubset = 0;
       
 10155                 ctxt->instate = XML_PARSER_PROLOG;
       
 10156 #ifdef DEBUG_PUSH
       
 10157                 xmlGenericError(xmlGenericErrorContext, "PP: entering PROLOG\n");
       
 10158 #endif
       
 10159             }
       
 10160         } else if ((cur == '<') && (next == '!') && (avail < 9)) {
       
 10161             goto done;
       
 10162         } else {
       
 10163             ctxt->instate = XML_PARSER_START_TAG;
       
 10164             ctxt->progressive = 1;
       
 10165             xmlParseGetLasts(ctxt, &lastlt, &lastgt);
       
 10166 #ifdef DEBUG_PUSH
       
 10167             xmlGenericError(xmlGenericErrorContext,
       
 10168                 "PP: entering START_TAG\n");
       
 10169 #endif
       
 10170         }
       
 10171         break;
       
 10172             case XML_PARSER_PROLOG:
       
 10173         SKIP_BLANKS;
       
 10174         if (ctxt->input->buf == NULL)
       
 10175             avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
       
 10176         else
       
 10177             avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
       
 10178         if (avail < 2)
       
 10179             goto done;
       
 10180         cur = ctxt->input->cur[0];
       
 10181         next = ctxt->input->cur[1];
       
 10182             if ((cur == '<') && (next == '?')) {
       
 10183             if ((!terminate) &&
       
 10184                 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
       
 10185             goto done;
       
 10186 #ifdef DEBUG_PUSH
       
 10187             xmlGenericError(xmlGenericErrorContext,
       
 10188                 "PP: Parsing PI\n");
       
 10189 #endif
       
 10190             xmlParsePI(ctxt);
       
 10191         } else if ((cur == '<') && (next == '!') &&
       
 10192             (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
       
 10193             if ((!terminate) &&
       
 10194                 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
       
 10195             goto done;
       
 10196 #ifdef DEBUG_PUSH
       
 10197             xmlGenericError(xmlGenericErrorContext,
       
 10198                 "PP: Parsing Comment\n");
       
 10199 #endif
       
 10200             xmlParseComment(ctxt);
       
 10201             ctxt->instate = XML_PARSER_PROLOG;
       
 10202         } else if ((cur == '<') && (next == '!') &&
       
 10203                    (avail < 4)) {
       
 10204             goto done;
       
 10205         } else {
       
 10206             ctxt->instate = XML_PARSER_START_TAG;
       
 10207             if (ctxt->progressive == 0)
       
 10208                 ctxt->progressive = 1;
       
 10209             xmlParseGetLasts(ctxt, &lastlt, &lastgt);
       
 10210 #ifdef DEBUG_PUSH
       
 10211             xmlGenericError(xmlGenericErrorContext,
       
 10212                 "PP: entering START_TAG\n");
       
 10213 #endif
       
 10214         }
       
 10215         break;
       
 10216             case XML_PARSER_EPILOG:
       
 10217         SKIP_BLANKS;
       
 10218         if (ctxt->input->buf == NULL)
       
 10219             avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
       
 10220         else
       
 10221             avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
       
 10222         if (avail < 2)
       
 10223             goto done;
       
 10224         cur = ctxt->input->cur[0];
       
 10225         next = ctxt->input->cur[1];
       
 10226             if ((cur == '<') && (next == '?')) {
       
 10227             if ((!terminate) &&
       
 10228                 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
       
 10229             goto done;
       
 10230 #ifdef DEBUG_PUSH
       
 10231             xmlGenericError(xmlGenericErrorContext,
       
 10232                 "PP: Parsing PI\n");
       
 10233 #endif
       
 10234             xmlParsePI(ctxt);
       
 10235             ctxt->instate = XML_PARSER_EPILOG;
       
 10236         } else if ((cur == '<') && (next == '!') &&
       
 10237             (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
       
 10238             if ((!terminate) &&
       
 10239                 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
       
 10240             goto done;
       
 10241 #ifdef DEBUG_PUSH
       
 10242             xmlGenericError(xmlGenericErrorContext,
       
 10243                 "PP: Parsing Comment\n");
       
 10244 #endif
       
 10245             xmlParseComment(ctxt);
       
 10246             ctxt->instate = XML_PARSER_EPILOG;
       
 10247         } else if ((cur == '<') && (next == '!') &&
       
 10248                    (avail < 4)) {
       
 10249             goto done;
       
 10250         } else {
       
 10251             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
       
 10252             ctxt->instate = XML_PARSER_EOF;
       
 10253 #ifdef DEBUG_PUSH
       
 10254             xmlGenericError(xmlGenericErrorContext,
       
 10255                 "PP: entering EOF\n");
       
 10256 #endif
       
 10257             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
       
 10258             ctxt->sax->endDocument(ctxt->userData);
       
 10259             goto done;
       
 10260         }
       
 10261         break;
       
 10262             case XML_PARSER_DTD: {
       
 10263             /*
       
 10264          * Sorry but progressive parsing of the internal subset
       
 10265          * is not expected to be supported. We first check that
       
 10266          * the full content of the internal subset is available and
       
 10267          * the parsing is launched only at that point.
       
 10268          * Internal subset ends up with "']' S? '>'" in an unescaped
       
 10269          * section and not in a ']]>' sequence which are conditional
       
 10270          * sections (whoever argued to keep that crap in XML deserve
       
 10271          * a place in hell !).
       
 10272          */
       
 10273         int base, i;
       
 10274         xmlChar *buf;
       
 10275             xmlChar quote = 0;
       
 10276 
       
 10277         base = ctxt->input->cur - ctxt->input->base;
       
 10278         if (base < 0) return(0);
       
 10279         if (ctxt->checkIndex > base)
       
 10280             base = ctxt->checkIndex;
       
 10281         buf = ctxt->input->buf->buffer->content;
       
 10282         for (;(unsigned int) base < ctxt->input->buf->buffer->use;
       
 10283              base++) {
       
 10284             if (quote != 0) {
       
 10285                 if (buf[base] == quote)
       
 10286                 quote = 0;
       
 10287             continue;
       
 10288             }
       
 10289             if ((quote == 0) && (buf[base] == '<')) {
       
 10290                 int found  = 0;
       
 10291             /* special handling of comments */
       
 10292                 if (((unsigned int) base + 4 <
       
 10293                  ctxt->input->buf->buffer->use) &&
       
 10294                 (buf[base + 1] == '!') &&
       
 10295                 (buf[base + 2] == '-') &&
       
 10296                 (buf[base + 3] == '-')) {
       
 10297                 for (;(unsigned int) base + 3 <
       
 10298                       ctxt->input->buf->buffer->use; base++) {
       
 10299                 if ((buf[base] == '-') &&
       
 10300                     (buf[base + 1] == '-') &&
       
 10301                     (buf[base + 2] == '>')) {
       
 10302                     found = 1;
       
 10303                     base += 2;
       
 10304                     break;
       
 10305                 }
       
 10306                     }
       
 10307                 if (!found) {
       
 10308                     break; /* for */
       
 10309                     }
       
 10310                     continue;
       
 10311             }
       
 10312             }
       
 10313             if (buf[base] == '"') {
       
 10314                 quote = '"';
       
 10315             continue;
       
 10316             }
       
 10317             if (buf[base] == '\'') {
       
 10318                 quote = '\'';
       
 10319             continue;
       
 10320             }
       
 10321             if (buf[base] == ']') {
       
 10322                 if ((unsigned int) base +1 >=
       
 10323                     ctxt->input->buf->buffer->use)
       
 10324                 break;
       
 10325             if (buf[base + 1] == ']') {
       
 10326                 /* conditional crap, skip both ']' ! */
       
 10327                 base++;
       
 10328                 continue;
       
 10329             }
       
 10330                 for (i = 0;
       
 10331              (unsigned int) base + i < ctxt->input->buf->buffer->use;
       
 10332                      i++) {
       
 10333                 if (buf[base + i] == '>')
       
 10334                     goto found_end_int_subset;
       
 10335             }
       
 10336                 break;
       
 10337             }
       
 10338         }
       
 10339         /*
       
 10340          * We didn't found the end of the Internal subset
       
 10341          */
       
 10342         if (quote == 0)
       
 10343             ctxt->checkIndex = base;
       
 10344 #ifdef DEBUG_PUSH
       
 10345         if (next == 0)
       
 10346             xmlGenericError(xmlGenericErrorContext,
       
 10347                 "PP: lookup of int subset end filed\n");
       
 10348 #endif
       
 10349             goto done;
       
 10350 
       
 10351 found_end_int_subset:
       
 10352         xmlParseInternalSubset(ctxt);
       
 10353         if(OOM_FLAG)
       
 10354             {
       
 10355             return 0;
       
 10356             }
       
 10357         ctxt->inSubset = 2;
       
 10358         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
       
 10359             (ctxt->sax->externalSubset != NULL))
       
 10360             ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
       
 10361                 ctxt->extSubSystem, ctxt->extSubURI);
       
 10362         ctxt->inSubset = 0;
       
 10363         ctxt->instate = XML_PARSER_PROLOG;
       
 10364         ctxt->checkIndex = 0;
       
 10365 #ifdef DEBUG_PUSH
       
 10366         xmlGenericError(xmlGenericErrorContext,
       
 10367             "PP: entering PROLOG\n");
       
 10368 #endif
       
 10369                 break;
       
 10370         }
       
 10371             case XML_PARSER_COMMENT:
       
 10372         xmlGenericError(xmlGenericErrorContext,
       
 10373             EMBED_ERRTXT("PP: internal error, state == COMMENT\n"));
       
 10374         ctxt->instate = XML_PARSER_CONTENT;
       
 10375 #ifdef DEBUG_PUSH
       
 10376         xmlGenericError(xmlGenericErrorContext,
       
 10377             "PP: entering CONTENT\n");
       
 10378 #endif
       
 10379         break;
       
 10380             case XML_PARSER_IGNORE:
       
 10381         xmlGenericError(xmlGenericErrorContext,
       
 10382             EMBED_ERRTXT("PP: internal error, state == IGNORE"));
       
 10383             ctxt->instate = XML_PARSER_DTD;
       
 10384 #ifdef DEBUG_PUSH
       
 10385         xmlGenericError(xmlGenericErrorContext,
       
 10386             "PP: entering DTD\n");
       
 10387 #endif
       
 10388             break;
       
 10389             case XML_PARSER_PI:
       
 10390         xmlGenericError(xmlGenericErrorContext,
       
 10391             EMBED_ERRTXT("PP: internal error, state == PI\n"));
       
 10392         ctxt->instate = XML_PARSER_CONTENT;
       
 10393 #ifdef DEBUG_PUSH
       
 10394         xmlGenericError(xmlGenericErrorContext,
       
 10395             "PP: entering CONTENT\n");
       
 10396 #endif
       
 10397         break;
       
 10398             case XML_PARSER_ENTITY_DECL:
       
 10399         xmlGenericError(xmlGenericErrorContext,
       
 10400             EMBED_ERRTXT("PP: internal error, state == ENTITY_DECL\n"));
       
 10401         ctxt->instate = XML_PARSER_DTD;
       
 10402 #ifdef DEBUG_PUSH
       
 10403         xmlGenericError(xmlGenericErrorContext,
       
 10404             "PP: entering DTD\n");
       
 10405 #endif
       
 10406         break;
       
 10407             case XML_PARSER_ENTITY_VALUE:
       
 10408         xmlGenericError(xmlGenericErrorContext,
       
 10409             EMBED_ERRTXT("PP: internal error, state == ENTITY_VALUE\n"));
       
 10410         ctxt->instate = XML_PARSER_CONTENT;
       
 10411 #ifdef DEBUG_PUSH
       
 10412         xmlGenericError(xmlGenericErrorContext,
       
 10413             "PP: entering DTD\n");
       
 10414 #endif
       
 10415         break;
       
 10416             case XML_PARSER_ATTRIBUTE_VALUE:
       
 10417         xmlGenericError(xmlGenericErrorContext,
       
 10418             EMBED_ERRTXT("PP: internal error, state == ATTRIBUTE_VALUE\n"));
       
 10419         ctxt->instate = XML_PARSER_START_TAG;
       
 10420 #ifdef DEBUG_PUSH
       
 10421         xmlGenericError(xmlGenericErrorContext,
       
 10422             "PP: entering START_TAG\n");
       
 10423 #endif
       
 10424         break;
       
 10425             case XML_PARSER_SYSTEM_LITERAL:
       
 10426         xmlGenericError(xmlGenericErrorContext,
       
 10427             EMBED_ERRTXT("PP: internal error, state == SYSTEM_LITERAL\n"));
       
 10428         ctxt->instate = XML_PARSER_START_TAG;
       
 10429 #ifdef DEBUG_PUSH
       
 10430         xmlGenericError(xmlGenericErrorContext,
       
 10431             "PP: entering START_TAG\n");
       
 10432 #endif
       
 10433         break;
       
 10434             case XML_PARSER_PUBLIC_LITERAL:
       
 10435         xmlGenericError(xmlGenericErrorContext,
       
 10436             EMBED_ERRTXT("PP: internal error, state == PUBLIC_LITERAL\n"));
       
 10437         ctxt->instate = XML_PARSER_START_TAG;
       
 10438 #ifdef DEBUG_PUSH
       
 10439         xmlGenericError(xmlGenericErrorContext,
       
 10440             "PP: entering START_TAG\n");
       
 10441 #endif
       
 10442         break;
       
 10443     }
       
 10444     }
       
 10445 done:
       
 10446 #ifdef DEBUG_PUSH
       
 10447     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
       
 10448 #endif
       
 10449     return(ret);
       
 10450 encoding_error:
       
 10451     {
       
 10452     char buffer[150];
       
 10453     snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
       
 10454             ctxt->input->cur[0], ctxt->input->cur[1],
       
 10455             ctxt->input->cur[2], ctxt->input->cur[3]);
       
 10456     __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
       
 10457              "Input is not proper UTF-8, indicate encoding !\n%s",
       
 10458              BAD_CAST buffer, NULL);
       
 10459     }
       
 10460     return(0);
       
 10461 }
       
 10462 
       
 10463 /**
       
 10464  * xmlParseChunk:
       
 10465  * @param ctxt an XML parser context
       
 10466  * @param chunk an char array
       
 10467  * @param size the size in byte of the chunk
       
 10468  * @param terminate last chunk indicator
       
 10469  *
       
 10470  * Parse a Chunk of memory
       
 10471  *
       
 10472  * Returns zero if no error, the xmlParserErrors otherwise.
       
 10473  */
       
 10474 XMLPUBFUNEXPORT int
       
 10475 xmlParseChunk(xmlParserCtxtPtr ctxt, const char* chunk, int size, int terminate)
       
 10476 {
       
 10477 	LOAD_GS_SAFE_CTXT(ctxt)
       
 10478     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
       
 10479         return(ctxt->errNo);
       
 10480 
       
 10481     if (ctxt->instate == XML_PARSER_START)
       
 10482         {
       
 10483         xmlDetectSAX2(ctxt);
       
 10484         if( OOM_FLAG )
       
 10485             {
       
 10486             xmlParserOOMErr(ctxt);
       
 10487             return(XML_ERR_NO_MEMORY);
       
 10488             }
       
 10489         }
       
 10490 
       
 10491     if (size > 0         &&
       
 10492         chunk            &&
       
 10493         ctxt->input      &&
       
 10494         ctxt->input->buf &&
       
 10495         ctxt->instate != XML_PARSER_EOF)
       
 10496     {
       
 10497         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
       
 10498         int cur = ctxt->input->cur - ctxt->input->base;
       
 10499 
       
 10500         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
       
 10501         ctxt->input->base = ctxt->input->buf->buffer->content + base;
       
 10502         ctxt->input->cur = ctxt->input->base + cur;
       
 10503         ctxt->input->end = &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
       
 10504 #ifdef DEBUG_PUSH
       
 10505         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
       
 10506 #endif
       
 10507     }
       
 10508     else if (ctxt->instate != XML_PARSER_EOF)
       
 10509     {
       
 10510         if (ctxt->input && ctxt->input->buf)
       
 10511         {
       
 10512             xmlParserInputBufferPtr in = ctxt->input->buf;
       
 10513             if (in->encoder &&
       
 10514                 in->buffer  &&
       
 10515                 in->raw)
       
 10516             {
       
 10517                 int nbchars;
       
 10518 
       
 10519                 nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
       
 10520                 if (nbchars < 0)
       
 10521                 {
       
 10522                     
       
 10523                     xmlGenericError(xmlGenericErrorContext,
       
 10524                             EMBED_ERRTXT("xmlParseChunk: encoder error\n"));
       
 10525                     return(XML_ERR_INVALID_ENCODING);
       
 10526                 }
       
 10527             }
       
 10528         }
       
 10529     }
       
 10530     //-----------------------------------
       
 10531     xmlParseTryOrFinish(ctxt, terminate);
       
 10532     //-----------------------------------
       
 10533     if( OOM_FLAG )
       
 10534         {
       
 10535         xmlParserOOMErr(ctxt); // set error state and disable parser
       
 10536         }
       
 10537     if (ctxt->errNo != XML_ERR_OK &&
       
 10538         ctxt->disableSAX == 1)
       
 10539     {
       
 10540         return(ctxt->errNo);
       
 10541     }
       
 10542     if (terminate)
       
 10543     {
       
 10544         /*
       
 10545         * Check for termination
       
 10546         */
       
 10547         xmlParserInputPtr input = ctxt->input;
       
 10548         int avail = (input->buf
       
 10549                         ? input->buf->buffer->use
       
 10550                         : input->length )
       
 10551                      - (input->cur - input->base);
       
 10552 
       
 10553         if ( ((ctxt->instate != XML_PARSER_EOF)     &&
       
 10554               (ctxt->instate != XML_PARSER_EPILOG))
       
 10555                 ||
       
 10556              ((ctxt->instate == XML_PARSER_EPILOG)  &&
       
 10557               (avail > 0))
       
 10558            )
       
 10559         {
       
 10560             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
       
 10561         }
       
 10562         if (ctxt->instate != XML_PARSER_EOF)
       
 10563         {
       
 10564             if (ctxt->sax && ctxt->sax->endDocument)
       
 10565                 ctxt->sax->endDocument(ctxt->userData);
       
 10566         }
       
 10567         ctxt->instate = XML_PARSER_EOF;
       
 10568     }
       
 10569     return ((xmlParserErrors) ctxt->errNo);
       
 10570 }
       
 10571 
       
 10572 /************************************************************************
       
 10573  *                                                                      *
       
 10574  *      I/O front end functions to the parser                           *
       
 10575  *                                                                      *
       
 10576  ************************************************************************/
       
 10577 
       
 10578 /**
       
 10579  * xmlStopParser:
       
 10580  * @param ctxt an XML parser context
       
 10581  *
       
 10582  * Blocks further parser processing
       
 10583  */
       
 10584 XMLPUBFUNEXPORT void
       
 10585 xmlStopParser(xmlParserCtxtPtr ctxt) {
       
 10586     if (ctxt == NULL)
       
 10587         return;
       
 10588     ctxt->instate = XML_PARSER_EOF;
       
 10589     ctxt->disableSAX = 1;
       
 10590     if (ctxt->input != NULL)
       
 10591         ctxt->input->cur = BAD_CAST"";
       
 10592 }
       
 10593 
       
 10594 /**
       
 10595  * xmlCreatePushParserCtxt:
       
 10596  * @param sax a SAX handler
       
 10597  * @param user_data The user data returned on SAX callbacks
       
 10598  * @param chunk a pointer to an array of chars
       
 10599  * @param size number of chars in the array
       
 10600  * @param filename an optional file name or URI
       
 10601  *
       
 10602  * Create a parser context for using the XML parser in push mode.
       
 10603  * If buffer and size are non-NULL, the data is used to detect
       
 10604  * the encoding.  The remaining characters will be parsed so they
       
 10605  * don't need to be fed in again through xmlParseChunk.
       
 10606  * To allow content encoding detection, size should be >= 4
       
 10607  * The value of filename is used for fetching external entities
       
 10608  * and error/warning reports.
       
 10609  *
       
 10610  * Returns the new parser context or NULL
       
 10611  *
       
 10612  * OOM: possible --> returns NULL
       
 10613  */
       
 10614 
       
 10615 XMLPUBFUNEXPORT xmlParserCtxtPtr
       
 10616 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void* user_data,
       
 10617                         const char* chunk, int size, const char* filename)
       
 10618 {
       
 10619 	LOAD_GS_DIRECT
       
 10620 	xmlParserCtxtPtr ctxt;
       
 10621     xmlParserInputPtr inputStream;
       
 10622     xmlParserInputBufferPtr buf;
       
 10623     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
       
 10624     
       
 10625     /*
       
 10626      * plug some encoding conversion routines
       
 10627      */
       
 10628     if (chunk && (size >= 4))
       
 10629         enc = xmlDetectCharEncoding((const xmlChar*) chunk, size);
       
 10630 
       
 10631     buf = xmlAllocParserInputBuffer(enc); // OOM possible
       
 10632     if (!buf)
       
 10633         goto OOM;
       
 10634 
       
 10635     ctxt = xmlNewParserCtxt();
       
 10636     if (!ctxt) {
       
 10637         goto OOM_buf;
       
 10638     }
       
 10639 	ctxt->pushTab = (void**) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar*));
       
 10640 
       
 10641     if (!ctxt->pushTab) {
       
 10642         goto OOM_ctxt_buf;
       
 10643     }
       
 10644 
       
 10645     if (sax) {
       
 10646 #ifdef LIBXML_SAX1_ENABLED
       
 10647         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
       
 10648 #endif /* LIBXML_SAX1_ENABLED */
       
 10649         {
       
 10650             xmlFree(ctxt->sax);
       
 10651         }
       
 10652         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
       
 10653         if (!ctxt->sax) {
       
 10654             goto OOM_ctxt_buf;
       
 10655         }
       
 10656         memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
       
 10657         if (user_data)
       
 10658             ctxt->userData = user_data;
       
 10659     }
       
 10660     // DONE: just call xmlParserGetDirectory it returns NULL for NULL argument
       
 10661     ctxt->directory = filename
       
 10662                             ? xmlParserGetDirectory(filename)
       
 10663                             : NULL;
       
 10664 
       
 10665     inputStream = xmlNewInputStream(ctxt);
       
 10666     if (!inputStream) {
       
 10667         goto OOM_ctxt_buf;
       
 10668     }
       
 10669 
       
 10670     inputStream->filename = filename
       
 10671                                 ? (char *) xmlCanonicPath((const xmlChar*) filename)
       
 10672                                 : NULL;
       
 10673     
       
 10674     inputStream->buf = buf;
       
 10675     inputStream->base = inputStream->buf->buffer->content;
       
 10676     inputStream->cur = inputStream->buf->buffer->content;
       
 10677     inputStream->end = &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
       
 10678 
       
 10679     if (inputPush(ctxt, inputStream) < 0)
       
 10680     {
       
 10681         goto OOM_istream_ctxt_buf;
       
 10682     }
       
 10683 
       
 10684     if (size > 0    &&
       
 10685         chunk       &&
       
 10686         ctxt->input &&
       
 10687         ctxt->input->buf)
       
 10688     {
       
 10689         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
       
 10690         int cur = ctxt->input->cur - ctxt->input->base;
       
 10691 
       
 10692         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
       
 10693 
       
 10694         ctxt->input->base = ctxt->input->buf->buffer->content + base;
       
 10695         ctxt->input->cur = ctxt->input->base + cur;
       
 10696         ctxt->input->end = &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
       
 10697 #ifdef DEBUG_PUSH
       
 10698         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
       
 10699 #endif
       
 10700     }
       
 10701 
       
 10702     if (enc != XML_CHAR_ENCODING_NONE) {
       
 10703         xmlSwitchEncoding(ctxt, enc); 
       
 10704     }
       
 10705 
       
 10706     return(ctxt);
       
 10707 //------------------------------
       
 10708 OOM_istream_ctxt_buf:
       
 10709     inputStream->buf = NULL; // NOTE: 'buf' is already part of inputStream -- do not free it twice!!!
       
 10710     xmlFreeInputStream(inputStream);
       
 10711 OOM_ctxt_buf:
       
 10712     xmlFreeParserCtxt(ctxt);
       
 10713 OOM_buf:
       
 10714     xmlFreeParserInputBuffer(buf);
       
 10715 OOM:
       
 10716     xmlParserOOMErr(NULL);
       
 10717     return(NULL);
       
 10718 }
       
 10719 #endif /* LIBXML_PUSH_ENABLED */
       
 10720 
       
 10721 
       
 10722 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
 10723 /**
       
 10724  * xmlCreateIOParserCtxt:
       
 10725  * @param sax a SAX handler
       
 10726  * @param user_data The user data returned on SAX callbacks
       
 10727  * @param ioread an I/O read function
       
 10728  * @param ioclose an I/O close function
       
 10729  * @param ioctx an I/O handler
       
 10730  * @param enc the charset encoding if known
       
 10731  *
       
 10732  * Create a parser context for using the XML parser with an existing
       
 10733  * I/O stream
       
 10734  *
       
 10735  * Returns the new parser context or NULL
       
 10736  */
       
 10737 xmlParserCtxtPtr
       
 10738 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
       
 10739                       xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
       
 10740                       void *ioctx, xmlCharEncoding enc)
       
 10741 {
       
 10742     xmlParserCtxtPtr ctxt;
       
 10743     xmlParserInputPtr inputStream;
       
 10744     xmlParserInputBufferPtr buf;
       
 10745 
       
 10746     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
       
 10747     if (buf == NULL) return(NULL);
       
 10748 
       
 10749     ctxt = xmlNewParserCtxt();
       
 10750     if (ctxt == NULL) {
       
 10751         xmlFree(buf);
       
 10752         return(NULL);
       
 10753     }
       
 10754     if (sax != NULL) {
       
 10755 #ifdef LIBXML_SAX1_ENABLED
       
 10756         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
       
 10757 #endif /* LIBXML_SAX1_ENABLED */
       
 10758             xmlFree(ctxt->sax);
       
 10759         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
       
 10760         if (ctxt->sax == NULL) {
       
 10761             xmlParserOOMErr(ctxt);
       
 10762             xmlFree(ctxt);
       
 10763             return(NULL);
       
 10764         }
       
 10765         memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
       
 10766         if (user_data != NULL)
       
 10767             ctxt->userData = user_data;
       
 10768     }
       
 10769 
       
 10770     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
       
 10771     if (inputStream == NULL) {
       
 10772         xmlFreeParserCtxt(ctxt);
       
 10773         return(NULL);
       
 10774     }
       
 10775     inputPush(ctxt, inputStream);
       
 10776 
       
 10777     return(ctxt);
       
 10778 }
       
 10779 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
 10780 
       
 10781 
       
 10782 #ifdef LIBXML_VALID_ENABLED
       
 10783 /************************************************************************
       
 10784  *                                                                      *
       
 10785  *      Front ends when parsing a DTD                                   *
       
 10786  *                                                                      *
       
 10787  ************************************************************************/
       
 10788 
       
 10789 /**
       
 10790  * xmlIOParseDTD:
       
 10791  * @param sax the SAX handler block or NULL
       
 10792  * @param input an Input Buffer
       
 10793  * @param enc the charset encoding if known
       
 10794  *
       
 10795  * Load and parse a DTD
       
 10796  *
       
 10797  * Returns the resulting xmlDtdPtr or NULL in case of error.
       
 10798  * input will be freed at parsing end.
       
 10799  */
       
 10800 
       
 10801 xmlDtdPtr
       
 10802 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
       
 10803           xmlCharEncoding enc)
       
 10804 {
       
 10805     xmlDtdPtr ret = NULL;
       
 10806     xmlParserCtxtPtr ctxt;
       
 10807     xmlParserInputPtr pinput = NULL;
       
 10808     xmlChar start[4];
       
 10809 
       
 10810     if (input == NULL)
       
 10811         return(NULL);
       
 10812 
       
 10813     ctxt = xmlNewParserCtxt();
       
 10814     if (ctxt == NULL) {
       
 10815         return(NULL);
       
 10816     }
       
 10817 
       
 10818     /*
       
 10819      * Set-up the SAX context
       
 10820      */
       
 10821     if (sax != NULL) {
       
 10822     if (ctxt->sax != NULL)
       
 10823         xmlFree(ctxt->sax);
       
 10824         ctxt->sax = sax;
       
 10825         ctxt->userData = ctxt;
       
 10826     }
       
 10827     xmlDetectSAX2(ctxt);
       
 10828 
       
 10829     /*
       
 10830      * generate a parser input from the I/O handler
       
 10831      */
       
 10832 
       
 10833     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
       
 10834     if (pinput == NULL) {
       
 10835         if (sax != NULL) ctxt->sax = NULL;
       
 10836     xmlFreeParserCtxt(ctxt);
       
 10837     return(NULL);
       
 10838     }
       
 10839 
       
 10840     /*
       
 10841      * plug some encoding conversion routines here.
       
 10842      */
       
 10843     xmlPushInput(ctxt, pinput);
       
 10844     if (enc != XML_CHAR_ENCODING_NONE) {
       
 10845         xmlSwitchEncoding(ctxt, enc);
       
 10846     }
       
 10847 
       
 10848     pinput->filename = NULL;
       
 10849     pinput->line = 1;
       
 10850     pinput->col = 1;
       
 10851     pinput->base = ctxt->input->cur;
       
 10852     pinput->cur = ctxt->input->cur;
       
 10853     pinput->free = NULL;
       
 10854 
       
 10855     /*
       
 10856      * let's parse that entity knowing it's an external subset.
       
 10857      */
       
 10858     ctxt->inSubset = 2;
       
 10859     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
       
 10860     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
       
 10861                                    BAD_CAST "none", BAD_CAST "none");
       
 10862 
       
 10863     if ((enc == XML_CHAR_ENCODING_NONE) &&
       
 10864         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
       
 10865     /*
       
 10866      * Get the 4 first bytes and decode the charset
       
 10867      * if enc != XML_CHAR_ENCODING_NONE
       
 10868      * plug some encoding conversion routines.
       
 10869      */
       
 10870     start[0] = RAW;
       
 10871     start[1] = NXT(1);
       
 10872     start[2] = NXT(2);
       
 10873     start[3] = NXT(3);
       
 10874     enc = xmlDetectCharEncoding(start, 4);
       
 10875     if (enc != XML_CHAR_ENCODING_NONE) {
       
 10876         xmlSwitchEncoding(ctxt, enc);
       
 10877     }
       
 10878     }
       
 10879 
       
 10880     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
       
 10881 
       
 10882     if (ctxt->myDoc != NULL) {
       
 10883     if (ctxt->wellFormed) {
       
 10884         ret = ctxt->myDoc->extSubset;
       
 10885         ctxt->myDoc->extSubset = NULL;
       
 10886         if (ret != NULL) {
       
 10887         xmlNodePtr tmp;
       
 10888 
       
 10889         ret->doc = NULL;
       
 10890         tmp = ret->children;
       
 10891         while (tmp != NULL) {
       
 10892             tmp->doc = NULL;
       
 10893             tmp = tmp->next;
       
 10894         }
       
 10895         }
       
 10896     } else {
       
 10897         ret = NULL;
       
 10898     }
       
 10899         xmlFreeDoc(ctxt->myDoc);
       
 10900         ctxt->myDoc = NULL;
       
 10901     }
       
 10902     if (sax != NULL) ctxt->sax = NULL;
       
 10903     xmlFreeParserCtxt(ctxt);
       
 10904 
       
 10905     return(ret);
       
 10906 }
       
 10907 
       
 10908 /**
       
 10909  * xmlSAXParseDTD:
       
 10910  * @param sax the SAX handler block
       
 10911  * @param ExternalID a NAME* containing the External ID of the DTD
       
 10912  * @param SystemID a NAME* containing the URL to the DTD
       
 10913  *
       
 10914  * Load and parse an external subset.
       
 10915  *
       
 10916  * Returns the resulting xmlDtdPtr or NULL in case of error.
       
 10917  */
       
 10918 
       
 10919 xmlDtdPtr
       
 10920 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
       
 10921                           const xmlChar *SystemID) {
       
 10922     xmlDtdPtr ret = NULL;
       
 10923     xmlParserCtxtPtr ctxt;
       
 10924     xmlParserInputPtr input = NULL;
       
 10925     xmlCharEncoding enc;
       
 10926 
       
 10927     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
       
 10928 
       
 10929     ctxt = xmlNewParserCtxt();
       
 10930     if (ctxt == NULL) {
       
 10931     return(NULL);
       
 10932     }
       
 10933 
       
 10934     /*
       
 10935      * Set-up the SAX context
       
 10936      */
       
 10937     if (sax != NULL) {
       
 10938     if (ctxt->sax != NULL)
       
 10939         xmlFree(ctxt->sax);
       
 10940         ctxt->sax = sax;
       
 10941         ctxt->userData = ctxt;
       
 10942     }
       
 10943 
       
 10944     /*
       
 10945      * Ask the Entity resolver to load the damn thing
       
 10946      */
       
 10947 
       
 10948     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
       
 10949     input = ctxt->sax->resolveEntity(ctxt, ExternalID, SystemID);
       
 10950     if (input == NULL) {
       
 10951         if (sax != NULL) ctxt->sax = NULL;
       
 10952     xmlFreeParserCtxt(ctxt);
       
 10953     return(NULL);
       
 10954     }
       
 10955 
       
 10956     /*
       
 10957      * plug some encoding conversion routines here.
       
 10958      */
       
 10959     xmlPushInput(ctxt, input);
       
 10960     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
       
 10961     enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
       
 10962     xmlSwitchEncoding(ctxt, enc);
       
 10963     }
       
 10964 
       
 10965     if (input->filename == NULL)
       
 10966     input->filename = (char *) xmlCanonicPath(SystemID);
       
 10967     input->line = 1;
       
 10968     input->col = 1;
       
 10969     input->base = ctxt->input->cur;
       
 10970     input->cur = ctxt->input->cur;
       
 10971     input->free = NULL;
       
 10972 
       
 10973     /*
       
 10974      * let's parse that entity knowing it's an external subset.
       
 10975      */
       
 10976     ctxt->inSubset = 2;
       
 10977     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
       
 10978     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
       
 10979                                    ExternalID, SystemID);
       
 10980     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
       
 10981 
       
 10982     if (ctxt->myDoc != NULL) {
       
 10983     if (ctxt->wellFormed) {
       
 10984         ret = ctxt->myDoc->extSubset;
       
 10985         ctxt->myDoc->extSubset = NULL;
       
 10986         if (ret != NULL) {
       
 10987         xmlNodePtr tmp;
       
 10988 
       
 10989         ret->doc = NULL;
       
 10990         tmp = ret->children;
       
 10991         while (tmp != NULL) {
       
 10992             tmp->doc = NULL;
       
 10993             tmp = tmp->next;
       
 10994         }
       
 10995         }
       
 10996     } else {
       
 10997         ret = NULL;
       
 10998     }
       
 10999         xmlFreeDoc(ctxt->myDoc);
       
 11000         ctxt->myDoc = NULL;
       
 11001     }
       
 11002     if (sax != NULL) ctxt->sax = NULL;
       
 11003     xmlFreeParserCtxt(ctxt);
       
 11004 
       
 11005     return(ret);
       
 11006 }
       
 11007 
       
 11008 
       
 11009 /**
       
 11010  * xmlParseDTD:
       
 11011  * @param ExternalID a NAME* containing the External ID of the DTD
       
 11012  * @param SystemID a NAME* containing the URL to the DTD
       
 11013  *
       
 11014  * Load and parse an external subset.
       
 11015  *
       
 11016  * Returns the resulting xmlDtdPtr or NULL in case of error.
       
 11017  */
       
 11018 
       
 11019 xmlDtdPtr
       
 11020 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
       
 11021     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
       
 11022 }
       
 11023 #endif /* LIBXML_VALID_ENABLED */
       
 11024 
       
 11025 /************************************************************************
       
 11026  *                                                                      *
       
 11027  *      Front ends when parsing an Entity                               *
       
 11028  *                                                                      *
       
 11029  ************************************************************************/
       
 11030 
       
 11031 /**
       
 11032  * xmlParseCtxtExternalEntity:
       
 11033  * @param ctx the existing parsing context
       
 11034  * @param URL the URL for the entity to load
       
 11035  * @param ID the System ID for the entity to load
       
 11036  * @param lst the return value for the set of parsed nodes
       
 11037  *
       
 11038  * Parse an external general entity within an existing parsing context
       
 11039  * An external general parsed entity is well-formed if it matches the
       
 11040  * production labeled extParsedEnt.
       
 11041  *
       
 11042  * [78] extParsedEnt ::= TextDecl? content
       
 11043  *
       
 11044  * Returns 0 if the entity is well formed, -1 in case of args problem and
       
 11045  *    the parser error code otherwise
       
 11046  */
       
 11047 
       
 11048 XMLPUBFUNEXPORT int
       
 11049 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
       
 11050                    const xmlChar *ID, xmlNodePtr *lst) {
       
 11051     xmlParserCtxtPtr ctxt;
       
 11052     xmlDocPtr newDoc;
       
 11053     xmlSAXHandlerPtr oldsax = NULL;
       
 11054     int ret = 0;
       
 11055     xmlChar start[4];
       
 11056     xmlCharEncoding enc;
       
 11057 
       
 11058     if (ctx->depth > 40) {
       
 11059     return(XML_ERR_ENTITY_LOOP);
       
 11060     }
       
 11061 
       
 11062     if (lst != NULL)
       
 11063         *lst = NULL;
       
 11064     if ((URL == NULL) && (ID == NULL))
       
 11065     return(-1);
       
 11066     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
       
 11067     return(-1);
       
 11068 
       
 11069 
       
 11070     ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
       
 11071     if (ctxt == NULL) return(-1);
       
 11072     ctxt->userData = ctxt;
       
 11073     ctxt->_private = ctx->_private;
       
 11074     oldsax = ctxt->sax;
       
 11075     ctxt->sax = ctx->sax;
       
 11076     xmlDetectSAX2(ctxt);
       
 11077     newDoc = xmlNewDoc(BAD_CAST "1.0");
       
 11078     if (newDoc == NULL) {
       
 11079     xmlFreeParserCtxt(ctxt);
       
 11080     return(-1);
       
 11081     }
       
 11082     if (ctx->myDoc != NULL) {
       
 11083     newDoc->intSubset = ctx->myDoc->intSubset;
       
 11084     newDoc->extSubset = ctx->myDoc->extSubset;
       
 11085     }
       
 11086     if (ctx->myDoc->URL != NULL) {
       
 11087     newDoc->URL = xmlStrdup(ctx->myDoc->URL);
       
 11088     }
       
 11089     newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
       
 11090     if (newDoc->children == NULL) {
       
 11091     ctxt->sax = oldsax;
       
 11092     xmlFreeParserCtxt(ctxt);
       
 11093     newDoc->intSubset = NULL;
       
 11094     newDoc->extSubset = NULL;
       
 11095         xmlFreeDoc(newDoc);
       
 11096     return(-1);
       
 11097     }
       
 11098     nodePush(ctxt, newDoc->children); 
       
 11099     if (ctx->myDoc == NULL) {
       
 11100     ctxt->myDoc = newDoc;
       
 11101     } else {
       
 11102     ctxt->myDoc = ctx->myDoc;
       
 11103     newDoc->children->doc = ctx->myDoc;
       
 11104     }
       
 11105 
       
 11106     /*
       
 11107      * Get the 4 first bytes and decode the charset
       
 11108      * if enc != XML_CHAR_ENCODING_NONE
       
 11109      * plug some encoding conversion routines.
       
 11110      */
       
 11111     GROW
       
 11112     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
       
 11113     start[0] = RAW;
       
 11114     start[1] = NXT(1);
       
 11115     start[2] = NXT(2);
       
 11116     start[3] = NXT(3);
       
 11117     enc = xmlDetectCharEncoding(start, 4);
       
 11118     if (enc != XML_CHAR_ENCODING_NONE) {
       
 11119         xmlSwitchEncoding(ctxt, enc);
       
 11120     }
       
 11121     }
       
 11122 
       
 11123     /*
       
 11124      * Parse a possible text declaration first
       
 11125      */
       
 11126     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
       
 11127     xmlParseTextDecl(ctxt);
       
 11128     }
       
 11129 
       
 11130     /*
       
 11131      * Doing validity checking on chunk doesn't make sense
       
 11132      */
       
 11133     ctxt->instate = XML_PARSER_CONTENT;
       
 11134     ctxt->validate = ctx->validate;
       
 11135     ctxt->valid = ctx->valid;
       
 11136     ctxt->loadsubset = ctx->loadsubset;
       
 11137     ctxt->depth = ctx->depth + 1;
       
 11138     ctxt->replaceEntities = ctx->replaceEntities;
       
 11139     if (ctxt->validate) {
       
 11140         ctxt->vctxt.error = ctx->vctxt.error;
       
 11141         ctxt->vctxt.warning = ctx->vctxt.warning;
       
 11142     } else {
       
 11143         ctxt->vctxt.error = NULL;
       
 11144         ctxt->vctxt.warning = NULL;
       
 11145     }
       
 11146     ctxt->vctxt.nodeTab = NULL;
       
 11147     ctxt->vctxt.nodeNr = 0;
       
 11148     ctxt->vctxt.nodeMax = 0;
       
 11149     ctxt->vctxt.node = NULL;
       
 11150     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
       
 11151     ctxt->dict = ctx->dict;
       
 11152     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
       
 11153     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
       
 11154     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
       
 11155     ctxt->dictNames = ctx->dictNames;
       
 11156     ctxt->attsDefault = ctx->attsDefault;
       
 11157     ctxt->attsSpecial = ctx->attsSpecial;
       
 11158 
       
 11159     xmlParseContent(ctxt);
       
 11160 
       
 11161     ctx->validate = ctxt->validate;
       
 11162     ctx->valid = ctxt->valid;
       
 11163     if ((RAW == '<') && (NXT(1) == '/')) {
       
 11164     xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11165     } else if (RAW != 0) {
       
 11166     xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
       
 11167     }
       
 11168     if (ctxt->node != newDoc->children) {
       
 11169     xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11170     }
       
 11171 
       
 11172     if (!ctxt->wellFormed) {
       
 11173         if (ctxt->errNo == 0)
       
 11174         ret = 1;
       
 11175     else
       
 11176         ret = ctxt->errNo;
       
 11177     } else {
       
 11178     if (lst != NULL) {
       
 11179         xmlNodePtr cur;
       
 11180 
       
 11181         /*
       
 11182          * Return the newly created nodeset after unlinking it from
       
 11183          * they pseudo parent.
       
 11184          */
       
 11185         cur = newDoc->children->children;
       
 11186         *lst = cur;
       
 11187         while (cur != NULL) {
       
 11188         cur->parent = NULL;
       
 11189         cur = cur->next;
       
 11190         }
       
 11191             newDoc->children->children = NULL;
       
 11192     }
       
 11193     ret = 0;
       
 11194     }
       
 11195     ctxt->sax = oldsax;
       
 11196     ctxt->dict = NULL;
       
 11197     ctxt->attsDefault = NULL;
       
 11198     ctxt->attsSpecial = NULL;
       
 11199     xmlFreeParserCtxt(ctxt);
       
 11200     newDoc->intSubset = NULL;
       
 11201     newDoc->extSubset = NULL;
       
 11202     xmlFreeDoc(newDoc);
       
 11203 
       
 11204     return(ret);
       
 11205 }
       
 11206 
       
 11207 /**
       
 11208  * xmlParseExternalEntityPrivate:
       
 11209  * @param doc the document the chunk pertains to
       
 11210  * @param oldctxt the previous parser context if available
       
 11211  * @param sax the SAX handler bloc (possibly NULL)
       
 11212  * @param user_data The user data returned on SAX callbacks (possibly NULL)
       
 11213  * @param depth Used for loop detection, use 0
       
 11214  * @param URL the URL for the entity to load
       
 11215  * @param systemID the System ID for the entity to load
       
 11216  * @param list the return value for the set of parsed nodes
       
 11217  *
       
 11218  * Private version of xmlParseExternalEntity()
       
 11219  *
       
 11220  * Returns 0 if the entity is well formed, -1 in case of args problem and
       
 11221  *    the parser error code otherwise
       
 11222  */
       
 11223 
       
 11224 static xmlParserErrors
       
 11225 xmlParseExternalEntityPrivate(xmlDocPtr doc,
       
 11226                     xmlParserCtxtPtr oldctxt,
       
 11227                     xmlSAXHandlerPtr sax,
       
 11228                     void *user_data,
       
 11229                     int depth,
       
 11230                     const xmlChar *URL,
       
 11231                     const xmlChar *systemID,
       
 11232                     xmlNodePtr *list)
       
 11233 {
       
 11234     xmlParserCtxtPtr ctxt;
       
 11235     xmlDocPtr newDoc;
       
 11236     xmlSAXHandlerPtr oldsax = NULL;
       
 11237     xmlParserErrors ret = XML_ERR_OK;
       
 11238     xmlChar start[4];
       
 11239     xmlCharEncoding enc;
       
 11240 
       
 11241     if (depth > 40) {
       
 11242         return(XML_ERR_ENTITY_LOOP);
       
 11243     }
       
 11244 
       
 11245     if (list != NULL)
       
 11246         *list = NULL;
       
 11247     if ((URL == NULL) && (systemID == NULL))
       
 11248         return(XML_ERR_INTERNAL_ERROR);
       
 11249     if (doc == NULL) /* @@ relax but check for dereferences */
       
 11250         return(XML_ERR_INTERNAL_ERROR);
       
 11251 
       
 11252 
       
 11253     ctxt = xmlCreateEntityParserCtxt(URL, systemID, NULL);
       
 11254 
       
 11255     if (ctxt == NULL)
       
 11256         return(XML_WAR_UNDECLARED_ENTITY);
       
 11257     ctxt->userData = ctxt;
       
 11258     if (oldctxt != NULL) {
       
 11259         ctxt->_private = oldctxt->_private;
       
 11260         ctxt->loadsubset = oldctxt->loadsubset;
       
 11261         ctxt->validate = oldctxt->validate;
       
 11262         ctxt->external = oldctxt->external;
       
 11263 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
 11264         ctxt->record_info = oldctxt->record_info;
       
 11265         ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
       
 11266         ctxt->node_seq.length = oldctxt->node_seq.length;
       
 11267         ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
       
 11268 #endif
       
 11269     } else {
       
 11270         /*
       
 11271          * Doing validity checking on chunk without context
       
 11272          * doesn't make sense
       
 11273          */
       
 11274         ctxt->_private = NULL;
       
 11275         ctxt->validate = 0;
       
 11276         ctxt->external = 2;
       
 11277         ctxt->loadsubset = 0;
       
 11278     }
       
 11279     if (sax != NULL) {
       
 11280         oldsax = ctxt->sax;
       
 11281             ctxt->sax = sax;
       
 11282         if (user_data != NULL)
       
 11283             ctxt->userData = user_data;
       
 11284     }
       
 11285     xmlDetectSAX2(ctxt);
       
 11286     newDoc = xmlNewDoc(BAD_CAST "1.0");
       
 11287     if (newDoc == NULL) {
       
 11288         // OOM
       
 11289 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
 11290         ctxt->node_seq.maximum = 0;
       
 11291         ctxt->node_seq.length = 0;
       
 11292         ctxt->node_seq.buffer = NULL;
       
 11293 #endif
       
 11294         xmlFreeParserCtxt(ctxt);
       
 11295         return(XML_ERR_INTERNAL_ERROR);
       
 11296     }
       
 11297     if (doc != NULL) {
       
 11298         newDoc->intSubset = doc->intSubset;
       
 11299         newDoc->extSubset = doc->extSubset;
       
 11300         if (doc->URL != NULL) {
       
 11301             newDoc->URL = xmlStrdup(doc->URL);
       
 11302         }
       
 11303     }
       
 11304     newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
       
 11305     if (newDoc->children == NULL) {
       
 11306         // OOM
       
 11307         if (sax != NULL)
       
 11308             ctxt->sax = oldsax;
       
 11309 
       
 11310 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
 11311         ctxt->node_seq.maximum = 0;
       
 11312         ctxt->node_seq.length = 0;
       
 11313         ctxt->node_seq.buffer = NULL;
       
 11314 #endif
       
 11315         xmlFreeParserCtxt(ctxt);
       
 11316         newDoc->intSubset = NULL;
       
 11317         newDoc->extSubset = NULL;
       
 11318         xmlFreeDoc(newDoc);
       
 11319         return(XML_ERR_INTERNAL_ERROR);
       
 11320     }
       
 11321     nodePush(ctxt, newDoc->children); 
       
 11322     if (doc == NULL) {
       
 11323         ctxt->myDoc = newDoc;
       
 11324     } else {
       
 11325         ctxt->myDoc = doc;
       
 11326         newDoc->children->doc = doc;
       
 11327     }
       
 11328 
       
 11329     /*
       
 11330      * Get the 4 first bytes and decode the charset
       
 11331      * if enc != XML_CHAR_ENCODING_NONE
       
 11332      * plug some encoding conversion routines.
       
 11333      */
       
 11334     GROW;
       
 11335     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
       
 11336         start[0] = RAW;
       
 11337         start[1] = NXT(1);
       
 11338         start[2] = NXT(2);
       
 11339         start[3] = NXT(3);
       
 11340         enc = xmlDetectCharEncoding(start, 4);
       
 11341         if (enc != XML_CHAR_ENCODING_NONE) {
       
 11342             xmlSwitchEncoding(ctxt, enc);
       
 11343         }
       
 11344     }
       
 11345 
       
 11346     /*
       
 11347      * Parse a possible text declaration first
       
 11348      */
       
 11349     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
       
 11350         xmlParseTextDecl(ctxt);
       
 11351     }
       
 11352 
       
 11353     ctxt->instate = XML_PARSER_CONTENT;
       
 11354     ctxt->depth = depth;
       
 11355 
       
 11356     xmlParseContent(ctxt);
       
 11357 
       
 11358     if ((RAW == '<') && (NXT(1) == '/')) {
       
 11359         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11360     } else if (RAW != 0) {
       
 11361         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
       
 11362     }
       
 11363     if (ctxt->node != newDoc->children) {
       
 11364         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11365     }
       
 11366 
       
 11367     if (!ctxt->wellFormed) {
       
 11368         if (ctxt->errNo == 0)
       
 11369             ret = XML_ERR_INTERNAL_ERROR;
       
 11370         else
       
 11371             ret = (xmlParserErrors)ctxt->errNo;
       
 11372     } else {
       
 11373         if (list != NULL) {
       
 11374             xmlNodePtr cur;
       
 11375 
       
 11376             /*
       
 11377              * Return the newly created nodeset after unlinking it from
       
 11378              * they pseudo parent.
       
 11379              */
       
 11380             cur = newDoc->children->children;
       
 11381             *list = cur;
       
 11382             while (cur != NULL) {
       
 11383                 cur->parent = NULL;
       
 11384                 cur = cur->next;
       
 11385             }
       
 11386             newDoc->children->children = NULL;
       
 11387         }
       
 11388         ret = XML_ERR_OK;
       
 11389     }
       
 11390     if (sax != NULL)
       
 11391         ctxt->sax = oldsax;
       
 11392 
       
 11393 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
 11394     if(oldctxt)
       
 11395     {
       
 11396         oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
       
 11397         oldctxt->node_seq.length = ctxt->node_seq.length;
       
 11398         oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
       
 11399     }
       
 11400     ctxt->node_seq.maximum = 0;
       
 11401     ctxt->node_seq.length = 0;
       
 11402     ctxt->node_seq.buffer = NULL;
       
 11403 #endif
       
 11404 
       
 11405     xmlFreeParserCtxt(ctxt);
       
 11406     newDoc->intSubset = NULL;
       
 11407     newDoc->extSubset = NULL;
       
 11408     xmlFreeDoc(newDoc);
       
 11409 
       
 11410     return(ret);
       
 11411 }
       
 11412 
       
 11413 #ifdef LIBXML_SAX1_ENABLED
       
 11414 /**
       
 11415  * xmlParseExternalEntity:
       
 11416  * @param doc the document the chunk pertains to
       
 11417  * @param sax the SAX handler bloc (possibly NULL)
       
 11418  * @param user_data The user data returned on SAX callbacks (possibly NULL)
       
 11419  * @param depth Used for loop detection, use 0
       
 11420  * @param URL the URL for the entity to load
       
 11421  * @param systemID the System ID for the entity to load
       
 11422  * @param lst the return value for the set of parsed nodes
       
 11423  *
       
 11424  * Parse an external general entity
       
 11425  * An external general parsed entity is well-formed if it matches the
       
 11426  * production labeled extParsedEnt.
       
 11427  *
       
 11428  * [78] extParsedEnt ::= TextDecl? content
       
 11429  *
       
 11430  * Returns 0 if the entity is well formed, -1 in case of args problem and
       
 11431  *    the parser error code otherwise
       
 11432  */
       
 11433 
       
 11434 XMLPUBFUNEXPORT int
       
 11435 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
       
 11436       int depth, const xmlChar *URL, const xmlChar *systemID, xmlNodePtr *lst) {
       
 11437     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
       
 11438                                systemID, lst));
       
 11439 }
       
 11440 
       
 11441 /**
       
 11442  * xmlParseBalancedChunkMemory:
       
 11443  * @param doc the document the chunk pertains to
       
 11444  * @param sax the SAX handler bloc (possibly NULL)
       
 11445  * @param user_data The user data returned on SAX callbacks (possibly NULL)
       
 11446  * @param depth Used for loop detection, use 0
       
 11447  * @param string the input string in UTF8 or ISO-Latin (zero terminated)
       
 11448  * @param lst the return value for the set of parsed nodes
       
 11449  *
       
 11450  * Parse a well-balanced chunk of an XML document
       
 11451  * called by the parser
       
 11452  * The allowed sequence for the Well Balanced Chunk is the one defined by
       
 11453  * the content production in the XML grammar:
       
 11454  *
       
 11455  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
       
 11456  *
       
 11457  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
       
 11458  *    the parser error code otherwise
       
 11459  */
       
 11460 
       
 11461 XMLPUBFUNEXPORT int
       
 11462 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
       
 11463      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
       
 11464     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
       
 11465                                                 depth, string, lst, 0 );
       
 11466 }
       
 11467 #endif /* LIBXML_SAX1_ENABLED */
       
 11468 
       
 11469 /**
       
 11470  * xmlParseBalancedChunkMemoryInternal:
       
 11471  * @param oldctxt the existing parsing context
       
 11472  * @param string the input string in UTF8 or ISO-Latin (zero terminated)
       
 11473  * @param user_data the user data field for the parser context
       
 11474  * @param lst the return value for the set of parsed nodes
       
 11475  *
       
 11476  *
       
 11477  * Parse a well-balanced chunk of an XML document
       
 11478  * called by the parser
       
 11479  * The allowed sequence for the Well Balanced Chunk is the one defined by
       
 11480  * the content production in the XML grammar:
       
 11481  *
       
 11482  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
       
 11483  *
       
 11484  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
       
 11485  * error code otherwise
       
 11486  *
       
 11487  * In case recover is set to 1, the nodelist will not be empty even if
       
 11488  * the parsed chunk is not well balanced.
       
 11489  */
       
 11490 static xmlParserErrors
       
 11491 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
       
 11492     const xmlChar *string, void *user_data, xmlNodePtr *lst) {
       
 11493     xmlParserCtxtPtr ctxt;
       
 11494     xmlDocPtr newDoc = NULL;
       
 11495     xmlSAXHandlerPtr oldsax = NULL;
       
 11496     xmlNodePtr content = NULL;
       
 11497     int size;
       
 11498     xmlParserErrors ret = XML_ERR_OK;
       
 11499     LOAD_GS_SAFE_CTXT(oldctxt)
       
 11500 
       
 11501     if (oldctxt->depth > 40) {
       
 11502     return(XML_ERR_ENTITY_LOOP);
       
 11503     }
       
 11504 
       
 11505 
       
 11506     if (lst != NULL)
       
 11507         *lst = NULL;
       
 11508     if (string == NULL)
       
 11509         return(XML_ERR_INTERNAL_ERROR);
       
 11510 
       
 11511     size = xmlStrlen(string);
       
 11512 
       
 11513     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
       
 11514     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
       
 11515     if (user_data != NULL)
       
 11516     ctxt->userData = user_data;
       
 11517     else
       
 11518     ctxt->userData = ctxt;
       
 11519     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
       
 11520     ctxt->dict = oldctxt->dict;
       
 11521     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
       
 11522     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
       
 11523     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
       
 11524 
       
 11525     oldsax = ctxt->sax;
       
 11526     ctxt->sax = oldctxt->sax;
       
 11527     xmlDetectSAX2(ctxt);
       
 11528     ctxt->replaceEntities = oldctxt->replaceEntities;
       
 11529     ctxt->options = oldctxt->options;
       
 11530 
       
 11531     ctxt->_private = oldctxt->_private;
       
 11532     if (oldctxt->myDoc == NULL) {
       
 11533     newDoc = xmlNewDoc(BAD_CAST "1.0");
       
 11534     if (newDoc == NULL) {
       
 11535         ctxt->sax = oldsax;
       
 11536         ctxt->dict = NULL;
       
 11537         xmlFreeParserCtxt(ctxt);
       
 11538         return(XML_ERR_INTERNAL_ERROR);
       
 11539     }
       
 11540     ctxt->myDoc = newDoc;
       
 11541     } else {
       
 11542     ctxt->myDoc = oldctxt->myDoc;
       
 11543         content = ctxt->myDoc->children;
       
 11544     }
       
 11545     ctxt->myDoc->children = xmlNewDocNode(ctxt->myDoc, NULL,
       
 11546                                       BAD_CAST "pseudoroot", NULL);
       
 11547     if (ctxt->myDoc->children == NULL) {
       
 11548     ctxt->sax = oldsax;
       
 11549     ctxt->dict = NULL;
       
 11550     xmlFreeParserCtxt(ctxt);
       
 11551     if (newDoc != NULL)
       
 11552         xmlFreeDoc(newDoc);
       
 11553     return(XML_ERR_INTERNAL_ERROR);
       
 11554     }
       
 11555     nodePush(ctxt, ctxt->myDoc->children); 
       
 11556     ctxt->instate = XML_PARSER_CONTENT; // can be XML_PARSER_EOF if error!
       
 11557     ctxt->depth = oldctxt->depth + 1;
       
 11558 
       
 11559     ctxt->validate = 0;
       
 11560     ctxt->loadsubset = oldctxt->loadsubset;
       
 11561     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
       
 11562         /*
       
 11563          * ID/IDREF registration will be done in xmlValidateElement below
       
 11564          */
       
 11565         ctxt->loadsubset |= XML_SKIP_IDS;
       
 11566     }
       
 11567     ctxt->dictNames = oldctxt->dictNames;
       
 11568     ctxt->attsDefault = oldctxt->attsDefault;
       
 11569     ctxt->attsSpecial = oldctxt->attsSpecial;
       
 11570 
       
 11571     xmlParseContent(ctxt);
       
 11572     if(OOM_FLAG)
       
 11573         {
       
 11574         xmlFreeParserCtxt(ctxt);
       
 11575         xmlParserOOMErr(ctxt);
       
 11576         return(XML_ERR_NO_MEMORY);
       
 11577         }
       
 11578     if ((RAW == '<') && (NXT(1) == '/')) {
       
 11579         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11580     } else if (RAW != 0) {
       
 11581         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
       
 11582     }
       
 11583     if (ctxt->node != ctxt->myDoc->children) {
       
 11584         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11585     }
       
 11586 
       
 11587     if (!ctxt->wellFormed) {
       
 11588         if (ctxt->errNo == 0)
       
 11589             ret = XML_ERR_INTERNAL_ERROR;
       
 11590         else
       
 11591             ret = (xmlParserErrors)ctxt->errNo;
       
 11592     } else {
       
 11593       ret = XML_ERR_OK;
       
 11594     }
       
 11595 
       
 11596     if ((lst != NULL) && (ret == XML_ERR_OK)) {
       
 11597     xmlNodePtr cur;
       
 11598 
       
 11599     /*
       
 11600      * Return the newly created nodeset after unlinking it from
       
 11601      * they pseudo parent.
       
 11602      */
       
 11603     cur = ctxt->myDoc->children->children;
       
 11604     *lst = cur;
       
 11605     while (cur != NULL) {
       
 11606 #ifdef LIBXML_VALID_ENABLED
       
 11607         if (oldctxt->validate && oldctxt->wellFormed &&
       
 11608         oldctxt->myDoc && oldctxt->myDoc->intSubset) {
       
 11609         oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
       
 11610             oldctxt->myDoc, cur);
       
 11611         }
       
 11612 #endif /* LIBXML_VALID_ENABLED */
       
 11613         cur->parent = NULL;
       
 11614         cur = cur->next;
       
 11615     }
       
 11616     ctxt->myDoc->children->children = NULL;
       
 11617     }
       
 11618     if (ctxt->myDoc != NULL) {
       
 11619     xmlFreeNode(ctxt->myDoc->children);
       
 11620         ctxt->myDoc->children = content;
       
 11621     }
       
 11622 
       
 11623     ctxt->sax = oldsax;
       
 11624     ctxt->dict = NULL;
       
 11625     ctxt->attsDefault = NULL;
       
 11626     ctxt->attsSpecial = NULL;
       
 11627     xmlFreeParserCtxt(ctxt);
       
 11628     if (newDoc != NULL)
       
 11629     xmlFreeDoc(newDoc);
       
 11630 
       
 11631     return(ret);
       
 11632 }
       
 11633 
       
 11634 // XMLENGINE: this function [xmlParseInNodeContext] is taken from
       
 11635 //            the newer version of the code (2.6.21);
       
 11636 //            It is required for WS-Security implementation (xmlsec)
       
 11637 
       
 11638 /**
       
 11639  * xmlParseInNodeContext:
       
 11640  * @param node the context node
       
 11641  * @param data the input string
       
 11642  * @param datalen the input string length in bytes
       
 11643  * @param options a combination of xmlParserOption
       
 11644  * @param lst the return value for the set of parsed nodes
       
 11645  *
       
 11646  * Parse a well-balanced chunk of an XML document
       
 11647  * within the context (DTD, namespaces, etc ...) of the given node.
       
 11648  *
       
 11649  * The allowed sequence for the data is a Well Balanced Chunk defined by
       
 11650  * the content production in the XML grammar:
       
 11651  *
       
 11652  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
       
 11653  *
       
 11654  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
       
 11655  * error code otherwise
       
 11656  */
       
 11657 XMLPUBFUNEXPORT xmlParserErrors
       
 11658 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
       
 11659                       int options, xmlNodePtr *lst)
       
 11660 {
       
 11661 #ifdef SAX2
       
 11662     xmlParserCtxtPtr ctxt;
       
 11663     xmlDocPtr doc = NULL;
       
 11664     xmlNodePtr fake, cur;
       
 11665     int nsnr = 0;
       
 11666 
       
 11667     xmlParserErrors ret = XML_ERR_OK;
       
 11668     LOAD_GS_SAFE_NODE(node)
       
 11669 
       
 11670     /*
       
 11671      * check all input parameters, grab the document
       
 11672      */
       
 11673     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
       
 11674     {
       
 11675         return(XML_ERR_INTERNAL_ERROR);
       
 11676     }
       
 11677 
       
 11678     switch (node->type) {
       
 11679         case XML_ELEMENT_NODE:
       
 11680         case XML_ATTRIBUTE_NODE:
       
 11681         case XML_TEXT_NODE:
       
 11682         case XML_CDATA_SECTION_NODE:
       
 11683         case XML_ENTITY_REF_NODE:
       
 11684         case XML_PI_NODE:
       
 11685         case XML_COMMENT_NODE:
       
 11686         case XML_DOCUMENT_NODE:
       
 11687         case XML_HTML_DOCUMENT_NODE:
       
 11688         break;
       
 11689     default:
       
 11690         return(XML_ERR_INTERNAL_ERROR);
       
 11691 
       
 11692     }
       
 11693 
       
 11694     while ((node != NULL) &&
       
 11695         (node->type != XML_ELEMENT_NODE) &&
       
 11696         (node->type != XML_DOCUMENT_NODE) &&
       
 11697         (node->type != XML_HTML_DOCUMENT_NODE))
       
 11698     {
       
 11699         node = node->parent;
       
 11700     }
       
 11701 
       
 11702     if (node == NULL)
       
 11703         return(XML_ERR_INTERNAL_ERROR);
       
 11704 
       
 11705     if (node->type == XML_ELEMENT_NODE){
       
 11706         doc = node->doc;
       
 11707     } else {
       
 11708         doc = (xmlDocPtr) node;
       
 11709     }
       
 11710 
       
 11711     if (doc == NULL)
       
 11712         return(XML_ERR_INTERNAL_ERROR);
       
 11713 
       
 11714     /*
       
 11715      * allocate a context and set-up everything not related to the
       
 11716      * node position in the tree
       
 11717      */
       
 11718     if (doc->type == XML_DOCUMENT_NODE)
       
 11719         ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
       
 11720 #ifdef LIBXML_HTML_ENABLED
       
 11721     else if (doc->type == XML_HTML_DOCUMENT_NODE)
       
 11722         ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
       
 11723 #endif
       
 11724     else
       
 11725         return(XML_ERR_INTERNAL_ERROR);
       
 11726 
       
 11727     if (ctxt == NULL)
       
 11728         return(XML_ERR_NO_MEMORY);
       
 11729 
       
 11730     fake = xmlNewComment(NULL);
       
 11731     if (fake == NULL) {
       
 11732         xmlFreeParserCtxt(ctxt);
       
 11733         return(XML_ERR_NO_MEMORY);
       
 11734     }
       
 11735     xmlAddChild(node, fake);
       
 11736 
       
 11737     /*
       
 11738      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
       
 11739      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
       
 11740      * we must wait until the last moment to free the original one.
       
 11741      */
       
 11742     if (doc->dict) {
       
 11743         if (ctxt->dict)
       
 11744             xmlDictFree(ctxt->dict);
       
 11745         ctxt->dict = doc->dict;
       
 11746     } else {
       
 11747         options |= XML_PARSE_NODICT;
       
 11748     }
       
 11749 
       
 11750     xmlCtxtUseOptions(ctxt, options);
       
 11751     xmlDetectSAX2(ctxt);
       
 11752     ctxt->myDoc = doc;
       
 11753     if ( OOM_FLAG ) 
       
 11754         {           
       
 11755         xmlFreeParserCtxt(ctxt);
       
 11756         return(XML_ERR_NO_MEMORY);
       
 11757         }    
       
 11758 
       
 11759     if (node->type == XML_ELEMENT_NODE)
       
 11760     {
       
 11761         nodePush(ctxt, node); 
       
 11762         /*
       
 11763          * initialize the SAX2 namespaces stack
       
 11764          */
       
 11765         cur = node;
       
 11766         while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE))
       
 11767         {
       
 11768             xmlNsPtr ns = cur->nsDef;
       
 11769             const xmlChar *iprefix, *ihref;
       
 11770 
       
 11771             while (ns != NULL)
       
 11772             {
       
 11773                 if (ctxt->dict) {
       
 11774                     iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
       
 11775                     ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
       
 11776                 } else {
       
 11777                     iprefix = ns->prefix;
       
 11778                     ihref = ns->href;
       
 11779                 }
       
 11780 
       
 11781                 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
       
 11782                     nsPush(ctxt, iprefix, ihref);
       
 11783                     nsnr++;
       
 11784                 }
       
 11785                 ns = ns->next;
       
 11786             }
       
 11787             cur = cur->parent;
       
 11788         }
       
 11789         ctxt->instate = XML_PARSER_CONTENT;
       
 11790     }
       
 11791 
       
 11792     if ((ctxt->validate) || (ctxt->replaceEntities != 0))
       
 11793     {
       
 11794         /*
       
 11795          * ID/IDREF registration will be done in xmlValidateElement below
       
 11796          */
       
 11797         ctxt->loadsubset |= XML_SKIP_IDS;
       
 11798     }
       
 11799 
       
 11800     xmlParseContent(ctxt);
       
 11801     if ( OOM_FLAG ) 
       
 11802         {           
       
 11803         xmlFreeParserCtxt(ctxt);
       
 11804         return(XML_ERR_NO_MEMORY);
       
 11805         }    
       
 11806     nsPop(ctxt, nsnr);
       
 11807     if ((RAW == '<') && (NXT(1) == '/')) {
       
 11808         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11809     } else if (RAW != 0) {
       
 11810         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
       
 11811     }
       
 11812     if ((ctxt->node != NULL) && (ctxt->node != node)) {
       
 11813         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11814         ctxt->wellFormed = 0;
       
 11815     }
       
 11816 
       
 11817     if (!ctxt->wellFormed) {
       
 11818         if (ctxt->errNo == 0)
       
 11819             ret = XML_ERR_INTERNAL_ERROR;
       
 11820         else
       
 11821             ret = (xmlParserErrors)ctxt->errNo;
       
 11822     } else {
       
 11823         ret = XML_ERR_OK;
       
 11824     }
       
 11825 
       
 11826     /*
       
 11827      * Return the newly created nodeset after unlinking it from
       
 11828      * the pseudo sibling.
       
 11829      */
       
 11830 
       
 11831     cur = fake->next;
       
 11832     fake->next = NULL;
       
 11833     node->last = fake;
       
 11834 
       
 11835     if (cur != NULL) {
       
 11836         cur->prev = NULL;
       
 11837     }
       
 11838 
       
 11839     *lst = cur;
       
 11840 
       
 11841     while (cur != NULL) {
       
 11842         cur->parent = NULL;
       
 11843         cur = cur->next;
       
 11844     }
       
 11845 
       
 11846     xmlUnlinkNode(fake);
       
 11847     xmlFreeNode(fake);
       
 11848 
       
 11849 
       
 11850     if (ret != XML_ERR_OK) {
       
 11851         xmlFreeNodeList(*lst);
       
 11852         *lst = NULL;
       
 11853     }
       
 11854 
       
 11855     if (doc->dict != NULL)
       
 11856         ctxt->dict = NULL;
       
 11857     xmlFreeParserCtxt(ctxt);
       
 11858 
       
 11859     return(ret);
       
 11860 #else /* !SAX2 */
       
 11861     return(XML_ERR_INTERNAL_ERROR);
       
 11862 #endif
       
 11863 }
       
 11864 
       
 11865 #ifdef LIBXML_SAX1_ENABLED
       
 11866 /**
       
 11867  * xmlParseBalancedChunkMemoryRecover:
       
 11868  * @param doc the document the chunk pertains to
       
 11869  * @param sax the SAX handler bloc (possibly NULL)
       
 11870  * @param user_data The user data returned on SAX callbacks (possibly NULL)
       
 11871  * @param depth Used for loop detection, use 0
       
 11872  * @param string the input string in UTF8 or ISO-Latin (zero terminated)
       
 11873  * @param lst the return value for the set of parsed nodes
       
 11874  * @param recover return nodes even if the data is broken (use 0)
       
 11875  *
       
 11876  *
       
 11877  * Parse a well-balanced chunk of an XML document
       
 11878  * called by the parser
       
 11879  * The allowed sequence for the Well Balanced Chunk is the one defined by
       
 11880  * the content production in the XML grammar:
       
 11881  *
       
 11882  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
       
 11883  *
       
 11884  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
       
 11885  *    the parser error code otherwise
       
 11886  *
       
 11887  * In case recover is set to 1, the nodelist will not be empty even if
       
 11888  * the parsed chunk is not well balanced.
       
 11889  */
       
 11890 XMLPUBFUNEXPORT int
       
 11891 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
       
 11892      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
       
 11893      int recover) {
       
 11894     xmlParserCtxtPtr ctxt;
       
 11895     xmlDocPtr newDoc;
       
 11896     xmlSAXHandlerPtr oldsax = NULL;
       
 11897     xmlNodePtr content;
       
 11898     int size;
       
 11899     int ret = 0;
       
 11900 
       
 11901     if (depth > 40) {
       
 11902     return(XML_ERR_ENTITY_LOOP);
       
 11903     }
       
 11904 
       
 11905 
       
 11906     if (lst != NULL)
       
 11907         *lst = NULL;
       
 11908     if (string == NULL)
       
 11909         return(-1);
       
 11910 
       
 11911     size = xmlStrlen(string);
       
 11912 
       
 11913     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
       
 11914     if (ctxt == NULL) return(-1);
       
 11915     ctxt->userData = ctxt;
       
 11916     if (sax != NULL) {
       
 11917     oldsax = ctxt->sax;
       
 11918         ctxt->sax = sax;
       
 11919     if (user_data != NULL)
       
 11920         ctxt->userData = user_data;
       
 11921     }
       
 11922     newDoc = xmlNewDoc(BAD_CAST "1.0");
       
 11923     if (newDoc == NULL) {
       
 11924     xmlFreeParserCtxt(ctxt);
       
 11925     return(-1);
       
 11926     }
       
 11927     if (doc != NULL) {
       
 11928     newDoc->intSubset = doc->intSubset;
       
 11929     newDoc->extSubset = doc->extSubset;
       
 11930     }
       
 11931     newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
       
 11932     if (newDoc->children == NULL) {
       
 11933     if (sax != NULL)
       
 11934         ctxt->sax = oldsax;
       
 11935     xmlFreeParserCtxt(ctxt);
       
 11936     newDoc->intSubset = NULL;
       
 11937     newDoc->extSubset = NULL;
       
 11938         xmlFreeDoc(newDoc);
       
 11939     return(-1);
       
 11940     }
       
 11941     nodePush(ctxt, newDoc->children);
       
 11942     if (doc == NULL) {
       
 11943     ctxt->myDoc = newDoc;
       
 11944     } else {
       
 11945     ctxt->myDoc = newDoc;
       
 11946     newDoc->children->doc = doc;
       
 11947     }
       
 11948     ctxt->instate = XML_PARSER_CONTENT;
       
 11949     ctxt->depth = depth;
       
 11950 
       
 11951     /*
       
 11952      * Doing validity checking on chunk doesn't make sense
       
 11953      */
       
 11954     ctxt->validate = 0;
       
 11955     ctxt->loadsubset = 0;
       
 11956     xmlDetectSAX2(ctxt);
       
 11957 
       
 11958     if ( doc != NULL ){
       
 11959         content = doc->children;
       
 11960         doc->children = NULL;
       
 11961         xmlParseContent(ctxt);
       
 11962         doc->children = content;
       
 11963     }
       
 11964     else {
       
 11965         xmlParseContent(ctxt);
       
 11966     }
       
 11967     if ((RAW == '<') && (NXT(1) == '/')) {
       
 11968     xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11969     } else if (RAW != 0) {
       
 11970     xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
       
 11971     }
       
 11972     if (ctxt->node != newDoc->children) {
       
 11973     xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
       
 11974     }
       
 11975 
       
 11976     if (!ctxt->wellFormed) {
       
 11977         if (ctxt->errNo == 0)
       
 11978         ret = 1;
       
 11979     else
       
 11980         ret = ctxt->errNo;
       
 11981     } else {
       
 11982       ret = 0;
       
 11983     }
       
 11984 
       
 11985     if (lst != NULL && (ret == 0 || recover == 1)) {
       
 11986       xmlNodePtr cur;
       
 11987 
       
 11988         /*
       
 11989          * Return the newly created nodeset after unlinking it from
       
 11990          * they pseudo parent.
       
 11991          */
       
 11992         cur = newDoc->children->children;
       
 11993         *lst = cur;
       
 11994         while (cur != NULL) {
       
 11995         cur->parent = NULL;
       
 11996         cur = cur->next;
       
 11997         }
       
 11998             newDoc->children->children = NULL;
       
 11999     }
       
 12000 
       
 12001     if (sax != NULL)
       
 12002     ctxt->sax = oldsax;
       
 12003     xmlFreeParserCtxt(ctxt);
       
 12004     newDoc->intSubset = NULL;
       
 12005     newDoc->extSubset = NULL;
       
 12006     xmlFreeDoc(newDoc);
       
 12007 
       
 12008     return(ret);
       
 12009 }
       
 12010 
       
 12011 /**
       
 12012  * xmlSAXParseEntity:
       
 12013  * @param sax the SAX handler block
       
 12014  * @param filename the filename
       
 12015  *
       
 12016  * parse an XML external entity out of context and build a tree.
       
 12017  * It use the given SAX function block to handle the parsing callback.
       
 12018  * If sax is NULL, fallback to the default DOM tree building routines.
       
 12019  *
       
 12020  * [78] extParsedEnt ::= TextDecl? content
       
 12021  *
       
 12022  * This correspond to a "Well Balanced" chunk
       
 12023  *
       
 12024  * Returns the resulting document tree
       
 12025  */
       
 12026 
       
 12027 XMLPUBFUNEXPORT xmlDocPtr
       
 12028 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
       
 12029     xmlDocPtr ret;
       
 12030     xmlParserCtxtPtr ctxt;
       
 12031 
       
 12032     ctxt = xmlCreateFileParserCtxt(filename);
       
 12033     if (ctxt == NULL) {
       
 12034     return(NULL);
       
 12035     }
       
 12036     if (sax != NULL) {
       
 12037     if (ctxt->sax != NULL)
       
 12038         xmlFree(ctxt->sax);
       
 12039         ctxt->sax = sax;
       
 12040         ctxt->userData = NULL;
       
 12041     }
       
 12042 
       
 12043     xmlParseExtParsedEnt(ctxt);
       
 12044 
       
 12045     if (ctxt->wellFormed)
       
 12046     ret = ctxt->myDoc;
       
 12047     else {
       
 12048         ret = NULL;
       
 12049         xmlFreeDoc(ctxt->myDoc);
       
 12050         ctxt->myDoc = NULL;
       
 12051     }
       
 12052     if (sax != NULL)
       
 12053         ctxt->sax = NULL;
       
 12054     xmlFreeParserCtxt(ctxt);
       
 12055 
       
 12056     return(ret);
       
 12057 }
       
 12058 
       
 12059 /**
       
 12060  * xmlParseEntity:
       
 12061  * @param filename the filename
       
 12062  *
       
 12063  * parse an XML external entity out of context and build a tree.
       
 12064  *
       
 12065  * [78] extParsedEnt ::= TextDecl? content
       
 12066  *
       
 12067  * This correspond to a "Well Balanced" chunk
       
 12068  *
       
 12069  * Returns the resulting document tree
       
 12070  */
       
 12071 
       
 12072 XMLPUBFUNEXPORT xmlDocPtr
       
 12073 xmlParseEntity(const char *filename) {
       
 12074     return(xmlSAXParseEntity(NULL, filename));
       
 12075 }
       
 12076 #endif /* LIBXML_SAX1_ENABLED */
       
 12077 
       
 12078 /**
       
 12079  * xmlCreateEntityParserCtxt:
       
 12080  * @param URL the entity URL
       
 12081  * @param ID the entity PUBLIC ID
       
 12082  * @param base a possible base for the target URI
       
 12083  *
       
 12084  * Create a parser context for an external entity
       
 12085  * Automatic support for ZLIB/Compress compressed document is provided
       
 12086  * by default if found at compile-time.
       
 12087  *
       
 12088  * Returns the new parser context or NULL
       
 12089  */
       
 12090 XMLPUBFUNEXPORT xmlParserCtxtPtr
       
 12091 xmlCreateEntityParserCtxt(const xmlChar* URL,
       
 12092                           const xmlChar* ID,
       
 12093                           const xmlChar* base)
       
 12094 {
       
 12095     xmlParserCtxtPtr  ctxt;
       
 12096     xmlParserInputPtr inputStream;
       
 12097     // local variable 'directory' was removed (function was optimized)
       
 12098     xmlChar*          uri;
       
 12099 
       
 12100     ctxt = xmlNewParserCtxt();
       
 12101     if (!ctxt)
       
 12102         return(NULL);
       
 12103 
       
 12104     uri = xmlBuildURI(URL, base);
       
 12105 
       
 12106     if (!uri) {
       
 12107         inputStream = xmlLoadExternalEntity((char*) URL, (char*) ID, ctxt);
       
 12108         if (!inputStream) {
       
 12109             xmlFreeParserCtxt(ctxt);
       
 12110             return(NULL);
       
 12111         }
       
 12112         inputPush(ctxt, inputStream);
       
 12113 
       
 12114         if (!ctxt->directory)
       
 12115             ctxt->directory = xmlParserGetDirectory((char*) URL);
       
 12116     } else {
       
 12117         inputStream = xmlLoadExternalEntity((char*) uri, (char*) ID, ctxt);
       
 12118         if (!inputStream) {
       
 12119             xmlFree(uri);
       
 12120             xmlFreeParserCtxt(ctxt);
       
 12121             return(NULL);
       
 12122         }
       
 12123 
       
 12124         inputPush(ctxt, inputStream);
       
 12125 
       
 12126         if (!ctxt->directory)
       
 12127             ctxt->directory = xmlParserGetDirectory((char*) uri); // oom POSSIBLE
       
 12128 
       
 12129         xmlFree(uri);
       
 12130     }
       
 12131     return(ctxt);
       
 12132 }
       
 12133 
       
 12134 /************************************************************************
       
 12135  *                                                                      *
       
 12136  *      Front ends when parsing from a file                             *
       
 12137  *                                                                      *
       
 12138  ************************************************************************/
       
 12139 
       
 12140 /**
       
 12141  * xmlCreateURLParserCtxt:
       
 12142  * @param filename the filename or URL
       
 12143  * @param options a combination of xmlParserOption
       
 12144  *
       
 12145  * Create a parser context for a file or URL content.
       
 12146  * Automatic support for ZLIB/Compress compressed document is provided
       
 12147  * by default if found at compile-time and for file accesses
       
 12148  *
       
 12149  * Returns the new parser context or NULL
       
 12150  */
       
 12151 XMLPUBFUNEXPORT xmlParserCtxtPtr
       
 12152 xmlCreateURLParserCtxt(const char* filename, int options)
       
 12153 {
       
 12154     xmlParserCtxtPtr ctxt;
       
 12155     xmlParserInputPtr inputStream;
       
 12156     // local variable 'directory' was removed (function was optimized)
       
 12157 
       
 12158     ctxt = xmlNewParserCtxt();
       
 12159     if (!ctxt) {
       
 12160         xmlParserOOMErr(ctxt);
       
 12161         return(NULL);
       
 12162     }
       
 12163 
       
 12164     if (options != 0)
       
 12165         xmlCtxtUseOptions(ctxt, options);
       
 12166 
       
 12167     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
       
 12168     if (!inputStream) {
       
 12169         xmlFreeParserCtxt(ctxt);
       
 12170         return(NULL);
       
 12171     }
       
 12172 
       
 12173     inputPush(ctxt, inputStream);
       
 12174     if (!ctxt->directory)
       
 12175         ctxt->directory = xmlParserGetDirectory(filename);
       
 12176 
       
 12177     return(ctxt);
       
 12178 }
       
 12179 
       
 12180 
       
 12181 /**
       
 12182  * xmlCreateFileParserCtxt:
       
 12183  * @param filename the filename
       
 12184  *
       
 12185  * Create a parser context for a file content.
       
 12186  * Automatic support for ZLIB/Compress compressed document is provided
       
 12187  * by default if found at compile-time.
       
 12188  *
       
 12189  * Returns the new parser context or NULL
       
 12190  */
       
 12191 XMLPUBFUNEXPORT xmlParserCtxtPtr
       
 12192 xmlCreateFileParserCtxt(const char *filename)
       
 12193 {
       
 12194     return(xmlCreateURLParserCtxt(filename, 0));
       
 12195 }
       
 12196 
       
 12197 /**
       
 12198  * xmlSAXParseFileWithData:
       
 12199  * @param sax the SAX handler block
       
 12200  * @param filename the filename
       
 12201  * @param recovery work in recovery mode, i.e. tries to read no Well Formed
       
 12202  *             documents
       
 12203  * @param data the userdata
       
 12204  *
       
 12205  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
       
 12206  * compressed document is provided by default if found at compile-time.
       
 12207  * It use the given SAX function block to handle the parsing callback.
       
 12208  * If sax is NULL, fallback to the default DOM tree building routines.
       
 12209  *
       
 12210  * User data (void *) is stored within the parser context in the
       
 12211  * context's _private member, so it is available nearly everywhere in libxml
       
 12212  *
       
 12213  * Returns the resulting document tree
       
 12214  */
       
 12215 
       
 12216 XMLPUBFUNEXPORT xmlDocPtr
       
 12217 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
       
 12218                         int recovery, void *data) {
       
 12219     xmlDocPtr ret;
       
 12220     xmlParserCtxtPtr ctxt;
       
 12221     // local variable 'directory' was removed (function was optimized)
       
 12222 
       
 12223     xmlInitParser();
       
 12224     
       
 12225 
       
 12226     ctxt = xmlCreateFileParserCtxt(filename);
       
 12227     if (!ctxt) {
       
 12228         return(NULL);
       
 12229     }
       
 12230 
       
 12231     if (sax) {
       
 12232         if (ctxt->sax)
       
 12233             xmlFree(ctxt->sax);
       
 12234         ctxt->sax = sax;
       
 12235     }
       
 12236 
       
 12237     xmlDetectSAX2(ctxt);
       
 12238     if (data) {
       
 12239         ctxt->_private = data;
       
 12240     }
       
 12241 
       
 12242     if (!ctxt->directory)
       
 12243         ctxt->directory = xmlParserGetDirectory(filename);
       
 12244 
       
 12245     ctxt->recovery = recovery;
       
 12246 
       
 12247     xmlParseDocument(ctxt);
       
 12248 
       
 12249     if (ctxt->wellFormed || recovery) {
       
 12250         ret = ctxt->myDoc;
       
 12251         if (ret) {
       
 12252             if (ctxt->input->buf->compressed > 0)
       
 12253                 ret->compression = 9;
       
 12254             else
       
 12255                 ret->compression = ctxt->input->buf->compressed;
       
 12256         }
       
 12257     } else {
       
 12258        // not well-formed and w/o recovery
       
 12259        ret = NULL;
       
 12260        xmlFreeDoc(ctxt->myDoc);
       
 12261        ctxt->myDoc = NULL;
       
 12262     }
       
 12263 
       
 12264     if(sax)
       
 12265         ctxt->sax = NULL;
       
 12266     xmlFreeParserCtxt(ctxt);
       
 12267 
       
 12268     return(ret);
       
 12269 }
       
 12270 
       
 12271 /**
       
 12272  * xmlSAXParseFile:
       
 12273  * @param sax the SAX handler block
       
 12274  * @param filename the filename
       
 12275  * @param recovery work in recovery mode, i.e. tries to read no Well Formed
       
 12276  *             documents
       
 12277  *
       
 12278  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
       
 12279  * compressed document is provided by default if found at compile-time.
       
 12280  * It use the given SAX function block to handle the parsing callback.
       
 12281  * If sax is NULL, fallback to the default DOM tree building routines.
       
 12282  *
       
 12283  * Returns the resulting document tree
       
 12284  */
       
 12285 
       
 12286 XMLPUBFUNEXPORT xmlDocPtr
       
 12287 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
       
 12288                           int recovery) {
       
 12289     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
       
 12290 }
       
 12291 
       
 12292 /**
       
 12293  * xmlRecoverDoc:
       
 12294  * @param cur a pointer to an array of xmlChar
       
 12295  *
       
 12296  * parse an XML in-memory document and build a tree.
       
 12297  * In the case the document is not Well Formed, a tree is built anyway
       
 12298  *
       
 12299  * Returns the resulting document tree
       
 12300  */
       
 12301 
       
 12302 XMLPUBFUNEXPORT xmlDocPtr
       
 12303 xmlRecoverDoc(xmlChar *cur) {
       
 12304     return(xmlSAXParseDoc(NULL, cur, 0, 1,NULL));
       
 12305 }
       
 12306 
       
 12307 /**
       
 12308  * xmlRecoverFile:
       
 12309  * @param filename the filename
       
 12310  *
       
 12311  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
       
 12312  * compressed document is provided by default if found at compile-time.
       
 12313  * In the case the document is not Well Formed, a tree is built anyway
       
 12314  *
       
 12315  * Returns the resulting document tree
       
 12316  */
       
 12317 
       
 12318 XMLPUBFUNEXPORT xmlDocPtr
       
 12319 xmlRecoverFile(const char *filename) {
       
 12320     return(xmlSAXParseFile(NULL, filename, 1));
       
 12321 }
       
 12322 
       
 12323 
       
 12324 /**
       
 12325  * xmlParseFile:
       
 12326  * @param filename the filename
       
 12327  *
       
 12328  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
       
 12329  * compressed document is provided by default if found at compile-time.
       
 12330  *
       
 12331  * Returns the resulting document tree if the file was wellformed,
       
 12332  * NULL otherwise.
       
 12333  */
       
 12334 
       
 12335 XMLPUBFUNEXPORT xmlDocPtr
       
 12336 xmlParseFile(const char *filename) {
       
 12337     return(xmlSAXParseFile(NULL, filename, 0));
       
 12338 }
       
 12339 
       
 12340 /**
       
 12341  * xmlSetupParserForBuffer:
       
 12342  * @param ctxt an XML parser context
       
 12343  * @param buffer a xmlChar * buffer
       
 12344  * @param filename a file name
       
 12345  *
       
 12346  * Setup the parser context to parse a new buffer; Clears any prior
       
 12347  * contents from the parser context. The buffer parameter must not be
       
 12348  * NULL, but the filename parameter can be
       
 12349  */
       
 12350 XMLPUBFUNEXPORT void
       
 12351 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
       
 12352                              const char* filename)
       
 12353 {
       
 12354     xmlParserInputPtr input;
       
 12355 
       
 12356     input = xmlNewInputStream(ctxt);
       
 12357     if (input == NULL) {
       
 12358         xmlParserOOMErr(ctxt);
       
 12359         xmlFree(ctxt);
       
 12360         return;
       
 12361     }
       
 12362 
       
 12363     xmlClearParserCtxt(ctxt);
       
 12364     if (filename != NULL)
       
 12365         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
       
 12366     input->base = buffer;
       
 12367     input->cur = buffer;
       
 12368     input->end = &buffer[xmlStrlen(buffer)];
       
 12369     inputPush(ctxt, input);
       
 12370 }
       
 12371 
       
 12372 /**
       
 12373  * xmlSAXUserParseFile:
       
 12374  * @param sax a SAX handler
       
 12375  * @param user_data The user data returned on SAX callbacks
       
 12376  * @param filename a file name
       
 12377  *
       
 12378  * parse an XML file and call the given SAX handler routines.
       
 12379  * Automatic support for ZLIB/Compress compressed document is provided
       
 12380  *
       
 12381  * Returns 0 in case of success or a error number otherwise
       
 12382  */
       
 12383 XMLPUBFUNEXPORT int
       
 12384 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
       
 12385                     const char *filename) {
       
 12386 	LOAD_GS_DIRECT
       
 12387 	
       
 12388     int ret = 0;
       
 12389     xmlParserCtxtPtr ctxt;
       
 12390 
       
 12391     ctxt = xmlCreateFileParserCtxt(filename);
       
 12392     if (ctxt == NULL) return -1;
       
 12393 #ifdef LIBXML_SAX1_ENABLED
       
 12394     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
       
 12395 #endif /* LIBXML_SAX1_ENABLED */
       
 12396         xmlFree(ctxt->sax);
       
 12397     ctxt->sax = sax;
       
 12398     xmlDetectSAX2(ctxt);
       
 12399 
       
 12400     if (user_data != NULL)
       
 12401         ctxt->userData = user_data;
       
 12402 
       
 12403     xmlParseDocument(ctxt);
       
 12404 
       
 12405     if (ctxt->wellFormed)
       
 12406         ret = 0;
       
 12407     else {
       
 12408         if (ctxt->errNo != 0)
       
 12409             ret = ctxt->errNo;
       
 12410         else
       
 12411             ret = -1;
       
 12412     }
       
 12413     if (sax != NULL)
       
 12414         ctxt->sax = NULL;
       
 12415 
       
 12416     xmlFreeParserCtxt(ctxt);
       
 12417 
       
 12418     return ret;
       
 12419 }
       
 12420 
       
 12421 
       
 12422 /************************************************************************
       
 12423  *                                                                      *
       
 12424  *      Front-ends when parsing from memory                             *
       
 12425  *                                                                      *
       
 12426  ************************************************************************/
       
 12427 
       
 12428 /**
       
 12429  * xmlCreateMemoryParserCtxt:
       
 12430  * @param buffer a pointer to a char array
       
 12431  * @param size the size of the array
       
 12432  *
       
 12433  * Create a parser context for an XML in-memory document.
       
 12434  *
       
 12435  * Returns the new parser context or NULL
       
 12436  *
       
 12437  * OOM: possible --> returns NULL, OOM flag is set
       
 12438  */
       
 12439 XMLPUBFUNEXPORT xmlParserCtxtPtr
       
 12440 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
       
 12441     xmlParserCtxtPtr ctxt;
       
 12442     xmlParserInputPtr input;
       
 12443     xmlParserInputBufferPtr buf;
       
 12444 
       
 12445     if (!buffer || size <= 0)
       
 12446         return(NULL);
       
 12447 
       
 12448     ctxt = xmlNewParserCtxt();
       
 12449     if (!ctxt)
       
 12450         return(NULL); // OOM
       
 12451 
       
 12452     
       
 12453     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
       
 12454     if (!buf)
       
 12455         goto OOM_ctxt;
       
 12456 
       
 12457     input = xmlNewInputStream(ctxt);
       
 12458     if (!input)
       
 12459         goto OOM_buf_ctxt;
       
 12460 
       
 12461     // input->filename = NULL; // It is NULL after xmlNewInputStream()
       
 12462     input->buf = buf;
       
 12463     input->base = input->buf->buffer->content;
       
 12464     input->cur = input->buf->buffer->content;
       
 12465     input->end = &input->buf->buffer->content[input->buf->buffer->use];
       
 12466 
       
 12467     if( inputPush(ctxt, input) < 0 ){
       
 12468         xmlFreeInputStream(input);
       
 12469         goto OOM_ctxt;
       
 12470     }
       
 12471     return(ctxt);
       
 12472 //--------------------------------------------
       
 12473 OOM_buf_ctxt:
       
 12474     xmlFreeParserInputBuffer(buf);
       
 12475 OOM_ctxt:
       
 12476     xmlFreeParserCtxt(ctxt);
       
 12477     return(NULL);
       
 12478 }
       
 12479 
       
 12480 /**
       
 12481  * xmlSAXParseMemoryWithData:
       
 12482  * @param sax the SAX handler block
       
 12483  * @param buffer an pointer to a char array
       
 12484  * @param size the size of the array
       
 12485  * @param recovery work in recovery mode, i.e. tries to read no Well Formed
       
 12486  *             documents
       
 12487  * @param data the userdata
       
 12488  *
       
 12489  * parse an XML in-memory block and use the given SAX function block
       
 12490  * to handle the parsing callback. If sax is NULL, fallback to the default
       
 12491  * DOM tree building routines.
       
 12492  *
       
 12493  * User data (void *) is stored within the parser context in the
       
 12494  * context's _private member, so it is available nearly everywhere in libxml
       
 12495  *
       
 12496  * Returns the resulting document tree
       
 12497  */
       
 12498 
       
 12499 XMLPUBFUNEXPORT xmlDocPtr
       
 12500 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
       
 12501               int size, int recovery, void *data) {
       
 12502     xmlDocPtr ret;
       
 12503     xmlParserCtxtPtr ctxt;
       
 12504 
       
 12505     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
       
 12506     if (ctxt == NULL) return(NULL);
       
 12507     if (sax != NULL) {
       
 12508         if (ctxt->sax != NULL)
       
 12509             xmlFree(ctxt->sax);
       
 12510         ctxt->sax = sax;
       
 12511     }
       
 12512     xmlDetectSAX2(ctxt);
       
 12513     if (data!=NULL) {
       
 12514         ctxt->_private=data;
       
 12515     }
       
 12516 
       
 12517     ctxt->recovery = recovery;
       
 12518 
       
 12519     xmlParseDocument(ctxt);
       
 12520 
       
 12521     if ((ctxt->wellFormed) || recovery)
       
 12522         ret = ctxt->myDoc;
       
 12523     else {
       
 12524         ret = NULL;
       
 12525         xmlFreeDoc(ctxt->myDoc);
       
 12526         ctxt->myDoc = NULL;
       
 12527     }
       
 12528     if (sax != NULL)
       
 12529         ctxt->sax = NULL;
       
 12530     xmlFreeParserCtxt(ctxt);
       
 12531 
       
 12532     return(ret);
       
 12533 }
       
 12534 
       
 12535 
       
 12536 
       
 12537 /**
       
 12538  * xmlSAXParseMemory:
       
 12539  * @param sax the SAX handler block
       
 12540  * @param buffer an pointer to a char array
       
 12541  * @param size the size of the array
       
 12542  * @param recovery work in recovery mode, i.e. tries to read not Well Formed
       
 12543  *             documents
       
 12544  *
       
 12545  * parse an XML in-memory block and use the given SAX function block
       
 12546  * to handle the parsing callback. If sax is NULL, fallback to the default
       
 12547  * DOM tree building routines.
       
 12548  *
       
 12549  * Returns the resulting document tree
       
 12550  */
       
 12551 XMLPUBFUNEXPORT xmlDocPtr
       
 12552 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
       
 12553               int size, int recovery) {
       
 12554     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
       
 12555 }
       
 12556 
       
 12557 /**
       
 12558  * xmlParseMemory:
       
 12559  * @param buffer an pointer to a char array
       
 12560  * @param size the size of the array
       
 12561  *
       
 12562  * parse an XML in-memory block and build a tree.
       
 12563  *
       
 12564  * Returns the resulting document tree
       
 12565  */
       
 12566 
       
 12567 XMLPUBFUNEXPORT xmlDocPtr xmlParseMemory(const char *buffer, int size) {
       
 12568    return(xmlSAXParseMemory(NULL, buffer, size, 0));
       
 12569 }
       
 12570 
       
 12571 /**
       
 12572  * xmlRecoverMemory:
       
 12573  * @param buffer an pointer to a char array
       
 12574  * @param size the size of the array
       
 12575  *
       
 12576  * parse an XML in-memory block and build a tree.
       
 12577  * In the case the document is not Well Formed, a tree is built anyway
       
 12578  *
       
 12579  * Returns the resulting document tree
       
 12580  */
       
 12581 
       
 12582 XMLPUBFUNEXPORT xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
       
 12583    return(xmlSAXParseMemory(NULL, buffer, size, 1));
       
 12584 }
       
 12585 
       
 12586 /**
       
 12587  * xmlSAXUserParseMemory:
       
 12588  * @param sax a SAX handler
       
 12589  * @param user_data The user data returned on SAX callbacks
       
 12590  * @param buffer an in-memory XML document input
       
 12591  * @param size the length of the XML document in bytes
       
 12592  *
       
 12593  * A better SAX parsing routine.
       
 12594  * parse an XML in-memory buffer and call the given SAX handler routines.
       
 12595  *
       
 12596  * Returns 0 in case of success or a error number otherwise
       
 12597  */
       
 12598 XMLPUBFUNEXPORT int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
       
 12599               const char *buffer, int size) {
       
 12600     int ret = 0;
       
 12601     xmlParserCtxtPtr ctxt;
       
 12602     xmlSAXHandlerPtr oldsax = NULL;
       
 12603 
       
 12604     if (sax == NULL) return -1;
       
 12605     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
       
 12606     if (ctxt == NULL) return -1;
       
 12607     oldsax = ctxt->sax;
       
 12608     ctxt->sax = sax;
       
 12609     xmlDetectSAX2(ctxt);
       
 12610     if (user_data != NULL)
       
 12611     ctxt->userData = user_data;
       
 12612 
       
 12613     xmlParseDocument(ctxt);
       
 12614 
       
 12615     if (ctxt->wellFormed)
       
 12616     ret = 0;
       
 12617     else {
       
 12618         if (ctxt->errNo != 0)
       
 12619         ret = ctxt->errNo;
       
 12620     else
       
 12621         ret = -1;
       
 12622     }
       
 12623     ctxt->sax = oldsax;
       
 12624     xmlFreeParserCtxt(ctxt);
       
 12625 
       
 12626     return ret;
       
 12627 }
       
 12628 
       
 12629 /**
       
 12630  * xmlCreateDocParserCtxt:
       
 12631  * @param cur a pointer to an array of xmlChar
       
 12632  * @param length size (bytes) of the array (0 if it should be calculated)
       
 12633  *
       
 12634  * Creates a parser context for an XML in-memory document.
       
 12635  *
       
 12636  * Returns the new parser context or NULL
       
 12637  *
       
 12638  * OOM: possible --> returns NULL for cur!=NULL && length>0;  OOM flag is set
       
 12639  */
       
 12640 XMLPUBFUNEXPORT xmlParserCtxtPtr
       
 12641 xmlCreateDocParserCtxt(const xmlChar *cur, int length) {
       
 12642     int len;
       
 12643 
       
 12644     if (!cur)
       
 12645         return(NULL);
       
 12646     len = (length > 0) ? length : xmlStrlen(cur);
       
 12647     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
       
 12648 }
       
 12649 
       
 12650 //#ifdef LIBXML_SAX1_ENABLED
       
 12651 /**
       
 12652  * xmlSAXParseDoc:
       
 12653  * @param sax the SAX handler block
       
 12654  * @param cur a pointer to an array of xmlChar
       
 12655  * @param length size (bytes) of the array (0 if it should be calculated)
       
 12656  * @param recovery work in recovery mode, i.e. tries to read no Well Formed
       
 12657  *             documents
       
 12658  * @param errorCode last error code is recorded, 0 is no errors
       
 12659  *
       
 12660  * parse an XML in-memory document and build a tree.
       
 12661  * It use the given SAX function block to handle the parsing callback.
       
 12662  * If sax is NULL, fallback to the default DOM tree building routines.
       
 12663  *
       
 12664  * Returns the resulting document tree
       
 12665  *
       
 12666  * OOM: possible --> OOM flag is set (and NULL is returned too)
       
 12667  */
       
 12668 
       
 12669 XMLPUBFUNEXPORT xmlDocPtr
       
 12670 xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar* cur, int length, int recovery, int* errorCode) {
       
 12671 	LOAD_GS_DIRECT
       
 12672 	
       
 12673     xmlDocPtr ret;
       
 12674     xmlParserCtxtPtr ctxt;
       
 12675 
       
 12676     if (!cur)
       
 12677         return(NULL);
       
 12678 
       
 12679     ctxt = xmlCreateDocParserCtxt(cur, length); // may set OOM flag
       
 12680     if (!ctxt)
       
 12681         return(NULL); // OOM or wrong args
       
 12682     if (sax) {
       
 12683         ctxt->sax = sax;
       
 12684         ctxt->userData = NULL;
       
 12685     }
       
 12686     xmlDetectSAX2(ctxt);
       
 12687     ret = NULL;
       
 12688 
       
 12689     if(OOM_FLAG)
       
 12690         goto cleanup;
       
 12691 
       
 12692     xmlParseDocument(ctxt); // may set OOM flag 
       
 12693 
       
 12694     if (!OOM_FLAG &&
       
 12695         (ctxt->wellFormed || recovery))
       
 12696     {
       
 12697         ret = ctxt->myDoc;
       
 12698     }
       
 12699     else
       
 12700     {
       
 12701         //ret = NULL; // Moved upwards
       
 12702         xmlFreeDoc(ctxt->myDoc);
       
 12703         //ctxt->myDoc = NULL; // unneccessary, xmlFreeParserCtxt does not try to free it
       
 12704     }
       
 12705 cleanup:
       
 12706     if (sax)
       
 12707         ctxt->sax = NULL; // do not free set of custom callbacks
       
 12708     if(errorCode)
       
 12709         *errorCode = ctxt->errNo; // write error code to output argument
       
 12710 
       
 12711     xmlFreeParserCtxt(ctxt);
       
 12712 
       
 12713     return(ret);
       
 12714 }
       
 12715 
       
 12716 /**
       
 12717  * xmlParseDoc:
       
 12718  * @param cur a pointer to an array of xmlChar
       
 12719  *
       
 12720  * parse an XML in-memory document and build a tree.
       
 12721  *
       
 12722  * Returns the resulting document tree
       
 12723  */
       
 12724 
       
 12725 XMLPUBFUNEXPORT xmlDocPtr
       
 12726 xmlParseDoc(xmlChar *cur) {
       
 12727     return(xmlSAXParseDoc(NULL, cur, 0, 0, NULL));
       
 12728 }
       
 12729 //#endif /* LIBXML_SAX1_ENABLED */
       
 12730 
       
 12731 #ifdef LIBXML_LEGACY_ENABLED
       
 12732 /************************************************************************
       
 12733  *                                                                      *
       
 12734  *  Specific function to keep track of entities references              *
       
 12735  *  and used by the XSLT debugger                                       *
       
 12736  *                                                                      *
       
 12737  ************************************************************************/
       
 12738 
       
 12739 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
       
 12740 
       
 12741 /**
       
 12742  * xmlAddEntityReference:
       
 12743  * @param ent A valid entity
       
 12744  * @param firstNode A valid first node for children of entity
       
 12745  * @param lastNode A valid last node of children entity
       
 12746  *
       
 12747  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
       
 12748  */
       
 12749 static void
       
 12750 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
       
 12751                       xmlNodePtr lastNode)
       
 12752 {
       
 12753     if (xmlEntityRefFunc != NULL) {
       
 12754         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
       
 12755     }
       
 12756 }
       
 12757 
       
 12758 
       
 12759 /**
       
 12760  * xmlSetEntityReferenceFunc:
       
 12761  * @param func A valid function
       
 12762  *
       
 12763  * Set the function to call call back when a xml reference has been made
       
 12764  */
       
 12765 void
       
 12766 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
       
 12767 {
       
 12768     xmlEntityRefFunc = func;
       
 12769 }
       
 12770 #endif /* LIBXML_LEGACY_ENABLED */
       
 12771 
       
 12772 /************************************************************************
       
 12773  *                                                                      *
       
 12774  *              Miscellaneous                                           *
       
 12775  *                                                                      *
       
 12776  ************************************************************************/
       
 12777 
       
 12778 #ifdef LIBXML_XPATH_ENABLED
       
 12779 #include <stdapis/libxml2/libxml2_xpath.h>
       
 12780 #endif
       
 12781 
       
 12782 extern void xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
       
 12783 
       
 12784 /**
       
 12785  * xmlInitParser:
       
 12786  *
       
 12787  * Initialization function for the XML parser.
       
 12788  * This is not reentrant. Call once before processing in case of
       
 12789  * use in multithreaded programs.
       
 12790  *
       
 12791  * OOM: possible --> OOM flag is set
       
 12792  */
       
 12793 
       
 12794 XMLPUBFUNEXPORT void
       
 12795 xmlInitParser(void) {
       
 12796 	DEFINE_GS_PROXY //note: ensure GS proxy initialize before any GS member access
       
 12797     xmlGlobalStatePtr gs = xmlGetGlobalState();
       
 12798     if (!gs)
       
 12799         {
       
 12800         gs = xmlCreateAndInitializeGlobalState();
       
 12801         if (!gs)
       
 12802             return;
       
 12803         }
       
 12804     SET_GS_PROXY(gs)
       
 12805 
       
 12806     if (xmlParserInitialized != 0)
       
 12807         return;
       
 12808     
       
 12809     if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
       
 12810         (xmlGenericError == NULL))
       
 12811     {
       
 12812         initGenericErrorDefaultFunc(NULL);
       
 12813     }
       
 12814     xmlInitGlobals();
       
 12815     xmlInitThreads();
       
 12816     xmlInitMemory();
       
 12817     xmlInitCharEncodingHandlers(); // may set OOM flag
       
 12818     xmlDefaultSAXHandlerInit();
       
 12819     xmlRegisterDefaultInputCallbacks();
       
 12820 #ifdef LIBXML_OUTPUT_ENABLED
       
 12821     xmlRegisterDefaultOutputCallbacks();
       
 12822 #endif /* LIBXML_OUTPUT_ENABLED */
       
 12823 #ifdef LIBXML_HTML_ENABLED
       
 12824     htmlInitAutoClose();
       
 12825     htmlDefaultSAXHandlerInit();
       
 12826 #endif
       
 12827 #ifdef LIBXML_XPATH_ENABLED
       
 12828     xmlXPathInit();
       
 12829 #endif
       
 12830     //xmlParserMaxDepth = 1024;
       
 12831     xmlParserInitialized = 1;
       
 12832 }
       
 12833 
       
 12834 /**
       
 12835  * xmlCleanupParser:
       
 12836  *
       
 12837  * Cleanup function for the XML library. It tries to reclaim all
       
 12838  * parsing related global memory allocated for the library processing.
       
 12839  * It doesn't deallocate any document related memory. Calling this
       
 12840  * function should not prevent reusing the library but one should
       
 12841  * call xmlCleanupParser() only when the process has
       
 12842  * finished using the library or XML document built with it.
       
 12843  *
       
 12844  * OOM: never
       
 12845  */
       
 12846 
       
 12847 XMLPUBFUNEXPORT void
       
 12848 xmlCleanupParser(void) {
       
 12849 	LOAD_GS_DIRECT
       
 12850     if (!xmlParserInitialized)
       
 12851         return;
       
 12852 
       
 12853     xmlCleanupCharEncodingHandlers();
       
 12854 #ifdef LIBXML_CATALOG_ENABLED
       
 12855     xmlCatalogCleanup();
       
 12856 #endif
       
 12857     xmlCleanupInputCallbacks();
       
 12858 #ifdef LIBXML_OUTPUT_ENABLED
       
 12859     xmlCleanupOutputCallbacks();
       
 12860 #endif
       
 12861     xmlCleanupGlobals();
       
 12862     xmlResetLastError();
       
 12863     xmlCleanupThreads(); /* must be last if called not from the main thread */
       
 12864     xmlCleanupMemory();
       
 12865     xmlParserInitialized = 0;
       
 12866 }
       
 12867 
       
 12868 /************************************************************************
       
 12869  *                                                                      *
       
 12870  *  New set (2.6.0) of simpler and more flexible APIs                   *
       
 12871  *                                                                      *
       
 12872  ************************************************************************/
       
 12873 
       
 12874 /**
       
 12875  * DICT_FREE:
       
 12876  * @param str a string
       
 12877  *
       
 12878  * Free a string if it is not owned by the "dict" dictionnary in the
       
 12879  * current scope
       
 12880  */
       
 12881 #define DICT_FREE(str)                                      \
       
 12882     if ((str) && ((!dict) ||                                \
       
 12883         (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
       
 12884         xmlFree((char *)(str));
       
 12885 
       
 12886 /**
       
 12887  * xmlCtxtReset:
       
 12888  * @param ctxt an XML parser context
       
 12889  *
       
 12890  * Reset a parser context
       
 12891  */
       
 12892 XMLPUBFUNEXPORT void
       
 12893 xmlCtxtReset(xmlParserCtxtPtr ctxt)
       
 12894 {
       
 12895     xmlParserInputPtr input;
       
 12896     xmlDictPtr dict = ctxt->dict;
       
 12897 
       
 12898     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
       
 12899         xmlFreeInputStream(input);
       
 12900     }
       
 12901     ctxt->inputNr = 0;
       
 12902     ctxt->input = NULL;
       
 12903 
       
 12904     ctxt->spaceNr = 0;
       
 12905     ctxt->spaceTab[0] = -1;
       
 12906     ctxt->space = &ctxt->spaceTab[0];
       
 12907 
       
 12908 
       
 12909     ctxt->nodeNr = 0;
       
 12910     ctxt->node = NULL;
       
 12911 
       
 12912     ctxt->nameNr = 0;
       
 12913     ctxt->name = NULL;
       
 12914 
       
 12915     DICT_FREE(ctxt->version);
       
 12916     ctxt->version = NULL;
       
 12917     DICT_FREE(ctxt->encoding);
       
 12918     ctxt->encoding = NULL;
       
 12919     DICT_FREE(ctxt->directory);
       
 12920     ctxt->directory = NULL;
       
 12921     DICT_FREE(ctxt->extSubURI);
       
 12922     ctxt->extSubURI = NULL;
       
 12923     DICT_FREE(ctxt->extSubSystem);
       
 12924     ctxt->extSubSystem = NULL;
       
 12925     if (ctxt->myDoc != NULL)
       
 12926         xmlFreeDoc(ctxt->myDoc);
       
 12927     ctxt->myDoc = NULL;
       
 12928 
       
 12929     ctxt->standalone = -1;
       
 12930     ctxt->hasExternalSubset = 0;
       
 12931     ctxt->hasPErefs = 0;
       
 12932     ctxt->html = 0;
       
 12933     ctxt->external = 0;
       
 12934     ctxt->instate = XML_PARSER_START;
       
 12935     ctxt->token = 0;
       
 12936 
       
 12937     ctxt->wellFormed = 1;
       
 12938     ctxt->nsWellFormed = 1;
       
 12939     ctxt->disableSAX = 0;
       
 12940     ctxt->valid = 1;
       
 12941 
       
 12942 #if 0
       
 12943     ctxt->vctxt.userData = ctxt;
       
 12944     ctxt->vctxt.error = xmlParserValidityError;
       
 12945     ctxt->vctxt.warning = xmlParserValidityWarning;
       
 12946 #endif
       
 12947 
       
 12948 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
 12949     
       
 12950     ctxt->record_info = 0;
       
 12951     xmlInitNodeInfoSeq(&ctxt->node_seq);
       
 12952 #endif
       
 12953     ctxt->nbChars = 0;
       
 12954     ctxt->checkIndex = 0;
       
 12955     ctxt->inSubset = 0;
       
 12956     ctxt->errNo = XML_ERR_OK;
       
 12957     ctxt->depth = 0;
       
 12958     ctxt->charset = XML_CHAR_ENCODING_UTF8;
       
 12959     ctxt->catalogs = NULL;
       
 12960 
       
 12961     if (ctxt->attsDefault != NULL) {
       
 12962         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
       
 12963         ctxt->attsDefault = NULL;
       
 12964     }
       
 12965     if (ctxt->attsSpecial != NULL) {
       
 12966         xmlHashFree(ctxt->attsSpecial, NULL);
       
 12967         ctxt->attsSpecial = NULL;
       
 12968     }
       
 12969 
       
 12970 #ifdef LIBXML_CATALOG_ENABLED
       
 12971     if (ctxt->catalogs != NULL)
       
 12972         xmlCatalogFreeLocal(ctxt->catalogs);
       
 12973 #endif
       
 12974     if (ctxt->lastError.code != XML_ERR_OK)
       
 12975         xmlResetError(&ctxt->lastError);
       
 12976 }
       
 12977 
       
 12978 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
 12979 /**
       
 12980  * xmlCtxtResetPush:
       
 12981  * @param ctxt an XML parser context
       
 12982  * @param chunk a pointer to an array of chars
       
 12983  * @param size number of chars in the array
       
 12984  * @param filename an optional file name or URI
       
 12985  * @param encoding the document encoding, or NULL
       
 12986  *
       
 12987  * Reset a push parser context
       
 12988  *
       
 12989  * Returns 0 in case of success and 1 in case of error
       
 12990  */
       
 12991 int
       
 12992 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
       
 12993                  int size, const char *filename, const char *encoding)
       
 12994 {
       
 12995     xmlParserInputPtr inputStream;
       
 12996     xmlParserInputBufferPtr buf;
       
 12997     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
       
 12998 
       
 12999     if (ctxt == NULL)
       
 13000         return(1);
       
 13001 
       
 13002     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
       
 13003         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
       
 13004 
       
 13005     buf = xmlAllocParserInputBuffer(enc);
       
 13006     if (buf == NULL)
       
 13007         return(1);
       
 13008 
       
 13009     if (ctxt == NULL) {
       
 13010         xmlFreeParserInputBuffer(buf);
       
 13011         return(1);
       
 13012     }
       
 13013 
       
 13014     xmlCtxtReset(ctxt);
       
 13015 
       
 13016     if (ctxt->pushTab == NULL) {
       
 13017         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
       
 13018                                         sizeof(xmlChar *));
       
 13019         if (ctxt->pushTab == NULL) {
       
 13020             xmlParserOOMErr(ctxt);
       
 13021             xmlFreeParserInputBuffer(buf);
       
 13022             return(1);
       
 13023         }
       
 13024     }
       
 13025 
       
 13026     if (filename == NULL) {
       
 13027         ctxt->directory = NULL;
       
 13028     } else {
       
 13029         ctxt->directory = xmlParserGetDirectory(filename);
       
 13030     }
       
 13031 
       
 13032     inputStream = xmlNewInputStream(ctxt);
       
 13033     if (inputStream == NULL) {
       
 13034         xmlFreeParserInputBuffer(buf);
       
 13035         return(1);
       
 13036     }
       
 13037 
       
 13038     if (filename == NULL)
       
 13039         inputStream->filename = NULL;
       
 13040     else
       
 13041         inputStream->filename = (char *)
       
 13042 
       
 13043     xmlCanonicPath((const xmlChar *) filename);
       
 13044     inputStream->buf = buf;
       
 13045     inputStream->base = inputStream->buf->buffer->content;
       
 13046     inputStream->cur = inputStream->buf->buffer->content;
       
 13047     inputStream->end = &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
       
 13048 
       
 13049     inputPush(ctxt, inputStream);
       
 13050 
       
 13051     if ((size > 0) && (chunk != NULL) &&
       
 13052         (ctxt->input != NULL) &&
       
 13053         (ctxt->input->buf != NULL))
       
 13054     {
       
 13055         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
       
 13056         int cur = ctxt->input->cur - ctxt->input->base;
       
 13057 
       
 13058         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
       
 13059 
       
 13060         ctxt->input->base = ctxt->input->buf->buffer->content + base;
       
 13061         ctxt->input->cur = ctxt->input->base + cur;
       
 13062         ctxt->input->end =
       
 13063             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
       
 13064 #ifdef DEBUG_PUSH
       
 13065         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
       
 13066 #endif
       
 13067     }
       
 13068 
       
 13069     if (encoding != NULL) {
       
 13070         xmlCharEncodingHandlerPtr hdlr;
       
 13071 
       
 13072         hdlr = xmlFindCharEncodingHandler(encoding);
       
 13073         if (hdlr != NULL) {
       
 13074             xmlSwitchToEncoding(ctxt, hdlr);
       
 13075     } else {
       
 13076         xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
       
 13077                   EMBED_ERRTXT("Unsupported encoding %s\n"), BAD_CAST encoding);
       
 13078         }
       
 13079     } else if (enc != XML_CHAR_ENCODING_NONE) {
       
 13080         xmlSwitchEncoding(ctxt, enc);
       
 13081     }
       
 13082 
       
 13083     return(0);
       
 13084 }
       
 13085 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
 13086 
       
 13087 
       
 13088 /**
       
 13089  * xmlCtxtUseOptions:
       
 13090  * @param ctxt an XML parser context
       
 13091  * @param options a combination of xmlParserOption
       
 13092  *
       
 13093  * Applies the options to the parser context
       
 13094  *
       
 13095  * Returns 0 in case of success, the set of unknown or unimplemented options
       
 13096  *         in case of error.
       
 13097  */
       
 13098 XMLPUBFUNEXPORT int
       
 13099 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
       
 13100 {
       
 13101     if (options & XML_PARSE_RECOVER) {
       
 13102         ctxt->recovery = 1;
       
 13103         options -= XML_PARSE_RECOVER;
       
 13104     } else
       
 13105         ctxt->recovery = 0;
       
 13106     if (options & XML_PARSE_DTDLOAD) {
       
 13107         ctxt->loadsubset = XML_DETECT_IDS;
       
 13108         options -= XML_PARSE_DTDLOAD;
       
 13109     } else
       
 13110         ctxt->loadsubset = 0;
       
 13111     if (options & XML_PARSE_DTDATTR) {
       
 13112         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
       
 13113         options -= XML_PARSE_DTDATTR;
       
 13114     }
       
 13115     if (options & XML_PARSE_NOENT) {
       
 13116         ctxt->replaceEntities = 1;
       
 13117         /* ctxt->loadsubset |= XML_DETECT_IDS; */
       
 13118         options -= XML_PARSE_NOENT;
       
 13119     } else
       
 13120         ctxt->replaceEntities = 0;
       
 13121     if (options & XML_PARSE_NOWARNING) {
       
 13122         ctxt->sax->warning = NULL;
       
 13123         options -= XML_PARSE_NOWARNING;
       
 13124     }
       
 13125     if (options & XML_PARSE_NOERROR) {
       
 13126         ctxt->sax->error = NULL;
       
 13127         ctxt->sax->fatalError = NULL;
       
 13128         options -= XML_PARSE_NOERROR;
       
 13129     }
       
 13130     if (options & XML_PARSE_PEDANTIC) {
       
 13131         ctxt->pedantic = 1;
       
 13132         options -= XML_PARSE_PEDANTIC;
       
 13133     } else
       
 13134         ctxt->pedantic = 0;
       
 13135     if (options & XML_PARSE_NOBLANKS) {
       
 13136         ctxt->keepBlanks = 0;
       
 13137         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
       
 13138         options -= XML_PARSE_NOBLANKS;
       
 13139     } else
       
 13140         ctxt->keepBlanks = 1;
       
 13141     if (options & XML_PARSE_DTDVALID) {
       
 13142         ctxt->validate = 1;
       
 13143         if (options & XML_PARSE_NOWARNING)
       
 13144             ctxt->vctxt.warning = NULL;
       
 13145         if (options & XML_PARSE_NOERROR)
       
 13146             ctxt->vctxt.error = NULL;
       
 13147         options -= XML_PARSE_DTDVALID;
       
 13148     } else
       
 13149         ctxt->validate = 0;
       
 13150 #ifdef LIBXML_SAX1_ENABLED
       
 13151     if (options & XML_PARSE_SAX1) {
       
 13152         ctxt->sax->startElement = xmlSAX2StartElement;
       
 13153         ctxt->sax->endElement = xmlSAX2EndElement;
       
 13154         ctxt->sax->startElementNs = NULL;
       
 13155         ctxt->sax->endElementNs = NULL;
       
 13156         ctxt->sax->initialized = 1;
       
 13157         options -= XML_PARSE_SAX1;
       
 13158     }
       
 13159 #endif /* LIBXML_SAX1_ENABLED */
       
 13160     if (options & XML_PARSE_NODICT) {
       
 13161         ctxt->dictNames = 0;
       
 13162         options -= XML_PARSE_NODICT;
       
 13163     } else {
       
 13164         ctxt->dictNames = 1;
       
 13165     }
       
 13166     if (options & XML_PARSE_NOCDATA) {
       
 13167         ctxt->sax->cdataBlock = NULL;
       
 13168         options -= XML_PARSE_NOCDATA;
       
 13169     }
       
 13170     if (options & XML_PARSE_NSCLEAN) {
       
 13171     ctxt->options |= XML_PARSE_NSCLEAN;
       
 13172         options -= XML_PARSE_NSCLEAN;
       
 13173     }
       
 13174     if (options & XML_PARSE_NONET) {
       
 13175     ctxt->options |= XML_PARSE_NONET;
       
 13176         options -= XML_PARSE_NONET;
       
 13177     }
       
 13178 #ifdef LIBXML_ENABLE_NODE_LINEINFO
       
 13179     ctxt->linenumbers = 1;
       
 13180 #endif
       
 13181     return (options);
       
 13182 }
       
 13183 
       
 13184 /**
       
 13185  * xmlDoRead:
       
 13186  * @param ctxt an XML parser context
       
 13187  * @param URL the base URL to use for the document
       
 13188  * @param encoding the document encoding, or NULL
       
 13189  * @param options a combination of xmlParserOption
       
 13190  * @param reuse keep the context for reuse
       
 13191  *
       
 13192  * Common front-end for the xmlRead functions
       
 13193  *
       
 13194  * Returns the resulting document tree or NULL
       
 13195  */
       
 13196 static xmlDocPtr
       
 13197 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
       
 13198           int options, int reuse)
       
 13199 {
       
 13200     xmlDocPtr ret;
       
 13201 
       
 13202     xmlCtxtUseOptions(ctxt, options);
       
 13203     if (encoding != NULL) {
       
 13204         xmlCharEncodingHandlerPtr hdlr;
       
 13205 
       
 13206         hdlr = xmlFindCharEncodingHandler(encoding);
       
 13207         if (hdlr != NULL)
       
 13208             xmlSwitchToEncoding(ctxt, hdlr);
       
 13209     }
       
 13210     if ((URL != NULL) &&
       
 13211         (ctxt->input != NULL) &&
       
 13212         (ctxt->input->filename == NULL))
       
 13213     {
       
 13214         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
       
 13215     }
       
 13216     xmlParseDocument(ctxt);
       
 13217     if ((ctxt->wellFormed) || ctxt->recovery)
       
 13218         ret = ctxt->myDoc;
       
 13219     else {
       
 13220         ret = NULL;
       
 13221         if (ctxt->myDoc != NULL) {
       
 13222             xmlFreeDoc(ctxt->myDoc);
       
 13223         }
       
 13224     }
       
 13225     ctxt->myDoc = NULL;
       
 13226     if (!reuse) {
       
 13227         xmlFreeParserCtxt(ctxt);
       
 13228     }
       
 13229 
       
 13230     return (ret);
       
 13231 }
       
 13232 
       
 13233 /**
       
 13234  * xmlReadDoc:
       
 13235  * @param cur a pointer to a zero terminated string
       
 13236  * @param URL the base URL to use for the document
       
 13237  * @param encoding the document encoding, or NULL
       
 13238  * @param options a combination of xmlParserOption
       
 13239  *
       
 13240  * parse an XML in-memory document and build a tree.
       
 13241  *
       
 13242  * Returns the resulting document tree
       
 13243  */
       
 13244 
       
 13245 XMLPUBFUNEXPORT xmlDocPtr
       
 13246 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
       
 13247 {
       
 13248     xmlParserCtxtPtr ctxt;
       
 13249 
       
 13250     if (cur == NULL)
       
 13251         return (NULL);
       
 13252 
       
 13253     ctxt = xmlCreateDocParserCtxt(cur, 0);
       
 13254     if (ctxt == NULL)
       
 13255         return (NULL);
       
 13256     return (xmlDoRead(ctxt, URL, encoding, options, 0));
       
 13257 }
       
 13258 
       
 13259 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
 13260 /**
       
 13261  * xmlReadFile:
       
 13262  * @param filename a file or URL
       
 13263  * @param encoding the document encoding, or NULL
       
 13264  * @param options a combination of xmlParserOption
       
 13265  *
       
 13266  * parse an XML file from the filesystem or the network.
       
 13267  *
       
 13268  * Returns the resulting document tree
       
 13269  */
       
 13270 xmlDocPtr
       
 13271 xmlReadFile(const char *filename, const char *encoding, int options)
       
 13272 {
       
 13273     xmlParserCtxtPtr ctxt;
       
 13274 
       
 13275     ctxt = xmlCreateURLParserCtxt(filename, options);
       
 13276     if (ctxt == NULL)
       
 13277         return (NULL);
       
 13278     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
       
 13279 }
       
 13280 #endif
       
 13281 
       
 13282 /**
       
 13283  * xmlReadMemory:
       
 13284  * @param buffer a pointer to a char array
       
 13285  * @param size the size of the array
       
 13286  * @param URL the base URL to use for the document
       
 13287  * @param encoding the document encoding, or NULL
       
 13288  * @param options a combination of xmlParserOption
       
 13289  *
       
 13290  * parse an XML in-memory document and build a tree.
       
 13291  *
       
 13292  * Returns the resulting document tree
       
 13293  */
       
 13294 XMLPUBFUNEXPORT xmlDocPtr
       
 13295 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
       
 13296 {
       
 13297     xmlParserCtxtPtr ctxt;
       
 13298 
       
 13299     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
       
 13300     if (ctxt == NULL)
       
 13301         return (NULL);
       
 13302     return (xmlDoRead(ctxt, URL, encoding, options, 0));
       
 13303 }
       
 13304 
       
 13305 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
 13306 /**
       
 13307  * xmlReadFd:
       
 13308  * @param fd an open file descriptor
       
 13309  * @param URL the base URL to use for the document
       
 13310  * @param encoding the document encoding, or NULL
       
 13311  * @param options a combination of xmlParserOption
       
 13312  *
       
 13313  * parse an XML from a file descriptor and build a tree.
       
 13314  * NOTE that the file descriptor will not be closed when the
       
 13315  *      reader is closed or reset.
       
 13316  *
       
 13317  * Returns the resulting document tree
       
 13318  */
       
 13319 xmlDocPtr
       
 13320 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
       
 13321 {
       
 13322     xmlParserCtxtPtr ctxt;
       
 13323     xmlParserInputBufferPtr input;
       
 13324     xmlParserInputPtr stream;
       
 13325 
       
 13326     if (fd < 0)
       
 13327         return (NULL);
       
 13328 
       
 13329     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
       
 13330     if (input == NULL)
       
 13331         return (NULL);
       
 13332     input->closecallback = NULL;
       
 13333     ctxt = xmlNewParserCtxt();
       
 13334     if (ctxt == NULL) {
       
 13335         xmlFreeParserInputBuffer(input);
       
 13336         return (NULL);
       
 13337     }
       
 13338     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
       
 13339     if (stream == NULL) {
       
 13340         xmlFreeParserInputBuffer(input);
       
 13341     xmlFreeParserCtxt(ctxt);
       
 13342         return (NULL);
       
 13343     }
       
 13344     inputPush(ctxt, stream);
       
 13345     return (xmlDoRead(ctxt, URL, encoding, options, 0));
       
 13346 }
       
 13347 
       
 13348 
       
 13349 // XMLENGINE: This may be reused for xDC
       
 13350 
       
 13351 /**
       
 13352  * xmlReadIO:
       
 13353  * @param ioread an I/O read function
       
 13354  * @param ioclose an I/O close function
       
 13355  * @param ioctx an I/O handler
       
 13356  * @param URL the base URL to use for the document
       
 13357  * @param encoding the document encoding, or NULL
       
 13358  * @param options a combination of xmlParserOption
       
 13359  *
       
 13360  * parse an XML document from I/O functions and source and build a tree.
       
 13361  *
       
 13362  * Returns the resulting document tree
       
 13363  */
       
 13364 xmlDocPtr
       
 13365 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
       
 13366           void *ioctx, const char *URL, const char *encoding, int options)
       
 13367 {
       
 13368     xmlParserCtxtPtr ctxt;
       
 13369     xmlParserInputBufferPtr input;
       
 13370     xmlParserInputPtr stream;
       
 13371 
       
 13372     if (ioread == NULL)
       
 13373         return (NULL);
       
 13374 
       
 13375     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
       
 13376                                          XML_CHAR_ENCODING_NONE);
       
 13377     if (input == NULL)
       
 13378         return (NULL);
       
 13379     ctxt = xmlNewParserCtxt();
       
 13380     if (ctxt == NULL) {
       
 13381         xmlFreeParserInputBuffer(input);
       
 13382         return (NULL);
       
 13383     }
       
 13384     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
       
 13385     if (stream == NULL) {
       
 13386         xmlFreeParserInputBuffer(input);
       
 13387     xmlFreeParserCtxt(ctxt);
       
 13388         return (NULL);
       
 13389     }
       
 13390     inputPush(ctxt, stream);
       
 13391     return (xmlDoRead(ctxt, URL, encoding, options, 0));
       
 13392 }
       
 13393 
       
 13394 
       
 13395 /**
       
 13396  * xmlCtxtReadDoc:
       
 13397  * @param ctxt an XML parser context
       
 13398  * @param cur a pointer to a zero terminated string
       
 13399  * @param URL the base URL to use for the document
       
 13400  * @param encoding the document encoding, or NULL
       
 13401  * @param options a combination of xmlParserOption
       
 13402  *
       
 13403  * parse an XML in-memory document and build a tree.
       
 13404  * This reuses the existing ctxt parser context
       
 13405  *
       
 13406  * Returns the resulting document tree
       
 13407  */
       
 13408 xmlDocPtr
       
 13409 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
       
 13410                const char *URL, const char *encoding, int options)
       
 13411 {
       
 13412     xmlParserInputPtr stream;
       
 13413 
       
 13414     if (cur == NULL)
       
 13415         return (NULL);
       
 13416     if (ctxt == NULL)
       
 13417         return (NULL);
       
 13418 
       
 13419     xmlCtxtReset(ctxt);
       
 13420 
       
 13421     stream = xmlNewStringInputStream(ctxt, cur);
       
 13422     if (stream == NULL) {
       
 13423         return (NULL);
       
 13424     }
       
 13425     inputPush(ctxt, stream);
       
 13426     return (xmlDoRead(ctxt, URL, encoding, options, 1));
       
 13427 }
       
 13428 
       
 13429 /**
       
 13430  * xmlCtxtReadFile:
       
 13431  * @param ctxt an XML parser context
       
 13432  * @param filename a file or URL
       
 13433  * @param encoding the document encoding, or NULL
       
 13434  * @param options a combination of xmlParserOption
       
 13435  *
       
 13436  * parse an XML file from the filesystem or the network.
       
 13437  * This reuses the existing ctxt parser context
       
 13438  *
       
 13439  * Returns the resulting document tree
       
 13440  */
       
 13441 xmlDocPtr
       
 13442 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
       
 13443                 const char *encoding, int options)
       
 13444 {
       
 13445     xmlParserInputPtr stream;
       
 13446 
       
 13447     if (filename == NULL)
       
 13448         return (NULL);
       
 13449     if (ctxt == NULL)
       
 13450         return (NULL);
       
 13451 
       
 13452     xmlCtxtReset(ctxt);
       
 13453 
       
 13454     stream = xmlNewInputFromFile(ctxt, filename);
       
 13455     if (stream == NULL) {
       
 13456         return (NULL);
       
 13457     }
       
 13458     inputPush(ctxt, stream);
       
 13459     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
       
 13460 }
       
 13461 
       
 13462 
       
 13463 /**
       
 13464  * xmlCtxtReadMemory:
       
 13465  * @param ctxt an XML parser context
       
 13466  * @param buffer a pointer to a char array
       
 13467  * @param size the size of the array
       
 13468  * @param URL the base URL to use for the document
       
 13469  * @param encoding the document encoding, or NULL
       
 13470  * @param options a combination of xmlParserOption
       
 13471  *
       
 13472  * parse an XML in-memory document and build a tree.
       
 13473  * This reuses the existing ctxt parser context
       
 13474  *
       
 13475  * Returns the resulting document tree
       
 13476  */
       
 13477 xmlDocPtr
       
 13478 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
       
 13479                   const char *URL, const char *encoding, int options)
       
 13480 {
       
 13481     xmlParserInputBufferPtr input;
       
 13482     xmlParserInputPtr stream;
       
 13483 
       
 13484     if (ctxt == NULL)
       
 13485         return (NULL);
       
 13486     if (buffer == NULL)
       
 13487         return (NULL);
       
 13488 
       
 13489     xmlCtxtReset(ctxt);
       
 13490 
       
 13491     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
       
 13492     if (input == NULL) {
       
 13493     return(NULL);
       
 13494     }
       
 13495 
       
 13496     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
       
 13497     if (stream == NULL) {
       
 13498     xmlFreeParserInputBuffer(input);
       
 13499     return(NULL);
       
 13500     }
       
 13501 
       
 13502     inputPush(ctxt, stream);
       
 13503     return (xmlDoRead(ctxt, URL, encoding, options, 1));
       
 13504 }
       
 13505 
       
 13506 
       
 13507 /**
       
 13508  * xmlCtxtReadFd:
       
 13509  * @param ctxt an XML parser context
       
 13510  * @param fd an open file descriptor
       
 13511  * @param URL the base URL to use for the document
       
 13512  * @param encoding the document encoding, or NULL
       
 13513  * @param options a combination of xmlParserOption
       
 13514  *
       
 13515  * parse an XML from a file descriptor and build a tree.
       
 13516  * This reuses the existing ctxt parser context
       
 13517  * NOTE that the file descriptor will not be closed when the
       
 13518  *      reader is closed or reset.
       
 13519  *
       
 13520  * Returns the resulting document tree
       
 13521  */
       
 13522 xmlDocPtr
       
 13523 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
       
 13524               const char *URL, const char *encoding, int options)
       
 13525 {
       
 13526     xmlParserInputBufferPtr input;
       
 13527     xmlParserInputPtr stream;
       
 13528 
       
 13529     if (fd < 0)
       
 13530         return (NULL);
       
 13531     if (ctxt == NULL)
       
 13532         return (NULL);
       
 13533 
       
 13534     xmlCtxtReset(ctxt);
       
 13535 
       
 13536 
       
 13537     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
       
 13538     if (input == NULL)
       
 13539         return (NULL);
       
 13540     input->closecallback = NULL;
       
 13541     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
       
 13542     if (stream == NULL) {
       
 13543         xmlFreeParserInputBuffer(input);
       
 13544         return (NULL);
       
 13545     }
       
 13546     inputPush(ctxt, stream);
       
 13547     return (xmlDoRead(ctxt, URL, encoding, options, 1));
       
 13548 }
       
 13549 
       
 13550 /**
       
 13551  * xmlCtxtReadIO:
       
 13552  * @param ctxt an XML parser context
       
 13553  * @param ioread an I/O read function
       
 13554  * @param ioclose an I/O close function
       
 13555  * @param ioctx an I/O handler
       
 13556  * @param URL the base URL to use for the document
       
 13557  * @param encoding the document encoding, or NULL
       
 13558  * @param options a combination of xmlParserOption
       
 13559  *
       
 13560  * parse an XML document from I/O functions and source and build a tree.
       
 13561  * This reuses the existing ctxt parser context
       
 13562  *
       
 13563  * Returns the resulting document tree
       
 13564  */
       
 13565 xmlDocPtr
       
 13566 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
       
 13567               xmlInputCloseCallback ioclose, void *ioctx,
       
 13568           const char *URL,
       
 13569               const char *encoding, int options)
       
 13570 {
       
 13571     xmlParserInputBufferPtr input;
       
 13572     xmlParserInputPtr stream;
       
 13573 
       
 13574     if (ioread == NULL)
       
 13575         return (NULL);
       
 13576     if (ctxt == NULL)
       
 13577         return (NULL);
       
 13578 
       
 13579     xmlCtxtReset(ctxt);
       
 13580 
       
 13581     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
       
 13582                                          XML_CHAR_ENCODING_NONE);
       
 13583     if (input == NULL)
       
 13584         return (NULL);
       
 13585     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
       
 13586     if (stream == NULL) {
       
 13587         xmlFreeParserInputBuffer(input);
       
 13588         return (NULL);
       
 13589     }
       
 13590     inputPush(ctxt, stream);
       
 13591     return (xmlDoRead(ctxt, URL, encoding, options, 1));
       
 13592 }
       
 13593 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */