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