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