Home | History | Annotate | Line # | Download | only in lib
xmlparse.c revision 1.2.6.1
      1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
      2    See the file COPYING for copying permission.
      3 */
      4 
      5 #include <stddef.h>
      6 #include <string.h>                     /* memset(), memcpy() */
      7 #include <assert.h>
      8 #include <limits.h>                     /* UINT_MAX */
      9 #include <time.h>                       /* time() */
     10 
     11 #define XML_BUILDING_EXPAT 1
     12 
     13 #ifdef COMPILED_FROM_DSP
     14 #include "winconfig.h"
     15 #elif defined(MACOS_CLASSIC)
     16 #include "macconfig.h"
     17 #elif defined(__amigaos4__)
     18 #include "amigaconfig.h"
     19 #elif defined(__WATCOMC__)
     20 #include "watcomconfig.h"
     21 #elif defined(HAVE_EXPAT_CONFIG_H)
     22 #include <expat_config.h>
     23 #endif /* ndef COMPILED_FROM_DSP */
     24 
     25 #include "ascii.h"
     26 #include "expat.h"
     27 
     28 #ifdef XML_UNICODE
     29 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
     30 #define XmlConvert XmlUtf16Convert
     31 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
     32 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
     33 #define XmlEncode XmlUtf16Encode
     34 /* Using pointer subtraction to convert to integer type. */
     35 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
     36 typedef unsigned short ICHAR;
     37 #else
     38 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
     39 #define XmlConvert XmlUtf8Convert
     40 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
     41 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
     42 #define XmlEncode XmlUtf8Encode
     43 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
     44 typedef char ICHAR;
     45 #endif
     46 
     47 
     48 #ifndef XML_NS
     49 
     50 #define XmlInitEncodingNS XmlInitEncoding
     51 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
     52 #undef XmlGetInternalEncodingNS
     53 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
     54 #define XmlParseXmlDeclNS XmlParseXmlDecl
     55 
     56 #endif
     57 
     58 #ifdef XML_UNICODE
     59 
     60 #ifdef XML_UNICODE_WCHAR_T
     61 #define XML_T(x) (const wchar_t)x
     62 #define XML_L(x) L ## x
     63 #else
     64 #define XML_T(x) (const unsigned short)x
     65 #define XML_L(x) x
     66 #endif
     67 
     68 #else
     69 
     70 #define XML_T(x) x
     71 #define XML_L(x) x
     72 
     73 #endif
     74 
     75 /* Round up n to be a multiple of sz, where sz is a power of 2. */
     76 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
     77 
     78 /* Handle the case where memmove() doesn't exist. */
     79 #ifndef HAVE_MEMMOVE
     80 #ifdef HAVE_BCOPY
     81 #define memmove(d,s,l) bcopy((s),(d),(l))
     82 #else
     83 #error memmove does not exist on this platform, nor is a substitute available
     84 #endif /* HAVE_BCOPY */
     85 #endif /* HAVE_MEMMOVE */
     86 
     87 #include "internal.h"
     88 #include "xmltok.h"
     89 #include "xmlrole.h"
     90 
     91 typedef const XML_Char *KEY;
     92 
     93 typedef struct {
     94   KEY name;
     95 } NAMED;
     96 
     97 typedef struct {
     98   NAMED **v;
     99   unsigned char power;
    100   size_t size;
    101   size_t used;
    102   const XML_Memory_Handling_Suite *mem;
    103 } HASH_TABLE;
    104 
    105 /* Basic character hash algorithm, taken from Python's string hash:
    106    h = h * 1000003 ^ character, the constant being a prime number.
    107 
    108 */
    109 #ifdef XML_UNICODE
    110 #define CHAR_HASH(h, c) \
    111   (((h) * 0xF4243) ^ (unsigned short)(c))
    112 #else
    113 #define CHAR_HASH(h, c) \
    114   (((h) * 0xF4243) ^ (unsigned char)(c))
    115 #endif
    116 
    117 /* For probing (after a collision) we need a step size relative prime
    118    to the hash table size, which is a power of 2. We use double-hashing,
    119    since we can calculate a second hash value cheaply by taking those bits
    120    of the first hash value that were discarded (masked out) when the table
    121    index was calculated: index = hash & mask, where mask = table->size - 1.
    122    We limit the maximum step size to table->size / 4 (mask >> 2) and make
    123    it odd, since odd numbers are always relative prime to a power of 2.
    124 */
    125 #define SECOND_HASH(hash, mask, power) \
    126   ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
    127 #define PROBE_STEP(hash, mask, power) \
    128   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
    129 
    130 typedef struct {
    131   NAMED **p;
    132   NAMED **end;
    133 } HASH_TABLE_ITER;
    134 
    135 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
    136 #define INIT_DATA_BUF_SIZE 1024
    137 #define INIT_ATTS_SIZE 16
    138 #define INIT_ATTS_VERSION 0xFFFFFFFF
    139 #define INIT_BLOCK_SIZE 1024
    140 #define INIT_BUFFER_SIZE 1024
    141 
    142 #define EXPAND_SPARE 24
    143 
    144 typedef struct binding {
    145   struct prefix *prefix;
    146   struct binding *nextTagBinding;
    147   struct binding *prevPrefixBinding;
    148   const struct attribute_id *attId;
    149   XML_Char *uri;
    150   int uriLen;
    151   int uriAlloc;
    152 } BINDING;
    153 
    154 typedef struct prefix {
    155   const XML_Char *name;
    156   BINDING *binding;
    157 } PREFIX;
    158 
    159 typedef struct {
    160   const XML_Char *str;
    161   const XML_Char *localPart;
    162   const XML_Char *prefix;
    163   int strLen;
    164   int uriLen;
    165   int prefixLen;
    166 } TAG_NAME;
    167 
    168 /* TAG represents an open element.
    169    The name of the element is stored in both the document and API
    170    encodings.  The memory buffer 'buf' is a separately-allocated
    171    memory area which stores the name.  During the XML_Parse()/
    172    XMLParseBuffer() when the element is open, the memory for the 'raw'
    173    version of the name (in the document encoding) is shared with the
    174    document buffer.  If the element is open across calls to
    175    XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
    176    contain the 'raw' name as well.
    177 
    178    A parser re-uses these structures, maintaining a list of allocated
    179    TAG objects in a free list.
    180 */
    181 typedef struct tag {
    182   struct tag *parent;           /* parent of this element */
    183   const char *rawName;          /* tagName in the original encoding */
    184   int rawNameLength;
    185   TAG_NAME name;                /* tagName in the API encoding */
    186   char *buf;                    /* buffer for name components */
    187   char *bufEnd;                 /* end of the buffer */
    188   BINDING *bindings;
    189 } TAG;
    190 
    191 typedef struct {
    192   const XML_Char *name;
    193   const XML_Char *textPtr;
    194   int textLen;                  /* length in XML_Chars */
    195   int processed;                /* # of processed bytes - when suspended */
    196   const XML_Char *systemId;
    197   const XML_Char *base;
    198   const XML_Char *publicId;
    199   const XML_Char *notation;
    200   XML_Bool open;
    201   XML_Bool is_param;
    202   XML_Bool is_internal; /* true if declared in internal subset outside PE */
    203 } ENTITY;
    204 
    205 typedef struct {
    206   enum XML_Content_Type         type;
    207   enum XML_Content_Quant        quant;
    208   const XML_Char *              name;
    209   int                           firstchild;
    210   int                           lastchild;
    211   int                           childcnt;
    212   int                           nextsib;
    213 } CONTENT_SCAFFOLD;
    214 
    215 #define INIT_SCAFFOLD_ELEMENTS 32
    216 
    217 typedef struct block {
    218   struct block *next;
    219   int size;
    220   XML_Char s[1];
    221 } BLOCK;
    222 
    223 typedef struct {
    224   BLOCK *blocks;
    225   BLOCK *freeBlocks;
    226   const XML_Char *end;
    227   XML_Char *ptr;
    228   XML_Char *start;
    229   const XML_Memory_Handling_Suite *mem;
    230 } STRING_POOL;
    231 
    232 /* The XML_Char before the name is used to determine whether
    233    an attribute has been specified. */
    234 typedef struct attribute_id {
    235   XML_Char *name;
    236   PREFIX *prefix;
    237   XML_Bool maybeTokenized;
    238   XML_Bool xmlns;
    239 } ATTRIBUTE_ID;
    240 
    241 typedef struct {
    242   const ATTRIBUTE_ID *id;
    243   XML_Bool isCdata;
    244   const XML_Char *value;
    245 } DEFAULT_ATTRIBUTE;
    246 
    247 typedef struct {
    248   unsigned long version;
    249   unsigned long hash;
    250   const XML_Char *uriName;
    251 } NS_ATT;
    252 
    253 typedef struct {
    254   const XML_Char *name;
    255   PREFIX *prefix;
    256   const ATTRIBUTE_ID *idAtt;
    257   int nDefaultAtts;
    258   int allocDefaultAtts;
    259   DEFAULT_ATTRIBUTE *defaultAtts;
    260 } ELEMENT_TYPE;
    261 
    262 typedef struct {
    263   HASH_TABLE generalEntities;
    264   HASH_TABLE elementTypes;
    265   HASH_TABLE attributeIds;
    266   HASH_TABLE prefixes;
    267   STRING_POOL pool;
    268   STRING_POOL entityValuePool;
    269   /* false once a parameter entity reference has been skipped */
    270   XML_Bool keepProcessing;
    271   /* true once an internal or external PE reference has been encountered;
    272      this includes the reference to an external subset */
    273   XML_Bool hasParamEntityRefs;
    274   XML_Bool standalone;
    275 #ifdef XML_DTD
    276   /* indicates if external PE has been read */
    277   XML_Bool paramEntityRead;
    278   HASH_TABLE paramEntities;
    279 #endif /* XML_DTD */
    280   PREFIX defaultPrefix;
    281   /* === scaffolding for building content model === */
    282   XML_Bool in_eldecl;
    283   CONTENT_SCAFFOLD *scaffold;
    284   unsigned contentStringLen;
    285   unsigned scaffSize;
    286   unsigned scaffCount;
    287   int scaffLevel;
    288   int *scaffIndex;
    289 } DTD;
    290 
    291 typedef struct open_internal_entity {
    292   const char *internalEventPtr;
    293   const char *internalEventEndPtr;
    294   struct open_internal_entity *next;
    295   ENTITY *entity;
    296   int startTagLevel;
    297   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
    298 } OPEN_INTERNAL_ENTITY;
    299 
    300 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
    301                                          const char *start,
    302                                          const char *end,
    303                                          const char **endPtr);
    304 
    305 static Processor prologProcessor;
    306 static Processor prologInitProcessor;
    307 static Processor contentProcessor;
    308 static Processor cdataSectionProcessor;
    309 #ifdef XML_DTD
    310 static Processor ignoreSectionProcessor;
    311 static Processor externalParEntProcessor;
    312 static Processor externalParEntInitProcessor;
    313 static Processor entityValueProcessor;
    314 static Processor entityValueInitProcessor;
    315 #endif /* XML_DTD */
    316 static Processor epilogProcessor;
    317 static Processor errorProcessor;
    318 static Processor externalEntityInitProcessor;
    319 static Processor externalEntityInitProcessor2;
    320 static Processor externalEntityInitProcessor3;
    321 static Processor externalEntityContentProcessor;
    322 static Processor internalEntityProcessor;
    323 
    324 static enum XML_Error
    325 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
    326 static enum XML_Error
    327 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
    328                const char *s, const char *next);
    329 static enum XML_Error
    330 initializeEncoding(XML_Parser parser);
    331 static enum XML_Error
    332 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
    333          const char *end, int tok, const char *next, const char **nextPtr,
    334          XML_Bool haveMore);
    335 static enum XML_Error
    336 processInternalEntity(XML_Parser parser, ENTITY *entity,
    337                       XML_Bool betweenDecl);
    338 static enum XML_Error
    339 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
    340           const char *start, const char *end, const char **endPtr,
    341           XML_Bool haveMore);
    342 static enum XML_Error
    343 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
    344                const char *end, const char **nextPtr, XML_Bool haveMore);
    345 #ifdef XML_DTD
    346 static enum XML_Error
    347 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
    348                 const char *end, const char **nextPtr, XML_Bool haveMore);
    349 #endif /* XML_DTD */
    350 
    351 static enum XML_Error
    352 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
    353           TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
    354 static enum XML_Error
    355 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
    356            const XML_Char *uri, BINDING **bindingsPtr);
    357 static int
    358 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
    359                 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
    360 static enum XML_Error
    361 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
    362                     const char *, const char *, STRING_POOL *);
    363 static enum XML_Error
    364 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
    365                      const char *, const char *, STRING_POOL *);
    366 static ATTRIBUTE_ID *
    367 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
    368                const char *end);
    369 static int
    370 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
    371 static enum XML_Error
    372 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
    373                  const char *end);
    374 static int
    375 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
    376                             const char *start, const char *end);
    377 static int
    378 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
    379               const char *end);
    380 static void
    381 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
    382               const char *end);
    383 
    384 static const XML_Char * getContext(XML_Parser parser);
    385 static XML_Bool
    386 setContext(XML_Parser parser, const XML_Char *context);
    387 
    388 static void FASTCALL normalizePublicId(XML_Char *s);
    389 
    390 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
    391 /* do not call if parentParser != NULL */
    392 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
    393 static void
    394 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
    395 static int
    396 dtdCopy(XML_Parser oldParser,
    397         DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
    398 static int
    399 copyEntityTable(XML_Parser oldParser,
    400                 HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
    401 static NAMED *
    402 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
    403 static void FASTCALL
    404 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
    405 static void FASTCALL hashTableClear(HASH_TABLE *);
    406 static void FASTCALL hashTableDestroy(HASH_TABLE *);
    407 static void FASTCALL
    408 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
    409 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
    410 
    411 static void FASTCALL
    412 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
    413 static void FASTCALL poolClear(STRING_POOL *);
    414 static void FASTCALL poolDestroy(STRING_POOL *);
    415 static XML_Char *
    416 poolAppend(STRING_POOL *pool, const ENCODING *enc,
    417            const char *ptr, const char *end);
    418 static XML_Char *
    419 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
    420                 const char *ptr, const char *end);
    421 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
    422 static const XML_Char * FASTCALL
    423 poolCopyString(STRING_POOL *pool, const XML_Char *s);
    424 static const XML_Char *
    425 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
    426 static const XML_Char * FASTCALL
    427 poolAppendString(STRING_POOL *pool, const XML_Char *s);
    428 
    429 static int FASTCALL nextScaffoldPart(XML_Parser parser);
    430 static XML_Content * build_model(XML_Parser parser);
    431 static ELEMENT_TYPE *
    432 getElementType(XML_Parser parser, const ENCODING *enc,
    433                const char *ptr, const char *end);
    434 
    435 static unsigned long generate_hash_secret_salt(void);
    436 static XML_Bool startParsing(XML_Parser parser);
    437 
    438 static XML_Parser
    439 parserCreate(const XML_Char *encodingName,
    440              const XML_Memory_Handling_Suite *memsuite,
    441              const XML_Char *nameSep,
    442              DTD *dtd);
    443 
    444 static void
    445 parserInit(XML_Parser parser, const XML_Char *encodingName);
    446 
    447 #define poolStart(pool) ((pool)->start)
    448 #define poolEnd(pool) ((pool)->ptr)
    449 #define poolLength(pool) ((pool)->ptr - (pool)->start)
    450 #define poolChop(pool) ((void)--(pool->ptr))
    451 #define poolLastChar(pool) (((pool)->ptr)[-1])
    452 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
    453 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
    454 #define poolAppendChar(pool, c) \
    455   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
    456    ? 0 \
    457    : ((*((pool)->ptr)++ = c), 1))
    458 
    459 struct XML_ParserStruct {
    460   /* The first member must be userData so that the XML_GetUserData
    461      macro works. */
    462   void *m_userData;
    463   void *m_handlerArg;
    464   char *m_buffer;
    465   const XML_Memory_Handling_Suite m_mem;
    466   /* first character to be parsed */
    467   const char *m_bufferPtr;
    468   /* past last character to be parsed */
    469   char *m_bufferEnd;
    470   /* allocated end of buffer */
    471   const char *m_bufferLim;
    472   XML_Index m_parseEndByteIndex;
    473   const char *m_parseEndPtr;
    474   XML_Char *m_dataBuf;
    475   XML_Char *m_dataBufEnd;
    476   XML_StartElementHandler m_startElementHandler;
    477   XML_EndElementHandler m_endElementHandler;
    478   XML_CharacterDataHandler m_characterDataHandler;
    479   XML_ProcessingInstructionHandler m_processingInstructionHandler;
    480   XML_CommentHandler m_commentHandler;
    481   XML_StartCdataSectionHandler m_startCdataSectionHandler;
    482   XML_EndCdataSectionHandler m_endCdataSectionHandler;
    483   XML_DefaultHandler m_defaultHandler;
    484   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
    485   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
    486   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
    487   XML_NotationDeclHandler m_notationDeclHandler;
    488   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
    489   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
    490   XML_NotStandaloneHandler m_notStandaloneHandler;
    491   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
    492   XML_Parser m_externalEntityRefHandlerArg;
    493   XML_SkippedEntityHandler m_skippedEntityHandler;
    494   XML_UnknownEncodingHandler m_unknownEncodingHandler;
    495   XML_ElementDeclHandler m_elementDeclHandler;
    496   XML_AttlistDeclHandler m_attlistDeclHandler;
    497   XML_EntityDeclHandler m_entityDeclHandler;
    498   XML_XmlDeclHandler m_xmlDeclHandler;
    499   const ENCODING *m_encoding;
    500   INIT_ENCODING m_initEncoding;
    501   const ENCODING *m_internalEncoding;
    502   const XML_Char *m_protocolEncodingName;
    503   XML_Bool m_ns;
    504   XML_Bool m_ns_triplets;
    505   void *m_unknownEncodingMem;
    506   void *m_unknownEncodingData;
    507   void *m_unknownEncodingHandlerData;
    508   void (XMLCALL *m_unknownEncodingRelease)(void *);
    509   PROLOG_STATE m_prologState;
    510   Processor *m_processor;
    511   enum XML_Error m_errorCode;
    512   const char *m_eventPtr;
    513   const char *m_eventEndPtr;
    514   const char *m_positionPtr;
    515   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
    516   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
    517   XML_Bool m_defaultExpandInternalEntities;
    518   int m_tagLevel;
    519   ENTITY *m_declEntity;
    520   const XML_Char *m_doctypeName;
    521   const XML_Char *m_doctypeSysid;
    522   const XML_Char *m_doctypePubid;
    523   const XML_Char *m_declAttributeType;
    524   const XML_Char *m_declNotationName;
    525   const XML_Char *m_declNotationPublicId;
    526   ELEMENT_TYPE *m_declElementType;
    527   ATTRIBUTE_ID *m_declAttributeId;
    528   XML_Bool m_declAttributeIsCdata;
    529   XML_Bool m_declAttributeIsId;
    530   DTD *m_dtd;
    531   const XML_Char *m_curBase;
    532   TAG *m_tagStack;
    533   TAG *m_freeTagList;
    534   BINDING *m_inheritedBindings;
    535   BINDING *m_freeBindingList;
    536   int m_attsSize;
    537   int m_nSpecifiedAtts;
    538   int m_idAttIndex;
    539   ATTRIBUTE *m_atts;
    540   NS_ATT *m_nsAtts;
    541   unsigned long m_nsAttsVersion;
    542   unsigned char m_nsAttsPower;
    543   POSITION m_position;
    544   STRING_POOL m_tempPool;
    545   STRING_POOL m_temp2Pool;
    546   char *m_groupConnector;
    547   unsigned int m_groupSize;
    548   XML_Char m_namespaceSeparator;
    549   XML_Parser m_parentParser;
    550   XML_ParsingStatus m_parsingStatus;
    551 #ifdef XML_DTD
    552   XML_Bool m_isParamEntity;
    553   XML_Bool m_useForeignDTD;
    554   enum XML_ParamEntityParsing m_paramEntityParsing;
    555 #endif
    556   unsigned long m_hash_secret_salt;
    557 };
    558 
    559 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
    560 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
    561 #define FREE(p) (parser->m_mem.free_fcn((p)))
    562 
    563 #define userData (parser->m_userData)
    564 #define handlerArg (parser->m_handlerArg)
    565 #define startElementHandler (parser->m_startElementHandler)
    566 #define endElementHandler (parser->m_endElementHandler)
    567 #define characterDataHandler (parser->m_characterDataHandler)
    568 #define processingInstructionHandler \
    569         (parser->m_processingInstructionHandler)
    570 #define commentHandler (parser->m_commentHandler)
    571 #define startCdataSectionHandler \
    572         (parser->m_startCdataSectionHandler)
    573 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
    574 #define defaultHandler (parser->m_defaultHandler)
    575 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
    576 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
    577 #define unparsedEntityDeclHandler \
    578         (parser->m_unparsedEntityDeclHandler)
    579 #define notationDeclHandler (parser->m_notationDeclHandler)
    580 #define startNamespaceDeclHandler \
    581         (parser->m_startNamespaceDeclHandler)
    582 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
    583 #define notStandaloneHandler (parser->m_notStandaloneHandler)
    584 #define externalEntityRefHandler \
    585         (parser->m_externalEntityRefHandler)
    586 #define externalEntityRefHandlerArg \
    587         (parser->m_externalEntityRefHandlerArg)
    588 #define internalEntityRefHandler \
    589         (parser->m_internalEntityRefHandler)
    590 #define skippedEntityHandler (parser->m_skippedEntityHandler)
    591 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
    592 #define elementDeclHandler (parser->m_elementDeclHandler)
    593 #define attlistDeclHandler (parser->m_attlistDeclHandler)
    594 #define entityDeclHandler (parser->m_entityDeclHandler)
    595 #define xmlDeclHandler (parser->m_xmlDeclHandler)
    596 #define encoding (parser->m_encoding)
    597 #define initEncoding (parser->m_initEncoding)
    598 #define internalEncoding (parser->m_internalEncoding)
    599 #define unknownEncodingMem (parser->m_unknownEncodingMem)
    600 #define unknownEncodingData (parser->m_unknownEncodingData)
    601 #define unknownEncodingHandlerData \
    602   (parser->m_unknownEncodingHandlerData)
    603 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
    604 #define protocolEncodingName (parser->m_protocolEncodingName)
    605 #define ns (parser->m_ns)
    606 #define ns_triplets (parser->m_ns_triplets)
    607 #define prologState (parser->m_prologState)
    608 #define processor (parser->m_processor)
    609 #define errorCode (parser->m_errorCode)
    610 #define eventPtr (parser->m_eventPtr)
    611 #define eventEndPtr (parser->m_eventEndPtr)
    612 #define positionPtr (parser->m_positionPtr)
    613 #define position (parser->m_position)
    614 #define openInternalEntities (parser->m_openInternalEntities)
    615 #define freeInternalEntities (parser->m_freeInternalEntities)
    616 #define defaultExpandInternalEntities \
    617         (parser->m_defaultExpandInternalEntities)
    618 #define tagLevel (parser->m_tagLevel)
    619 #define buffer (parser->m_buffer)
    620 #define bufferPtr (parser->m_bufferPtr)
    621 #define bufferEnd (parser->m_bufferEnd)
    622 #define parseEndByteIndex (parser->m_parseEndByteIndex)
    623 #define parseEndPtr (parser->m_parseEndPtr)
    624 #define bufferLim (parser->m_bufferLim)
    625 #define dataBuf (parser->m_dataBuf)
    626 #define dataBufEnd (parser->m_dataBufEnd)
    627 #define _dtd (parser->m_dtd)
    628 #define curBase (parser->m_curBase)
    629 #define declEntity (parser->m_declEntity)
    630 #define doctypeName (parser->m_doctypeName)
    631 #define doctypeSysid (parser->m_doctypeSysid)
    632 #define doctypePubid (parser->m_doctypePubid)
    633 #define declAttributeType (parser->m_declAttributeType)
    634 #define declNotationName (parser->m_declNotationName)
    635 #define declNotationPublicId (parser->m_declNotationPublicId)
    636 #define declElementType (parser->m_declElementType)
    637 #define declAttributeId (parser->m_declAttributeId)
    638 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
    639 #define declAttributeIsId (parser->m_declAttributeIsId)
    640 #define freeTagList (parser->m_freeTagList)
    641 #define freeBindingList (parser->m_freeBindingList)
    642 #define inheritedBindings (parser->m_inheritedBindings)
    643 #define tagStack (parser->m_tagStack)
    644 #define atts (parser->m_atts)
    645 #define attsSize (parser->m_attsSize)
    646 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
    647 #define idAttIndex (parser->m_idAttIndex)
    648 #define nsAtts (parser->m_nsAtts)
    649 #define nsAttsVersion (parser->m_nsAttsVersion)
    650 #define nsAttsPower (parser->m_nsAttsPower)
    651 #define tempPool (parser->m_tempPool)
    652 #define temp2Pool (parser->m_temp2Pool)
    653 #define groupConnector (parser->m_groupConnector)
    654 #define groupSize (parser->m_groupSize)
    655 #define namespaceSeparator (parser->m_namespaceSeparator)
    656 #define parentParser (parser->m_parentParser)
    657 #define ps_parsing (parser->m_parsingStatus.parsing)
    658 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
    659 #ifdef XML_DTD
    660 #define isParamEntity (parser->m_isParamEntity)
    661 #define useForeignDTD (parser->m_useForeignDTD)
    662 #define paramEntityParsing (parser->m_paramEntityParsing)
    663 #endif /* XML_DTD */
    664 #define hash_secret_salt (parser->m_hash_secret_salt)
    665 
    666 XML_Parser XMLCALL
    667 XML_ParserCreate(const XML_Char *encodingName)
    668 {
    669   return XML_ParserCreate_MM(encodingName, NULL, NULL);
    670 }
    671 
    672 XML_Parser XMLCALL
    673 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
    674 {
    675   XML_Char tmp[2];
    676   *tmp = nsSep;
    677   return XML_ParserCreate_MM(encodingName, NULL, tmp);
    678 }
    679 
    680 static const XML_Char implicitContext[] = {
    681   ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
    682   ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
    683   ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
    684   ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
    685   ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
    686   ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
    687 };
    688 
    689 static unsigned long
    690 generate_hash_secret_salt(void)
    691 {
    692   unsigned int seed = time(NULL) % UINT_MAX;
    693   srand(seed);
    694   return rand();
    695 }
    696 
    697 static XML_Bool  /* only valid for root parser */
    698 startParsing(XML_Parser parser)
    699 {
    700     /* hash functions must be initialized before setContext() is called */
    701     if (hash_secret_salt == 0)
    702       hash_secret_salt = generate_hash_secret_salt();
    703     if (ns) {
    704       /* implicit context only set for root parser, since child
    705          parsers (i.e. external entity parsers) will inherit it
    706       */
    707       return setContext(parser, implicitContext);
    708     }
    709     return XML_TRUE;
    710 }
    711 
    712 XML_Parser XMLCALL
    713 XML_ParserCreate_MM(const XML_Char *encodingName,
    714                     const XML_Memory_Handling_Suite *memsuite,
    715                     const XML_Char *nameSep)
    716 {
    717   return parserCreate(encodingName, memsuite, nameSep, NULL);
    718 }
    719 
    720 static XML_Parser
    721 parserCreate(const XML_Char *encodingName,
    722              const XML_Memory_Handling_Suite *memsuite,
    723              const XML_Char *nameSep,
    724              DTD *dtd)
    725 {
    726   XML_Parser parser;
    727 
    728   if (memsuite) {
    729     XML_Memory_Handling_Suite *mtemp;
    730     parser = (XML_Parser)
    731       memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
    732     if (parser != NULL) {
    733       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
    734       mtemp->malloc_fcn = memsuite->malloc_fcn;
    735       mtemp->realloc_fcn = memsuite->realloc_fcn;
    736       mtemp->free_fcn = memsuite->free_fcn;
    737     }
    738   }
    739   else {
    740     XML_Memory_Handling_Suite *mtemp;
    741     parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
    742     if (parser != NULL) {
    743       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
    744       mtemp->malloc_fcn = malloc;
    745       mtemp->realloc_fcn = realloc;
    746       mtemp->free_fcn = free;
    747     }
    748   }
    749 
    750   if (!parser)
    751     return parser;
    752 
    753   buffer = NULL;
    754   bufferLim = NULL;
    755 
    756   attsSize = INIT_ATTS_SIZE;
    757   atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
    758   if (atts == NULL) {
    759     FREE(parser);
    760     return NULL;
    761   }
    762   dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
    763   if (dataBuf == NULL) {
    764     FREE(atts);
    765     FREE(parser);
    766     return NULL;
    767   }
    768   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
    769 
    770   if (dtd)
    771     _dtd = dtd;
    772   else {
    773     _dtd = dtdCreate(&parser->m_mem);
    774     if (_dtd == NULL) {
    775       FREE(dataBuf);
    776       FREE(atts);
    777       FREE(parser);
    778       return NULL;
    779     }
    780   }
    781 
    782   freeBindingList = NULL;
    783   freeTagList = NULL;
    784   freeInternalEntities = NULL;
    785 
    786   groupSize = 0;
    787   groupConnector = NULL;
    788 
    789   unknownEncodingHandler = NULL;
    790   unknownEncodingHandlerData = NULL;
    791 
    792   namespaceSeparator = ASCII_EXCL;
    793   ns = XML_FALSE;
    794   ns_triplets = XML_FALSE;
    795 
    796   nsAtts = NULL;
    797   nsAttsVersion = 0;
    798   nsAttsPower = 0;
    799 
    800   poolInit(&tempPool, &(parser->m_mem));
    801   poolInit(&temp2Pool, &(parser->m_mem));
    802   parserInit(parser, encodingName);
    803 
    804   if (encodingName && !protocolEncodingName) {
    805     XML_ParserFree(parser);
    806     return NULL;
    807   }
    808 
    809   if (nameSep) {
    810     ns = XML_TRUE;
    811     internalEncoding = XmlGetInternalEncodingNS();
    812     namespaceSeparator = *nameSep;
    813   }
    814   else {
    815     internalEncoding = XmlGetInternalEncoding();
    816   }
    817 
    818   return parser;
    819 }
    820 
    821 static void
    822 parserInit(XML_Parser parser, const XML_Char *encodingName)
    823 {
    824   processor = prologInitProcessor;
    825   XmlPrologStateInit(&prologState);
    826   protocolEncodingName = (encodingName != NULL
    827                           ? poolCopyString(&tempPool, encodingName)
    828                           : NULL);
    829   curBase = NULL;
    830   XmlInitEncoding(&initEncoding, &encoding, 0);
    831   userData = NULL;
    832   handlerArg = NULL;
    833   startElementHandler = NULL;
    834   endElementHandler = NULL;
    835   characterDataHandler = NULL;
    836   processingInstructionHandler = NULL;
    837   commentHandler = NULL;
    838   startCdataSectionHandler = NULL;
    839   endCdataSectionHandler = NULL;
    840   defaultHandler = NULL;
    841   startDoctypeDeclHandler = NULL;
    842   endDoctypeDeclHandler = NULL;
    843   unparsedEntityDeclHandler = NULL;
    844   notationDeclHandler = NULL;
    845   startNamespaceDeclHandler = NULL;
    846   endNamespaceDeclHandler = NULL;
    847   notStandaloneHandler = NULL;
    848   externalEntityRefHandler = NULL;
    849   externalEntityRefHandlerArg = parser;
    850   skippedEntityHandler = NULL;
    851   elementDeclHandler = NULL;
    852   attlistDeclHandler = NULL;
    853   entityDeclHandler = NULL;
    854   xmlDeclHandler = NULL;
    855   bufferPtr = buffer;
    856   bufferEnd = buffer;
    857   parseEndByteIndex = 0;
    858   parseEndPtr = NULL;
    859   declElementType = NULL;
    860   declAttributeId = NULL;
    861   declEntity = NULL;
    862   doctypeName = NULL;
    863   doctypeSysid = NULL;
    864   doctypePubid = NULL;
    865   declAttributeType = NULL;
    866   declNotationName = NULL;
    867   declNotationPublicId = NULL;
    868   declAttributeIsCdata = XML_FALSE;
    869   declAttributeIsId = XML_FALSE;
    870   memset(&position, 0, sizeof(POSITION));
    871   errorCode = XML_ERROR_NONE;
    872   eventPtr = NULL;
    873   eventEndPtr = NULL;
    874   positionPtr = NULL;
    875   openInternalEntities = NULL;
    876   defaultExpandInternalEntities = XML_TRUE;
    877   tagLevel = 0;
    878   tagStack = NULL;
    879   inheritedBindings = NULL;
    880   nSpecifiedAtts = 0;
    881   unknownEncodingMem = NULL;
    882   unknownEncodingRelease = NULL;
    883   unknownEncodingData = NULL;
    884   parentParser = NULL;
    885   ps_parsing = XML_INITIALIZED;
    886 #ifdef XML_DTD
    887   isParamEntity = XML_FALSE;
    888   useForeignDTD = XML_FALSE;
    889   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
    890 #endif
    891   hash_secret_salt = 0;
    892 }
    893 
    894 /* moves list of bindings to freeBindingList */
    895 static void FASTCALL
    896 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
    897 {
    898   while (bindings) {
    899     BINDING *b = bindings;
    900     bindings = bindings->nextTagBinding;
    901     b->nextTagBinding = freeBindingList;
    902     freeBindingList = b;
    903   }
    904 }
    905 
    906 XML_Bool XMLCALL
    907 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
    908 {
    909   TAG *tStk;
    910   OPEN_INTERNAL_ENTITY *openEntityList;
    911   if (parentParser)
    912     return XML_FALSE;
    913   /* move tagStack to freeTagList */
    914   tStk = tagStack;
    915   while (tStk) {
    916     TAG *tag = tStk;
    917     tStk = tStk->parent;
    918     tag->parent = freeTagList;
    919     moveToFreeBindingList(parser, tag->bindings);
    920     tag->bindings = NULL;
    921     freeTagList = tag;
    922   }
    923   /* move openInternalEntities to freeInternalEntities */
    924   openEntityList = openInternalEntities;
    925   while (openEntityList) {
    926     OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
    927     openEntityList = openEntity->next;
    928     openEntity->next = freeInternalEntities;
    929     freeInternalEntities = openEntity;
    930   }
    931   moveToFreeBindingList(parser, inheritedBindings);
    932   FREE(unknownEncodingMem);
    933   if (unknownEncodingRelease)
    934     unknownEncodingRelease(unknownEncodingData);
    935   poolClear(&tempPool);
    936   poolClear(&temp2Pool);
    937   parserInit(parser, encodingName);
    938   dtdReset(_dtd, &parser->m_mem);
    939   return XML_TRUE;
    940 }
    941 
    942 enum XML_Status XMLCALL
    943 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
    944 {
    945   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
    946      XXX There's no way for the caller to determine which of the
    947      XXX possible error cases caused the XML_STATUS_ERROR return.
    948   */
    949   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
    950     return XML_STATUS_ERROR;
    951   if (encodingName == NULL)
    952     protocolEncodingName = NULL;
    953   else {
    954     protocolEncodingName = poolCopyString(&tempPool, encodingName);
    955     if (!protocolEncodingName)
    956       return XML_STATUS_ERROR;
    957   }
    958   return XML_STATUS_OK;
    959 }
    960 
    961 XML_Parser XMLCALL
    962 XML_ExternalEntityParserCreate(XML_Parser oldParser,
    963                                const XML_Char *context,
    964                                const XML_Char *encodingName)
    965 {
    966   XML_Parser parser = oldParser;
    967   DTD *newDtd = NULL;
    968   DTD *oldDtd = _dtd;
    969   XML_StartElementHandler oldStartElementHandler = startElementHandler;
    970   XML_EndElementHandler oldEndElementHandler = endElementHandler;
    971   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
    972   XML_ProcessingInstructionHandler oldProcessingInstructionHandler
    973       = processingInstructionHandler;
    974   XML_CommentHandler oldCommentHandler = commentHandler;
    975   XML_StartCdataSectionHandler oldStartCdataSectionHandler
    976       = startCdataSectionHandler;
    977   XML_EndCdataSectionHandler oldEndCdataSectionHandler
    978       = endCdataSectionHandler;
    979   XML_DefaultHandler oldDefaultHandler = defaultHandler;
    980   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
    981       = unparsedEntityDeclHandler;
    982   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
    983   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
    984       = startNamespaceDeclHandler;
    985   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
    986       = endNamespaceDeclHandler;
    987   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
    988   XML_ExternalEntityRefHandler oldExternalEntityRefHandler
    989       = externalEntityRefHandler;
    990   XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
    991   XML_UnknownEncodingHandler oldUnknownEncodingHandler
    992       = unknownEncodingHandler;
    993   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
    994   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
    995   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
    996   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
    997   ELEMENT_TYPE * oldDeclElementType = declElementType;
    998 
    999   void *oldUserData = userData;
   1000   void *oldHandlerArg = handlerArg;
   1001   XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
   1002   XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
   1003 #ifdef XML_DTD
   1004   enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
   1005   int oldInEntityValue = prologState.inEntityValue;
   1006 #endif
   1007   XML_Bool oldns_triplets = ns_triplets;
   1008   /* Note that the new parser shares the same hash secret as the old
   1009      parser, so that dtdCopy and copyEntityTable can lookup values
   1010      from hash tables associated with either parser without us having
   1011      to worry which hash secrets each table has.
   1012   */
   1013   unsigned long oldhash_secret_salt = hash_secret_salt;
   1014 
   1015 #ifdef XML_DTD
   1016   if (!context)
   1017     newDtd = oldDtd;
   1018 #endif /* XML_DTD */
   1019 
   1020   /* Note that the magical uses of the pre-processor to make field
   1021      access look more like C++ require that `parser' be overwritten
   1022      here.  This makes this function more painful to follow than it
   1023      would be otherwise.
   1024   */
   1025   if (ns) {
   1026     XML_Char tmp[2];
   1027     *tmp = namespaceSeparator;
   1028     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
   1029   }
   1030   else {
   1031     parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
   1032   }
   1033 
   1034   if (!parser)
   1035     return NULL;
   1036 
   1037   startElementHandler = oldStartElementHandler;
   1038   endElementHandler = oldEndElementHandler;
   1039   characterDataHandler = oldCharacterDataHandler;
   1040   processingInstructionHandler = oldProcessingInstructionHandler;
   1041   commentHandler = oldCommentHandler;
   1042   startCdataSectionHandler = oldStartCdataSectionHandler;
   1043   endCdataSectionHandler = oldEndCdataSectionHandler;
   1044   defaultHandler = oldDefaultHandler;
   1045   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
   1046   notationDeclHandler = oldNotationDeclHandler;
   1047   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
   1048   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
   1049   notStandaloneHandler = oldNotStandaloneHandler;
   1050   externalEntityRefHandler = oldExternalEntityRefHandler;
   1051   skippedEntityHandler = oldSkippedEntityHandler;
   1052   unknownEncodingHandler = oldUnknownEncodingHandler;
   1053   elementDeclHandler = oldElementDeclHandler;
   1054   attlistDeclHandler = oldAttlistDeclHandler;
   1055   entityDeclHandler = oldEntityDeclHandler;
   1056   xmlDeclHandler = oldXmlDeclHandler;
   1057   declElementType = oldDeclElementType;
   1058   userData = oldUserData;
   1059   if (oldUserData == oldHandlerArg)
   1060     handlerArg = userData;
   1061   else
   1062     handlerArg = parser;
   1063   if (oldExternalEntityRefHandlerArg != oldParser)
   1064     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
   1065   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
   1066   ns_triplets = oldns_triplets;
   1067   hash_secret_salt = oldhash_secret_salt;
   1068   parentParser = oldParser;
   1069 #ifdef XML_DTD
   1070   paramEntityParsing = oldParamEntityParsing;
   1071   prologState.inEntityValue = oldInEntityValue;
   1072   if (context) {
   1073 #endif /* XML_DTD */
   1074     if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
   1075       || !setContext(parser, context)) {
   1076       XML_ParserFree(parser);
   1077       return NULL;
   1078     }
   1079     processor = externalEntityInitProcessor;
   1080 #ifdef XML_DTD
   1081   }
   1082   else {
   1083     /* The DTD instance referenced by _dtd is shared between the document's
   1084        root parser and external PE parsers, therefore one does not need to
   1085        call setContext. In addition, one also *must* not call setContext,
   1086        because this would overwrite existing prefix->binding pointers in
   1087        _dtd with ones that get destroyed with the external PE parser.
   1088        This would leave those prefixes with dangling pointers.
   1089     */
   1090     isParamEntity = XML_TRUE;
   1091     XmlPrologStateInitExternalEntity(&prologState);
   1092     processor = externalParEntInitProcessor;
   1093   }
   1094 #endif /* XML_DTD */
   1095   return parser;
   1096 }
   1097 
   1098 static void FASTCALL
   1099 destroyBindings(BINDING *bindings, XML_Parser parser)
   1100 {
   1101   for (;;) {
   1102     BINDING *b = bindings;
   1103     if (!b)
   1104       break;
   1105     bindings = b->nextTagBinding;
   1106     FREE(b->uri);
   1107     FREE(b);
   1108   }
   1109 }
   1110 
   1111 void XMLCALL
   1112 XML_ParserFree(XML_Parser parser)
   1113 {
   1114   TAG *tagList;
   1115   OPEN_INTERNAL_ENTITY *entityList;
   1116   if (parser == NULL)
   1117     return;
   1118   /* free tagStack and freeTagList */
   1119   tagList = tagStack;
   1120   for (;;) {
   1121     TAG *p;
   1122     if (tagList == NULL) {
   1123       if (freeTagList == NULL)
   1124         break;
   1125       tagList = freeTagList;
   1126       freeTagList = NULL;
   1127     }
   1128     p = tagList;
   1129     tagList = tagList->parent;
   1130     FREE(p->buf);
   1131     destroyBindings(p->bindings, parser);
   1132     FREE(p);
   1133   }
   1134   /* free openInternalEntities and freeInternalEntities */
   1135   entityList = openInternalEntities;
   1136   for (;;) {
   1137     OPEN_INTERNAL_ENTITY *openEntity;
   1138     if (entityList == NULL) {
   1139       if (freeInternalEntities == NULL)
   1140         break;
   1141       entityList = freeInternalEntities;
   1142       freeInternalEntities = NULL;
   1143     }
   1144     openEntity = entityList;
   1145     entityList = entityList->next;
   1146     FREE(openEntity);
   1147   }
   1148 
   1149   destroyBindings(freeBindingList, parser);
   1150   destroyBindings(inheritedBindings, parser);
   1151   poolDestroy(&tempPool);
   1152   poolDestroy(&temp2Pool);
   1153 #ifdef XML_DTD
   1154   /* external parameter entity parsers share the DTD structure
   1155      parser->m_dtd with the root parser, so we must not destroy it
   1156   */
   1157   if (!isParamEntity && _dtd)
   1158 #else
   1159   if (_dtd)
   1160 #endif /* XML_DTD */
   1161     dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
   1162   FREE((void *)atts);
   1163   FREE(groupConnector);
   1164   FREE(buffer);
   1165   FREE(dataBuf);
   1166   FREE(nsAtts);
   1167   FREE(unknownEncodingMem);
   1168   if (unknownEncodingRelease)
   1169     unknownEncodingRelease(unknownEncodingData);
   1170   FREE(parser);
   1171 }
   1172 
   1173 void XMLCALL
   1174 XML_UseParserAsHandlerArg(XML_Parser parser)
   1175 {
   1176   handlerArg = parser;
   1177 }
   1178 
   1179 enum XML_Error XMLCALL
   1180 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
   1181 {
   1182 #ifdef XML_DTD
   1183   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   1184   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
   1185     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
   1186   useForeignDTD = useDTD;
   1187   return XML_ERROR_NONE;
   1188 #else
   1189   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
   1190 #endif
   1191 }
   1192 
   1193 void XMLCALL
   1194 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
   1195 {
   1196   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   1197   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
   1198     return;
   1199   ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
   1200 }
   1201 
   1202 void XMLCALL
   1203 XML_SetUserData(XML_Parser parser, void *p)
   1204 {
   1205   if (handlerArg == userData)
   1206     handlerArg = userData = p;
   1207   else
   1208     userData = p;
   1209 }
   1210 
   1211 enum XML_Status XMLCALL
   1212 XML_SetBase(XML_Parser parser, const XML_Char *p)
   1213 {
   1214   if (p) {
   1215     p = poolCopyString(&_dtd->pool, p);
   1216     if (!p)
   1217       return XML_STATUS_ERROR;
   1218     curBase = p;
   1219   }
   1220   else
   1221     curBase = NULL;
   1222   return XML_STATUS_OK;
   1223 }
   1224 
   1225 const XML_Char * XMLCALL
   1226 XML_GetBase(XML_Parser parser)
   1227 {
   1228   return curBase;
   1229 }
   1230 
   1231 int XMLCALL
   1232 XML_GetSpecifiedAttributeCount(XML_Parser parser)
   1233 {
   1234   return nSpecifiedAtts;
   1235 }
   1236 
   1237 int XMLCALL
   1238 XML_GetIdAttributeIndex(XML_Parser parser)
   1239 {
   1240   return idAttIndex;
   1241 }
   1242 
   1243 void XMLCALL
   1244 XML_SetElementHandler(XML_Parser parser,
   1245                       XML_StartElementHandler start,
   1246                       XML_EndElementHandler end)
   1247 {
   1248   startElementHandler = start;
   1249   endElementHandler = end;
   1250 }
   1251 
   1252 void XMLCALL
   1253 XML_SetStartElementHandler(XML_Parser parser,
   1254                            XML_StartElementHandler start) {
   1255   startElementHandler = start;
   1256 }
   1257 
   1258 void XMLCALL
   1259 XML_SetEndElementHandler(XML_Parser parser,
   1260                          XML_EndElementHandler end) {
   1261   endElementHandler = end;
   1262 }
   1263 
   1264 void XMLCALL
   1265 XML_SetCharacterDataHandler(XML_Parser parser,
   1266                             XML_CharacterDataHandler handler)
   1267 {
   1268   characterDataHandler = handler;
   1269 }
   1270 
   1271 void XMLCALL
   1272 XML_SetProcessingInstructionHandler(XML_Parser parser,
   1273                                     XML_ProcessingInstructionHandler handler)
   1274 {
   1275   processingInstructionHandler = handler;
   1276 }
   1277 
   1278 void XMLCALL
   1279 XML_SetCommentHandler(XML_Parser parser,
   1280                       XML_CommentHandler handler)
   1281 {
   1282   commentHandler = handler;
   1283 }
   1284 
   1285 void XMLCALL
   1286 XML_SetCdataSectionHandler(XML_Parser parser,
   1287                            XML_StartCdataSectionHandler start,
   1288                            XML_EndCdataSectionHandler end)
   1289 {
   1290   startCdataSectionHandler = start;
   1291   endCdataSectionHandler = end;
   1292 }
   1293 
   1294 void XMLCALL
   1295 XML_SetStartCdataSectionHandler(XML_Parser parser,
   1296                                 XML_StartCdataSectionHandler start) {
   1297   startCdataSectionHandler = start;
   1298 }
   1299 
   1300 void XMLCALL
   1301 XML_SetEndCdataSectionHandler(XML_Parser parser,
   1302                               XML_EndCdataSectionHandler end) {
   1303   endCdataSectionHandler = end;
   1304 }
   1305 
   1306 void XMLCALL
   1307 XML_SetDefaultHandler(XML_Parser parser,
   1308                       XML_DefaultHandler handler)
   1309 {
   1310   defaultHandler = handler;
   1311   defaultExpandInternalEntities = XML_FALSE;
   1312 }
   1313 
   1314 void XMLCALL
   1315 XML_SetDefaultHandlerExpand(XML_Parser parser,
   1316                             XML_DefaultHandler handler)
   1317 {
   1318   defaultHandler = handler;
   1319   defaultExpandInternalEntities = XML_TRUE;
   1320 }
   1321 
   1322 void XMLCALL
   1323 XML_SetDoctypeDeclHandler(XML_Parser parser,
   1324                           XML_StartDoctypeDeclHandler start,
   1325                           XML_EndDoctypeDeclHandler end)
   1326 {
   1327   startDoctypeDeclHandler = start;
   1328   endDoctypeDeclHandler = end;
   1329 }
   1330 
   1331 void XMLCALL
   1332 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
   1333                                XML_StartDoctypeDeclHandler start) {
   1334   startDoctypeDeclHandler = start;
   1335 }
   1336 
   1337 void XMLCALL
   1338 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
   1339                              XML_EndDoctypeDeclHandler end) {
   1340   endDoctypeDeclHandler = end;
   1341 }
   1342 
   1343 void XMLCALL
   1344 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
   1345                                  XML_UnparsedEntityDeclHandler handler)
   1346 {
   1347   unparsedEntityDeclHandler = handler;
   1348 }
   1349 
   1350 void XMLCALL
   1351 XML_SetNotationDeclHandler(XML_Parser parser,
   1352                            XML_NotationDeclHandler handler)
   1353 {
   1354   notationDeclHandler = handler;
   1355 }
   1356 
   1357 void XMLCALL
   1358 XML_SetNamespaceDeclHandler(XML_Parser parser,
   1359                             XML_StartNamespaceDeclHandler start,
   1360                             XML_EndNamespaceDeclHandler end)
   1361 {
   1362   startNamespaceDeclHandler = start;
   1363   endNamespaceDeclHandler = end;
   1364 }
   1365 
   1366 void XMLCALL
   1367 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
   1368                                  XML_StartNamespaceDeclHandler start) {
   1369   startNamespaceDeclHandler = start;
   1370 }
   1371 
   1372 void XMLCALL
   1373 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
   1374                                XML_EndNamespaceDeclHandler end) {
   1375   endNamespaceDeclHandler = end;
   1376 }
   1377 
   1378 void XMLCALL
   1379 XML_SetNotStandaloneHandler(XML_Parser parser,
   1380                             XML_NotStandaloneHandler handler)
   1381 {
   1382   notStandaloneHandler = handler;
   1383 }
   1384 
   1385 void XMLCALL
   1386 XML_SetExternalEntityRefHandler(XML_Parser parser,
   1387                                 XML_ExternalEntityRefHandler handler)
   1388 {
   1389   externalEntityRefHandler = handler;
   1390 }
   1391 
   1392 void XMLCALL
   1393 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
   1394 {
   1395   if (arg)
   1396     externalEntityRefHandlerArg = (XML_Parser)arg;
   1397   else
   1398     externalEntityRefHandlerArg = parser;
   1399 }
   1400 
   1401 void XMLCALL
   1402 XML_SetSkippedEntityHandler(XML_Parser parser,
   1403                             XML_SkippedEntityHandler handler)
   1404 {
   1405   skippedEntityHandler = handler;
   1406 }
   1407 
   1408 void XMLCALL
   1409 XML_SetUnknownEncodingHandler(XML_Parser parser,
   1410                               XML_UnknownEncodingHandler handler,
   1411                               void *data)
   1412 {
   1413   unknownEncodingHandler = handler;
   1414   unknownEncodingHandlerData = data;
   1415 }
   1416 
   1417 void XMLCALL
   1418 XML_SetElementDeclHandler(XML_Parser parser,
   1419                           XML_ElementDeclHandler eldecl)
   1420 {
   1421   elementDeclHandler = eldecl;
   1422 }
   1423 
   1424 void XMLCALL
   1425 XML_SetAttlistDeclHandler(XML_Parser parser,
   1426                           XML_AttlistDeclHandler attdecl)
   1427 {
   1428   attlistDeclHandler = attdecl;
   1429 }
   1430 
   1431 void XMLCALL
   1432 XML_SetEntityDeclHandler(XML_Parser parser,
   1433                          XML_EntityDeclHandler handler)
   1434 {
   1435   entityDeclHandler = handler;
   1436 }
   1437 
   1438 void XMLCALL
   1439 XML_SetXmlDeclHandler(XML_Parser parser,
   1440                       XML_XmlDeclHandler handler) {
   1441   xmlDeclHandler = handler;
   1442 }
   1443 
   1444 int XMLCALL
   1445 XML_SetParamEntityParsing(XML_Parser parser,
   1446                           enum XML_ParamEntityParsing peParsing)
   1447 {
   1448   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   1449   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
   1450     return 0;
   1451 #ifdef XML_DTD
   1452   paramEntityParsing = peParsing;
   1453   return 1;
   1454 #else
   1455   return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
   1456 #endif
   1457 }
   1458 
   1459 int XMLCALL
   1460 XML_SetHashSalt(XML_Parser parser,
   1461                 unsigned long hash_salt)
   1462 {
   1463   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   1464   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
   1465     return 0;
   1466   hash_secret_salt = hash_salt;
   1467   return 1;
   1468 }
   1469 
   1470 enum XML_Status XMLCALL
   1471 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
   1472 {
   1473   switch (ps_parsing) {
   1474   case XML_SUSPENDED:
   1475     errorCode = XML_ERROR_SUSPENDED;
   1476     return XML_STATUS_ERROR;
   1477   case XML_FINISHED:
   1478     errorCode = XML_ERROR_FINISHED;
   1479     return XML_STATUS_ERROR;
   1480   case XML_INITIALIZED:
   1481     if (parentParser == NULL && !startParsing(parser)) {
   1482       errorCode = XML_ERROR_NO_MEMORY;
   1483       return XML_STATUS_ERROR;
   1484     }
   1485   default:
   1486     ps_parsing = XML_PARSING;
   1487   }
   1488 
   1489   if (len == 0) {
   1490     ps_finalBuffer = (XML_Bool)isFinal;
   1491     if (!isFinal)
   1492       return XML_STATUS_OK;
   1493     positionPtr = bufferPtr;
   1494     parseEndPtr = bufferEnd;
   1495 
   1496     /* If data are left over from last buffer, and we now know that these
   1497        data are the final chunk of input, then we have to check them again
   1498        to detect errors based on that fact.
   1499     */
   1500     errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
   1501 
   1502     if (errorCode == XML_ERROR_NONE) {
   1503       switch (ps_parsing) {
   1504       case XML_SUSPENDED:
   1505         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
   1506         positionPtr = bufferPtr;
   1507         return XML_STATUS_SUSPENDED;
   1508       case XML_INITIALIZED:
   1509       case XML_PARSING:
   1510         ps_parsing = XML_FINISHED;
   1511         /* fall through */
   1512       default:
   1513         return XML_STATUS_OK;
   1514       }
   1515     }
   1516     eventEndPtr = eventPtr;
   1517     processor = errorProcessor;
   1518     return XML_STATUS_ERROR;
   1519   }
   1520 #ifndef XML_CONTEXT_BYTES
   1521   else if (bufferPtr == bufferEnd) {
   1522     const char *end;
   1523     int nLeftOver;
   1524     enum XML_Error result;
   1525     parseEndByteIndex += len;
   1526     positionPtr = s;
   1527     ps_finalBuffer = (XML_Bool)isFinal;
   1528 
   1529     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
   1530 
   1531     if (errorCode != XML_ERROR_NONE) {
   1532       eventEndPtr = eventPtr;
   1533       processor = errorProcessor;
   1534       return XML_STATUS_ERROR;
   1535     }
   1536     else {
   1537       switch (ps_parsing) {
   1538       case XML_SUSPENDED:
   1539         result = XML_STATUS_SUSPENDED;
   1540         break;
   1541       case XML_INITIALIZED:
   1542       case XML_PARSING:
   1543         if (isFinal) {
   1544           ps_parsing = XML_FINISHED;
   1545           return XML_STATUS_OK;
   1546         }
   1547       /* fall through */
   1548       default:
   1549         result = XML_STATUS_OK;
   1550       }
   1551     }
   1552 
   1553     XmlUpdatePosition(encoding, positionPtr, end, &position);
   1554     nLeftOver = s + len - end;
   1555     if (nLeftOver) {
   1556       if (buffer == NULL || nLeftOver > bufferLim - buffer) {
   1557         /* FIXME avoid integer overflow */
   1558         char *temp;
   1559         temp = (buffer == NULL
   1560                 ? (char *)MALLOC(len * 2)
   1561                 : (char *)REALLOC(buffer, len * 2));
   1562         if (temp == NULL) {
   1563           errorCode = XML_ERROR_NO_MEMORY;
   1564           return XML_STATUS_ERROR;
   1565         }
   1566         buffer = temp;
   1567         if (!buffer) {
   1568           errorCode = XML_ERROR_NO_MEMORY;
   1569           eventPtr = eventEndPtr = NULL;
   1570           processor = errorProcessor;
   1571           return XML_STATUS_ERROR;
   1572         }
   1573         bufferLim = buffer + len * 2;
   1574       }
   1575       memcpy(buffer, end, nLeftOver);
   1576     }
   1577     bufferPtr = buffer;
   1578     bufferEnd = buffer + nLeftOver;
   1579     positionPtr = bufferPtr;
   1580     parseEndPtr = bufferEnd;
   1581     eventPtr = bufferPtr;
   1582     eventEndPtr = bufferPtr;
   1583     return result;
   1584   }
   1585 #endif  /* not defined XML_CONTEXT_BYTES */
   1586   else {
   1587     void *buff = XML_GetBuffer(parser, len);
   1588     if (buff == NULL)
   1589       return XML_STATUS_ERROR;
   1590     else {
   1591       memcpy(buff, s, len);
   1592       return XML_ParseBuffer(parser, len, isFinal);
   1593     }
   1594   }
   1595 }
   1596 
   1597 enum XML_Status XMLCALL
   1598 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
   1599 {
   1600   const char *start;
   1601   enum XML_Status result = XML_STATUS_OK;
   1602 
   1603   switch (ps_parsing) {
   1604   case XML_SUSPENDED:
   1605     errorCode = XML_ERROR_SUSPENDED;
   1606     return XML_STATUS_ERROR;
   1607   case XML_FINISHED:
   1608     errorCode = XML_ERROR_FINISHED;
   1609     return XML_STATUS_ERROR;
   1610   case XML_INITIALIZED:
   1611     if (parentParser == NULL && !startParsing(parser)) {
   1612       errorCode = XML_ERROR_NO_MEMORY;
   1613       return XML_STATUS_ERROR;
   1614     }
   1615   default:
   1616     ps_parsing = XML_PARSING;
   1617   }
   1618 
   1619   start = bufferPtr;
   1620   positionPtr = start;
   1621   bufferEnd += len;
   1622   parseEndPtr = bufferEnd;
   1623   parseEndByteIndex += len;
   1624   ps_finalBuffer = (XML_Bool)isFinal;
   1625 
   1626   errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
   1627 
   1628   if (errorCode != XML_ERROR_NONE) {
   1629     eventEndPtr = eventPtr;
   1630     processor = errorProcessor;
   1631     return XML_STATUS_ERROR;
   1632   }
   1633   else {
   1634     switch (ps_parsing) {
   1635     case XML_SUSPENDED:
   1636       result = XML_STATUS_SUSPENDED;
   1637       break;
   1638     case XML_INITIALIZED:
   1639     case XML_PARSING:
   1640       if (isFinal) {
   1641         ps_parsing = XML_FINISHED;
   1642         return result;
   1643       }
   1644     default: ;  /* should not happen */
   1645     }
   1646   }
   1647 
   1648   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
   1649   positionPtr = bufferPtr;
   1650   return result;
   1651 }
   1652 
   1653 void * XMLCALL
   1654 XML_GetBuffer(XML_Parser parser, int len)
   1655 {
   1656   switch (ps_parsing) {
   1657   case XML_SUSPENDED:
   1658     errorCode = XML_ERROR_SUSPENDED;
   1659     return NULL;
   1660   case XML_FINISHED:
   1661     errorCode = XML_ERROR_FINISHED;
   1662     return NULL;
   1663   default: ;
   1664   }
   1665 
   1666   if (len > bufferLim - bufferEnd) {
   1667     /* FIXME avoid integer overflow */
   1668     int neededSize = len + (int)(bufferEnd - bufferPtr);
   1669 #ifdef XML_CONTEXT_BYTES
   1670     int keep = (int)(bufferPtr - buffer);
   1671 
   1672     if (keep > XML_CONTEXT_BYTES)
   1673       keep = XML_CONTEXT_BYTES;
   1674     neededSize += keep;
   1675 #endif  /* defined XML_CONTEXT_BYTES */
   1676     if (neededSize  <= bufferLim - buffer) {
   1677 #ifdef XML_CONTEXT_BYTES
   1678       if (keep < bufferPtr - buffer) {
   1679         int offset = (int)(bufferPtr - buffer) - keep;
   1680         memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
   1681         bufferEnd -= offset;
   1682         bufferPtr -= offset;
   1683       }
   1684 #else
   1685       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
   1686       bufferEnd = buffer + (bufferEnd - bufferPtr);
   1687       bufferPtr = buffer;
   1688 #endif  /* not defined XML_CONTEXT_BYTES */
   1689     }
   1690     else {
   1691       char *newBuf;
   1692       int bufferSize = (int)(bufferLim - bufferPtr);
   1693       if (bufferSize == 0)
   1694         bufferSize = INIT_BUFFER_SIZE;
   1695       do {
   1696         bufferSize *= 2;
   1697       } while (bufferSize < neededSize);
   1698       newBuf = (char *)MALLOC(bufferSize);
   1699       if (newBuf == 0) {
   1700         errorCode = XML_ERROR_NO_MEMORY;
   1701         return NULL;
   1702       }
   1703       bufferLim = newBuf + bufferSize;
   1704 #ifdef XML_CONTEXT_BYTES
   1705       if (bufferPtr) {
   1706         int keep = (int)(bufferPtr - buffer);
   1707         if (keep > XML_CONTEXT_BYTES)
   1708           keep = XML_CONTEXT_BYTES;
   1709         memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
   1710         FREE(buffer);
   1711         buffer = newBuf;
   1712         bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
   1713         bufferPtr = buffer + keep;
   1714       }
   1715       else {
   1716         bufferEnd = newBuf + (bufferEnd - bufferPtr);
   1717         bufferPtr = buffer = newBuf;
   1718       }
   1719 #else
   1720       if (bufferPtr) {
   1721         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
   1722         FREE(buffer);
   1723       }
   1724       bufferEnd = newBuf + (bufferEnd - bufferPtr);
   1725       bufferPtr = buffer = newBuf;
   1726 #endif  /* not defined XML_CONTEXT_BYTES */
   1727     }
   1728   }
   1729   return bufferEnd;
   1730 }
   1731 
   1732 enum XML_Status XMLCALL
   1733 XML_StopParser(XML_Parser parser, XML_Bool resumable)
   1734 {
   1735   switch (ps_parsing) {
   1736   case XML_SUSPENDED:
   1737     if (resumable) {
   1738       errorCode = XML_ERROR_SUSPENDED;
   1739       return XML_STATUS_ERROR;
   1740     }
   1741     ps_parsing = XML_FINISHED;
   1742     break;
   1743   case XML_FINISHED:
   1744     errorCode = XML_ERROR_FINISHED;
   1745     return XML_STATUS_ERROR;
   1746   default:
   1747     if (resumable) {
   1748 #ifdef XML_DTD
   1749       if (isParamEntity) {
   1750         errorCode = XML_ERROR_SUSPEND_PE;
   1751         return XML_STATUS_ERROR;
   1752       }
   1753 #endif
   1754       ps_parsing = XML_SUSPENDED;
   1755     }
   1756     else
   1757       ps_parsing = XML_FINISHED;
   1758   }
   1759   return XML_STATUS_OK;
   1760 }
   1761 
   1762 enum XML_Status XMLCALL
   1763 XML_ResumeParser(XML_Parser parser)
   1764 {
   1765   enum XML_Status result = XML_STATUS_OK;
   1766 
   1767   if (ps_parsing != XML_SUSPENDED) {
   1768     errorCode = XML_ERROR_NOT_SUSPENDED;
   1769     return XML_STATUS_ERROR;
   1770   }
   1771   ps_parsing = XML_PARSING;
   1772 
   1773   errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
   1774 
   1775   if (errorCode != XML_ERROR_NONE) {
   1776     eventEndPtr = eventPtr;
   1777     processor = errorProcessor;
   1778     return XML_STATUS_ERROR;
   1779   }
   1780   else {
   1781     switch (ps_parsing) {
   1782     case XML_SUSPENDED:
   1783       result = XML_STATUS_SUSPENDED;
   1784       break;
   1785     case XML_INITIALIZED:
   1786     case XML_PARSING:
   1787       if (ps_finalBuffer) {
   1788         ps_parsing = XML_FINISHED;
   1789         return result;
   1790       }
   1791     default: ;
   1792     }
   1793   }
   1794 
   1795   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
   1796   positionPtr = bufferPtr;
   1797   return result;
   1798 }
   1799 
   1800 void XMLCALL
   1801 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
   1802 {
   1803   assert(status != NULL);
   1804   *status = parser->m_parsingStatus;
   1805 }
   1806 
   1807 enum XML_Error XMLCALL
   1808 XML_GetErrorCode(XML_Parser parser)
   1809 {
   1810   return errorCode;
   1811 }
   1812 
   1813 XML_Index XMLCALL
   1814 XML_GetCurrentByteIndex(XML_Parser parser)
   1815 {
   1816   if (eventPtr)
   1817     return parseEndByteIndex - (parseEndPtr - eventPtr);
   1818   return -1;
   1819 }
   1820 
   1821 int XMLCALL
   1822 XML_GetCurrentByteCount(XML_Parser parser)
   1823 {
   1824   if (eventEndPtr && eventPtr)
   1825     return (int)(eventEndPtr - eventPtr);
   1826   return 0;
   1827 }
   1828 
   1829 const char * XMLCALL
   1830 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
   1831 {
   1832 #ifdef XML_CONTEXT_BYTES
   1833   if (eventPtr && buffer) {
   1834     *offset = (int)(eventPtr - buffer);
   1835     *size   = (int)(bufferEnd - buffer);
   1836     return buffer;
   1837   }
   1838 #endif /* defined XML_CONTEXT_BYTES */
   1839   return (char *) 0;
   1840 }
   1841 
   1842 XML_Size XMLCALL
   1843 XML_GetCurrentLineNumber(XML_Parser parser)
   1844 {
   1845   if (eventPtr && eventPtr >= positionPtr) {
   1846     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
   1847     positionPtr = eventPtr;
   1848   }
   1849   return position.lineNumber + 1;
   1850 }
   1851 
   1852 XML_Size XMLCALL
   1853 XML_GetCurrentColumnNumber(XML_Parser parser)
   1854 {
   1855   if (eventPtr && eventPtr >= positionPtr) {
   1856     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
   1857     positionPtr = eventPtr;
   1858   }
   1859   return position.columnNumber;
   1860 }
   1861 
   1862 void XMLCALL
   1863 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
   1864 {
   1865   FREE(model);
   1866 }
   1867 
   1868 void * XMLCALL
   1869 XML_MemMalloc(XML_Parser parser, size_t size)
   1870 {
   1871   return MALLOC(size);
   1872 }
   1873 
   1874 void * XMLCALL
   1875 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
   1876 {
   1877   return REALLOC(ptr, size);
   1878 }
   1879 
   1880 void XMLCALL
   1881 XML_MemFree(XML_Parser parser, void *ptr)
   1882 {
   1883   FREE(ptr);
   1884 }
   1885 
   1886 void XMLCALL
   1887 XML_DefaultCurrent(XML_Parser parser)
   1888 {
   1889   if (defaultHandler) {
   1890     if (openInternalEntities)
   1891       reportDefault(parser,
   1892                     internalEncoding,
   1893                     openInternalEntities->internalEventPtr,
   1894                     openInternalEntities->internalEventEndPtr);
   1895     else
   1896       reportDefault(parser, encoding, eventPtr, eventEndPtr);
   1897   }
   1898 }
   1899 
   1900 const XML_LChar * XMLCALL
   1901 XML_ErrorString(enum XML_Error code)
   1902 {
   1903   static const XML_LChar* const message[] = {
   1904     0,
   1905     XML_L("out of memory"),
   1906     XML_L("syntax error"),
   1907     XML_L("no element found"),
   1908     XML_L("not well-formed (invalid token)"),
   1909     XML_L("unclosed token"),
   1910     XML_L("partial character"),
   1911     XML_L("mismatched tag"),
   1912     XML_L("duplicate attribute"),
   1913     XML_L("junk after document element"),
   1914     XML_L("illegal parameter entity reference"),
   1915     XML_L("undefined entity"),
   1916     XML_L("recursive entity reference"),
   1917     XML_L("asynchronous entity"),
   1918     XML_L("reference to invalid character number"),
   1919     XML_L("reference to binary entity"),
   1920     XML_L("reference to external entity in attribute"),
   1921     XML_L("XML or text declaration not at start of entity"),
   1922     XML_L("unknown encoding"),
   1923     XML_L("encoding specified in XML declaration is incorrect"),
   1924     XML_L("unclosed CDATA section"),
   1925     XML_L("error in processing external entity reference"),
   1926     XML_L("document is not standalone"),
   1927     XML_L("unexpected parser state - please send a bug report"),
   1928     XML_L("entity declared in parameter entity"),
   1929     XML_L("requested feature requires XML_DTD support in Expat"),
   1930     XML_L("cannot change setting once parsing has begun"),
   1931     XML_L("unbound prefix"),
   1932     XML_L("must not undeclare prefix"),
   1933     XML_L("incomplete markup in parameter entity"),
   1934     XML_L("XML declaration not well-formed"),
   1935     XML_L("text declaration not well-formed"),
   1936     XML_L("illegal character(s) in public id"),
   1937     XML_L("parser suspended"),
   1938     XML_L("parser not suspended"),
   1939     XML_L("parsing aborted"),
   1940     XML_L("parsing finished"),
   1941     XML_L("cannot suspend in external parameter entity"),
   1942     XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
   1943     XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
   1944     XML_L("prefix must not be bound to one of the reserved namespace names")
   1945   };
   1946   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
   1947     return message[code];
   1948   return NULL;
   1949 }
   1950 
   1951 const XML_LChar * XMLCALL
   1952 XML_ExpatVersion(void) {
   1953 
   1954   /* V1 is used to string-ize the version number. However, it would
   1955      string-ize the actual version macro *names* unless we get them
   1956      substituted before being passed to V1. CPP is defined to expand
   1957      a macro, then rescan for more expansions. Thus, we use V2 to expand
   1958      the version macros, then CPP will expand the resulting V1() macro
   1959      with the correct numerals. */
   1960   /* ### I'm assuming cpp is portable in this respect... */
   1961 
   1962 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
   1963 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
   1964 
   1965   return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
   1966 
   1967 #undef V1
   1968 #undef V2
   1969 }
   1970 
   1971 XML_Expat_Version XMLCALL
   1972 XML_ExpatVersionInfo(void)
   1973 {
   1974   XML_Expat_Version version;
   1975 
   1976   version.major = XML_MAJOR_VERSION;
   1977   version.minor = XML_MINOR_VERSION;
   1978   version.micro = XML_MICRO_VERSION;
   1979 
   1980   return version;
   1981 }
   1982 
   1983 const XML_Feature * XMLCALL
   1984 XML_GetFeatureList(void)
   1985 {
   1986   static const XML_Feature features[] = {
   1987     {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
   1988      sizeof(XML_Char)},
   1989     {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
   1990      sizeof(XML_LChar)},
   1991 #ifdef XML_UNICODE
   1992     {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
   1993 #endif
   1994 #ifdef XML_UNICODE_WCHAR_T
   1995     {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
   1996 #endif
   1997 #ifdef XML_DTD
   1998     {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
   1999 #endif
   2000 #ifdef XML_CONTEXT_BYTES
   2001     {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
   2002      XML_CONTEXT_BYTES},
   2003 #endif
   2004 #ifdef XML_MIN_SIZE
   2005     {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
   2006 #endif
   2007 #ifdef XML_NS
   2008     {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
   2009 #endif
   2010 #ifdef XML_LARGE_SIZE
   2011     {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
   2012 #endif
   2013     {XML_FEATURE_END,              NULL, 0}
   2014   };
   2015 
   2016   return features;
   2017 }
   2018 
   2019 /* Initially tag->rawName always points into the parse buffer;
   2020    for those TAG instances opened while the current parse buffer was
   2021    processed, and not yet closed, we need to store tag->rawName in a more
   2022    permanent location, since the parse buffer is about to be discarded.
   2023 */
   2024 static XML_Bool
   2025 storeRawNames(XML_Parser parser)
   2026 {
   2027   TAG *tag = tagStack;
   2028   while (tag) {
   2029     int bufSize;
   2030     int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
   2031     char *rawNameBuf = tag->buf + nameLen;
   2032     /* Stop if already stored.  Since tagStack is a stack, we can stop
   2033        at the first entry that has already been copied; everything
   2034        below it in the stack is already been accounted for in a
   2035        previous call to this function.
   2036     */
   2037     if (tag->rawName == rawNameBuf)
   2038       break;
   2039     /* For re-use purposes we need to ensure that the
   2040        size of tag->buf is a multiple of sizeof(XML_Char).
   2041     */
   2042     bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
   2043     if (bufSize > tag->bufEnd - tag->buf) {
   2044       char *temp = (char *)REALLOC(tag->buf, bufSize);
   2045       if (temp == NULL)
   2046         return XML_FALSE;
   2047       /* if tag->name.str points to tag->buf (only when namespace
   2048          processing is off) then we have to update it
   2049       */
   2050       if (tag->name.str == (XML_Char *)tag->buf)
   2051         tag->name.str = (XML_Char *)temp;
   2052       /* if tag->name.localPart is set (when namespace processing is on)
   2053          then update it as well, since it will always point into tag->buf
   2054       */
   2055       if (tag->name.localPart)
   2056         tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
   2057                                                   (XML_Char *)tag->buf);
   2058       tag->buf = temp;
   2059       tag->bufEnd = temp + bufSize;
   2060       rawNameBuf = temp + nameLen;
   2061     }
   2062     memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
   2063     tag->rawName = rawNameBuf;
   2064     tag = tag->parent;
   2065   }
   2066   return XML_TRUE;
   2067 }
   2068 
   2069 static enum XML_Error PTRCALL
   2070 contentProcessor(XML_Parser parser,
   2071                  const char *start,
   2072                  const char *end,
   2073                  const char **endPtr)
   2074 {
   2075   enum XML_Error result = doContent(parser, 0, encoding, start, end,
   2076                                     endPtr, (XML_Bool)!ps_finalBuffer);
   2077   if (result == XML_ERROR_NONE) {
   2078     if (!storeRawNames(parser))
   2079       return XML_ERROR_NO_MEMORY;
   2080   }
   2081   return result;
   2082 }
   2083 
   2084 static enum XML_Error PTRCALL
   2085 externalEntityInitProcessor(XML_Parser parser,
   2086                             const char *start,
   2087                             const char *end,
   2088                             const char **endPtr)
   2089 {
   2090   enum XML_Error result = initializeEncoding(parser);
   2091   if (result != XML_ERROR_NONE)
   2092     return result;
   2093   processor = externalEntityInitProcessor2;
   2094   return externalEntityInitProcessor2(parser, start, end, endPtr);
   2095 }
   2096 
   2097 static enum XML_Error PTRCALL
   2098 externalEntityInitProcessor2(XML_Parser parser,
   2099                              const char *start,
   2100                              const char *end,
   2101                              const char **endPtr)
   2102 {
   2103   const char *next = start; /* XmlContentTok doesn't always set the last arg */
   2104   int tok = XmlContentTok(encoding, start, end, &next);
   2105   switch (tok) {
   2106   case XML_TOK_BOM:
   2107     /* If we are at the end of the buffer, this would cause the next stage,
   2108        i.e. externalEntityInitProcessor3, to pass control directly to
   2109        doContent (by detecting XML_TOK_NONE) without processing any xml text
   2110        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
   2111     */
   2112     if (next == end && !ps_finalBuffer) {
   2113       *endPtr = next;
   2114       return XML_ERROR_NONE;
   2115     }
   2116     start = next;
   2117     break;
   2118   case XML_TOK_PARTIAL:
   2119     if (!ps_finalBuffer) {
   2120       *endPtr = start;
   2121       return XML_ERROR_NONE;
   2122     }
   2123     eventPtr = start;
   2124     return XML_ERROR_UNCLOSED_TOKEN;
   2125   case XML_TOK_PARTIAL_CHAR:
   2126     if (!ps_finalBuffer) {
   2127       *endPtr = start;
   2128       return XML_ERROR_NONE;
   2129     }
   2130     eventPtr = start;
   2131     return XML_ERROR_PARTIAL_CHAR;
   2132   }
   2133   processor = externalEntityInitProcessor3;
   2134   return externalEntityInitProcessor3(parser, start, end, endPtr);
   2135 }
   2136 
   2137 static enum XML_Error PTRCALL
   2138 externalEntityInitProcessor3(XML_Parser parser,
   2139                              const char *start,
   2140                              const char *end,
   2141                              const char **endPtr)
   2142 {
   2143   int tok;
   2144   const char *next = start; /* XmlContentTok doesn't always set the last arg */
   2145   eventPtr = start;
   2146   tok = XmlContentTok(encoding, start, end, &next);
   2147   eventEndPtr = next;
   2148 
   2149   switch (tok) {
   2150   case XML_TOK_XML_DECL:
   2151     {
   2152       enum XML_Error result;
   2153       result = processXmlDecl(parser, 1, start, next);
   2154       if (result != XML_ERROR_NONE)
   2155         return result;
   2156       switch (ps_parsing) {
   2157       case XML_SUSPENDED:
   2158         *endPtr = next;
   2159         return XML_ERROR_NONE;
   2160       case XML_FINISHED:
   2161         return XML_ERROR_ABORTED;
   2162       default:
   2163         start = next;
   2164       }
   2165     }
   2166     break;
   2167   case XML_TOK_PARTIAL:
   2168     if (!ps_finalBuffer) {
   2169       *endPtr = start;
   2170       return XML_ERROR_NONE;
   2171     }
   2172     return XML_ERROR_UNCLOSED_TOKEN;
   2173   case XML_TOK_PARTIAL_CHAR:
   2174     if (!ps_finalBuffer) {
   2175       *endPtr = start;
   2176       return XML_ERROR_NONE;
   2177     }
   2178     return XML_ERROR_PARTIAL_CHAR;
   2179   }
   2180   processor = externalEntityContentProcessor;
   2181   tagLevel = 1;
   2182   return externalEntityContentProcessor(parser, start, end, endPtr);
   2183 }
   2184 
   2185 static enum XML_Error PTRCALL
   2186 externalEntityContentProcessor(XML_Parser parser,
   2187                                const char *start,
   2188                                const char *end,
   2189                                const char **endPtr)
   2190 {
   2191   enum XML_Error result = doContent(parser, 1, encoding, start, end,
   2192                                     endPtr, (XML_Bool)!ps_finalBuffer);
   2193   if (result == XML_ERROR_NONE) {
   2194     if (!storeRawNames(parser))
   2195       return XML_ERROR_NO_MEMORY;
   2196   }
   2197   return result;
   2198 }
   2199 
   2200 static enum XML_Error
   2201 doContent(XML_Parser parser,
   2202           int startTagLevel,
   2203           const ENCODING *enc,
   2204           const char *s,
   2205           const char *end,
   2206           const char **nextPtr,
   2207           XML_Bool haveMore)
   2208 {
   2209   /* save one level of indirection */
   2210   DTD * const dtd = _dtd;
   2211 
   2212   const char **eventPP;
   2213   const char **eventEndPP;
   2214   if (enc == encoding) {
   2215     eventPP = &eventPtr;
   2216     eventEndPP = &eventEndPtr;
   2217   }
   2218   else {
   2219     eventPP = &(openInternalEntities->internalEventPtr);
   2220     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   2221   }
   2222   *eventPP = s;
   2223 
   2224   for (;;) {
   2225     const char *next = s; /* XmlContentTok doesn't always set the last arg */
   2226     int tok = XmlContentTok(enc, s, end, &next);
   2227     *eventEndPP = next;
   2228     switch (tok) {
   2229     case XML_TOK_TRAILING_CR:
   2230       if (haveMore) {
   2231         *nextPtr = s;
   2232         return XML_ERROR_NONE;
   2233       }
   2234       *eventEndPP = end;
   2235       if (characterDataHandler) {
   2236         XML_Char c = 0xA;
   2237         characterDataHandler(handlerArg, &c, 1);
   2238       }
   2239       else if (defaultHandler)
   2240         reportDefault(parser, enc, s, end);
   2241       /* We are at the end of the final buffer, should we check for
   2242          XML_SUSPENDED, XML_FINISHED?
   2243       */
   2244       if (startTagLevel == 0)
   2245         return XML_ERROR_NO_ELEMENTS;
   2246       if (tagLevel != startTagLevel)
   2247         return XML_ERROR_ASYNC_ENTITY;
   2248       *nextPtr = end;
   2249       return XML_ERROR_NONE;
   2250     case XML_TOK_NONE:
   2251       if (haveMore) {
   2252         *nextPtr = s;
   2253         return XML_ERROR_NONE;
   2254       }
   2255       if (startTagLevel > 0) {
   2256         if (tagLevel != startTagLevel)
   2257           return XML_ERROR_ASYNC_ENTITY;
   2258         *nextPtr = s;
   2259         return XML_ERROR_NONE;
   2260       }
   2261       return XML_ERROR_NO_ELEMENTS;
   2262     case XML_TOK_INVALID:
   2263       *eventPP = next;
   2264       return XML_ERROR_INVALID_TOKEN;
   2265     case XML_TOK_PARTIAL:
   2266       if (haveMore) {
   2267         *nextPtr = s;
   2268         return XML_ERROR_NONE;
   2269       }
   2270       return XML_ERROR_UNCLOSED_TOKEN;
   2271     case XML_TOK_PARTIAL_CHAR:
   2272       if (haveMore) {
   2273         *nextPtr = s;
   2274         return XML_ERROR_NONE;
   2275       }
   2276       return XML_ERROR_PARTIAL_CHAR;
   2277     case XML_TOK_ENTITY_REF:
   2278       {
   2279         const XML_Char *name;
   2280         ENTITY *entity;
   2281         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
   2282                                               s + enc->minBytesPerChar,
   2283                                               next - enc->minBytesPerChar);
   2284         if (ch) {
   2285           if (characterDataHandler)
   2286             characterDataHandler(handlerArg, &ch, 1);
   2287           else if (defaultHandler)
   2288             reportDefault(parser, enc, s, next);
   2289           break;
   2290         }
   2291         name = poolStoreString(&dtd->pool, enc,
   2292                                 s + enc->minBytesPerChar,
   2293                                 next - enc->minBytesPerChar);
   2294         if (!name)
   2295           return XML_ERROR_NO_MEMORY;
   2296         entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
   2297         poolDiscard(&dtd->pool);
   2298         /* First, determine if a check for an existing declaration is needed;
   2299            if yes, check that the entity exists, and that it is internal,
   2300            otherwise call the skipped entity or default handler.
   2301         */
   2302         if (!dtd->hasParamEntityRefs || dtd->standalone) {
   2303           if (!entity)
   2304             return XML_ERROR_UNDEFINED_ENTITY;
   2305           else if (!entity->is_internal)
   2306             return XML_ERROR_ENTITY_DECLARED_IN_PE;
   2307         }
   2308         else if (!entity) {
   2309           if (skippedEntityHandler)
   2310             skippedEntityHandler(handlerArg, name, 0);
   2311           else if (defaultHandler)
   2312             reportDefault(parser, enc, s, next);
   2313           break;
   2314         }
   2315         if (entity->open)
   2316           return XML_ERROR_RECURSIVE_ENTITY_REF;
   2317         if (entity->notation)
   2318           return XML_ERROR_BINARY_ENTITY_REF;
   2319         if (entity->textPtr) {
   2320           enum XML_Error result;
   2321           if (!defaultExpandInternalEntities) {
   2322             if (skippedEntityHandler)
   2323               skippedEntityHandler(handlerArg, entity->name, 0);
   2324             else if (defaultHandler)
   2325               reportDefault(parser, enc, s, next);
   2326             break;
   2327           }
   2328           result = processInternalEntity(parser, entity, XML_FALSE);
   2329           if (result != XML_ERROR_NONE)
   2330             return result;
   2331         }
   2332         else if (externalEntityRefHandler) {
   2333           const XML_Char *context;
   2334           entity->open = XML_TRUE;
   2335           context = getContext(parser);
   2336           entity->open = XML_FALSE;
   2337           if (!context)
   2338             return XML_ERROR_NO_MEMORY;
   2339           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
   2340                                         context,
   2341                                         entity->base,
   2342                                         entity->systemId,
   2343                                         entity->publicId))
   2344             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
   2345           poolDiscard(&tempPool);
   2346         }
   2347         else if (defaultHandler)
   2348           reportDefault(parser, enc, s, next);
   2349         break;
   2350       }
   2351     case XML_TOK_START_TAG_NO_ATTS:
   2352       /* fall through */
   2353     case XML_TOK_START_TAG_WITH_ATTS:
   2354       {
   2355         TAG *tag;
   2356         enum XML_Error result;
   2357         XML_Char *toPtr;
   2358         if (freeTagList) {
   2359           tag = freeTagList;
   2360           freeTagList = freeTagList->parent;
   2361         }
   2362         else {
   2363           tag = (TAG *)MALLOC(sizeof(TAG));
   2364           if (!tag)
   2365             return XML_ERROR_NO_MEMORY;
   2366           tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
   2367           if (!tag->buf) {
   2368             FREE(tag);
   2369             return XML_ERROR_NO_MEMORY;
   2370           }
   2371           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
   2372         }
   2373         tag->bindings = NULL;
   2374         tag->parent = tagStack;
   2375         tagStack = tag;
   2376         tag->name.localPart = NULL;
   2377         tag->name.prefix = NULL;
   2378         tag->rawName = s + enc->minBytesPerChar;
   2379         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
   2380         ++tagLevel;
   2381         {
   2382           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
   2383           const char *fromPtr = tag->rawName;
   2384           toPtr = (XML_Char *)tag->buf;
   2385           for (;;) {
   2386             int bufSize;
   2387             int convLen;
   2388             XmlConvert(enc,
   2389                        &fromPtr, rawNameEnd,
   2390                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
   2391             convLen = (int)(toPtr - (XML_Char *)tag->buf);
   2392             if (fromPtr == rawNameEnd) {
   2393               tag->name.strLen = convLen;
   2394               break;
   2395             }
   2396             bufSize = (int)(tag->bufEnd - tag->buf) << 1;
   2397             {
   2398               char *temp = (char *)REALLOC(tag->buf, bufSize);
   2399               if (temp == NULL)
   2400                 return XML_ERROR_NO_MEMORY;
   2401               tag->buf = temp;
   2402               tag->bufEnd = temp + bufSize;
   2403               toPtr = (XML_Char *)temp + convLen;
   2404             }
   2405           }
   2406         }
   2407         tag->name.str = (XML_Char *)tag->buf;
   2408         *toPtr = XML_T('\0');
   2409         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
   2410         if (result)
   2411           return result;
   2412         if (startElementHandler)
   2413           startElementHandler(handlerArg, tag->name.str,
   2414                               (const XML_Char **)atts);
   2415         else if (defaultHandler)
   2416           reportDefault(parser, enc, s, next);
   2417         poolClear(&tempPool);
   2418         break;
   2419       }
   2420     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
   2421       /* fall through */
   2422     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
   2423       {
   2424         const char *rawName = s + enc->minBytesPerChar;
   2425         enum XML_Error result;
   2426         BINDING *bindings = NULL;
   2427         XML_Bool noElmHandlers = XML_TRUE;
   2428         TAG_NAME name;
   2429         name.str = poolStoreString(&tempPool, enc, rawName,
   2430                                    rawName + XmlNameLength(enc, rawName));
   2431         if (!name.str)
   2432           return XML_ERROR_NO_MEMORY;
   2433         poolFinish(&tempPool);
   2434         result = storeAtts(parser, enc, s, &name, &bindings);
   2435         if (result)
   2436           return result;
   2437         poolFinish(&tempPool);
   2438         if (startElementHandler) {
   2439           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
   2440           noElmHandlers = XML_FALSE;
   2441         }
   2442         if (endElementHandler) {
   2443           if (startElementHandler)
   2444             *eventPP = *eventEndPP;
   2445           endElementHandler(handlerArg, name.str);
   2446           noElmHandlers = XML_FALSE;
   2447         }
   2448         if (noElmHandlers && defaultHandler)
   2449           reportDefault(parser, enc, s, next);
   2450         poolClear(&tempPool);
   2451         while (bindings) {
   2452           BINDING *b = bindings;
   2453           if (endNamespaceDeclHandler)
   2454             endNamespaceDeclHandler(handlerArg, b->prefix->name);
   2455           bindings = bindings->nextTagBinding;
   2456           b->nextTagBinding = freeBindingList;
   2457           freeBindingList = b;
   2458           b->prefix->binding = b->prevPrefixBinding;
   2459         }
   2460       }
   2461       if (tagLevel == 0)
   2462         return epilogProcessor(parser, next, end, nextPtr);
   2463       break;
   2464     case XML_TOK_END_TAG:
   2465       if (tagLevel == startTagLevel)
   2466         return XML_ERROR_ASYNC_ENTITY;
   2467       else {
   2468         int len;
   2469         const char *rawName;
   2470         TAG *tag = tagStack;
   2471         tagStack = tag->parent;
   2472         tag->parent = freeTagList;
   2473         freeTagList = tag;
   2474         rawName = s + enc->minBytesPerChar*2;
   2475         len = XmlNameLength(enc, rawName);
   2476         if (len != tag->rawNameLength
   2477             || memcmp(tag->rawName, rawName, len) != 0) {
   2478           *eventPP = rawName;
   2479           return XML_ERROR_TAG_MISMATCH;
   2480         }
   2481         --tagLevel;
   2482         if (endElementHandler) {
   2483           const XML_Char *localPart;
   2484           const XML_Char *prefix;
   2485           XML_Char *uri;
   2486           localPart = tag->name.localPart;
   2487           if (ns && localPart) {
   2488             /* localPart and prefix may have been overwritten in
   2489                tag->name.str, since this points to the binding->uri
   2490                buffer which gets re-used; so we have to add them again
   2491             */
   2492             uri = (XML_Char *)tag->name.str + tag->name.uriLen;
   2493             /* don't need to check for space - already done in storeAtts() */
   2494             while (*localPart) *uri++ = *localPart++;
   2495             prefix = (XML_Char *)tag->name.prefix;
   2496             if (ns_triplets && prefix) {
   2497               *uri++ = namespaceSeparator;
   2498               while (*prefix) *uri++ = *prefix++;
   2499              }
   2500             *uri = XML_T('\0');
   2501           }
   2502           endElementHandler(handlerArg, tag->name.str);
   2503         }
   2504         else if (defaultHandler)
   2505           reportDefault(parser, enc, s, next);
   2506         while (tag->bindings) {
   2507           BINDING *b = tag->bindings;
   2508           if (endNamespaceDeclHandler)
   2509             endNamespaceDeclHandler(handlerArg, b->prefix->name);
   2510           tag->bindings = tag->bindings->nextTagBinding;
   2511           b->nextTagBinding = freeBindingList;
   2512           freeBindingList = b;
   2513           b->prefix->binding = b->prevPrefixBinding;
   2514         }
   2515         if (tagLevel == 0)
   2516           return epilogProcessor(parser, next, end, nextPtr);
   2517       }
   2518       break;
   2519     case XML_TOK_CHAR_REF:
   2520       {
   2521         int n = XmlCharRefNumber(enc, s);
   2522         if (n < 0)
   2523           return XML_ERROR_BAD_CHAR_REF;
   2524         if (characterDataHandler) {
   2525           XML_Char buf[XML_ENCODE_MAX];
   2526           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
   2527         }
   2528         else if (defaultHandler)
   2529           reportDefault(parser, enc, s, next);
   2530       }
   2531       break;
   2532     case XML_TOK_XML_DECL:
   2533       return XML_ERROR_MISPLACED_XML_PI;
   2534     case XML_TOK_DATA_NEWLINE:
   2535       if (characterDataHandler) {
   2536         XML_Char c = 0xA;
   2537         characterDataHandler(handlerArg, &c, 1);
   2538       }
   2539       else if (defaultHandler)
   2540         reportDefault(parser, enc, s, next);
   2541       break;
   2542     case XML_TOK_CDATA_SECT_OPEN:
   2543       {
   2544         enum XML_Error result;
   2545         if (startCdataSectionHandler)
   2546           startCdataSectionHandler(handlerArg);
   2547 #if 0
   2548         /* Suppose you doing a transformation on a document that involves
   2549            changing only the character data.  You set up a defaultHandler
   2550            and a characterDataHandler.  The defaultHandler simply copies
   2551            characters through.  The characterDataHandler does the
   2552            transformation and writes the characters out escaping them as
   2553            necessary.  This case will fail to work if we leave out the
   2554            following two lines (because & and < inside CDATA sections will
   2555            be incorrectly escaped).
   2556 
   2557            However, now we have a start/endCdataSectionHandler, so it seems
   2558            easier to let the user deal with this.
   2559         */
   2560         else if (characterDataHandler)
   2561           characterDataHandler(handlerArg, dataBuf, 0);
   2562 #endif
   2563         else if (defaultHandler)
   2564           reportDefault(parser, enc, s, next);
   2565         result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
   2566         if (result != XML_ERROR_NONE)
   2567           return result;
   2568         else if (!next) {
   2569           processor = cdataSectionProcessor;
   2570           return result;
   2571         }
   2572       }
   2573       break;
   2574     case XML_TOK_TRAILING_RSQB:
   2575       if (haveMore) {
   2576         *nextPtr = s;
   2577         return XML_ERROR_NONE;
   2578       }
   2579       if (characterDataHandler) {
   2580         if (MUST_CONVERT(enc, s)) {
   2581           ICHAR *dataPtr = (ICHAR *)dataBuf;
   2582           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
   2583           characterDataHandler(handlerArg, dataBuf,
   2584                                (int)(dataPtr - (ICHAR *)dataBuf));
   2585         }
   2586         else
   2587           characterDataHandler(handlerArg,
   2588                                (XML_Char *)s,
   2589                                (int)((XML_Char *)end - (XML_Char *)s));
   2590       }
   2591       else if (defaultHandler)
   2592         reportDefault(parser, enc, s, end);
   2593       /* We are at the end of the final buffer, should we check for
   2594          XML_SUSPENDED, XML_FINISHED?
   2595       */
   2596       if (startTagLevel == 0) {
   2597         *eventPP = end;
   2598         return XML_ERROR_NO_ELEMENTS;
   2599       }
   2600       if (tagLevel != startTagLevel) {
   2601         *eventPP = end;
   2602         return XML_ERROR_ASYNC_ENTITY;
   2603       }
   2604       *nextPtr = end;
   2605       return XML_ERROR_NONE;
   2606     case XML_TOK_DATA_CHARS:
   2607       {
   2608         XML_CharacterDataHandler charDataHandler = characterDataHandler;
   2609         if (charDataHandler) {
   2610           if (MUST_CONVERT(enc, s)) {
   2611             for (;;) {
   2612               ICHAR *dataPtr = (ICHAR *)dataBuf;
   2613               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
   2614               *eventEndPP = s;
   2615               charDataHandler(handlerArg, dataBuf,
   2616                               (int)(dataPtr - (ICHAR *)dataBuf));
   2617               if (s == next)
   2618                 break;
   2619               *eventPP = s;
   2620             }
   2621           }
   2622           else
   2623             charDataHandler(handlerArg,
   2624                             (XML_Char *)s,
   2625                             (int)((XML_Char *)next - (XML_Char *)s));
   2626         }
   2627         else if (defaultHandler)
   2628           reportDefault(parser, enc, s, next);
   2629       }
   2630       break;
   2631     case XML_TOK_PI:
   2632       if (!reportProcessingInstruction(parser, enc, s, next))
   2633         return XML_ERROR_NO_MEMORY;
   2634       break;
   2635     case XML_TOK_COMMENT:
   2636       if (!reportComment(parser, enc, s, next))
   2637         return XML_ERROR_NO_MEMORY;
   2638       break;
   2639     default:
   2640       if (defaultHandler)
   2641         reportDefault(parser, enc, s, next);
   2642       break;
   2643     }
   2644     *eventPP = s = next;
   2645     switch (ps_parsing) {
   2646     case XML_SUSPENDED:
   2647       *nextPtr = next;
   2648       return XML_ERROR_NONE;
   2649     case XML_FINISHED:
   2650       return XML_ERROR_ABORTED;
   2651     default: ;
   2652     }
   2653   }
   2654   /* not reached */
   2655 }
   2656 
   2657 /* Precondition: all arguments must be non-NULL;
   2658    Purpose:
   2659    - normalize attributes
   2660    - check attributes for well-formedness
   2661    - generate namespace aware attribute names (URI, prefix)
   2662    - build list of attributes for startElementHandler
   2663    - default attributes
   2664    - process namespace declarations (check and report them)
   2665    - generate namespace aware element name (URI, prefix)
   2666 */
   2667 static enum XML_Error
   2668 storeAtts(XML_Parser parser, const ENCODING *enc,
   2669           const char *attStr, TAG_NAME *tagNamePtr,
   2670           BINDING **bindingsPtr)
   2671 {
   2672   DTD * const dtd = _dtd;  /* save one level of indirection */
   2673   ELEMENT_TYPE *elementType;
   2674   int nDefaultAtts;
   2675   const XML_Char **appAtts;   /* the attribute list for the application */
   2676   int attIndex = 0;
   2677   int prefixLen;
   2678   int i;
   2679   int n;
   2680   XML_Char *uri;
   2681   int nPrefixes = 0;
   2682   BINDING *binding;
   2683   const XML_Char *localPart;
   2684 
   2685   /* lookup the element type name */
   2686   elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
   2687   if (!elementType) {
   2688     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
   2689     if (!name)
   2690       return XML_ERROR_NO_MEMORY;
   2691     elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
   2692                                          sizeof(ELEMENT_TYPE));
   2693     if (!elementType)
   2694       return XML_ERROR_NO_MEMORY;
   2695     if (ns && !setElementTypePrefix(parser, elementType))
   2696       return XML_ERROR_NO_MEMORY;
   2697   }
   2698   nDefaultAtts = elementType->nDefaultAtts;
   2699 
   2700   /* get the attributes from the tokenizer */
   2701   n = XmlGetAttributes(enc, attStr, attsSize, atts);
   2702   if (n + nDefaultAtts > attsSize) {
   2703     int oldAttsSize = attsSize;
   2704     ATTRIBUTE *temp;
   2705     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
   2706     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
   2707     if (temp == NULL)
   2708       return XML_ERROR_NO_MEMORY;
   2709     atts = temp;
   2710     if (n > oldAttsSize)
   2711       XmlGetAttributes(enc, attStr, n, atts);
   2712   }
   2713 
   2714   appAtts = (const XML_Char **)atts;
   2715   for (i = 0; i < n; i++) {
   2716     /* add the name and value to the attribute list */
   2717     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
   2718                                          atts[i].name
   2719                                          + XmlNameLength(enc, atts[i].name));
   2720     if (!attId)
   2721       return XML_ERROR_NO_MEMORY;
   2722     /* Detect duplicate attributes by their QNames. This does not work when
   2723        namespace processing is turned on and different prefixes for the same
   2724        namespace are used. For this case we have a check further down.
   2725     */
   2726     if ((attId->name)[-1]) {
   2727       if (enc == encoding)
   2728         eventPtr = atts[i].name;
   2729       return XML_ERROR_DUPLICATE_ATTRIBUTE;
   2730     }
   2731     (attId->name)[-1] = 1;
   2732     appAtts[attIndex++] = attId->name;
   2733     if (!atts[i].normalized) {
   2734       enum XML_Error result;
   2735       XML_Bool isCdata = XML_TRUE;
   2736 
   2737       /* figure out whether declared as other than CDATA */
   2738       if (attId->maybeTokenized) {
   2739         int j;
   2740         for (j = 0; j < nDefaultAtts; j++) {
   2741           if (attId == elementType->defaultAtts[j].id) {
   2742             isCdata = elementType->defaultAtts[j].isCdata;
   2743             break;
   2744           }
   2745         }
   2746       }
   2747 
   2748       /* normalize the attribute value */
   2749       result = storeAttributeValue(parser, enc, isCdata,
   2750                                    atts[i].valuePtr, atts[i].valueEnd,
   2751                                    &tempPool);
   2752       if (result)
   2753         return result;
   2754       appAtts[attIndex] = poolStart(&tempPool);
   2755       poolFinish(&tempPool);
   2756     }
   2757     else {
   2758       /* the value did not need normalizing */
   2759       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
   2760                                           atts[i].valueEnd);
   2761       if (appAtts[attIndex] == 0)
   2762         return XML_ERROR_NO_MEMORY;
   2763       poolFinish(&tempPool);
   2764     }
   2765     /* handle prefixed attribute names */
   2766     if (attId->prefix) {
   2767       if (attId->xmlns) {
   2768         /* deal with namespace declarations here */
   2769         enum XML_Error result = addBinding(parser, attId->prefix, attId,
   2770                                            appAtts[attIndex], bindingsPtr);
   2771         if (result)
   2772           return result;
   2773         --attIndex;
   2774       }
   2775       else {
   2776         /* deal with other prefixed names later */
   2777         attIndex++;
   2778         nPrefixes++;
   2779         (attId->name)[-1] = 2;
   2780       }
   2781     }
   2782     else
   2783       attIndex++;
   2784   }
   2785 
   2786   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
   2787   nSpecifiedAtts = attIndex;
   2788   if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
   2789     for (i = 0; i < attIndex; i += 2)
   2790       if (appAtts[i] == elementType->idAtt->name) {
   2791         idAttIndex = i;
   2792         break;
   2793       }
   2794   }
   2795   else
   2796     idAttIndex = -1;
   2797 
   2798   /* do attribute defaulting */
   2799   for (i = 0; i < nDefaultAtts; i++) {
   2800     const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
   2801     if (!(da->id->name)[-1] && da->value) {
   2802       if (da->id->prefix) {
   2803         if (da->id->xmlns) {
   2804           enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
   2805                                              da->value, bindingsPtr);
   2806           if (result)
   2807             return result;
   2808         }
   2809         else {
   2810           (da->id->name)[-1] = 2;
   2811           nPrefixes++;
   2812           appAtts[attIndex++] = da->id->name;
   2813           appAtts[attIndex++] = da->value;
   2814         }
   2815       }
   2816       else {
   2817         (da->id->name)[-1] = 1;
   2818         appAtts[attIndex++] = da->id->name;
   2819         appAtts[attIndex++] = da->value;
   2820       }
   2821     }
   2822   }
   2823   appAtts[attIndex] = 0;
   2824 
   2825   /* expand prefixed attribute names, check for duplicates,
   2826      and clear flags that say whether attributes were specified */
   2827   i = 0;
   2828   if (nPrefixes) {
   2829     int j;  /* hash table index */
   2830     unsigned long version = nsAttsVersion;
   2831     int nsAttsSize = (int)1 << nsAttsPower;
   2832     /* size of hash table must be at least 2 * (# of prefixed attributes) */
   2833     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
   2834       NS_ATT *temp;
   2835       /* hash table size must also be a power of 2 and >= 8 */
   2836       while (nPrefixes >> nsAttsPower++);
   2837       if (nsAttsPower < 3)
   2838         nsAttsPower = 3;
   2839       nsAttsSize = (int)1 << nsAttsPower;
   2840       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
   2841       if (!temp)
   2842         return XML_ERROR_NO_MEMORY;
   2843       nsAtts = temp;
   2844       version = 0;  /* force re-initialization of nsAtts hash table */
   2845     }
   2846     /* using a version flag saves us from initializing nsAtts every time */
   2847     if (!version) {  /* initialize version flags when version wraps around */
   2848       version = INIT_ATTS_VERSION;
   2849       for (j = nsAttsSize; j != 0; )
   2850         nsAtts[--j].version = version;
   2851     }
   2852     nsAttsVersion = --version;
   2853 
   2854     /* expand prefixed names and check for duplicates */
   2855     for (; i < attIndex; i += 2) {
   2856       const XML_Char *s = appAtts[i];
   2857       if (s[-1] == 2) {  /* prefixed */
   2858         ATTRIBUTE_ID *id;
   2859         const BINDING *b;
   2860         unsigned long uriHash = hash_secret_salt;
   2861         ((XML_Char *)s)[-1] = 0;  /* clear flag */
   2862         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
   2863         b = id->prefix->binding;
   2864         if (!b)
   2865           return XML_ERROR_UNBOUND_PREFIX;
   2866 
   2867         /* as we expand the name we also calculate its hash value */
   2868         for (j = 0; j < b->uriLen; j++) {
   2869           const XML_Char c = b->uri[j];
   2870           if (!poolAppendChar(&tempPool, c))
   2871             return XML_ERROR_NO_MEMORY;
   2872           uriHash = CHAR_HASH(uriHash, c);
   2873         }
   2874         while (*s++ != XML_T(ASCII_COLON))
   2875           ;
   2876         do {  /* copies null terminator */
   2877           const XML_Char c = *s;
   2878           if (!poolAppendChar(&tempPool, *s))
   2879             return XML_ERROR_NO_MEMORY;
   2880           uriHash = CHAR_HASH(uriHash, c);
   2881         } while (*s++);
   2882 
   2883         { /* Check hash table for duplicate of expanded name (uriName).
   2884              Derived from code in lookup(parser, HASH_TABLE *table, ...).
   2885           */
   2886           unsigned char step = 0;
   2887           unsigned long mask = nsAttsSize - 1;
   2888           j = uriHash & mask;  /* index into hash table */
   2889           while (nsAtts[j].version == version) {
   2890             /* for speed we compare stored hash values first */
   2891             if (uriHash == nsAtts[j].hash) {
   2892               const XML_Char *s1 = poolStart(&tempPool);
   2893               const XML_Char *s2 = nsAtts[j].uriName;
   2894               /* s1 is null terminated, but not s2 */
   2895               for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
   2896               if (*s1 == 0)
   2897                 return XML_ERROR_DUPLICATE_ATTRIBUTE;
   2898             }
   2899             if (!step)
   2900               step = PROBE_STEP(uriHash, mask, nsAttsPower);
   2901             j < step ? (j += nsAttsSize - step) : (j -= step);
   2902           }
   2903         }
   2904 
   2905         if (ns_triplets) {  /* append namespace separator and prefix */
   2906           tempPool.ptr[-1] = namespaceSeparator;
   2907           s = b->prefix->name;
   2908           do {
   2909             if (!poolAppendChar(&tempPool, *s))
   2910               return XML_ERROR_NO_MEMORY;
   2911           } while (*s++);
   2912         }
   2913 
   2914         /* store expanded name in attribute list */
   2915         s = poolStart(&tempPool);
   2916         poolFinish(&tempPool);
   2917         appAtts[i] = s;
   2918 
   2919         /* fill empty slot with new version, uriName and hash value */
   2920         nsAtts[j].version = version;
   2921         nsAtts[j].hash = uriHash;
   2922         nsAtts[j].uriName = s;
   2923 
   2924         if (!--nPrefixes) {
   2925           i += 2;
   2926           break;
   2927         }
   2928       }
   2929       else  /* not prefixed */
   2930         ((XML_Char *)s)[-1] = 0;  /* clear flag */
   2931     }
   2932   }
   2933   /* clear flags for the remaining attributes */
   2934   for (; i < attIndex; i += 2)
   2935     ((XML_Char *)(appAtts[i]))[-1] = 0;
   2936   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
   2937     binding->attId->name[-1] = 0;
   2938 
   2939   if (!ns)
   2940     return XML_ERROR_NONE;
   2941 
   2942   /* expand the element type name */
   2943   if (elementType->prefix) {
   2944     binding = elementType->prefix->binding;
   2945     if (!binding)
   2946       return XML_ERROR_UNBOUND_PREFIX;
   2947     localPart = tagNamePtr->str;
   2948     while (*localPart++ != XML_T(ASCII_COLON))
   2949       ;
   2950   }
   2951   else if (dtd->defaultPrefix.binding) {
   2952     binding = dtd->defaultPrefix.binding;
   2953     localPart = tagNamePtr->str;
   2954   }
   2955   else
   2956     return XML_ERROR_NONE;
   2957   prefixLen = 0;
   2958   if (ns_triplets && binding->prefix->name) {
   2959     for (; binding->prefix->name[prefixLen++];)
   2960       ;  /* prefixLen includes null terminator */
   2961   }
   2962   tagNamePtr->localPart = localPart;
   2963   tagNamePtr->uriLen = binding->uriLen;
   2964   tagNamePtr->prefix = binding->prefix->name;
   2965   tagNamePtr->prefixLen = prefixLen;
   2966   for (i = 0; localPart[i++];)
   2967     ;  /* i includes null terminator */
   2968   n = i + binding->uriLen + prefixLen;
   2969   if (n > binding->uriAlloc) {
   2970     TAG *p;
   2971     uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
   2972     if (!uri)
   2973       return XML_ERROR_NO_MEMORY;
   2974     binding->uriAlloc = n + EXPAND_SPARE;
   2975     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
   2976     for (p = tagStack; p; p = p->parent)
   2977       if (p->name.str == binding->uri)
   2978         p->name.str = uri;
   2979     FREE(binding->uri);
   2980     binding->uri = uri;
   2981   }
   2982   /* if namespaceSeparator != '\0' then uri includes it already */
   2983   uri = binding->uri + binding->uriLen;
   2984   memcpy(uri, localPart, i * sizeof(XML_Char));
   2985   /* we always have a namespace separator between localPart and prefix */
   2986   if (prefixLen) {
   2987     uri += i - 1;
   2988     *uri = namespaceSeparator;  /* replace null terminator */
   2989     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
   2990   }
   2991   tagNamePtr->str = binding->uri;
   2992   return XML_ERROR_NONE;
   2993 }
   2994 
   2995 /* addBinding() overwrites the value of prefix->binding without checking.
   2996    Therefore one must keep track of the old value outside of addBinding().
   2997 */
   2998 static enum XML_Error
   2999 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   3000            const XML_Char *uri, BINDING **bindingsPtr)
   3001 {
   3002   static const XML_Char xmlNamespace[] = {
   3003     ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
   3004     ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
   3005     ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
   3006     ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
   3007     ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
   3008     ASCII_e, '\0'
   3009   };
   3010   static const int xmlLen =
   3011     (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
   3012   static const XML_Char xmlnsNamespace[] = {
   3013     ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
   3014     ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
   3015     ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
   3016     ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
   3017     ASCII_SLASH, '\0'
   3018   };
   3019   static const int xmlnsLen =
   3020     (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
   3021 
   3022   XML_Bool mustBeXML = XML_FALSE;
   3023   XML_Bool isXML = XML_TRUE;
   3024   XML_Bool isXMLNS = XML_TRUE;
   3025 
   3026   BINDING *b;
   3027   int len;
   3028 
   3029   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
   3030   if (*uri == XML_T('\0') && prefix->name)
   3031     return XML_ERROR_UNDECLARING_PREFIX;
   3032 
   3033   if (prefix->name
   3034       && prefix->name[0] == XML_T(ASCII_x)
   3035       && prefix->name[1] == XML_T(ASCII_m)
   3036       && prefix->name[2] == XML_T(ASCII_l)) {
   3037 
   3038     /* Not allowed to bind xmlns */
   3039     if (prefix->name[3] == XML_T(ASCII_n)
   3040         && prefix->name[4] == XML_T(ASCII_s)
   3041         && prefix->name[5] == XML_T('\0'))
   3042       return XML_ERROR_RESERVED_PREFIX_XMLNS;
   3043 
   3044     if (prefix->name[3] == XML_T('\0'))
   3045       mustBeXML = XML_TRUE;
   3046   }
   3047 
   3048   for (len = 0; uri[len]; len++) {
   3049     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
   3050       isXML = XML_FALSE;
   3051 
   3052     if (!mustBeXML && isXMLNS
   3053         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
   3054       isXMLNS = XML_FALSE;
   3055   }
   3056   isXML = isXML && len == xmlLen;
   3057   isXMLNS = isXMLNS && len == xmlnsLen;
   3058 
   3059   if (mustBeXML != isXML)
   3060     return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
   3061                      : XML_ERROR_RESERVED_NAMESPACE_URI;
   3062 
   3063   if (isXMLNS)
   3064     return XML_ERROR_RESERVED_NAMESPACE_URI;
   3065 
   3066   if (namespaceSeparator)
   3067     len++;
   3068   if (freeBindingList) {
   3069     b = freeBindingList;
   3070     if (len > b->uriAlloc) {
   3071       XML_Char *temp = (XML_Char *)REALLOC(b->uri,
   3072                           sizeof(XML_Char) * (len + EXPAND_SPARE));
   3073       if (temp == NULL)
   3074         return XML_ERROR_NO_MEMORY;
   3075       b->uri = temp;
   3076       b->uriAlloc = len + EXPAND_SPARE;
   3077     }
   3078     freeBindingList = b->nextTagBinding;
   3079   }
   3080   else {
   3081     b = (BINDING *)MALLOC(sizeof(BINDING));
   3082     if (!b)
   3083       return XML_ERROR_NO_MEMORY;
   3084     b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
   3085     if (!b->uri) {
   3086       FREE(b);
   3087       return XML_ERROR_NO_MEMORY;
   3088     }
   3089     b->uriAlloc = len + EXPAND_SPARE;
   3090   }
   3091   b->uriLen = len;
   3092   memcpy(b->uri, uri, len * sizeof(XML_Char));
   3093   if (namespaceSeparator)
   3094     b->uri[len - 1] = namespaceSeparator;
   3095   b->prefix = prefix;
   3096   b->attId = attId;
   3097   b->prevPrefixBinding = prefix->binding;
   3098   /* NULL binding when default namespace undeclared */
   3099   if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
   3100     prefix->binding = NULL;
   3101   else
   3102     prefix->binding = b;
   3103   b->nextTagBinding = *bindingsPtr;
   3104   *bindingsPtr = b;
   3105   /* if attId == NULL then we are not starting a namespace scope */
   3106   if (attId && startNamespaceDeclHandler)
   3107     startNamespaceDeclHandler(handlerArg, prefix->name,
   3108                               prefix->binding ? uri : 0);
   3109   return XML_ERROR_NONE;
   3110 }
   3111 
   3112 /* The idea here is to avoid using stack for each CDATA section when
   3113    the whole file is parsed with one call.
   3114 */
   3115 static enum XML_Error PTRCALL
   3116 cdataSectionProcessor(XML_Parser parser,
   3117                       const char *start,
   3118                       const char *end,
   3119                       const char **endPtr)
   3120 {
   3121   enum XML_Error result = doCdataSection(parser, encoding, &start, end,
   3122                                          endPtr, (XML_Bool)!ps_finalBuffer);
   3123   if (result != XML_ERROR_NONE)
   3124     return result;
   3125   if (start) {
   3126     if (parentParser) {  /* we are parsing an external entity */
   3127       processor = externalEntityContentProcessor;
   3128       return externalEntityContentProcessor(parser, start, end, endPtr);
   3129     }
   3130     else {
   3131       processor = contentProcessor;
   3132       return contentProcessor(parser, start, end, endPtr);
   3133     }
   3134   }
   3135   return result;
   3136 }
   3137 
   3138 /* startPtr gets set to non-null if the section is closed, and to null if
   3139    the section is not yet closed.
   3140 */
   3141 static enum XML_Error
   3142 doCdataSection(XML_Parser parser,
   3143                const ENCODING *enc,
   3144                const char **startPtr,
   3145                const char *end,
   3146                const char **nextPtr,
   3147                XML_Bool haveMore)
   3148 {
   3149   const char *s = *startPtr;
   3150   const char **eventPP;
   3151   const char **eventEndPP;
   3152   if (enc == encoding) {
   3153     eventPP = &eventPtr;
   3154     *eventPP = s;
   3155     eventEndPP = &eventEndPtr;
   3156   }
   3157   else {
   3158     eventPP = &(openInternalEntities->internalEventPtr);
   3159     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   3160   }
   3161   *eventPP = s;
   3162   *startPtr = NULL;
   3163 
   3164   for (;;) {
   3165     const char *next;
   3166     int tok = XmlCdataSectionTok(enc, s, end, &next);
   3167     *eventEndPP = next;
   3168     switch (tok) {
   3169     case XML_TOK_CDATA_SECT_CLOSE:
   3170       if (endCdataSectionHandler)
   3171         endCdataSectionHandler(handlerArg);
   3172 #if 0
   3173       /* see comment under XML_TOK_CDATA_SECT_OPEN */
   3174       else if (characterDataHandler)
   3175         characterDataHandler(handlerArg, dataBuf, 0);
   3176 #endif
   3177       else if (defaultHandler)
   3178         reportDefault(parser, enc, s, next);
   3179       *startPtr = next;
   3180       *nextPtr = next;
   3181       if (ps_parsing == XML_FINISHED)
   3182         return XML_ERROR_ABORTED;
   3183       else
   3184         return XML_ERROR_NONE;
   3185     case XML_TOK_DATA_NEWLINE:
   3186       if (characterDataHandler) {
   3187         XML_Char c = 0xA;
   3188         characterDataHandler(handlerArg, &c, 1);
   3189       }
   3190       else if (defaultHandler)
   3191         reportDefault(parser, enc, s, next);
   3192       break;
   3193     case XML_TOK_DATA_CHARS:
   3194       {
   3195         XML_CharacterDataHandler charDataHandler = characterDataHandler;
   3196         if (charDataHandler) {
   3197           if (MUST_CONVERT(enc, s)) {
   3198             for (;;) {
   3199               ICHAR *dataPtr = (ICHAR *)dataBuf;
   3200               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
   3201               *eventEndPP = next;
   3202               charDataHandler(handlerArg, dataBuf,
   3203                               (int)(dataPtr - (ICHAR *)dataBuf));
   3204               if (s == next)
   3205                 break;
   3206               *eventPP = s;
   3207             }
   3208           }
   3209           else
   3210             charDataHandler(handlerArg,
   3211                             (XML_Char *)s,
   3212                             (int)((XML_Char *)next - (XML_Char *)s));
   3213         }
   3214         else if (defaultHandler)
   3215           reportDefault(parser, enc, s, next);
   3216       }
   3217       break;
   3218     case XML_TOK_INVALID:
   3219       *eventPP = next;
   3220       return XML_ERROR_INVALID_TOKEN;
   3221     case XML_TOK_PARTIAL_CHAR:
   3222       if (haveMore) {
   3223         *nextPtr = s;
   3224         return XML_ERROR_NONE;
   3225       }
   3226       return XML_ERROR_PARTIAL_CHAR;
   3227     case XML_TOK_PARTIAL:
   3228     case XML_TOK_NONE:
   3229       if (haveMore) {
   3230         *nextPtr = s;
   3231         return XML_ERROR_NONE;
   3232       }
   3233       return XML_ERROR_UNCLOSED_CDATA_SECTION;
   3234     default:
   3235       *eventPP = next;
   3236       return XML_ERROR_UNEXPECTED_STATE;
   3237     }
   3238 
   3239     *eventPP = s = next;
   3240     switch (ps_parsing) {
   3241     case XML_SUSPENDED:
   3242       *nextPtr = next;
   3243       return XML_ERROR_NONE;
   3244     case XML_FINISHED:
   3245       return XML_ERROR_ABORTED;
   3246     default: ;
   3247     }
   3248   }
   3249   /* not reached */
   3250 }
   3251 
   3252 #ifdef XML_DTD
   3253 
   3254 /* The idea here is to avoid using stack for each IGNORE section when
   3255    the whole file is parsed with one call.
   3256 */
   3257 static enum XML_Error PTRCALL
   3258 ignoreSectionProcessor(XML_Parser parser,
   3259                        const char *start,
   3260                        const char *end,
   3261                        const char **endPtr)
   3262 {
   3263   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
   3264                                           endPtr, (XML_Bool)!ps_finalBuffer);
   3265   if (result != XML_ERROR_NONE)
   3266     return result;
   3267   if (start) {
   3268     processor = prologProcessor;
   3269     return prologProcessor(parser, start, end, endPtr);
   3270   }
   3271   return result;
   3272 }
   3273 
   3274 /* startPtr gets set to non-null is the section is closed, and to null
   3275    if the section is not yet closed.
   3276 */
   3277 static enum XML_Error
   3278 doIgnoreSection(XML_Parser parser,
   3279                 const ENCODING *enc,
   3280                 const char **startPtr,
   3281                 const char *end,
   3282                 const char **nextPtr,
   3283                 XML_Bool haveMore)
   3284 {
   3285   const char *next;
   3286   int tok;
   3287   const char *s = *startPtr;
   3288   const char **eventPP;
   3289   const char **eventEndPP;
   3290   if (enc == encoding) {
   3291     eventPP = &eventPtr;
   3292     *eventPP = s;
   3293     eventEndPP = &eventEndPtr;
   3294   }
   3295   else {
   3296     eventPP = &(openInternalEntities->internalEventPtr);
   3297     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   3298   }
   3299   *eventPP = s;
   3300   *startPtr = NULL;
   3301   tok = XmlIgnoreSectionTok(enc, s, end, &next);
   3302   *eventEndPP = next;
   3303   switch (tok) {
   3304   case XML_TOK_IGNORE_SECT:
   3305     if (defaultHandler)
   3306       reportDefault(parser, enc, s, next);
   3307     *startPtr = next;
   3308     *nextPtr = next;
   3309     if (ps_parsing == XML_FINISHED)
   3310       return XML_ERROR_ABORTED;
   3311     else
   3312       return XML_ERROR_NONE;
   3313   case XML_TOK_INVALID:
   3314     *eventPP = next;
   3315     return XML_ERROR_INVALID_TOKEN;
   3316   case XML_TOK_PARTIAL_CHAR:
   3317     if (haveMore) {
   3318       *nextPtr = s;
   3319       return XML_ERROR_NONE;
   3320     }
   3321     return XML_ERROR_PARTIAL_CHAR;
   3322   case XML_TOK_PARTIAL:
   3323   case XML_TOK_NONE:
   3324     if (haveMore) {
   3325       *nextPtr = s;
   3326       return XML_ERROR_NONE;
   3327     }
   3328     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
   3329   default:
   3330     *eventPP = next;
   3331     return XML_ERROR_UNEXPECTED_STATE;
   3332   }
   3333   /* not reached */
   3334 }
   3335 
   3336 #endif /* XML_DTD */
   3337 
   3338 static enum XML_Error
   3339 initializeEncoding(XML_Parser parser)
   3340 {
   3341   const char *s;
   3342 #ifdef XML_UNICODE
   3343   char encodingBuf[128];
   3344   if (!protocolEncodingName)
   3345     s = NULL;
   3346   else {
   3347     int i;
   3348     for (i = 0; protocolEncodingName[i]; i++) {
   3349       if (i == sizeof(encodingBuf) - 1
   3350           || (protocolEncodingName[i] & ~0x7f) != 0) {
   3351         encodingBuf[0] = '\0';
   3352         break;
   3353       }
   3354       encodingBuf[i] = (char)protocolEncodingName[i];
   3355     }
   3356     encodingBuf[i] = '\0';
   3357     s = encodingBuf;
   3358   }
   3359 #else
   3360   s = protocolEncodingName;
   3361 #endif
   3362   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
   3363     return XML_ERROR_NONE;
   3364   return handleUnknownEncoding(parser, protocolEncodingName);
   3365 }
   3366 
   3367 static enum XML_Error
   3368 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
   3369                const char *s, const char *next)
   3370 {
   3371   const char *encodingName = NULL;
   3372   const XML_Char *storedEncName = NULL;
   3373   const ENCODING *newEncoding = NULL;
   3374   const char *version = NULL;
   3375   const char *versionend;
   3376   const XML_Char *storedversion = NULL;
   3377   int standalone = -1;
   3378   if (!(ns
   3379         ? XmlParseXmlDeclNS
   3380         : XmlParseXmlDecl)(isGeneralTextEntity,
   3381                            encoding,
   3382                            s,
   3383                            next,
   3384                            &eventPtr,
   3385                            &version,
   3386                            &versionend,
   3387                            &encodingName,
   3388                            &newEncoding,
   3389                            &standalone)) {
   3390     if (isGeneralTextEntity)
   3391       return XML_ERROR_TEXT_DECL;
   3392     else
   3393       return XML_ERROR_XML_DECL;
   3394   }
   3395   if (!isGeneralTextEntity && standalone == 1) {
   3396     _dtd->standalone = XML_TRUE;
   3397 #ifdef XML_DTD
   3398     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
   3399       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
   3400 #endif /* XML_DTD */
   3401   }
   3402   if (xmlDeclHandler) {
   3403     if (encodingName != NULL) {
   3404       storedEncName = poolStoreString(&temp2Pool,
   3405                                       encoding,
   3406                                       encodingName,
   3407                                       encodingName
   3408                                       + XmlNameLength(encoding, encodingName));
   3409       if (!storedEncName)
   3410               return XML_ERROR_NO_MEMORY;
   3411       poolFinish(&temp2Pool);
   3412     }
   3413     if (version) {
   3414       storedversion = poolStoreString(&temp2Pool,
   3415                                       encoding,
   3416                                       version,
   3417                                       versionend - encoding->minBytesPerChar);
   3418       if (!storedversion)
   3419         return XML_ERROR_NO_MEMORY;
   3420     }
   3421     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
   3422   }
   3423   else if (defaultHandler)
   3424     reportDefault(parser, encoding, s, next);
   3425   if (protocolEncodingName == NULL) {
   3426     if (newEncoding) {
   3427       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
   3428         eventPtr = encodingName;
   3429         return XML_ERROR_INCORRECT_ENCODING;
   3430       }
   3431       encoding = newEncoding;
   3432     }
   3433     else if (encodingName) {
   3434       enum XML_Error result;
   3435       if (!storedEncName) {
   3436         storedEncName = poolStoreString(
   3437           &temp2Pool, encoding, encodingName,
   3438           encodingName + XmlNameLength(encoding, encodingName));
   3439         if (!storedEncName)
   3440           return XML_ERROR_NO_MEMORY;
   3441       }
   3442       result = handleUnknownEncoding(parser, storedEncName);
   3443       poolClear(&temp2Pool);
   3444       if (result == XML_ERROR_UNKNOWN_ENCODING)
   3445         eventPtr = encodingName;
   3446       return result;
   3447     }
   3448   }
   3449 
   3450   if (storedEncName || storedversion)
   3451     poolClear(&temp2Pool);
   3452 
   3453   return XML_ERROR_NONE;
   3454 }
   3455 
   3456 static enum XML_Error
   3457 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
   3458 {
   3459   if (unknownEncodingHandler) {
   3460     XML_Encoding info;
   3461     int i;
   3462     for (i = 0; i < 256; i++)
   3463       info.map[i] = -1;
   3464     info.convert = NULL;
   3465     info.data = NULL;
   3466     info.release = NULL;
   3467     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
   3468                                &info)) {
   3469       ENCODING *enc;
   3470       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
   3471       if (!unknownEncodingMem) {
   3472         if (info.release)
   3473           info.release(info.data);
   3474         return XML_ERROR_NO_MEMORY;
   3475       }
   3476       enc = (ns
   3477              ? XmlInitUnknownEncodingNS
   3478              : XmlInitUnknownEncoding)(unknownEncodingMem,
   3479                                        info.map,
   3480                                        info.convert,
   3481                                        info.data);
   3482       if (enc) {
   3483         unknownEncodingData = info.data;
   3484         unknownEncodingRelease = info.release;
   3485         encoding = enc;
   3486         return XML_ERROR_NONE;
   3487       }
   3488     }
   3489     if (info.release != NULL)
   3490       info.release(info.data);
   3491   }
   3492   return XML_ERROR_UNKNOWN_ENCODING;
   3493 }
   3494 
   3495 static enum XML_Error PTRCALL
   3496 prologInitProcessor(XML_Parser parser,
   3497                     const char *s,
   3498                     const char *end,
   3499                     const char **nextPtr)
   3500 {
   3501   enum XML_Error result = initializeEncoding(parser);
   3502   if (result != XML_ERROR_NONE)
   3503     return result;
   3504   processor = prologProcessor;
   3505   return prologProcessor(parser, s, end, nextPtr);
   3506 }
   3507 
   3508 #ifdef XML_DTD
   3509 
   3510 static enum XML_Error PTRCALL
   3511 externalParEntInitProcessor(XML_Parser parser,
   3512                             const char *s,
   3513                             const char *end,
   3514                             const char **nextPtr)
   3515 {
   3516   enum XML_Error result = initializeEncoding(parser);
   3517   if (result != XML_ERROR_NONE)
   3518     return result;
   3519 
   3520   /* we know now that XML_Parse(Buffer) has been called,
   3521      so we consider the external parameter entity read */
   3522   _dtd->paramEntityRead = XML_TRUE;
   3523 
   3524   if (prologState.inEntityValue) {
   3525     processor = entityValueInitProcessor;
   3526     return entityValueInitProcessor(parser, s, end, nextPtr);
   3527   }
   3528   else {
   3529     processor = externalParEntProcessor;
   3530     return externalParEntProcessor(parser, s, end, nextPtr);
   3531   }
   3532 }
   3533 
   3534 static enum XML_Error PTRCALL
   3535 entityValueInitProcessor(XML_Parser parser,
   3536                          const char *s,
   3537                          const char *end,
   3538                          const char **nextPtr)
   3539 {
   3540   int tok;
   3541   const char *start = s;
   3542   const char *next = start;
   3543   eventPtr = start;
   3544 
   3545   for (;;) {
   3546     tok = XmlPrologTok(encoding, start, end, &next);
   3547     eventEndPtr = next;
   3548     if (tok <= 0) {
   3549       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
   3550         *nextPtr = s;
   3551         return XML_ERROR_NONE;
   3552       }
   3553       switch (tok) {
   3554       case XML_TOK_INVALID:
   3555         return XML_ERROR_INVALID_TOKEN;
   3556       case XML_TOK_PARTIAL:
   3557         return XML_ERROR_UNCLOSED_TOKEN;
   3558       case XML_TOK_PARTIAL_CHAR:
   3559         return XML_ERROR_PARTIAL_CHAR;
   3560       case XML_TOK_NONE:   /* start == end */
   3561       default:
   3562         break;
   3563       }
   3564       /* found end of entity value - can store it now */
   3565       return storeEntityValue(parser, encoding, s, end);
   3566     }
   3567     else if (tok == XML_TOK_XML_DECL) {
   3568       enum XML_Error result;
   3569       result = processXmlDecl(parser, 0, start, next);
   3570       if (result != XML_ERROR_NONE)
   3571         return result;
   3572       switch (ps_parsing) {
   3573       case XML_SUSPENDED:
   3574         *nextPtr = next;
   3575         return XML_ERROR_NONE;
   3576       case XML_FINISHED:
   3577         return XML_ERROR_ABORTED;
   3578       default:
   3579         *nextPtr = next;
   3580       }
   3581       /* stop scanning for text declaration - we found one */
   3582       processor = entityValueProcessor;
   3583       return entityValueProcessor(parser, next, end, nextPtr);
   3584     }
   3585     /* If we are at the end of the buffer, this would cause XmlPrologTok to
   3586        return XML_TOK_NONE on the next call, which would then cause the
   3587        function to exit with *nextPtr set to s - that is what we want for other
   3588        tokens, but not for the BOM - we would rather like to skip it;
   3589        then, when this routine is entered the next time, XmlPrologTok will
   3590        return XML_TOK_INVALID, since the BOM is still in the buffer
   3591     */
   3592     else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
   3593       *nextPtr = next;
   3594       return XML_ERROR_NONE;
   3595     }
   3596     start = next;
   3597     eventPtr = start;
   3598   }
   3599 }
   3600 
   3601 static enum XML_Error PTRCALL
   3602 externalParEntProcessor(XML_Parser parser,
   3603                         const char *s,
   3604                         const char *end,
   3605                         const char **nextPtr)
   3606 {
   3607   const char *next = s;
   3608   int tok;
   3609 
   3610   tok = XmlPrologTok(encoding, s, end, &next);
   3611   if (tok <= 0) {
   3612     if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
   3613       *nextPtr = s;
   3614       return XML_ERROR_NONE;
   3615     }
   3616     switch (tok) {
   3617     case XML_TOK_INVALID:
   3618       return XML_ERROR_INVALID_TOKEN;
   3619     case XML_TOK_PARTIAL:
   3620       return XML_ERROR_UNCLOSED_TOKEN;
   3621     case XML_TOK_PARTIAL_CHAR:
   3622       return XML_ERROR_PARTIAL_CHAR;
   3623     case XML_TOK_NONE:   /* start == end */
   3624     default:
   3625       break;
   3626     }
   3627   }
   3628   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
   3629      However, when parsing an external subset, doProlog will not accept a BOM
   3630      as valid, and report a syntax error, so we have to skip the BOM
   3631   */
   3632   else if (tok == XML_TOK_BOM) {
   3633     s = next;
   3634     tok = XmlPrologTok(encoding, s, end, &next);
   3635   }
   3636 
   3637   processor = prologProcessor;
   3638   return doProlog(parser, encoding, s, end, tok, next,
   3639                   nextPtr, (XML_Bool)!ps_finalBuffer);
   3640 }
   3641 
   3642 static enum XML_Error PTRCALL
   3643 entityValueProcessor(XML_Parser parser,
   3644                      const char *s,
   3645                      const char *end,
   3646                      const char **nextPtr)
   3647 {
   3648   const char *start = s;
   3649   const char *next = s;
   3650   const ENCODING *enc = encoding;
   3651   int tok;
   3652 
   3653   for (;;) {
   3654     tok = XmlPrologTok(enc, start, end, &next);
   3655     if (tok <= 0) {
   3656       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
   3657         *nextPtr = s;
   3658         return XML_ERROR_NONE;
   3659       }
   3660       switch (tok) {
   3661       case XML_TOK_INVALID:
   3662         return XML_ERROR_INVALID_TOKEN;
   3663       case XML_TOK_PARTIAL:
   3664         return XML_ERROR_UNCLOSED_TOKEN;
   3665       case XML_TOK_PARTIAL_CHAR:
   3666         return XML_ERROR_PARTIAL_CHAR;
   3667       case XML_TOK_NONE:   /* start == end */
   3668       default:
   3669         break;
   3670       }
   3671       /* found end of entity value - can store it now */
   3672       return storeEntityValue(parser, enc, s, end);
   3673     }
   3674     start = next;
   3675   }
   3676 }
   3677 
   3678 #endif /* XML_DTD */
   3679 
   3680 static enum XML_Error PTRCALL
   3681 prologProcessor(XML_Parser parser,
   3682                 const char *s,
   3683                 const char *end,
   3684                 const char **nextPtr)
   3685 {
   3686   const char *next = s;
   3687   int tok = XmlPrologTok(encoding, s, end, &next);
   3688   return doProlog(parser, encoding, s, end, tok, next,
   3689                   nextPtr, (XML_Bool)!ps_finalBuffer);
   3690 }
   3691 
   3692 static enum XML_Error
   3693 doProlog(XML_Parser parser,
   3694          const ENCODING *enc,
   3695          const char *s,
   3696          const char *end,
   3697          int tok,
   3698          const char *next,
   3699          const char **nextPtr,
   3700          XML_Bool haveMore)
   3701 {
   3702 #ifdef XML_DTD
   3703   static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
   3704 #endif /* XML_DTD */
   3705   static const XML_Char atypeCDATA[] =
   3706       { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
   3707   static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
   3708   static const XML_Char atypeIDREF[] =
   3709       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
   3710   static const XML_Char atypeIDREFS[] =
   3711       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
   3712   static const XML_Char atypeENTITY[] =
   3713       { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
   3714   static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
   3715       ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
   3716   static const XML_Char atypeNMTOKEN[] = {
   3717       ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
   3718   static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
   3719       ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
   3720   static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
   3721       ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
   3722   static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
   3723   static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
   3724 
   3725   /* save one level of indirection */
   3726   DTD * const dtd = _dtd;
   3727 
   3728   const char **eventPP;
   3729   const char **eventEndPP;
   3730   enum XML_Content_Quant quant;
   3731 
   3732   if (enc == encoding) {
   3733     eventPP = &eventPtr;
   3734     eventEndPP = &eventEndPtr;
   3735   }
   3736   else {
   3737     eventPP = &(openInternalEntities->internalEventPtr);
   3738     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   3739   }
   3740 
   3741   for (;;) {
   3742     int role;
   3743     XML_Bool handleDefault = XML_TRUE;
   3744     *eventPP = s;
   3745     *eventEndPP = next;
   3746     if (tok <= 0) {
   3747       if (haveMore && tok != XML_TOK_INVALID) {
   3748         *nextPtr = s;
   3749         return XML_ERROR_NONE;
   3750       }
   3751       switch (tok) {
   3752       case XML_TOK_INVALID:
   3753         *eventPP = next;
   3754         return XML_ERROR_INVALID_TOKEN;
   3755       case XML_TOK_PARTIAL:
   3756         return XML_ERROR_UNCLOSED_TOKEN;
   3757       case XML_TOK_PARTIAL_CHAR:
   3758         return XML_ERROR_PARTIAL_CHAR;
   3759       case -XML_TOK_PROLOG_S:
   3760 	tok = -tok;
   3761 	break;
   3762       case XML_TOK_NONE:
   3763 #ifdef XML_DTD
   3764         /* for internal PE NOT referenced between declarations */
   3765         if (enc != encoding && !openInternalEntities->betweenDecl) {
   3766           *nextPtr = s;
   3767           return XML_ERROR_NONE;
   3768         }
   3769         /* WFC: PE Between Declarations - must check that PE contains
   3770            complete markup, not only for external PEs, but also for
   3771            internal PEs if the reference occurs between declarations.
   3772         */
   3773         if (isParamEntity || enc != encoding) {
   3774           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
   3775               == XML_ROLE_ERROR)
   3776             return XML_ERROR_INCOMPLETE_PE;
   3777           *nextPtr = s;
   3778           return XML_ERROR_NONE;
   3779         }
   3780 #endif /* XML_DTD */
   3781         return XML_ERROR_NO_ELEMENTS;
   3782       default:
   3783         tok = -tok;
   3784         next = end;
   3785         break;
   3786       }
   3787     }
   3788     role = XmlTokenRole(&prologState, tok, s, next, enc);
   3789     switch (role) {
   3790     case XML_ROLE_XML_DECL:
   3791       {
   3792         enum XML_Error result = processXmlDecl(parser, 0, s, next);
   3793         if (result != XML_ERROR_NONE)
   3794           return result;
   3795         enc = encoding;
   3796         handleDefault = XML_FALSE;
   3797       }
   3798       break;
   3799     case XML_ROLE_DOCTYPE_NAME:
   3800       if (startDoctypeDeclHandler) {
   3801         doctypeName = poolStoreString(&tempPool, enc, s, next);
   3802         if (!doctypeName)
   3803           return XML_ERROR_NO_MEMORY;
   3804         poolFinish(&tempPool);
   3805         doctypePubid = NULL;
   3806         handleDefault = XML_FALSE;
   3807       }
   3808       doctypeSysid = NULL; /* always initialize to NULL */
   3809       break;
   3810     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
   3811       if (startDoctypeDeclHandler) {
   3812         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
   3813                                 doctypePubid, 1);
   3814         doctypeName = NULL;
   3815         poolClear(&tempPool);
   3816         handleDefault = XML_FALSE;
   3817       }
   3818       break;
   3819 #ifdef XML_DTD
   3820     case XML_ROLE_TEXT_DECL:
   3821       {
   3822         enum XML_Error result = processXmlDecl(parser, 1, s, next);
   3823         if (result != XML_ERROR_NONE)
   3824           return result;
   3825         enc = encoding;
   3826         handleDefault = XML_FALSE;
   3827       }
   3828       break;
   3829 #endif /* XML_DTD */
   3830     case XML_ROLE_DOCTYPE_PUBLIC_ID:
   3831 #ifdef XML_DTD
   3832       useForeignDTD = XML_FALSE;
   3833       declEntity = (ENTITY *)lookup(parser,
   3834                                     &dtd->paramEntities,
   3835                                     externalSubsetName,
   3836                                     sizeof(ENTITY));
   3837       if (!declEntity)
   3838         return XML_ERROR_NO_MEMORY;
   3839 #endif /* XML_DTD */
   3840       dtd->hasParamEntityRefs = XML_TRUE;
   3841       if (startDoctypeDeclHandler) {
   3842         if (!XmlIsPublicId(enc, s, next, eventPP))
   3843           return XML_ERROR_PUBLICID;
   3844         doctypePubid = poolStoreString(&tempPool, enc,
   3845                                        s + enc->minBytesPerChar,
   3846                                        next - enc->minBytesPerChar);
   3847         if (!doctypePubid)
   3848           return XML_ERROR_NO_MEMORY;
   3849         normalizePublicId((XML_Char *)doctypePubid);
   3850         poolFinish(&tempPool);
   3851         handleDefault = XML_FALSE;
   3852         goto alreadyChecked;
   3853       }
   3854       /* fall through */
   3855     case XML_ROLE_ENTITY_PUBLIC_ID:
   3856       if (!XmlIsPublicId(enc, s, next, eventPP))
   3857         return XML_ERROR_PUBLICID;
   3858     alreadyChecked:
   3859       if (dtd->keepProcessing && declEntity) {
   3860         XML_Char *tem = poolStoreString(&dtd->pool,
   3861                                         enc,
   3862                                         s + enc->minBytesPerChar,
   3863                                         next - enc->minBytesPerChar);
   3864         if (!tem)
   3865           return XML_ERROR_NO_MEMORY;
   3866         normalizePublicId(tem);
   3867         declEntity->publicId = tem;
   3868         poolFinish(&dtd->pool);
   3869         if (entityDeclHandler)
   3870           handleDefault = XML_FALSE;
   3871       }
   3872       break;
   3873     case XML_ROLE_DOCTYPE_CLOSE:
   3874       if (doctypeName) {
   3875         startDoctypeDeclHandler(handlerArg, doctypeName,
   3876                                 doctypeSysid, doctypePubid, 0);
   3877         poolClear(&tempPool);
   3878         handleDefault = XML_FALSE;
   3879       }
   3880       /* doctypeSysid will be non-NULL in the case of a previous
   3881          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
   3882          was not set, indicating an external subset
   3883       */
   3884 #ifdef XML_DTD
   3885       if (doctypeSysid || useForeignDTD) {
   3886         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
   3887         dtd->hasParamEntityRefs = XML_TRUE;
   3888         if (paramEntityParsing && externalEntityRefHandler) {
   3889           ENTITY *entity = (ENTITY *)lookup(parser,
   3890                                             &dtd->paramEntities,
   3891                                             externalSubsetName,
   3892                                             sizeof(ENTITY));
   3893           if (!entity)
   3894             return XML_ERROR_NO_MEMORY;
   3895           if (useForeignDTD)
   3896             entity->base = curBase;
   3897           dtd->paramEntityRead = XML_FALSE;
   3898           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
   3899                                         0,
   3900                                         entity->base,
   3901                                         entity->systemId,
   3902                                         entity->publicId))
   3903             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
   3904           if (dtd->paramEntityRead) {
   3905             if (!dtd->standalone &&
   3906                 notStandaloneHandler &&
   3907                 !notStandaloneHandler(handlerArg))
   3908               return XML_ERROR_NOT_STANDALONE;
   3909           }
   3910           /* if we didn't read the foreign DTD then this means that there
   3911              is no external subset and we must reset dtd->hasParamEntityRefs
   3912           */
   3913           else if (!doctypeSysid)
   3914             dtd->hasParamEntityRefs = hadParamEntityRefs;
   3915           /* end of DTD - no need to update dtd->keepProcessing */
   3916         }
   3917         useForeignDTD = XML_FALSE;
   3918       }
   3919 #endif /* XML_DTD */
   3920       if (endDoctypeDeclHandler) {
   3921         endDoctypeDeclHandler(handlerArg);
   3922         handleDefault = XML_FALSE;
   3923       }
   3924       break;
   3925     case XML_ROLE_INSTANCE_START:
   3926 #ifdef XML_DTD
   3927       /* if there is no DOCTYPE declaration then now is the
   3928          last chance to read the foreign DTD
   3929       */
   3930       if (useForeignDTD) {
   3931         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
   3932         dtd->hasParamEntityRefs = XML_TRUE;
   3933         if (paramEntityParsing && externalEntityRefHandler) {
   3934           ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
   3935                                             externalSubsetName,
   3936                                             sizeof(ENTITY));
   3937           if (!entity)
   3938             return XML_ERROR_NO_MEMORY;
   3939           entity->base = curBase;
   3940           dtd->paramEntityRead = XML_FALSE;
   3941           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
   3942                                         0,
   3943                                         entity->base,
   3944                                         entity->systemId,
   3945                                         entity->publicId))
   3946             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
   3947           if (dtd->paramEntityRead) {
   3948             if (!dtd->standalone &&
   3949                 notStandaloneHandler &&
   3950                 !notStandaloneHandler(handlerArg))
   3951               return XML_ERROR_NOT_STANDALONE;
   3952           }
   3953           /* if we didn't read the foreign DTD then this means that there
   3954              is no external subset and we must reset dtd->hasParamEntityRefs
   3955           */
   3956           else
   3957             dtd->hasParamEntityRefs = hadParamEntityRefs;
   3958           /* end of DTD - no need to update dtd->keepProcessing */
   3959         }
   3960       }
   3961 #endif /* XML_DTD */
   3962       processor = contentProcessor;
   3963       return contentProcessor(parser, s, end, nextPtr);
   3964     case XML_ROLE_ATTLIST_ELEMENT_NAME:
   3965       declElementType = getElementType(parser, enc, s, next);
   3966       if (!declElementType)
   3967         return XML_ERROR_NO_MEMORY;
   3968       goto checkAttListDeclHandler;
   3969     case XML_ROLE_ATTRIBUTE_NAME:
   3970       declAttributeId = getAttributeId(parser, enc, s, next);
   3971       if (!declAttributeId)
   3972         return XML_ERROR_NO_MEMORY;
   3973       declAttributeIsCdata = XML_FALSE;
   3974       declAttributeType = NULL;
   3975       declAttributeIsId = XML_FALSE;
   3976       goto checkAttListDeclHandler;
   3977     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
   3978       declAttributeIsCdata = XML_TRUE;
   3979       declAttributeType = atypeCDATA;
   3980       goto checkAttListDeclHandler;
   3981     case XML_ROLE_ATTRIBUTE_TYPE_ID:
   3982       declAttributeIsId = XML_TRUE;
   3983       declAttributeType = atypeID;
   3984       goto checkAttListDeclHandler;
   3985     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
   3986       declAttributeType = atypeIDREF;
   3987       goto checkAttListDeclHandler;
   3988     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
   3989       declAttributeType = atypeIDREFS;
   3990       goto checkAttListDeclHandler;
   3991     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
   3992       declAttributeType = atypeENTITY;
   3993       goto checkAttListDeclHandler;
   3994     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
   3995       declAttributeType = atypeENTITIES;
   3996       goto checkAttListDeclHandler;
   3997     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
   3998       declAttributeType = atypeNMTOKEN;
   3999       goto checkAttListDeclHandler;
   4000     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
   4001       declAttributeType = atypeNMTOKENS;
   4002     checkAttListDeclHandler:
   4003       if (dtd->keepProcessing && attlistDeclHandler)
   4004         handleDefault = XML_FALSE;
   4005       break;
   4006     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
   4007     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
   4008       if (dtd->keepProcessing && attlistDeclHandler) {
   4009         const XML_Char *prefix;
   4010         if (declAttributeType) {
   4011           prefix = enumValueSep;
   4012         }
   4013         else {
   4014           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
   4015                     ? notationPrefix
   4016                     : enumValueStart);
   4017         }
   4018         if (!poolAppendString(&tempPool, prefix))
   4019           return XML_ERROR_NO_MEMORY;
   4020         if (!poolAppend(&tempPool, enc, s, next))
   4021           return XML_ERROR_NO_MEMORY;
   4022         declAttributeType = tempPool.start;
   4023         handleDefault = XML_FALSE;
   4024       }
   4025       break;
   4026     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
   4027     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
   4028       if (dtd->keepProcessing) {
   4029         if (!defineAttribute(declElementType, declAttributeId,
   4030                              declAttributeIsCdata, declAttributeIsId,
   4031                              0, parser))
   4032           return XML_ERROR_NO_MEMORY;
   4033         if (attlistDeclHandler && declAttributeType) {
   4034           if (*declAttributeType == XML_T(ASCII_LPAREN)
   4035               || (*declAttributeType == XML_T(ASCII_N)
   4036                   && declAttributeType[1] == XML_T(ASCII_O))) {
   4037             /* Enumerated or Notation type */
   4038             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
   4039                 || !poolAppendChar(&tempPool, XML_T('\0')))
   4040               return XML_ERROR_NO_MEMORY;
   4041             declAttributeType = tempPool.start;
   4042             poolFinish(&tempPool);
   4043           }
   4044           *eventEndPP = s;
   4045           attlistDeclHandler(handlerArg, declElementType->name,
   4046                              declAttributeId->name, declAttributeType,
   4047                              0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
   4048           poolClear(&tempPool);
   4049           handleDefault = XML_FALSE;
   4050         }
   4051       }
   4052       break;
   4053     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
   4054     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
   4055       if (dtd->keepProcessing) {
   4056         const XML_Char *attVal;
   4057         enum XML_Error result =
   4058           storeAttributeValue(parser, enc, declAttributeIsCdata,
   4059                               s + enc->minBytesPerChar,
   4060                               next - enc->minBytesPerChar,
   4061                               &dtd->pool);
   4062         if (result)
   4063           return result;
   4064         attVal = poolStart(&dtd->pool);
   4065         poolFinish(&dtd->pool);
   4066         /* ID attributes aren't allowed to have a default */
   4067         if (!defineAttribute(declElementType, declAttributeId,
   4068                              declAttributeIsCdata, XML_FALSE, attVal, parser))
   4069           return XML_ERROR_NO_MEMORY;
   4070         if (attlistDeclHandler && declAttributeType) {
   4071           if (*declAttributeType == XML_T(ASCII_LPAREN)
   4072               || (*declAttributeType == XML_T(ASCII_N)
   4073                   && declAttributeType[1] == XML_T(ASCII_O))) {
   4074             /* Enumerated or Notation type */
   4075             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
   4076                 || !poolAppendChar(&tempPool, XML_T('\0')))
   4077               return XML_ERROR_NO_MEMORY;
   4078             declAttributeType = tempPool.start;
   4079             poolFinish(&tempPool);
   4080           }
   4081           *eventEndPP = s;
   4082           attlistDeclHandler(handlerArg, declElementType->name,
   4083                              declAttributeId->name, declAttributeType,
   4084                              attVal,
   4085                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
   4086           poolClear(&tempPool);
   4087           handleDefault = XML_FALSE;
   4088         }
   4089       }
   4090       break;
   4091     case XML_ROLE_ENTITY_VALUE:
   4092       if (dtd->keepProcessing) {
   4093         enum XML_Error result = storeEntityValue(parser, enc,
   4094                                             s + enc->minBytesPerChar,
   4095                                             next - enc->minBytesPerChar);
   4096         if (declEntity) {
   4097           declEntity->textPtr = poolStart(&dtd->entityValuePool);
   4098           declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
   4099           poolFinish(&dtd->entityValuePool);
   4100           if (entityDeclHandler) {
   4101             *eventEndPP = s;
   4102             entityDeclHandler(handlerArg,
   4103                               declEntity->name,
   4104                               declEntity->is_param,
   4105                               declEntity->textPtr,
   4106                               declEntity->textLen,
   4107                               curBase, 0, 0, 0);
   4108             handleDefault = XML_FALSE;
   4109           }
   4110         }
   4111         else
   4112           poolDiscard(&dtd->entityValuePool);
   4113         if (result != XML_ERROR_NONE)
   4114           return result;
   4115       }
   4116       break;
   4117     case XML_ROLE_DOCTYPE_SYSTEM_ID:
   4118 #ifdef XML_DTD
   4119       useForeignDTD = XML_FALSE;
   4120 #endif /* XML_DTD */
   4121       dtd->hasParamEntityRefs = XML_TRUE;
   4122       if (startDoctypeDeclHandler) {
   4123         doctypeSysid = poolStoreString(&tempPool, enc,
   4124                                        s + enc->minBytesPerChar,
   4125                                        next - enc->minBytesPerChar);
   4126         if (doctypeSysid == NULL)
   4127           return XML_ERROR_NO_MEMORY;
   4128         poolFinish(&tempPool);
   4129         handleDefault = XML_FALSE;
   4130       }
   4131 #ifdef XML_DTD
   4132       else
   4133         /* use externalSubsetName to make doctypeSysid non-NULL
   4134            for the case where no startDoctypeDeclHandler is set */
   4135         doctypeSysid = externalSubsetName;
   4136 #endif /* XML_DTD */
   4137       if (!dtd->standalone
   4138 #ifdef XML_DTD
   4139           && !paramEntityParsing
   4140 #endif /* XML_DTD */
   4141           && notStandaloneHandler
   4142           && !notStandaloneHandler(handlerArg))
   4143         return XML_ERROR_NOT_STANDALONE;
   4144 #ifndef XML_DTD
   4145       break;
   4146 #else /* XML_DTD */
   4147       if (!declEntity) {
   4148         declEntity = (ENTITY *)lookup(parser,
   4149                                       &dtd->paramEntities,
   4150                                       externalSubsetName,
   4151                                       sizeof(ENTITY));
   4152         if (!declEntity)
   4153           return XML_ERROR_NO_MEMORY;
   4154         declEntity->publicId = NULL;
   4155       }
   4156       /* fall through */
   4157 #endif /* XML_DTD */
   4158     case XML_ROLE_ENTITY_SYSTEM_ID:
   4159       if (dtd->keepProcessing && declEntity) {
   4160         declEntity->systemId = poolStoreString(&dtd->pool, enc,
   4161                                                s + enc->minBytesPerChar,
   4162                                                next - enc->minBytesPerChar);
   4163         if (!declEntity->systemId)
   4164           return XML_ERROR_NO_MEMORY;
   4165         declEntity->base = curBase;
   4166         poolFinish(&dtd->pool);
   4167         if (entityDeclHandler)
   4168           handleDefault = XML_FALSE;
   4169       }
   4170       break;
   4171     case XML_ROLE_ENTITY_COMPLETE:
   4172       if (dtd->keepProcessing && declEntity && entityDeclHandler) {
   4173         *eventEndPP = s;
   4174         entityDeclHandler(handlerArg,
   4175                           declEntity->name,
   4176                           declEntity->is_param,
   4177                           0,0,
   4178                           declEntity->base,
   4179                           declEntity->systemId,
   4180                           declEntity->publicId,
   4181                           0);
   4182         handleDefault = XML_FALSE;
   4183       }
   4184       break;
   4185     case XML_ROLE_ENTITY_NOTATION_NAME:
   4186       if (dtd->keepProcessing && declEntity) {
   4187         declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
   4188         if (!declEntity->notation)
   4189           return XML_ERROR_NO_MEMORY;
   4190         poolFinish(&dtd->pool);
   4191         if (unparsedEntityDeclHandler) {
   4192           *eventEndPP = s;
   4193           unparsedEntityDeclHandler(handlerArg,
   4194                                     declEntity->name,
   4195                                     declEntity->base,
   4196                                     declEntity->systemId,
   4197                                     declEntity->publicId,
   4198                                     declEntity->notation);
   4199           handleDefault = XML_FALSE;
   4200         }
   4201         else if (entityDeclHandler) {
   4202           *eventEndPP = s;
   4203           entityDeclHandler(handlerArg,
   4204                             declEntity->name,
   4205                             0,0,0,
   4206                             declEntity->base,
   4207                             declEntity->systemId,
   4208                             declEntity->publicId,
   4209                             declEntity->notation);
   4210           handleDefault = XML_FALSE;
   4211         }
   4212       }
   4213       break;
   4214     case XML_ROLE_GENERAL_ENTITY_NAME:
   4215       {
   4216         if (XmlPredefinedEntityName(enc, s, next)) {
   4217           declEntity = NULL;
   4218           break;
   4219         }
   4220         if (dtd->keepProcessing) {
   4221           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
   4222           if (!name)
   4223             return XML_ERROR_NO_MEMORY;
   4224           declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
   4225                                         sizeof(ENTITY));
   4226           if (!declEntity)
   4227             return XML_ERROR_NO_MEMORY;
   4228           if (declEntity->name != name) {
   4229             poolDiscard(&dtd->pool);
   4230             declEntity = NULL;
   4231           }
   4232           else {
   4233             poolFinish(&dtd->pool);
   4234             declEntity->publicId = NULL;
   4235             declEntity->is_param = XML_FALSE;
   4236             /* if we have a parent parser or are reading an internal parameter
   4237                entity, then the entity declaration is not considered "internal"
   4238             */
   4239             declEntity->is_internal = !(parentParser || openInternalEntities);
   4240             if (entityDeclHandler)
   4241               handleDefault = XML_FALSE;
   4242           }
   4243         }
   4244         else {
   4245           poolDiscard(&dtd->pool);
   4246           declEntity = NULL;
   4247         }
   4248       }
   4249       break;
   4250     case XML_ROLE_PARAM_ENTITY_NAME:
   4251 #ifdef XML_DTD
   4252       if (dtd->keepProcessing) {
   4253         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
   4254         if (!name)
   4255           return XML_ERROR_NO_MEMORY;
   4256         declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
   4257                                            name, sizeof(ENTITY));
   4258         if (!declEntity)
   4259           return XML_ERROR_NO_MEMORY;
   4260         if (declEntity->name != name) {
   4261           poolDiscard(&dtd->pool);
   4262           declEntity = NULL;
   4263         }
   4264         else {
   4265           poolFinish(&dtd->pool);
   4266           declEntity->publicId = NULL;
   4267           declEntity->is_param = XML_TRUE;
   4268           /* if we have a parent parser or are reading an internal parameter
   4269              entity, then the entity declaration is not considered "internal"
   4270           */
   4271           declEntity->is_internal = !(parentParser || openInternalEntities);
   4272           if (entityDeclHandler)
   4273             handleDefault = XML_FALSE;
   4274         }
   4275       }
   4276       else {
   4277         poolDiscard(&dtd->pool);
   4278         declEntity = NULL;
   4279       }
   4280 #else /* not XML_DTD */
   4281       declEntity = NULL;
   4282 #endif /* XML_DTD */
   4283       break;
   4284     case XML_ROLE_NOTATION_NAME:
   4285       declNotationPublicId = NULL;
   4286       declNotationName = NULL;
   4287       if (notationDeclHandler) {
   4288         declNotationName = poolStoreString(&tempPool, enc, s, next);
   4289         if (!declNotationName)
   4290           return XML_ERROR_NO_MEMORY;
   4291         poolFinish(&tempPool);
   4292         handleDefault = XML_FALSE;
   4293       }
   4294       break;
   4295     case XML_ROLE_NOTATION_PUBLIC_ID:
   4296       if (!XmlIsPublicId(enc, s, next, eventPP))
   4297         return XML_ERROR_PUBLICID;
   4298       if (declNotationName) {  /* means notationDeclHandler != NULL */
   4299         XML_Char *tem = poolStoreString(&tempPool,
   4300                                         enc,
   4301                                         s + enc->minBytesPerChar,
   4302                                         next - enc->minBytesPerChar);
   4303         if (!tem)
   4304           return XML_ERROR_NO_MEMORY;
   4305         normalizePublicId(tem);
   4306         declNotationPublicId = tem;
   4307         poolFinish(&tempPool);
   4308         handleDefault = XML_FALSE;
   4309       }
   4310       break;
   4311     case XML_ROLE_NOTATION_SYSTEM_ID:
   4312       if (declNotationName && notationDeclHandler) {
   4313         const XML_Char *systemId
   4314           = poolStoreString(&tempPool, enc,
   4315                             s + enc->minBytesPerChar,
   4316                             next - enc->minBytesPerChar);
   4317         if (!systemId)
   4318           return XML_ERROR_NO_MEMORY;
   4319         *eventEndPP = s;
   4320         notationDeclHandler(handlerArg,
   4321                             declNotationName,
   4322                             curBase,
   4323                             systemId,
   4324                             declNotationPublicId);
   4325         handleDefault = XML_FALSE;
   4326       }
   4327       poolClear(&tempPool);
   4328       break;
   4329     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
   4330       if (declNotationPublicId && notationDeclHandler) {
   4331         *eventEndPP = s;
   4332         notationDeclHandler(handlerArg,
   4333                             declNotationName,
   4334                             curBase,
   4335                             0,
   4336                             declNotationPublicId);
   4337         handleDefault = XML_FALSE;
   4338       }
   4339       poolClear(&tempPool);
   4340       break;
   4341     case XML_ROLE_ERROR:
   4342       switch (tok) {
   4343       case XML_TOK_PARAM_ENTITY_REF:
   4344         /* PE references in internal subset are
   4345            not allowed within declarations. */
   4346         return XML_ERROR_PARAM_ENTITY_REF;
   4347       case XML_TOK_XML_DECL:
   4348         return XML_ERROR_MISPLACED_XML_PI;
   4349       default:
   4350         return XML_ERROR_SYNTAX;
   4351       }
   4352 #ifdef XML_DTD
   4353     case XML_ROLE_IGNORE_SECT:
   4354       {
   4355         enum XML_Error result;
   4356         if (defaultHandler)
   4357           reportDefault(parser, enc, s, next);
   4358         handleDefault = XML_FALSE;
   4359         result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
   4360         if (result != XML_ERROR_NONE)
   4361           return result;
   4362         else if (!next) {
   4363           processor = ignoreSectionProcessor;
   4364           return result;
   4365         }
   4366       }
   4367       break;
   4368 #endif /* XML_DTD */
   4369     case XML_ROLE_GROUP_OPEN:
   4370       if (prologState.level >= groupSize) {
   4371         if (groupSize) {
   4372           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
   4373           if (temp == NULL)
   4374             return XML_ERROR_NO_MEMORY;
   4375           groupConnector = temp;
   4376           if (dtd->scaffIndex) {
   4377             int *temp = (int *)REALLOC(dtd->scaffIndex,
   4378                           groupSize * sizeof(int));
   4379             if (temp == NULL)
   4380               return XML_ERROR_NO_MEMORY;
   4381             dtd->scaffIndex = temp;
   4382           }
   4383         }
   4384         else {
   4385           groupConnector = (char *)MALLOC(groupSize = 32);
   4386           if (!groupConnector)
   4387             return XML_ERROR_NO_MEMORY;
   4388         }
   4389       }
   4390       groupConnector[prologState.level] = 0;
   4391       if (dtd->in_eldecl) {
   4392         int myindex = nextScaffoldPart(parser);
   4393         if (myindex < 0)
   4394           return XML_ERROR_NO_MEMORY;
   4395         dtd->scaffIndex[dtd->scaffLevel] = myindex;
   4396         dtd->scaffLevel++;
   4397         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
   4398         if (elementDeclHandler)
   4399           handleDefault = XML_FALSE;
   4400       }
   4401       break;
   4402     case XML_ROLE_GROUP_SEQUENCE:
   4403       if (groupConnector[prologState.level] == ASCII_PIPE)
   4404         return XML_ERROR_SYNTAX;
   4405       groupConnector[prologState.level] = ASCII_COMMA;
   4406       if (dtd->in_eldecl && elementDeclHandler)
   4407         handleDefault = XML_FALSE;
   4408       break;
   4409     case XML_ROLE_GROUP_CHOICE:
   4410       if (groupConnector[prologState.level] == ASCII_COMMA)
   4411         return XML_ERROR_SYNTAX;
   4412       if (dtd->in_eldecl
   4413           && !groupConnector[prologState.level]
   4414           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
   4415               != XML_CTYPE_MIXED)
   4416           ) {
   4417         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
   4418             = XML_CTYPE_CHOICE;
   4419         if (elementDeclHandler)
   4420           handleDefault = XML_FALSE;
   4421       }
   4422       groupConnector[prologState.level] = ASCII_PIPE;
   4423       break;
   4424     case XML_ROLE_PARAM_ENTITY_REF:
   4425 #ifdef XML_DTD
   4426     case XML_ROLE_INNER_PARAM_ENTITY_REF:
   4427       dtd->hasParamEntityRefs = XML_TRUE;
   4428       if (!paramEntityParsing)
   4429         dtd->keepProcessing = dtd->standalone;
   4430       else {
   4431         const XML_Char *name;
   4432         ENTITY *entity;
   4433         name = poolStoreString(&dtd->pool, enc,
   4434                                 s + enc->minBytesPerChar,
   4435                                 next - enc->minBytesPerChar);
   4436         if (!name)
   4437           return XML_ERROR_NO_MEMORY;
   4438         entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
   4439         poolDiscard(&dtd->pool);
   4440         /* first, determine if a check for an existing declaration is needed;
   4441            if yes, check that the entity exists, and that it is internal,
   4442            otherwise call the skipped entity handler
   4443         */
   4444         if (prologState.documentEntity &&
   4445             (dtd->standalone
   4446              ? !openInternalEntities
   4447              : !dtd->hasParamEntityRefs)) {
   4448           if (!entity)
   4449             return XML_ERROR_UNDEFINED_ENTITY;
   4450           else if (!entity->is_internal)
   4451             return XML_ERROR_ENTITY_DECLARED_IN_PE;
   4452         }
   4453         else if (!entity) {
   4454           dtd->keepProcessing = dtd->standalone;
   4455           /* cannot report skipped entities in declarations */
   4456           if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
   4457             skippedEntityHandler(handlerArg, name, 1);
   4458             handleDefault = XML_FALSE;
   4459           }
   4460           break;
   4461         }
   4462         if (entity->open)
   4463           return XML_ERROR_RECURSIVE_ENTITY_REF;
   4464         if (entity->textPtr) {
   4465           enum XML_Error result;
   4466           XML_Bool betweenDecl =
   4467             (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
   4468           result = processInternalEntity(parser, entity, betweenDecl);
   4469           if (result != XML_ERROR_NONE)
   4470             return result;
   4471           handleDefault = XML_FALSE;
   4472           break;
   4473         }
   4474         if (externalEntityRefHandler) {
   4475           dtd->paramEntityRead = XML_FALSE;
   4476           entity->open = XML_TRUE;
   4477           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
   4478                                         0,
   4479                                         entity->base,
   4480                                         entity->systemId,
   4481                                         entity->publicId)) {
   4482             entity->open = XML_FALSE;
   4483             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
   4484           }
   4485           entity->open = XML_FALSE;
   4486           handleDefault = XML_FALSE;
   4487           if (!dtd->paramEntityRead) {
   4488             dtd->keepProcessing = dtd->standalone;
   4489             break;
   4490           }
   4491         }
   4492         else {
   4493           dtd->keepProcessing = dtd->standalone;
   4494           break;
   4495         }
   4496       }
   4497 #endif /* XML_DTD */
   4498       if (!dtd->standalone &&
   4499           notStandaloneHandler &&
   4500           !notStandaloneHandler(handlerArg))
   4501         return XML_ERROR_NOT_STANDALONE;
   4502       break;
   4503 
   4504     /* Element declaration stuff */
   4505 
   4506     case XML_ROLE_ELEMENT_NAME:
   4507       if (elementDeclHandler) {
   4508         declElementType = getElementType(parser, enc, s, next);
   4509         if (!declElementType)
   4510           return XML_ERROR_NO_MEMORY;
   4511         dtd->scaffLevel = 0;
   4512         dtd->scaffCount = 0;
   4513         dtd->in_eldecl = XML_TRUE;
   4514         handleDefault = XML_FALSE;
   4515       }
   4516       break;
   4517 
   4518     case XML_ROLE_CONTENT_ANY:
   4519     case XML_ROLE_CONTENT_EMPTY:
   4520       if (dtd->in_eldecl) {
   4521         if (elementDeclHandler) {
   4522           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
   4523           if (!content)
   4524             return XML_ERROR_NO_MEMORY;
   4525           content->quant = XML_CQUANT_NONE;
   4526           content->name = NULL;
   4527           content->numchildren = 0;
   4528           content->children = NULL;
   4529           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
   4530                            XML_CTYPE_ANY :
   4531                            XML_CTYPE_EMPTY);
   4532           *eventEndPP = s;
   4533           elementDeclHandler(handlerArg, declElementType->name, content);
   4534           handleDefault = XML_FALSE;
   4535         }
   4536         dtd->in_eldecl = XML_FALSE;
   4537       }
   4538       break;
   4539 
   4540     case XML_ROLE_CONTENT_PCDATA:
   4541       if (dtd->in_eldecl) {
   4542         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
   4543             = XML_CTYPE_MIXED;
   4544         if (elementDeclHandler)
   4545           handleDefault = XML_FALSE;
   4546       }
   4547       break;
   4548 
   4549     case XML_ROLE_CONTENT_ELEMENT:
   4550       quant = XML_CQUANT_NONE;
   4551       goto elementContent;
   4552     case XML_ROLE_CONTENT_ELEMENT_OPT:
   4553       quant = XML_CQUANT_OPT;
   4554       goto elementContent;
   4555     case XML_ROLE_CONTENT_ELEMENT_REP:
   4556       quant = XML_CQUANT_REP;
   4557       goto elementContent;
   4558     case XML_ROLE_CONTENT_ELEMENT_PLUS:
   4559       quant = XML_CQUANT_PLUS;
   4560     elementContent:
   4561       if (dtd->in_eldecl) {
   4562         ELEMENT_TYPE *el;
   4563         const XML_Char *name;
   4564         int nameLen;
   4565         const char *nxt = (quant == XML_CQUANT_NONE
   4566                            ? next
   4567                            : next - enc->minBytesPerChar);
   4568         int myindex = nextScaffoldPart(parser);
   4569         if (myindex < 0)
   4570           return XML_ERROR_NO_MEMORY;
   4571         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
   4572         dtd->scaffold[myindex].quant = quant;
   4573         el = getElementType(parser, enc, s, nxt);
   4574         if (!el)
   4575           return XML_ERROR_NO_MEMORY;
   4576         name = el->name;
   4577         dtd->scaffold[myindex].name = name;
   4578         nameLen = 0;
   4579         for (; name[nameLen++]; );
   4580         dtd->contentStringLen +=  nameLen;
   4581         if (elementDeclHandler)
   4582           handleDefault = XML_FALSE;
   4583       }
   4584       break;
   4585 
   4586     case XML_ROLE_GROUP_CLOSE:
   4587       quant = XML_CQUANT_NONE;
   4588       goto closeGroup;
   4589     case XML_ROLE_GROUP_CLOSE_OPT:
   4590       quant = XML_CQUANT_OPT;
   4591       goto closeGroup;
   4592     case XML_ROLE_GROUP_CLOSE_REP:
   4593       quant = XML_CQUANT_REP;
   4594       goto closeGroup;
   4595     case XML_ROLE_GROUP_CLOSE_PLUS:
   4596       quant = XML_CQUANT_PLUS;
   4597     closeGroup:
   4598       if (dtd->in_eldecl) {
   4599         if (elementDeclHandler)
   4600           handleDefault = XML_FALSE;
   4601         dtd->scaffLevel--;
   4602         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
   4603         if (dtd->scaffLevel == 0) {
   4604           if (!handleDefault) {
   4605             XML_Content *model = build_model(parser);
   4606             if (!model)
   4607               return XML_ERROR_NO_MEMORY;
   4608             *eventEndPP = s;
   4609             elementDeclHandler(handlerArg, declElementType->name, model);
   4610           }
   4611           dtd->in_eldecl = XML_FALSE;
   4612           dtd->contentStringLen = 0;
   4613         }
   4614       }
   4615       break;
   4616       /* End element declaration stuff */
   4617 
   4618     case XML_ROLE_PI:
   4619       if (!reportProcessingInstruction(parser, enc, s, next))
   4620         return XML_ERROR_NO_MEMORY;
   4621       handleDefault = XML_FALSE;
   4622       break;
   4623     case XML_ROLE_COMMENT:
   4624       if (!reportComment(parser, enc, s, next))
   4625         return XML_ERROR_NO_MEMORY;
   4626       handleDefault = XML_FALSE;
   4627       break;
   4628     case XML_ROLE_NONE:
   4629       switch (tok) {
   4630       case XML_TOK_BOM:
   4631         handleDefault = XML_FALSE;
   4632         break;
   4633       }
   4634       break;
   4635     case XML_ROLE_DOCTYPE_NONE:
   4636       if (startDoctypeDeclHandler)
   4637         handleDefault = XML_FALSE;
   4638       break;
   4639     case XML_ROLE_ENTITY_NONE:
   4640       if (dtd->keepProcessing && entityDeclHandler)
   4641         handleDefault = XML_FALSE;
   4642       break;
   4643     case XML_ROLE_NOTATION_NONE:
   4644       if (notationDeclHandler)
   4645         handleDefault = XML_FALSE;
   4646       break;
   4647     case XML_ROLE_ATTLIST_NONE:
   4648       if (dtd->keepProcessing && attlistDeclHandler)
   4649         handleDefault = XML_FALSE;
   4650       break;
   4651     case XML_ROLE_ELEMENT_NONE:
   4652       if (elementDeclHandler)
   4653         handleDefault = XML_FALSE;
   4654       break;
   4655     } /* end of big switch */
   4656 
   4657     if (handleDefault && defaultHandler)
   4658       reportDefault(parser, enc, s, next);
   4659 
   4660     switch (ps_parsing) {
   4661     case XML_SUSPENDED:
   4662       *nextPtr = next;
   4663       return XML_ERROR_NONE;
   4664     case XML_FINISHED:
   4665       return XML_ERROR_ABORTED;
   4666     default:
   4667       s = next;
   4668       tok = XmlPrologTok(enc, s, end, &next);
   4669     }
   4670   }
   4671   /* not reached */
   4672 }
   4673 
   4674 static enum XML_Error PTRCALL
   4675 epilogProcessor(XML_Parser parser,
   4676                 const char *s,
   4677                 const char *end,
   4678                 const char **nextPtr)
   4679 {
   4680   processor = epilogProcessor;
   4681   eventPtr = s;
   4682   for (;;) {
   4683     const char *next = NULL;
   4684     int tok = XmlPrologTok(encoding, s, end, &next);
   4685     eventEndPtr = next;
   4686     switch (tok) {
   4687     /* report partial linebreak - it might be the last token */
   4688     case -XML_TOK_PROLOG_S:
   4689       if (defaultHandler) {
   4690         reportDefault(parser, encoding, s, next);
   4691         if (ps_parsing == XML_FINISHED)
   4692           return XML_ERROR_ABORTED;
   4693       }
   4694       *nextPtr = next;
   4695       return XML_ERROR_NONE;
   4696     case XML_TOK_NONE:
   4697       *nextPtr = s;
   4698       return XML_ERROR_NONE;
   4699     case XML_TOK_PROLOG_S:
   4700       if (defaultHandler)
   4701         reportDefault(parser, encoding, s, next);
   4702       break;
   4703     case XML_TOK_PI:
   4704       if (!reportProcessingInstruction(parser, encoding, s, next))
   4705         return XML_ERROR_NO_MEMORY;
   4706       break;
   4707     case XML_TOK_COMMENT:
   4708       if (!reportComment(parser, encoding, s, next))
   4709         return XML_ERROR_NO_MEMORY;
   4710       break;
   4711     case XML_TOK_INVALID:
   4712       eventPtr = next;
   4713       return XML_ERROR_INVALID_TOKEN;
   4714     case XML_TOK_PARTIAL:
   4715       if (!ps_finalBuffer) {
   4716         *nextPtr = s;
   4717         return XML_ERROR_NONE;
   4718       }
   4719       return XML_ERROR_UNCLOSED_TOKEN;
   4720     case XML_TOK_PARTIAL_CHAR:
   4721       if (!ps_finalBuffer) {
   4722         *nextPtr = s;
   4723         return XML_ERROR_NONE;
   4724       }
   4725       return XML_ERROR_PARTIAL_CHAR;
   4726     default:
   4727       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
   4728     }
   4729     eventPtr = s = next;
   4730     switch (ps_parsing) {
   4731     case XML_SUSPENDED:
   4732       *nextPtr = next;
   4733       return XML_ERROR_NONE;
   4734     case XML_FINISHED:
   4735       return XML_ERROR_ABORTED;
   4736     default: ;
   4737     }
   4738   }
   4739 }
   4740 
   4741 static enum XML_Error
   4742 processInternalEntity(XML_Parser parser, ENTITY *entity,
   4743                       XML_Bool betweenDecl)
   4744 {
   4745   const char *textStart, *textEnd;
   4746   const char *next;
   4747   enum XML_Error result;
   4748   OPEN_INTERNAL_ENTITY *openEntity;
   4749 
   4750   if (freeInternalEntities) {
   4751     openEntity = freeInternalEntities;
   4752     freeInternalEntities = openEntity->next;
   4753   }
   4754   else {
   4755     openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
   4756     if (!openEntity)
   4757       return XML_ERROR_NO_MEMORY;
   4758   }
   4759   entity->open = XML_TRUE;
   4760   entity->processed = 0;
   4761   openEntity->next = openInternalEntities;
   4762   openInternalEntities = openEntity;
   4763   openEntity->entity = entity;
   4764   openEntity->startTagLevel = tagLevel;
   4765   openEntity->betweenDecl = betweenDecl;
   4766   openEntity->internalEventPtr = NULL;
   4767   openEntity->internalEventEndPtr = NULL;
   4768   textStart = (char *)entity->textPtr;
   4769   textEnd = (char *)(entity->textPtr + entity->textLen);
   4770 
   4771 #ifdef XML_DTD
   4772   if (entity->is_param) {
   4773     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
   4774     result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
   4775                       next, &next, XML_FALSE);
   4776   }
   4777   else
   4778 #endif /* XML_DTD */
   4779     result = doContent(parser, tagLevel, internalEncoding, textStart,
   4780                        textEnd, &next, XML_FALSE);
   4781 
   4782   if (result == XML_ERROR_NONE) {
   4783     if (textEnd != next && ps_parsing == XML_SUSPENDED) {
   4784       entity->processed = (int)(next - textStart);
   4785       processor = internalEntityProcessor;
   4786     }
   4787     else {
   4788       entity->open = XML_FALSE;
   4789       openInternalEntities = openEntity->next;
   4790       /* put openEntity back in list of free instances */
   4791       openEntity->next = freeInternalEntities;
   4792       freeInternalEntities = openEntity;
   4793     }
   4794   }
   4795   return result;
   4796 }
   4797 
   4798 static enum XML_Error PTRCALL
   4799 internalEntityProcessor(XML_Parser parser,
   4800                         const char *s,
   4801                         const char *end,
   4802                         const char **nextPtr)
   4803 {
   4804   ENTITY *entity;
   4805   const char *textStart, *textEnd;
   4806   const char *next;
   4807   enum XML_Error result;
   4808   OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
   4809   if (!openEntity)
   4810     return XML_ERROR_UNEXPECTED_STATE;
   4811 
   4812   entity = openEntity->entity;
   4813   textStart = ((char *)entity->textPtr) + entity->processed;
   4814   textEnd = (char *)(entity->textPtr + entity->textLen);
   4815 
   4816 #ifdef XML_DTD
   4817   if (entity->is_param) {
   4818     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
   4819     result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
   4820                       next, &next, XML_FALSE);
   4821   }
   4822   else
   4823 #endif /* XML_DTD */
   4824     result = doContent(parser, openEntity->startTagLevel, internalEncoding,
   4825                        textStart, textEnd, &next, XML_FALSE);
   4826 
   4827   if (result != XML_ERROR_NONE)
   4828     return result;
   4829   else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
   4830     entity->processed = (int)(next - (char *)entity->textPtr);
   4831     return result;
   4832   }
   4833   else {
   4834     entity->open = XML_FALSE;
   4835     openInternalEntities = openEntity->next;
   4836     /* put openEntity back in list of free instances */
   4837     openEntity->next = freeInternalEntities;
   4838     freeInternalEntities = openEntity;
   4839   }
   4840 
   4841 #ifdef XML_DTD
   4842   if (entity->is_param) {
   4843     int tok;
   4844     processor = prologProcessor;
   4845     tok = XmlPrologTok(encoding, s, end, &next);
   4846     return doProlog(parser, encoding, s, end, tok, next, nextPtr,
   4847                     (XML_Bool)!ps_finalBuffer);
   4848   }
   4849   else
   4850 #endif /* XML_DTD */
   4851   {
   4852     processor = contentProcessor;
   4853     /* see externalEntityContentProcessor vs contentProcessor */
   4854     return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
   4855                      nextPtr, (XML_Bool)!ps_finalBuffer);
   4856   }
   4857 }
   4858 
   4859 static enum XML_Error PTRCALL
   4860 errorProcessor(XML_Parser parser,
   4861                const char *s,
   4862                const char *end,
   4863                const char **nextPtr)
   4864 {
   4865   return errorCode;
   4866 }
   4867 
   4868 static enum XML_Error
   4869 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
   4870                     const char *ptr, const char *end,
   4871                     STRING_POOL *pool)
   4872 {
   4873   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
   4874                                                end, pool);
   4875   if (result)
   4876     return result;
   4877   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
   4878     poolChop(pool);
   4879   if (!poolAppendChar(pool, XML_T('\0')))
   4880     return XML_ERROR_NO_MEMORY;
   4881   return XML_ERROR_NONE;
   4882 }
   4883 
   4884 static enum XML_Error
   4885 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
   4886                      const char *ptr, const char *end,
   4887                      STRING_POOL *pool)
   4888 {
   4889   DTD * const dtd = _dtd;  /* save one level of indirection */
   4890   for (;;) {
   4891     const char *next;
   4892     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
   4893     switch (tok) {
   4894     case XML_TOK_NONE:
   4895       return XML_ERROR_NONE;
   4896     case XML_TOK_INVALID:
   4897       if (enc == encoding)
   4898         eventPtr = next;
   4899       return XML_ERROR_INVALID_TOKEN;
   4900     case XML_TOK_PARTIAL:
   4901       if (enc == encoding)
   4902         eventPtr = ptr;
   4903       return XML_ERROR_INVALID_TOKEN;
   4904     case XML_TOK_CHAR_REF:
   4905       {
   4906         XML_Char buf[XML_ENCODE_MAX];
   4907         int i;
   4908         int n = XmlCharRefNumber(enc, ptr);
   4909         if (n < 0) {
   4910           if (enc == encoding)
   4911             eventPtr = ptr;
   4912           return XML_ERROR_BAD_CHAR_REF;
   4913         }
   4914         if (!isCdata
   4915             && n == 0x20 /* space */
   4916             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
   4917           break;
   4918         n = XmlEncode(n, (ICHAR *)buf);
   4919         if (!n) {
   4920           if (enc == encoding)
   4921             eventPtr = ptr;
   4922           return XML_ERROR_BAD_CHAR_REF;
   4923         }
   4924         for (i = 0; i < n; i++) {
   4925           if (!poolAppendChar(pool, buf[i]))
   4926             return XML_ERROR_NO_MEMORY;
   4927         }
   4928       }
   4929       break;
   4930     case XML_TOK_DATA_CHARS:
   4931       if (!poolAppend(pool, enc, ptr, next))
   4932         return XML_ERROR_NO_MEMORY;
   4933       break;
   4934     case XML_TOK_TRAILING_CR:
   4935       next = ptr + enc->minBytesPerChar;
   4936       /* fall through */
   4937     case XML_TOK_ATTRIBUTE_VALUE_S:
   4938     case XML_TOK_DATA_NEWLINE:
   4939       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
   4940         break;
   4941       if (!poolAppendChar(pool, 0x20))
   4942         return XML_ERROR_NO_MEMORY;
   4943       break;
   4944     case XML_TOK_ENTITY_REF:
   4945       {
   4946         const XML_Char *name;
   4947         ENTITY *entity;
   4948         char checkEntityDecl;
   4949         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
   4950                                               ptr + enc->minBytesPerChar,
   4951                                               next - enc->minBytesPerChar);
   4952         if (ch) {
   4953           if (!poolAppendChar(pool, ch))
   4954                 return XML_ERROR_NO_MEMORY;
   4955           break;
   4956         }
   4957         name = poolStoreString(&temp2Pool, enc,
   4958                                ptr + enc->minBytesPerChar,
   4959                                next - enc->minBytesPerChar);
   4960         if (!name)
   4961           return XML_ERROR_NO_MEMORY;
   4962         entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
   4963         poolDiscard(&temp2Pool);
   4964         /* First, determine if a check for an existing declaration is needed;
   4965            if yes, check that the entity exists, and that it is internal.
   4966         */
   4967         if (pool == &dtd->pool)  /* are we called from prolog? */
   4968           checkEntityDecl =
   4969 #ifdef XML_DTD
   4970               prologState.documentEntity &&
   4971 #endif /* XML_DTD */
   4972               (dtd->standalone
   4973                ? !openInternalEntities
   4974                : !dtd->hasParamEntityRefs);
   4975         else /* if (pool == &tempPool): we are called from content */
   4976           checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
   4977         if (checkEntityDecl) {
   4978           if (!entity)
   4979             return XML_ERROR_UNDEFINED_ENTITY;
   4980           else if (!entity->is_internal)
   4981             return XML_ERROR_ENTITY_DECLARED_IN_PE;
   4982         }
   4983         else if (!entity) {
   4984           /* Cannot report skipped entity here - see comments on
   4985              skippedEntityHandler.
   4986           if (skippedEntityHandler)
   4987             skippedEntityHandler(handlerArg, name, 0);
   4988           */
   4989           /* Cannot call the default handler because this would be
   4990              out of sync with the call to the startElementHandler.
   4991           if ((pool == &tempPool) && defaultHandler)
   4992             reportDefault(parser, enc, ptr, next);
   4993           */
   4994           break;
   4995         }
   4996         if (entity->open) {
   4997           if (enc == encoding)
   4998             eventPtr = ptr;
   4999           return XML_ERROR_RECURSIVE_ENTITY_REF;
   5000         }
   5001         if (entity->notation) {
   5002           if (enc == encoding)
   5003             eventPtr = ptr;
   5004           return XML_ERROR_BINARY_ENTITY_REF;
   5005         }
   5006         if (!entity->textPtr) {
   5007           if (enc == encoding)
   5008             eventPtr = ptr;
   5009               return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
   5010         }
   5011         else {
   5012           enum XML_Error result;
   5013           const XML_Char *textEnd = entity->textPtr + entity->textLen;
   5014           entity->open = XML_TRUE;
   5015           result = appendAttributeValue(parser, internalEncoding, isCdata,
   5016                                         (char *)entity->textPtr,
   5017                                         (char *)textEnd, pool);
   5018           entity->open = XML_FALSE;
   5019           if (result)
   5020             return result;
   5021         }
   5022       }
   5023       break;
   5024     default:
   5025       if (enc == encoding)
   5026         eventPtr = ptr;
   5027       return XML_ERROR_UNEXPECTED_STATE;
   5028     }
   5029     ptr = next;
   5030   }
   5031   /* not reached */
   5032 }
   5033 
   5034 static enum XML_Error
   5035 storeEntityValue(XML_Parser parser,
   5036                  const ENCODING *enc,
   5037                  const char *entityTextPtr,
   5038                  const char *entityTextEnd)
   5039 {
   5040   DTD * const dtd = _dtd;  /* save one level of indirection */
   5041   STRING_POOL *pool = &(dtd->entityValuePool);
   5042   enum XML_Error result = XML_ERROR_NONE;
   5043 #ifdef XML_DTD
   5044   int oldInEntityValue = prologState.inEntityValue;
   5045   prologState.inEntityValue = 1;
   5046 #endif /* XML_DTD */
   5047   /* never return Null for the value argument in EntityDeclHandler,
   5048      since this would indicate an external entity; therefore we
   5049      have to make sure that entityValuePool.start is not null */
   5050   if (!pool->blocks) {
   5051     if (!poolGrow(pool))
   5052       return XML_ERROR_NO_MEMORY;
   5053   }
   5054 
   5055   for (;;) {
   5056     const char *next;
   5057     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
   5058     switch (tok) {
   5059     case XML_TOK_PARAM_ENTITY_REF:
   5060 #ifdef XML_DTD
   5061       if (isParamEntity || enc != encoding) {
   5062         const XML_Char *name;
   5063         ENTITY *entity;
   5064         name = poolStoreString(&tempPool, enc,
   5065                                entityTextPtr + enc->minBytesPerChar,
   5066                                next - enc->minBytesPerChar);
   5067         if (!name) {
   5068           result = XML_ERROR_NO_MEMORY;
   5069           goto endEntityValue;
   5070         }
   5071         entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
   5072         poolDiscard(&tempPool);
   5073         if (!entity) {
   5074           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
   5075           /* cannot report skipped entity here - see comments on
   5076              skippedEntityHandler
   5077           if (skippedEntityHandler)
   5078             skippedEntityHandler(handlerArg, name, 0);
   5079           */
   5080           dtd->keepProcessing = dtd->standalone;
   5081           goto endEntityValue;
   5082         }
   5083         if (entity->open) {
   5084           if (enc == encoding)
   5085             eventPtr = entityTextPtr;
   5086           result = XML_ERROR_RECURSIVE_ENTITY_REF;
   5087           goto endEntityValue;
   5088         }
   5089         if (entity->systemId) {
   5090           if (externalEntityRefHandler) {
   5091             dtd->paramEntityRead = XML_FALSE;
   5092             entity->open = XML_TRUE;
   5093             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
   5094                                           0,
   5095                                           entity->base,
   5096                                           entity->systemId,
   5097                                           entity->publicId)) {
   5098               entity->open = XML_FALSE;
   5099               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
   5100               goto endEntityValue;
   5101             }
   5102             entity->open = XML_FALSE;
   5103             if (!dtd->paramEntityRead)
   5104               dtd->keepProcessing = dtd->standalone;
   5105           }
   5106           else
   5107             dtd->keepProcessing = dtd->standalone;
   5108         }
   5109         else {
   5110           entity->open = XML_TRUE;
   5111           result = storeEntityValue(parser,
   5112                                     internalEncoding,
   5113                                     (char *)entity->textPtr,
   5114                                     (char *)(entity->textPtr
   5115                                              + entity->textLen));
   5116           entity->open = XML_FALSE;
   5117           if (result)
   5118             goto endEntityValue;
   5119         }
   5120         break;
   5121       }
   5122 #endif /* XML_DTD */
   5123       /* In the internal subset, PE references are not legal
   5124          within markup declarations, e.g entity values in this case. */
   5125       eventPtr = entityTextPtr;
   5126       result = XML_ERROR_PARAM_ENTITY_REF;
   5127       goto endEntityValue;
   5128     case XML_TOK_NONE:
   5129       result = XML_ERROR_NONE;
   5130       goto endEntityValue;
   5131     case XML_TOK_ENTITY_REF:
   5132     case XML_TOK_DATA_CHARS:
   5133       if (!poolAppend(pool, enc, entityTextPtr, next)) {
   5134         result = XML_ERROR_NO_MEMORY;
   5135         goto endEntityValue;
   5136       }
   5137       break;
   5138     case XML_TOK_TRAILING_CR:
   5139       next = entityTextPtr + enc->minBytesPerChar;
   5140       /* fall through */
   5141     case XML_TOK_DATA_NEWLINE:
   5142       if (pool->end == pool->ptr && !poolGrow(pool)) {
   5143               result = XML_ERROR_NO_MEMORY;
   5144         goto endEntityValue;
   5145       }
   5146       *(pool->ptr)++ = 0xA;
   5147       break;
   5148     case XML_TOK_CHAR_REF:
   5149       {
   5150         XML_Char buf[XML_ENCODE_MAX];
   5151         int i;
   5152         int n = XmlCharRefNumber(enc, entityTextPtr);
   5153         if (n < 0) {
   5154           if (enc == encoding)
   5155             eventPtr = entityTextPtr;
   5156           result = XML_ERROR_BAD_CHAR_REF;
   5157           goto endEntityValue;
   5158         }
   5159         n = XmlEncode(n, (ICHAR *)buf);
   5160         if (!n) {
   5161           if (enc == encoding)
   5162             eventPtr = entityTextPtr;
   5163           result = XML_ERROR_BAD_CHAR_REF;
   5164           goto endEntityValue;
   5165         }
   5166         for (i = 0; i < n; i++) {
   5167           if (pool->end == pool->ptr && !poolGrow(pool)) {
   5168             result = XML_ERROR_NO_MEMORY;
   5169             goto endEntityValue;
   5170           }
   5171           *(pool->ptr)++ = buf[i];
   5172         }
   5173       }
   5174       break;
   5175     case XML_TOK_PARTIAL:
   5176       if (enc == encoding)
   5177         eventPtr = entityTextPtr;
   5178       result = XML_ERROR_INVALID_TOKEN;
   5179       goto endEntityValue;
   5180     case XML_TOK_INVALID:
   5181       if (enc == encoding)
   5182         eventPtr = next;
   5183       result = XML_ERROR_INVALID_TOKEN;
   5184       goto endEntityValue;
   5185     default:
   5186       if (enc == encoding)
   5187         eventPtr = entityTextPtr;
   5188       result = XML_ERROR_UNEXPECTED_STATE;
   5189       goto endEntityValue;
   5190     }
   5191     entityTextPtr = next;
   5192   }
   5193 endEntityValue:
   5194 #ifdef XML_DTD
   5195   prologState.inEntityValue = oldInEntityValue;
   5196 #endif /* XML_DTD */
   5197   return result;
   5198 }
   5199 
   5200 static void FASTCALL
   5201 normalizeLines(XML_Char *s)
   5202 {
   5203   XML_Char *p;
   5204   for (;; s++) {
   5205     if (*s == XML_T('\0'))
   5206       return;
   5207     if (*s == 0xD)
   5208       break;
   5209   }
   5210   p = s;
   5211   do {
   5212     if (*s == 0xD) {
   5213       *p++ = 0xA;
   5214       if (*++s == 0xA)
   5215         s++;
   5216     }
   5217     else
   5218       *p++ = *s++;
   5219   } while (*s);
   5220   *p = XML_T('\0');
   5221 }
   5222 
   5223 static int
   5224 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
   5225                             const char *start, const char *end)
   5226 {
   5227   const XML_Char *target;
   5228   XML_Char *data;
   5229   const char *tem;
   5230   if (!processingInstructionHandler) {
   5231     if (defaultHandler)
   5232       reportDefault(parser, enc, start, end);
   5233     return 1;
   5234   }
   5235   start += enc->minBytesPerChar * 2;
   5236   tem = start + XmlNameLength(enc, start);
   5237   target = poolStoreString(&tempPool, enc, start, tem);
   5238   if (!target)
   5239     return 0;
   5240   poolFinish(&tempPool);
   5241   data = poolStoreString(&tempPool, enc,
   5242                         XmlSkipS(enc, tem),
   5243                         end - enc->minBytesPerChar*2);
   5244   if (!data)
   5245     return 0;
   5246   normalizeLines(data);
   5247   processingInstructionHandler(handlerArg, target, data);
   5248   poolClear(&tempPool);
   5249   return 1;
   5250 }
   5251 
   5252 static int
   5253 reportComment(XML_Parser parser, const ENCODING *enc,
   5254               const char *start, const char *end)
   5255 {
   5256   XML_Char *data;
   5257   if (!commentHandler) {
   5258     if (defaultHandler)
   5259       reportDefault(parser, enc, start, end);
   5260     return 1;
   5261   }
   5262   data = poolStoreString(&tempPool,
   5263                          enc,
   5264                          start + enc->minBytesPerChar * 4,
   5265                          end - enc->minBytesPerChar * 3);
   5266   if (!data)
   5267     return 0;
   5268   normalizeLines(data);
   5269   commentHandler(handlerArg, data);
   5270   poolClear(&tempPool);
   5271   return 1;
   5272 }
   5273 
   5274 static void
   5275 reportDefault(XML_Parser parser, const ENCODING *enc,
   5276               const char *s, const char *end)
   5277 {
   5278   if (MUST_CONVERT(enc, s)) {
   5279     const char **eventPP;
   5280     const char **eventEndPP;
   5281     if (enc == encoding) {
   5282       eventPP = &eventPtr;
   5283       eventEndPP = &eventEndPtr;
   5284     }
   5285     else {
   5286       eventPP = &(openInternalEntities->internalEventPtr);
   5287       eventEndPP = &(openInternalEntities->internalEventEndPtr);
   5288     }
   5289     do {
   5290       ICHAR *dataPtr = (ICHAR *)dataBuf;
   5291       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
   5292       *eventEndPP = s;
   5293       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
   5294       *eventPP = s;
   5295     } while (s != end);
   5296   }
   5297   else
   5298     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
   5299 }
   5300 
   5301 
   5302 static int
   5303 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
   5304                 XML_Bool isId, const XML_Char *value, XML_Parser parser)
   5305 {
   5306   DEFAULT_ATTRIBUTE *att;
   5307   if (value || isId) {
   5308     /* The handling of default attributes gets messed up if we have
   5309        a default which duplicates a non-default. */
   5310     int i;
   5311     for (i = 0; i < type->nDefaultAtts; i++)
   5312       if (attId == type->defaultAtts[i].id)
   5313         return 1;
   5314     if (isId && !type->idAtt && !attId->xmlns)
   5315       type->idAtt = attId;
   5316   }
   5317   if (type->nDefaultAtts == type->allocDefaultAtts) {
   5318     if (type->allocDefaultAtts == 0) {
   5319       type->allocDefaultAtts = 8;
   5320       type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
   5321                             * sizeof(DEFAULT_ATTRIBUTE));
   5322       if (!type->defaultAtts)
   5323         return 0;
   5324     }
   5325     else {
   5326       DEFAULT_ATTRIBUTE *temp;
   5327       int count = type->allocDefaultAtts * 2;
   5328       temp = (DEFAULT_ATTRIBUTE *)
   5329         REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
   5330       if (temp == NULL)
   5331         return 0;
   5332       type->allocDefaultAtts = count;
   5333       type->defaultAtts = temp;
   5334     }
   5335   }
   5336   att = type->defaultAtts + type->nDefaultAtts;
   5337   att->id = attId;
   5338   att->value = value;
   5339   att->isCdata = isCdata;
   5340   if (!isCdata)
   5341     attId->maybeTokenized = XML_TRUE;
   5342   type->nDefaultAtts += 1;
   5343   return 1;
   5344 }
   5345 
   5346 static int
   5347 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
   5348 {
   5349   DTD * const dtd = _dtd;  /* save one level of indirection */
   5350   const XML_Char *name;
   5351   for (name = elementType->name; *name; name++) {
   5352     if (*name == XML_T(ASCII_COLON)) {
   5353       PREFIX *prefix;
   5354       const XML_Char *s;
   5355       for (s = elementType->name; s != name; s++) {
   5356         if (!poolAppendChar(&dtd->pool, *s))
   5357           return 0;
   5358       }
   5359       if (!poolAppendChar(&dtd->pool, XML_T('\0')))
   5360         return 0;
   5361       prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
   5362                                 sizeof(PREFIX));
   5363       if (!prefix)
   5364         return 0;
   5365       if (prefix->name == poolStart(&dtd->pool))
   5366         poolFinish(&dtd->pool);
   5367       else
   5368         poolDiscard(&dtd->pool);
   5369       elementType->prefix = prefix;
   5370 
   5371     }
   5372   }
   5373   return 1;
   5374 }
   5375 
   5376 static ATTRIBUTE_ID *
   5377 getAttributeId(XML_Parser parser, const ENCODING *enc,
   5378                const char *start, const char *end)
   5379 {
   5380   DTD * const dtd = _dtd;  /* save one level of indirection */
   5381   ATTRIBUTE_ID *id;
   5382   const XML_Char *name;
   5383   if (!poolAppendChar(&dtd->pool, XML_T('\0')))
   5384     return NULL;
   5385   name = poolStoreString(&dtd->pool, enc, start, end);
   5386   if (!name)
   5387     return NULL;
   5388   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
   5389   ++name;
   5390   id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
   5391   if (!id)
   5392     return NULL;
   5393   if (id->name != name)
   5394     poolDiscard(&dtd->pool);
   5395   else {
   5396     poolFinish(&dtd->pool);
   5397     if (!ns)
   5398       ;
   5399     else if (name[0] == XML_T(ASCII_x)
   5400         && name[1] == XML_T(ASCII_m)
   5401         && name[2] == XML_T(ASCII_l)
   5402         && name[3] == XML_T(ASCII_n)
   5403         && name[4] == XML_T(ASCII_s)
   5404         && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
   5405       if (name[5] == XML_T('\0'))
   5406         id->prefix = &dtd->defaultPrefix;
   5407       else
   5408         id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
   5409       id->xmlns = XML_TRUE;
   5410     }
   5411     else {
   5412       int i;
   5413       for (i = 0; name[i]; i++) {
   5414         /* attributes without prefix are *not* in the default namespace */
   5415         if (name[i] == XML_T(ASCII_COLON)) {
   5416           int j;
   5417           for (j = 0; j < i; j++) {
   5418             if (!poolAppendChar(&dtd->pool, name[j]))
   5419               return NULL;
   5420           }
   5421           if (!poolAppendChar(&dtd->pool, XML_T('\0')))
   5422             return NULL;
   5423           id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
   5424                                         sizeof(PREFIX));
   5425           if (id->prefix->name == poolStart(&dtd->pool))
   5426             poolFinish(&dtd->pool);
   5427           else
   5428             poolDiscard(&dtd->pool);
   5429           break;
   5430         }
   5431       }
   5432     }
   5433   }
   5434   return id;
   5435 }
   5436 
   5437 #define CONTEXT_SEP XML_T(ASCII_FF)
   5438 
   5439 static const XML_Char *
   5440 getContext(XML_Parser parser)
   5441 {
   5442   DTD * const dtd = _dtd;  /* save one level of indirection */
   5443   HASH_TABLE_ITER iter;
   5444   XML_Bool needSep = XML_FALSE;
   5445 
   5446   if (dtd->defaultPrefix.binding) {
   5447     int i;
   5448     int len;
   5449     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
   5450       return NULL;
   5451     len = dtd->defaultPrefix.binding->uriLen;
   5452     if (namespaceSeparator)
   5453       len--;
   5454     for (i = 0; i < len; i++)
   5455       if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
   5456         return NULL;
   5457     needSep = XML_TRUE;
   5458   }
   5459 
   5460   hashTableIterInit(&iter, &(dtd->prefixes));
   5461   for (;;) {
   5462     int i;
   5463     int len;
   5464     const XML_Char *s;
   5465     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
   5466     if (!prefix)
   5467       break;
   5468     if (!prefix->binding)
   5469       continue;
   5470     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
   5471       return NULL;
   5472     for (s = prefix->name; *s; s++)
   5473       if (!poolAppendChar(&tempPool, *s))
   5474         return NULL;
   5475     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
   5476       return NULL;
   5477     len = prefix->binding->uriLen;
   5478     if (namespaceSeparator)
   5479       len--;
   5480     for (i = 0; i < len; i++)
   5481       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
   5482         return NULL;
   5483     needSep = XML_TRUE;
   5484   }
   5485 
   5486 
   5487   hashTableIterInit(&iter, &(dtd->generalEntities));
   5488   for (;;) {
   5489     const XML_Char *s;
   5490     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
   5491     if (!e)
   5492       break;
   5493     if (!e->open)
   5494       continue;
   5495     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
   5496       return NULL;
   5497     for (s = e->name; *s; s++)
   5498       if (!poolAppendChar(&tempPool, *s))
   5499         return 0;
   5500     needSep = XML_TRUE;
   5501   }
   5502 
   5503   if (!poolAppendChar(&tempPool, XML_T('\0')))
   5504     return NULL;
   5505   return tempPool.start;
   5506 }
   5507 
   5508 static XML_Bool
   5509 setContext(XML_Parser parser, const XML_Char *context)
   5510 {
   5511   DTD * const dtd = _dtd;  /* save one level of indirection */
   5512   const XML_Char *s = context;
   5513 
   5514   while (*context != XML_T('\0')) {
   5515     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
   5516       ENTITY *e;
   5517       if (!poolAppendChar(&tempPool, XML_T('\0')))
   5518         return XML_FALSE;
   5519       e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
   5520       if (e)
   5521         e->open = XML_TRUE;
   5522       if (*s != XML_T('\0'))
   5523         s++;
   5524       context = s;
   5525       poolDiscard(&tempPool);
   5526     }
   5527     else if (*s == XML_T(ASCII_EQUALS)) {
   5528       PREFIX *prefix;
   5529       if (poolLength(&tempPool) == 0)
   5530         prefix = &dtd->defaultPrefix;
   5531       else {
   5532         if (!poolAppendChar(&tempPool, XML_T('\0')))
   5533           return XML_FALSE;
   5534         prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
   5535                                   sizeof(PREFIX));
   5536         if (!prefix)
   5537           return XML_FALSE;
   5538         if (prefix->name == poolStart(&tempPool)) {
   5539           prefix->name = poolCopyString(&dtd->pool, prefix->name);
   5540           if (!prefix->name)
   5541             return XML_FALSE;
   5542         }
   5543         poolDiscard(&tempPool);
   5544       }
   5545       for (context = s + 1;
   5546            *context != CONTEXT_SEP && *context != XML_T('\0');
   5547            context++)
   5548         if (!poolAppendChar(&tempPool, *context))
   5549           return XML_FALSE;
   5550       if (!poolAppendChar(&tempPool, XML_T('\0')))
   5551         return XML_FALSE;
   5552       if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
   5553                      &inheritedBindings) != XML_ERROR_NONE)
   5554         return XML_FALSE;
   5555       poolDiscard(&tempPool);
   5556       if (*context != XML_T('\0'))
   5557         ++context;
   5558       s = context;
   5559     }
   5560     else {
   5561       if (!poolAppendChar(&tempPool, *s))
   5562         return XML_FALSE;
   5563       s++;
   5564     }
   5565   }
   5566   return XML_TRUE;
   5567 }
   5568 
   5569 static void FASTCALL
   5570 normalizePublicId(XML_Char *publicId)
   5571 {
   5572   XML_Char *p = publicId;
   5573   XML_Char *s;
   5574   for (s = publicId; *s; s++) {
   5575     switch (*s) {
   5576     case 0x20:
   5577     case 0xD:
   5578     case 0xA:
   5579       if (p != publicId && p[-1] != 0x20)
   5580         *p++ = 0x20;
   5581       break;
   5582     default:
   5583       *p++ = *s;
   5584     }
   5585   }
   5586   if (p != publicId && p[-1] == 0x20)
   5587     --p;
   5588   *p = XML_T('\0');
   5589 }
   5590 
   5591 static DTD *
   5592 dtdCreate(const XML_Memory_Handling_Suite *ms)
   5593 {
   5594   DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
   5595   if (p == NULL)
   5596     return p;
   5597   poolInit(&(p->pool), ms);
   5598   poolInit(&(p->entityValuePool), ms);
   5599   hashTableInit(&(p->generalEntities), ms);
   5600   hashTableInit(&(p->elementTypes), ms);
   5601   hashTableInit(&(p->attributeIds), ms);
   5602   hashTableInit(&(p->prefixes), ms);
   5603 #ifdef XML_DTD
   5604   p->paramEntityRead = XML_FALSE;
   5605   hashTableInit(&(p->paramEntities), ms);
   5606 #endif /* XML_DTD */
   5607   p->defaultPrefix.name = NULL;
   5608   p->defaultPrefix.binding = NULL;
   5609 
   5610   p->in_eldecl = XML_FALSE;
   5611   p->scaffIndex = NULL;
   5612   p->scaffold = NULL;
   5613   p->scaffLevel = 0;
   5614   p->scaffSize = 0;
   5615   p->scaffCount = 0;
   5616   p->contentStringLen = 0;
   5617 
   5618   p->keepProcessing = XML_TRUE;
   5619   p->hasParamEntityRefs = XML_FALSE;
   5620   p->standalone = XML_FALSE;
   5621   return p;
   5622 }
   5623 
   5624 static void
   5625 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
   5626 {
   5627   HASH_TABLE_ITER iter;
   5628   hashTableIterInit(&iter, &(p->elementTypes));
   5629   for (;;) {
   5630     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
   5631     if (!e)
   5632       break;
   5633     if (e->allocDefaultAtts != 0)
   5634       ms->free_fcn(e->defaultAtts);
   5635   }
   5636   hashTableClear(&(p->generalEntities));
   5637 #ifdef XML_DTD
   5638   p->paramEntityRead = XML_FALSE;
   5639   hashTableClear(&(p->paramEntities));
   5640 #endif /* XML_DTD */
   5641   hashTableClear(&(p->elementTypes));
   5642   hashTableClear(&(p->attributeIds));
   5643   hashTableClear(&(p->prefixes));
   5644   poolClear(&(p->pool));
   5645   poolClear(&(p->entityValuePool));
   5646   p->defaultPrefix.name = NULL;
   5647   p->defaultPrefix.binding = NULL;
   5648 
   5649   p->in_eldecl = XML_FALSE;
   5650 
   5651   ms->free_fcn(p->scaffIndex);
   5652   p->scaffIndex = NULL;
   5653   ms->free_fcn(p->scaffold);
   5654   p->scaffold = NULL;
   5655 
   5656   p->scaffLevel = 0;
   5657   p->scaffSize = 0;
   5658   p->scaffCount = 0;
   5659   p->contentStringLen = 0;
   5660 
   5661   p->keepProcessing = XML_TRUE;
   5662   p->hasParamEntityRefs = XML_FALSE;
   5663   p->standalone = XML_FALSE;
   5664 }
   5665 
   5666 static void
   5667 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
   5668 {
   5669   HASH_TABLE_ITER iter;
   5670   hashTableIterInit(&iter, &(p->elementTypes));
   5671   for (;;) {
   5672     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
   5673     if (!e)
   5674       break;
   5675     if (e->allocDefaultAtts != 0)
   5676       ms->free_fcn(e->defaultAtts);
   5677   }
   5678   hashTableDestroy(&(p->generalEntities));
   5679 #ifdef XML_DTD
   5680   hashTableDestroy(&(p->paramEntities));
   5681 #endif /* XML_DTD */
   5682   hashTableDestroy(&(p->elementTypes));
   5683   hashTableDestroy(&(p->attributeIds));
   5684   hashTableDestroy(&(p->prefixes));
   5685   poolDestroy(&(p->pool));
   5686   poolDestroy(&(p->entityValuePool));
   5687   if (isDocEntity) {
   5688     ms->free_fcn(p->scaffIndex);
   5689     ms->free_fcn(p->scaffold);
   5690   }
   5691   ms->free_fcn(p);
   5692 }
   5693 
   5694 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
   5695    The new DTD has already been initialized.
   5696 */
   5697 static int
   5698 dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
   5699 {
   5700   HASH_TABLE_ITER iter;
   5701 
   5702   /* Copy the prefix table. */
   5703 
   5704   hashTableIterInit(&iter, &(oldDtd->prefixes));
   5705   for (;;) {
   5706     const XML_Char *name;
   5707     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
   5708     if (!oldP)
   5709       break;
   5710     name = poolCopyString(&(newDtd->pool), oldP->name);
   5711     if (!name)
   5712       return 0;
   5713     if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
   5714       return 0;
   5715   }
   5716 
   5717   hashTableIterInit(&iter, &(oldDtd->attributeIds));
   5718 
   5719   /* Copy the attribute id table. */
   5720 
   5721   for (;;) {
   5722     ATTRIBUTE_ID *newA;
   5723     const XML_Char *name;
   5724     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
   5725 
   5726     if (!oldA)
   5727       break;
   5728     /* Remember to allocate the scratch byte before the name. */
   5729     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
   5730       return 0;
   5731     name = poolCopyString(&(newDtd->pool), oldA->name);
   5732     if (!name)
   5733       return 0;
   5734     ++name;
   5735     newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
   5736                                   sizeof(ATTRIBUTE_ID));
   5737     if (!newA)
   5738       return 0;
   5739     newA->maybeTokenized = oldA->maybeTokenized;
   5740     if (oldA->prefix) {
   5741       newA->xmlns = oldA->xmlns;
   5742       if (oldA->prefix == &oldDtd->defaultPrefix)
   5743         newA->prefix = &newDtd->defaultPrefix;
   5744       else
   5745         newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
   5746                                         oldA->prefix->name, 0);
   5747     }
   5748   }
   5749 
   5750   /* Copy the element type table. */
   5751 
   5752   hashTableIterInit(&iter, &(oldDtd->elementTypes));
   5753 
   5754   for (;;) {
   5755     int i;
   5756     ELEMENT_TYPE *newE;
   5757     const XML_Char *name;
   5758     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
   5759     if (!oldE)
   5760       break;
   5761     name = poolCopyString(&(newDtd->pool), oldE->name);
   5762     if (!name)
   5763       return 0;
   5764     newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
   5765                                   sizeof(ELEMENT_TYPE));
   5766     if (!newE)
   5767       return 0;
   5768     if (oldE->nDefaultAtts) {
   5769       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
   5770           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
   5771       if (!newE->defaultAtts) {
   5772         ms->free_fcn(newE);
   5773         return 0;
   5774       }
   5775     }
   5776     if (oldE->idAtt)
   5777       newE->idAtt = (ATTRIBUTE_ID *)
   5778           lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
   5779     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
   5780     if (oldE->prefix)
   5781       newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
   5782                                       oldE->prefix->name, 0);
   5783     for (i = 0; i < newE->nDefaultAtts; i++) {
   5784       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
   5785           lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
   5786       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
   5787       if (oldE->defaultAtts[i].value) {
   5788         newE->defaultAtts[i].value
   5789             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
   5790         if (!newE->defaultAtts[i].value)
   5791           return 0;
   5792       }
   5793       else
   5794         newE->defaultAtts[i].value = NULL;
   5795     }
   5796   }
   5797 
   5798   /* Copy the entity tables. */
   5799   if (!copyEntityTable(oldParser,
   5800                        &(newDtd->generalEntities),
   5801                        &(newDtd->pool),
   5802                        &(oldDtd->generalEntities)))
   5803       return 0;
   5804 
   5805 #ifdef XML_DTD
   5806   if (!copyEntityTable(oldParser,
   5807                        &(newDtd->paramEntities),
   5808                        &(newDtd->pool),
   5809                        &(oldDtd->paramEntities)))
   5810       return 0;
   5811   newDtd->paramEntityRead = oldDtd->paramEntityRead;
   5812 #endif /* XML_DTD */
   5813 
   5814   newDtd->keepProcessing = oldDtd->keepProcessing;
   5815   newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
   5816   newDtd->standalone = oldDtd->standalone;
   5817 
   5818   /* Don't want deep copying for scaffolding */
   5819   newDtd->in_eldecl = oldDtd->in_eldecl;
   5820   newDtd->scaffold = oldDtd->scaffold;
   5821   newDtd->contentStringLen = oldDtd->contentStringLen;
   5822   newDtd->scaffSize = oldDtd->scaffSize;
   5823   newDtd->scaffLevel = oldDtd->scaffLevel;
   5824   newDtd->scaffIndex = oldDtd->scaffIndex;
   5825 
   5826   return 1;
   5827 }  /* End dtdCopy */
   5828 
   5829 static int
   5830 copyEntityTable(XML_Parser oldParser,
   5831                 HASH_TABLE *newTable,
   5832                 STRING_POOL *newPool,
   5833                 const HASH_TABLE *oldTable)
   5834 {
   5835   HASH_TABLE_ITER iter;
   5836   const XML_Char *cachedOldBase = NULL;
   5837   const XML_Char *cachedNewBase = NULL;
   5838 
   5839   hashTableIterInit(&iter, oldTable);
   5840 
   5841   for (;;) {
   5842     ENTITY *newE;
   5843     const XML_Char *name;
   5844     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
   5845     if (!oldE)
   5846       break;
   5847     name = poolCopyString(newPool, oldE->name);
   5848     if (!name)
   5849       return 0;
   5850     newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
   5851     if (!newE)
   5852       return 0;
   5853     if (oldE->systemId) {
   5854       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
   5855       if (!tem)
   5856         return 0;
   5857       newE->systemId = tem;
   5858       if (oldE->base) {
   5859         if (oldE->base == cachedOldBase)
   5860           newE->base = cachedNewBase;
   5861         else {
   5862           cachedOldBase = oldE->base;
   5863           tem = poolCopyString(newPool, cachedOldBase);
   5864           if (!tem)
   5865             return 0;
   5866           cachedNewBase = newE->base = tem;
   5867         }
   5868       }
   5869       if (oldE->publicId) {
   5870         tem = poolCopyString(newPool, oldE->publicId);
   5871         if (!tem)
   5872           return 0;
   5873         newE->publicId = tem;
   5874       }
   5875     }
   5876     else {
   5877       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
   5878                                             oldE->textLen);
   5879       if (!tem)
   5880         return 0;
   5881       newE->textPtr = tem;
   5882       newE->textLen = oldE->textLen;
   5883     }
   5884     if (oldE->notation) {
   5885       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
   5886       if (!tem)
   5887         return 0;
   5888       newE->notation = tem;
   5889     }
   5890     newE->is_param = oldE->is_param;
   5891     newE->is_internal = oldE->is_internal;
   5892   }
   5893   return 1;
   5894 }
   5895 
   5896 #define INIT_POWER 6
   5897 
   5898 static XML_Bool FASTCALL
   5899 keyeq(KEY s1, KEY s2)
   5900 {
   5901   for (; *s1 == *s2; s1++, s2++)
   5902     if (*s1 == 0)
   5903       return XML_TRUE;
   5904   return XML_FALSE;
   5905 }
   5906 
   5907 static unsigned long FASTCALL
   5908 hash(XML_Parser parser, KEY s)
   5909 {
   5910   unsigned long h = hash_secret_salt;
   5911   while (*s)
   5912     h = CHAR_HASH(h, *s++);
   5913   return h;
   5914 }
   5915 
   5916 static NAMED *
   5917 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
   5918 {
   5919   size_t i;
   5920   if (table->size == 0) {
   5921     size_t tsize;
   5922     if (!createSize)
   5923       return NULL;
   5924     table->power = INIT_POWER;
   5925     /* table->size is a power of 2 */
   5926     table->size = (size_t)1 << INIT_POWER;
   5927     tsize = table->size * sizeof(NAMED *);
   5928     table->v = (NAMED **)table->mem->malloc_fcn(tsize);
   5929     if (!table->v) {
   5930       table->size = 0;
   5931       return NULL;
   5932     }
   5933     memset(table->v, 0, tsize);
   5934     i = hash(parser, name) & ((unsigned long)table->size - 1);
   5935   }
   5936   else {
   5937     unsigned long h = hash(parser, name);
   5938     unsigned long mask = (unsigned long)table->size - 1;
   5939     unsigned char step = 0;
   5940     i = h & mask;
   5941     while (table->v[i]) {
   5942       if (keyeq(name, table->v[i]->name))
   5943         return table->v[i];
   5944       if (!step)
   5945         step = PROBE_STEP(h, mask, table->power);
   5946       i < step ? (i += table->size - step) : (i -= step);
   5947     }
   5948     if (!createSize)
   5949       return NULL;
   5950 
   5951     /* check for overflow (table is half full) */
   5952     if (table->used >> (table->power - 1)) {
   5953       unsigned char newPower = table->power + 1;
   5954       size_t newSize = (size_t)1 << newPower;
   5955       unsigned long newMask = (unsigned long)newSize - 1;
   5956       size_t tsize = newSize * sizeof(NAMED *);
   5957       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
   5958       if (!newV)
   5959         return NULL;
   5960       memset(newV, 0, tsize);
   5961       for (i = 0; i < table->size; i++)
   5962         if (table->v[i]) {
   5963           unsigned long newHash = hash(parser, table->v[i]->name);
   5964           size_t j = newHash & newMask;
   5965           step = 0;
   5966           while (newV[j]) {
   5967             if (!step)
   5968               step = PROBE_STEP(newHash, newMask, newPower);
   5969             j < step ? (j += newSize - step) : (j -= step);
   5970           }
   5971           newV[j] = table->v[i];
   5972         }
   5973       table->mem->free_fcn(table->v);
   5974       table->v = newV;
   5975       table->power = newPower;
   5976       table->size = newSize;
   5977       i = h & newMask;
   5978       step = 0;
   5979       while (table->v[i]) {
   5980         if (!step)
   5981           step = PROBE_STEP(h, newMask, newPower);
   5982         i < step ? (i += newSize - step) : (i -= step);
   5983       }
   5984     }
   5985   }
   5986   table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
   5987   if (!table->v[i])
   5988     return NULL;
   5989   memset(table->v[i], 0, createSize);
   5990   table->v[i]->name = name;
   5991   (table->used)++;
   5992   return table->v[i];
   5993 }
   5994 
   5995 static void FASTCALL
   5996 hashTableClear(HASH_TABLE *table)
   5997 {
   5998   size_t i;
   5999   for (i = 0; i < table->size; i++) {
   6000     table->mem->free_fcn(table->v[i]);
   6001     table->v[i] = NULL;
   6002   }
   6003   table->used = 0;
   6004 }
   6005 
   6006 static void FASTCALL
   6007 hashTableDestroy(HASH_TABLE *table)
   6008 {
   6009   size_t i;
   6010   for (i = 0; i < table->size; i++)
   6011     table->mem->free_fcn(table->v[i]);
   6012   table->mem->free_fcn(table->v);
   6013 }
   6014 
   6015 static void FASTCALL
   6016 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
   6017 {
   6018   p->power = 0;
   6019   p->size = 0;
   6020   p->used = 0;
   6021   p->v = NULL;
   6022   p->mem = ms;
   6023 }
   6024 
   6025 static void FASTCALL
   6026 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
   6027 {
   6028   iter->p = table->v;
   6029   iter->end = iter->p + table->size;
   6030 }
   6031 
   6032 static NAMED * FASTCALL
   6033 hashTableIterNext(HASH_TABLE_ITER *iter)
   6034 {
   6035   while (iter->p != iter->end) {
   6036     NAMED *tem = *(iter->p)++;
   6037     if (tem)
   6038       return tem;
   6039   }
   6040   return NULL;
   6041 }
   6042 
   6043 static void FASTCALL
   6044 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
   6045 {
   6046   pool->blocks = NULL;
   6047   pool->freeBlocks = NULL;
   6048   pool->start = NULL;
   6049   pool->ptr = NULL;
   6050   pool->end = NULL;
   6051   pool->mem = ms;
   6052 }
   6053 
   6054 static void FASTCALL
   6055 poolClear(STRING_POOL *pool)
   6056 {
   6057   if (!pool->freeBlocks)
   6058     pool->freeBlocks = pool->blocks;
   6059   else {
   6060     BLOCK *p = pool->blocks;
   6061     while (p) {
   6062       BLOCK *tem = p->next;
   6063       p->next = pool->freeBlocks;
   6064       pool->freeBlocks = p;
   6065       p = tem;
   6066     }
   6067   }
   6068   pool->blocks = NULL;
   6069   pool->start = NULL;
   6070   pool->ptr = NULL;
   6071   pool->end = NULL;
   6072 }
   6073 
   6074 static void FASTCALL
   6075 poolDestroy(STRING_POOL *pool)
   6076 {
   6077   BLOCK *p = pool->blocks;
   6078   while (p) {
   6079     BLOCK *tem = p->next;
   6080     pool->mem->free_fcn(p);
   6081     p = tem;
   6082   }
   6083   p = pool->freeBlocks;
   6084   while (p) {
   6085     BLOCK *tem = p->next;
   6086     pool->mem->free_fcn(p);
   6087     p = tem;
   6088   }
   6089 }
   6090 
   6091 static XML_Char *
   6092 poolAppend(STRING_POOL *pool, const ENCODING *enc,
   6093            const char *ptr, const char *end)
   6094 {
   6095   if (!pool->ptr && !poolGrow(pool))
   6096     return NULL;
   6097   for (;;) {
   6098     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
   6099     if (ptr == end)
   6100       break;
   6101     if (!poolGrow(pool))
   6102       return NULL;
   6103   }
   6104   return pool->start;
   6105 }
   6106 
   6107 static const XML_Char * FASTCALL
   6108 poolCopyString(STRING_POOL *pool, const XML_Char *s)
   6109 {
   6110   do {
   6111     if (!poolAppendChar(pool, *s))
   6112       return NULL;
   6113   } while (*s++);
   6114   s = pool->start;
   6115   poolFinish(pool);
   6116   return s;
   6117 }
   6118 
   6119 static const XML_Char *
   6120 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
   6121 {
   6122   if (!pool->ptr && !poolGrow(pool))
   6123     return NULL;
   6124   for (; n > 0; --n, s++) {
   6125     if (!poolAppendChar(pool, *s))
   6126       return NULL;
   6127   }
   6128   s = pool->start;
   6129   poolFinish(pool);
   6130   return s;
   6131 }
   6132 
   6133 static const XML_Char * FASTCALL
   6134 poolAppendString(STRING_POOL *pool, const XML_Char *s)
   6135 {
   6136   while (*s) {
   6137     if (!poolAppendChar(pool, *s))
   6138       return NULL;
   6139     s++;
   6140   }
   6141   return pool->start;
   6142 }
   6143 
   6144 static XML_Char *
   6145 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
   6146                 const char *ptr, const char *end)
   6147 {
   6148   if (!poolAppend(pool, enc, ptr, end))
   6149     return NULL;
   6150   if (pool->ptr == pool->end && !poolGrow(pool))
   6151     return NULL;
   6152   *(pool->ptr)++ = 0;
   6153   return pool->start;
   6154 }
   6155 
   6156 static XML_Bool FASTCALL
   6157 poolGrow(STRING_POOL *pool)
   6158 {
   6159   if (pool->freeBlocks) {
   6160     if (pool->start == 0) {
   6161       pool->blocks = pool->freeBlocks;
   6162       pool->freeBlocks = pool->freeBlocks->next;
   6163       pool->blocks->next = NULL;
   6164       pool->start = pool->blocks->s;
   6165       pool->end = pool->start + pool->blocks->size;
   6166       pool->ptr = pool->start;
   6167       return XML_TRUE;
   6168     }
   6169     if (pool->end - pool->start < pool->freeBlocks->size) {
   6170       BLOCK *tem = pool->freeBlocks->next;
   6171       pool->freeBlocks->next = pool->blocks;
   6172       pool->blocks = pool->freeBlocks;
   6173       pool->freeBlocks = tem;
   6174       memcpy(pool->blocks->s, pool->start,
   6175              (pool->end - pool->start) * sizeof(XML_Char));
   6176       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
   6177       pool->start = pool->blocks->s;
   6178       pool->end = pool->start + pool->blocks->size;
   6179       return XML_TRUE;
   6180     }
   6181   }
   6182   if (pool->blocks && pool->start == pool->blocks->s) {
   6183     int blockSize = (int)(pool->end - pool->start)*2;
   6184     BLOCK *temp = (BLOCK *)
   6185       pool->mem->realloc_fcn(pool->blocks,
   6186                              (offsetof(BLOCK, s)
   6187                               + blockSize * sizeof(XML_Char)));
   6188     if (temp == NULL)
   6189       return XML_FALSE;
   6190     pool->blocks = temp;
   6191     pool->blocks->size = blockSize;
   6192     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
   6193     pool->start = pool->blocks->s;
   6194     pool->end = pool->start + blockSize;
   6195   }
   6196   else {
   6197     BLOCK *tem;
   6198     int blockSize = (int)(pool->end - pool->start);
   6199     if (blockSize < INIT_BLOCK_SIZE)
   6200       blockSize = INIT_BLOCK_SIZE;
   6201     else
   6202       blockSize *= 2;
   6203     tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
   6204                                         + blockSize * sizeof(XML_Char));
   6205     if (!tem)
   6206       return XML_FALSE;
   6207     tem->size = blockSize;
   6208     tem->next = pool->blocks;
   6209     pool->blocks = tem;
   6210     if (pool->ptr != pool->start)
   6211       memcpy(tem->s, pool->start,
   6212              (pool->ptr - pool->start) * sizeof(XML_Char));
   6213     pool->ptr = tem->s + (pool->ptr - pool->start);
   6214     pool->start = tem->s;
   6215     pool->end = tem->s + blockSize;
   6216   }
   6217   return XML_TRUE;
   6218 }
   6219 
   6220 static int FASTCALL
   6221 nextScaffoldPart(XML_Parser parser)
   6222 {
   6223   DTD * const dtd = _dtd;  /* save one level of indirection */
   6224   CONTENT_SCAFFOLD * me;
   6225   int next;
   6226 
   6227   if (!dtd->scaffIndex) {
   6228     dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
   6229     if (!dtd->scaffIndex)
   6230       return -1;
   6231     dtd->scaffIndex[0] = 0;
   6232   }
   6233 
   6234   if (dtd->scaffCount >= dtd->scaffSize) {
   6235     CONTENT_SCAFFOLD *temp;
   6236     if (dtd->scaffold) {
   6237       temp = (CONTENT_SCAFFOLD *)
   6238         REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
   6239       if (temp == NULL)
   6240         return -1;
   6241       dtd->scaffSize *= 2;
   6242     }
   6243     else {
   6244       temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
   6245                                         * sizeof(CONTENT_SCAFFOLD));
   6246       if (temp == NULL)
   6247         return -1;
   6248       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
   6249     }
   6250     dtd->scaffold = temp;
   6251   }
   6252   next = dtd->scaffCount++;
   6253   me = &dtd->scaffold[next];
   6254   if (dtd->scaffLevel) {
   6255     CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
   6256     if (parent->lastchild) {
   6257       dtd->scaffold[parent->lastchild].nextsib = next;
   6258     }
   6259     if (!parent->childcnt)
   6260       parent->firstchild = next;
   6261     parent->lastchild = next;
   6262     parent->childcnt++;
   6263   }
   6264   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
   6265   return next;
   6266 }
   6267 
   6268 static void
   6269 build_node(XML_Parser parser,
   6270            int src_node,
   6271            XML_Content *dest,
   6272            XML_Content **contpos,
   6273            XML_Char **strpos)
   6274 {
   6275   DTD * const dtd = _dtd;  /* save one level of indirection */
   6276   dest->type = dtd->scaffold[src_node].type;
   6277   dest->quant = dtd->scaffold[src_node].quant;
   6278   if (dest->type == XML_CTYPE_NAME) {
   6279     const XML_Char *src;
   6280     dest->name = *strpos;
   6281     src = dtd->scaffold[src_node].name;
   6282     for (;;) {
   6283       *(*strpos)++ = *src;
   6284       if (!*src)
   6285         break;
   6286       src++;
   6287     }
   6288     dest->numchildren = 0;
   6289     dest->children = NULL;
   6290   }
   6291   else {
   6292     unsigned int i;
   6293     int cn;
   6294     dest->numchildren = dtd->scaffold[src_node].childcnt;
   6295     dest->children = *contpos;
   6296     *contpos += dest->numchildren;
   6297     for (i = 0, cn = dtd->scaffold[src_node].firstchild;
   6298          i < dest->numchildren;
   6299          i++, cn = dtd->scaffold[cn].nextsib) {
   6300       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
   6301     }
   6302     dest->name = NULL;
   6303   }
   6304 }
   6305 
   6306 static XML_Content *
   6307 build_model (XML_Parser parser)
   6308 {
   6309   DTD * const dtd = _dtd;  /* save one level of indirection */
   6310   XML_Content *ret;
   6311   XML_Content *cpos;
   6312   XML_Char * str;
   6313   int allocsize = (dtd->scaffCount * sizeof(XML_Content)
   6314                    + (dtd->contentStringLen * sizeof(XML_Char)));
   6315 
   6316   ret = (XML_Content *)MALLOC(allocsize);
   6317   if (!ret)
   6318     return NULL;
   6319 
   6320   str =  (XML_Char *) (&ret[dtd->scaffCount]);
   6321   cpos = &ret[1];
   6322 
   6323   build_node(parser, 0, ret, &cpos, &str);
   6324   return ret;
   6325 }
   6326 
   6327 static ELEMENT_TYPE *
   6328 getElementType(XML_Parser parser,
   6329                const ENCODING *enc,
   6330                const char *ptr,
   6331                const char *end)
   6332 {
   6333   DTD * const dtd = _dtd;  /* save one level of indirection */
   6334   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
   6335   ELEMENT_TYPE *ret;
   6336 
   6337   if (!name)
   6338     return NULL;
   6339   ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
   6340   if (!ret)
   6341     return NULL;
   6342   if (ret->name != name)
   6343     poolDiscard(&dtd->pool);
   6344   else {
   6345     poolFinish(&dtd->pool);
   6346     if (!setElementTypePrefix(parser, ret))
   6347       return NULL;
   6348   }
   6349   return ret;
   6350 }
   6351