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