LCOV - code coverage report
Current view: directory - parser/expat/lib - xmlparse.c (source / functions) Found Hit Coverage
Test: app.info Lines: 3167 1499 47.3 %
Date: 2012-06-02 Functions: 105 78 74.3 %

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

Generated by: LCOV version 1.7