LCOV - code coverage report
Current view: top level - simgear/xml - xmlparse.c (source / functions) Hit Total Coverage
Test: JSBSim-Coverage-Statistics Lines: 666 2970 22.4 %
Date: 2010-08-24 Functions: 34 122 27.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 238 2104 11.3 %

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

Generated by: LCOV version 1.9