LCOV - code coverage report
Current view: top level - parser/expat/lib - xmlparse.c (source / functions) Hit Total Coverage
Test: output.info Lines: 899 3164 28.4 %
Date: 2017-07-14 16:53:18 Functions: 53 102 52.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13