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