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