parser/expat/lib/xmlparse.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/parser/expat/lib/xmlparse.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,6420 @@
     1.4 +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
     1.5 +   See the file COPYING for copying permission.
     1.6 +*/
     1.7 +
     1.8 +#include <stddef.h>
     1.9 +#include <string.h>                     /* memset(), memcpy() */
    1.10 +#include <assert.h>
    1.11 +
    1.12 +#define XML_BUILDING_EXPAT 1
    1.13 +
    1.14 +#ifdef COMPILED_FROM_DSP
    1.15 +#include "winconfig.h"
    1.16 +#elif defined(MACOS_CLASSIC)
    1.17 +#include "macconfig.h"
    1.18 +#elif defined(__amigaos4__)
    1.19 +#include "amigaconfig.h"
    1.20 +#elif defined(HAVE_EXPAT_CONFIG_H)
    1.21 +#include <expat_config.h>
    1.22 +#endif /* ndef COMPILED_FROM_DSP */
    1.23 +
    1.24 +#include "expat.h"
    1.25 +
    1.26 +#ifdef XML_UNICODE
    1.27 +#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
    1.28 +#define XmlConvert XmlUtf16Convert
    1.29 +#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
    1.30 +#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
    1.31 +#define XmlEncode XmlUtf16Encode
    1.32 +#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
    1.33 +typedef unsigned short ICHAR;
    1.34 +#else
    1.35 +#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
    1.36 +#define XmlConvert XmlUtf8Convert
    1.37 +#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
    1.38 +#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
    1.39 +#define XmlEncode XmlUtf8Encode
    1.40 +#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
    1.41 +typedef char ICHAR;
    1.42 +#endif
    1.43 +
    1.44 +
    1.45 +#ifndef XML_NS
    1.46 +
    1.47 +#define XmlInitEncodingNS XmlInitEncoding
    1.48 +#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
    1.49 +#undef XmlGetInternalEncodingNS
    1.50 +#define XmlGetInternalEncodingNS XmlGetInternalEncoding
    1.51 +#define XmlParseXmlDeclNS XmlParseXmlDecl
    1.52 +
    1.53 +#endif
    1.54 +
    1.55 +/* BEGIN MOZILLA CHANGE (typedef XML_Char to char16_t) */
    1.56 +#if 0
    1.57 +
    1.58 +#ifdef XML_UNICODE
    1.59 +
    1.60 +#ifdef XML_UNICODE_WCHAR_T
    1.61 +#define XML_T(x) (const wchar_t)x
    1.62 +#define XML_L(x) L ## x
    1.63 +#else
    1.64 +#define XML_T(x) (const unsigned short)x
    1.65 +#define XML_L(x) x
    1.66 +#endif
    1.67 +
    1.68 +#else
    1.69 +
    1.70 +#define XML_T(x) x
    1.71 +#define XML_L(x) x
    1.72 +
    1.73 +#endif
    1.74 +
    1.75 +#endif
    1.76 +/* END MOZILLA CHANGE */
    1.77 +
    1.78 +/* Round up n to be a multiple of sz, where sz is a power of 2. */
    1.79 +#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
    1.80 +
    1.81 +/* Handle the case where memmove() doesn't exist. */
    1.82 +#ifndef HAVE_MEMMOVE
    1.83 +#ifdef HAVE_BCOPY
    1.84 +#define memmove(d,s,l) bcopy((s),(d),(l))
    1.85 +#else
    1.86 +#error memmove does not exist on this platform, nor is a substitute available
    1.87 +#endif /* HAVE_BCOPY */
    1.88 +#endif /* HAVE_MEMMOVE */
    1.89 +
    1.90 +#include "internal.h"
    1.91 +#include "xmltok.h"
    1.92 +#include "xmlrole.h"
    1.93 +
    1.94 +typedef const XML_Char *KEY;
    1.95 +
    1.96 +typedef struct {
    1.97 +  KEY name;
    1.98 +} NAMED;
    1.99 +
   1.100 +typedef struct {
   1.101 +  NAMED **v;
   1.102 +  unsigned char power;
   1.103 +  size_t size;
   1.104 +  size_t used;
   1.105 +  const XML_Memory_Handling_Suite *mem;
   1.106 +} HASH_TABLE;
   1.107 +
   1.108 +/* Basic character hash algorithm, taken from Python's string hash:
   1.109 +   h = h * 1000003 ^ character, the constant being a prime number.
   1.110 +
   1.111 +*/
   1.112 +#ifdef XML_UNICODE
   1.113 +#define CHAR_HASH(h, c) \
   1.114 +  (((h) * 0xF4243) ^ (unsigned short)(c))
   1.115 +#else
   1.116 +#define CHAR_HASH(h, c) \
   1.117 +  (((h) * 0xF4243) ^ (unsigned char)(c))
   1.118 +#endif
   1.119 +
   1.120 +/* For probing (after a collision) we need a step size relative prime
   1.121 +   to the hash table size, which is a power of 2. We use double-hashing,
   1.122 +   since we can calculate a second hash value cheaply by taking those bits
   1.123 +   of the first hash value that were discarded (masked out) when the table
   1.124 +   index was calculated: index = hash & mask, where mask = table->size - 1.
   1.125 +   We limit the maximum step size to table->size / 4 (mask >> 2) and make
   1.126 +   it odd, since odd numbers are always relative prime to a power of 2.
   1.127 +*/
   1.128 +#define SECOND_HASH(hash, mask, power) \
   1.129 +  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
   1.130 +#define PROBE_STEP(hash, mask, power) \
   1.131 +  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
   1.132 +
   1.133 +typedef struct {
   1.134 +  NAMED **p;
   1.135 +  NAMED **end;
   1.136 +} HASH_TABLE_ITER;
   1.137 +
   1.138 +#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
   1.139 +#define INIT_DATA_BUF_SIZE 1024
   1.140 +#define INIT_ATTS_SIZE 16
   1.141 +#define INIT_ATTS_VERSION 0xFFFFFFFF
   1.142 +#define INIT_BLOCK_SIZE 1024
   1.143 +#define INIT_BUFFER_SIZE 1024
   1.144 +
   1.145 +#define EXPAND_SPARE 24
   1.146 +
   1.147 +typedef struct binding {
   1.148 +  struct prefix *prefix;
   1.149 +  struct binding *nextTagBinding;
   1.150 +  struct binding *prevPrefixBinding;
   1.151 +  const struct attribute_id *attId;
   1.152 +  XML_Char *uri;
   1.153 +  int uriLen;
   1.154 +  int uriAlloc;
   1.155 +} BINDING;
   1.156 +
   1.157 +typedef struct prefix {
   1.158 +  const XML_Char *name;
   1.159 +  BINDING *binding;
   1.160 +} PREFIX;
   1.161 +
   1.162 +typedef struct {
   1.163 +  const XML_Char *str;
   1.164 +  const XML_Char *localPart;
   1.165 +  const XML_Char *prefix;
   1.166 +  int strLen;
   1.167 +  int uriLen;
   1.168 +  int prefixLen;
   1.169 +} TAG_NAME;
   1.170 +
   1.171 +/* TAG represents an open element.
   1.172 +   The name of the element is stored in both the document and API
   1.173 +   encodings.  The memory buffer 'buf' is a separately-allocated
   1.174 +   memory area which stores the name.  During the XML_Parse()/
   1.175 +   XMLParseBuffer() when the element is open, the memory for the 'raw'
   1.176 +   version of the name (in the document encoding) is shared with the
   1.177 +   document buffer.  If the element is open across calls to
   1.178 +   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
   1.179 +   contain the 'raw' name as well.
   1.180 +
   1.181 +   A parser re-uses these structures, maintaining a list of allocated
   1.182 +   TAG objects in a free list.
   1.183 +*/
   1.184 +typedef struct tag {
   1.185 +  struct tag *parent;           /* parent of this element */
   1.186 +  const char *rawName;          /* tagName in the original encoding */
   1.187 +  int rawNameLength;
   1.188 +  TAG_NAME name;                /* tagName in the API encoding */
   1.189 +  char *buf;                    /* buffer for name components */
   1.190 +  char *bufEnd;                 /* end of the buffer */
   1.191 +  BINDING *bindings;
   1.192 +} TAG;
   1.193 +
   1.194 +typedef struct {
   1.195 +  const XML_Char *name;
   1.196 +  const XML_Char *textPtr;
   1.197 +  int textLen;                  /* length in XML_Chars */
   1.198 +  int processed;                /* # of processed bytes - when suspended */
   1.199 +  const XML_Char *systemId;
   1.200 +  const XML_Char *base;
   1.201 +  const XML_Char *publicId;
   1.202 +  const XML_Char *notation;
   1.203 +  XML_Bool open;
   1.204 +  XML_Bool is_param;
   1.205 +  XML_Bool is_internal; /* true if declared in internal subset outside PE */
   1.206 +} ENTITY;
   1.207 +
   1.208 +typedef struct {
   1.209 +  enum XML_Content_Type         type;
   1.210 +  enum XML_Content_Quant        quant;
   1.211 +  const XML_Char *              name;
   1.212 +  int                           firstchild;
   1.213 +  int                           lastchild;
   1.214 +  int                           childcnt;
   1.215 +  int                           nextsib;
   1.216 +} CONTENT_SCAFFOLD;
   1.217 +
   1.218 +#define INIT_SCAFFOLD_ELEMENTS 32
   1.219 +
   1.220 +typedef struct block {
   1.221 +  struct block *next;
   1.222 +  int size;
   1.223 +  XML_Char s[1];
   1.224 +} BLOCK;
   1.225 +
   1.226 +typedef struct {
   1.227 +  BLOCK *blocks;
   1.228 +  BLOCK *freeBlocks;
   1.229 +  const XML_Char *end;
   1.230 +  XML_Char *ptr;
   1.231 +  XML_Char *start;
   1.232 +  const XML_Memory_Handling_Suite *mem;
   1.233 +} STRING_POOL;
   1.234 +
   1.235 +/* The XML_Char before the name is used to determine whether
   1.236 +   an attribute has been specified. */
   1.237 +typedef struct attribute_id {
   1.238 +  XML_Char *name;
   1.239 +  PREFIX *prefix;
   1.240 +  XML_Bool maybeTokenized;
   1.241 +  XML_Bool xmlns;
   1.242 +} ATTRIBUTE_ID;
   1.243 +
   1.244 +typedef struct {
   1.245 +  const ATTRIBUTE_ID *id;
   1.246 +  XML_Bool isCdata;
   1.247 +  const XML_Char *value;
   1.248 +} DEFAULT_ATTRIBUTE;
   1.249 +
   1.250 +typedef struct {
   1.251 +  unsigned long version;
   1.252 +  unsigned long hash;
   1.253 +  const XML_Char *uriName;
   1.254 +} NS_ATT;
   1.255 +
   1.256 +typedef struct {
   1.257 +  const XML_Char *name;
   1.258 +  PREFIX *prefix;
   1.259 +  const ATTRIBUTE_ID *idAtt;
   1.260 +  int nDefaultAtts;
   1.261 +  int allocDefaultAtts;
   1.262 +  DEFAULT_ATTRIBUTE *defaultAtts;
   1.263 +} ELEMENT_TYPE;
   1.264 +
   1.265 +typedef struct {
   1.266 +  HASH_TABLE generalEntities;
   1.267 +  HASH_TABLE elementTypes;
   1.268 +  HASH_TABLE attributeIds;
   1.269 +  HASH_TABLE prefixes;
   1.270 +  STRING_POOL pool;
   1.271 +  STRING_POOL entityValuePool;
   1.272 +  /* false once a parameter entity reference has been skipped */
   1.273 +  XML_Bool keepProcessing;
   1.274 +  /* true once an internal or external PE reference has been encountered;
   1.275 +     this includes the reference to an external subset */
   1.276 +  XML_Bool hasParamEntityRefs;
   1.277 +  XML_Bool standalone;
   1.278 +#ifdef XML_DTD
   1.279 +  /* indicates if external PE has been read */
   1.280 +  XML_Bool paramEntityRead;
   1.281 +  HASH_TABLE paramEntities;
   1.282 +#endif /* XML_DTD */
   1.283 +  PREFIX defaultPrefix;
   1.284 +  /* === scaffolding for building content model === */
   1.285 +  XML_Bool in_eldecl;
   1.286 +  CONTENT_SCAFFOLD *scaffold;
   1.287 +  unsigned contentStringLen;
   1.288 +  unsigned scaffSize;
   1.289 +  unsigned scaffCount;
   1.290 +  int scaffLevel;
   1.291 +  int *scaffIndex;
   1.292 +} DTD;
   1.293 +
   1.294 +typedef struct open_internal_entity {
   1.295 +  const char *internalEventPtr;
   1.296 +  const char *internalEventEndPtr;
   1.297 +  struct open_internal_entity *next;
   1.298 +  ENTITY *entity;
   1.299 +  int startTagLevel;
   1.300 +  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
   1.301 +} OPEN_INTERNAL_ENTITY;
   1.302 +
   1.303 +typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
   1.304 +                                         const char *start,
   1.305 +                                         const char *end,
   1.306 +                                         const char **endPtr);
   1.307 +
   1.308 +static Processor prologProcessor;
   1.309 +static Processor prologInitProcessor;
   1.310 +static Processor contentProcessor;
   1.311 +static Processor cdataSectionProcessor;
   1.312 +#ifdef XML_DTD
   1.313 +static Processor ignoreSectionProcessor;
   1.314 +static Processor externalParEntProcessor;
   1.315 +static Processor externalParEntInitProcessor;
   1.316 +static Processor entityValueProcessor;
   1.317 +static Processor entityValueInitProcessor;
   1.318 +#endif /* XML_DTD */
   1.319 +static Processor epilogProcessor;
   1.320 +static Processor errorProcessor;
   1.321 +static Processor externalEntityInitProcessor;
   1.322 +static Processor externalEntityInitProcessor2;
   1.323 +static Processor externalEntityInitProcessor3;
   1.324 +static Processor externalEntityContentProcessor;
   1.325 +static Processor internalEntityProcessor;
   1.326 +
   1.327 +static enum XML_Error
   1.328 +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
   1.329 +static enum XML_Error
   1.330 +processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
   1.331 +               const char *s, const char *next);
   1.332 +static enum XML_Error
   1.333 +initializeEncoding(XML_Parser parser);
   1.334 +static enum XML_Error
   1.335 +doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
   1.336 +         const char *end, int tok, const char *next, const char **nextPtr, 
   1.337 +         XML_Bool haveMore);
   1.338 +static enum XML_Error
   1.339 +processInternalEntity(XML_Parser parser, ENTITY *entity, 
   1.340 +                      XML_Bool betweenDecl);
   1.341 +static enum XML_Error
   1.342 +doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
   1.343 +          const char *start, const char *end, const char **endPtr, 
   1.344 +          XML_Bool haveMore);
   1.345 +static enum XML_Error
   1.346 +doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
   1.347 +               const char *end, const char **nextPtr, XML_Bool haveMore);
   1.348 +#ifdef XML_DTD
   1.349 +static enum XML_Error
   1.350 +doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
   1.351 +                const char *end, const char **nextPtr, XML_Bool haveMore);
   1.352 +#endif /* XML_DTD */
   1.353 +
   1.354 +static enum XML_Error
   1.355 +storeAtts(XML_Parser parser, const ENCODING *, const char *s,
   1.356 +          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
   1.357 +static enum XML_Error
   1.358 +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   1.359 +           const XML_Char *uri, BINDING **bindingsPtr);
   1.360 +static int
   1.361 +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
   1.362 +                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
   1.363 +static enum XML_Error
   1.364 +storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
   1.365 +                    const char *, const char *, STRING_POOL *);
   1.366 +static enum XML_Error
   1.367 +appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
   1.368 +                     const char *, const char *, STRING_POOL *);
   1.369 +static ATTRIBUTE_ID *
   1.370 +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
   1.371 +               const char *end);
   1.372 +static int
   1.373 +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
   1.374 +static enum XML_Error
   1.375 +storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
   1.376 +                 const char *end);
   1.377 +static int
   1.378 +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
   1.379 +                            const char *start, const char *end);
   1.380 +static int
   1.381 +reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
   1.382 +              const char *end);
   1.383 +static void
   1.384 +reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
   1.385 +              const char *end);
   1.386 +
   1.387 +static const XML_Char * getContext(XML_Parser parser);
   1.388 +static XML_Bool
   1.389 +setContext(XML_Parser parser, const XML_Char *context);
   1.390 +
   1.391 +static void FASTCALL normalizePublicId(XML_Char *s);
   1.392 +
   1.393 +static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
   1.394 +/* do not call if parentParser != NULL */
   1.395 +static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
   1.396 +static void
   1.397 +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
   1.398 +static int
   1.399 +dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
   1.400 +static int
   1.401 +copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
   1.402 +
   1.403 +static NAMED *
   1.404 +lookup(HASH_TABLE *table, KEY name, size_t createSize);
   1.405 +static void FASTCALL
   1.406 +hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
   1.407 +static void FASTCALL hashTableClear(HASH_TABLE *);
   1.408 +static void FASTCALL hashTableDestroy(HASH_TABLE *);
   1.409 +static void FASTCALL
   1.410 +hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
   1.411 +static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
   1.412 +
   1.413 +static void FASTCALL
   1.414 +poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
   1.415 +static void FASTCALL poolClear(STRING_POOL *);
   1.416 +static void FASTCALL poolDestroy(STRING_POOL *);
   1.417 +static XML_Char *
   1.418 +poolAppend(STRING_POOL *pool, const ENCODING *enc,
   1.419 +           const char *ptr, const char *end);
   1.420 +static XML_Char *
   1.421 +poolStoreString(STRING_POOL *pool, const ENCODING *enc,
   1.422 +                const char *ptr, const char *end);
   1.423 +static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
   1.424 +static const XML_Char * FASTCALL
   1.425 +poolCopyString(STRING_POOL *pool, const XML_Char *s);
   1.426 +static const XML_Char *
   1.427 +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
   1.428 +static const XML_Char * FASTCALL
   1.429 +poolAppendString(STRING_POOL *pool, const XML_Char *s);
   1.430 +
   1.431 +static int FASTCALL nextScaffoldPart(XML_Parser parser);
   1.432 +static XML_Content * build_model(XML_Parser parser);
   1.433 +static ELEMENT_TYPE *
   1.434 +getElementType(XML_Parser parser, const ENCODING *enc,
   1.435 +               const char *ptr, const char *end);
   1.436 +
   1.437 +static XML_Parser
   1.438 +parserCreate(const XML_Char *encodingName,
   1.439 +             const XML_Memory_Handling_Suite *memsuite,
   1.440 +             const XML_Char *nameSep,
   1.441 +             DTD *dtd);
   1.442 +static void
   1.443 +parserInit(XML_Parser parser, const XML_Char *encodingName);
   1.444 +
   1.445 +#define poolStart(pool) ((pool)->start)
   1.446 +#define poolEnd(pool) ((pool)->ptr)
   1.447 +#define poolLength(pool) ((pool)->ptr - (pool)->start)
   1.448 +#define poolChop(pool) ((void)--(pool->ptr))
   1.449 +#define poolLastChar(pool) (((pool)->ptr)[-1])
   1.450 +#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
   1.451 +#define poolFinish(pool) ((pool)->start = (pool)->ptr)
   1.452 +#define poolAppendChar(pool, c) \
   1.453 +  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
   1.454 +   ? 0 \
   1.455 +   : ((*((pool)->ptr)++ = c), 1))
   1.456 +
   1.457 +struct XML_ParserStruct {
   1.458 +  /* The first member must be userData so that the XML_GetUserData
   1.459 +     macro works. */
   1.460 +  void *m_userData;
   1.461 +  void *m_handlerArg;
   1.462 +  char *m_buffer;
   1.463 +  const XML_Memory_Handling_Suite m_mem;
   1.464 +  /* first character to be parsed */
   1.465 +  const char *m_bufferPtr;
   1.466 +  /* past last character to be parsed */
   1.467 +  char *m_bufferEnd;
   1.468 +  /* allocated end of buffer */
   1.469 +  const char *m_bufferLim;
   1.470 +  XML_Index m_parseEndByteIndex;
   1.471 +  const char *m_parseEndPtr;
   1.472 +  XML_Char *m_dataBuf;
   1.473 +  XML_Char *m_dataBufEnd;
   1.474 +  XML_StartElementHandler m_startElementHandler;
   1.475 +  XML_EndElementHandler m_endElementHandler;
   1.476 +  XML_CharacterDataHandler m_characterDataHandler;
   1.477 +  XML_ProcessingInstructionHandler m_processingInstructionHandler;
   1.478 +  XML_CommentHandler m_commentHandler;
   1.479 +  XML_StartCdataSectionHandler m_startCdataSectionHandler;
   1.480 +  XML_EndCdataSectionHandler m_endCdataSectionHandler;
   1.481 +  XML_DefaultHandler m_defaultHandler;
   1.482 +  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
   1.483 +  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
   1.484 +  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
   1.485 +  XML_NotationDeclHandler m_notationDeclHandler;
   1.486 +  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
   1.487 +  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
   1.488 +  XML_NotStandaloneHandler m_notStandaloneHandler;
   1.489 +  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
   1.490 +  XML_Parser m_externalEntityRefHandlerArg;
   1.491 +  XML_SkippedEntityHandler m_skippedEntityHandler;
   1.492 +  XML_UnknownEncodingHandler m_unknownEncodingHandler;
   1.493 +  XML_ElementDeclHandler m_elementDeclHandler;
   1.494 +  XML_AttlistDeclHandler m_attlistDeclHandler;
   1.495 +  XML_EntityDeclHandler m_entityDeclHandler;
   1.496 +  XML_XmlDeclHandler m_xmlDeclHandler;
   1.497 +  const ENCODING *m_encoding;
   1.498 +  INIT_ENCODING m_initEncoding;
   1.499 +  const ENCODING *m_internalEncoding;
   1.500 +  const XML_Char *m_protocolEncodingName;
   1.501 +  XML_Bool m_ns;
   1.502 +  XML_Bool m_ns_triplets;
   1.503 +  void *m_unknownEncodingMem;
   1.504 +  void *m_unknownEncodingData;
   1.505 +  void *m_unknownEncodingHandlerData;
   1.506 +  void (XMLCALL *m_unknownEncodingRelease)(void *);
   1.507 +  PROLOG_STATE m_prologState;
   1.508 +  Processor *m_processor;
   1.509 +  enum XML_Error m_errorCode;
   1.510 +  const char *m_eventPtr;
   1.511 +  const char *m_eventEndPtr;
   1.512 +  const char *m_positionPtr;
   1.513 +  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
   1.514 +  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
   1.515 +  XML_Bool m_defaultExpandInternalEntities;
   1.516 +  int m_tagLevel;
   1.517 +  ENTITY *m_declEntity;
   1.518 +  const XML_Char *m_doctypeName;
   1.519 +  const XML_Char *m_doctypeSysid;
   1.520 +  const XML_Char *m_doctypePubid;
   1.521 +  const XML_Char *m_declAttributeType;
   1.522 +  const XML_Char *m_declNotationName;
   1.523 +  const XML_Char *m_declNotationPublicId;
   1.524 +  ELEMENT_TYPE *m_declElementType;
   1.525 +  ATTRIBUTE_ID *m_declAttributeId;
   1.526 +  XML_Bool m_declAttributeIsCdata;
   1.527 +  XML_Bool m_declAttributeIsId;
   1.528 +  DTD *m_dtd;
   1.529 +  const XML_Char *m_curBase;
   1.530 +  TAG *m_tagStack;
   1.531 +  TAG *m_freeTagList;
   1.532 +  BINDING *m_inheritedBindings;
   1.533 +  BINDING *m_freeBindingList;
   1.534 +  int m_attsSize;
   1.535 +  int m_nSpecifiedAtts;
   1.536 +  int m_idAttIndex;
   1.537 +  ATTRIBUTE *m_atts;
   1.538 +  NS_ATT *m_nsAtts;
   1.539 +  unsigned long m_nsAttsVersion;
   1.540 +  unsigned char m_nsAttsPower;
   1.541 +  POSITION m_position;
   1.542 +  STRING_POOL m_tempPool;
   1.543 +  STRING_POOL m_temp2Pool;
   1.544 +  char *m_groupConnector;
   1.545 +  unsigned int m_groupSize;
   1.546 +  XML_Char m_namespaceSeparator;
   1.547 +  XML_Parser m_parentParser;
   1.548 +  XML_ParsingStatus m_parsingStatus;
   1.549 +#ifdef XML_DTD
   1.550 +  XML_Bool m_isParamEntity;
   1.551 +  XML_Bool m_useForeignDTD;
   1.552 +  enum XML_ParamEntityParsing m_paramEntityParsing;
   1.553 +#endif
   1.554 +/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
   1.555 +  const XML_Char* m_mismatch;
   1.556 +/* END MOZILLA CHANGE */
   1.557 +};
   1.558 +
   1.559 +#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
   1.560 +#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
   1.561 +#define FREE(p) (parser->m_mem.free_fcn((p)))
   1.562 +
   1.563 +#define userData (parser->m_userData)
   1.564 +#define handlerArg (parser->m_handlerArg)
   1.565 +#define startElementHandler (parser->m_startElementHandler)
   1.566 +#define endElementHandler (parser->m_endElementHandler)
   1.567 +#define characterDataHandler (parser->m_characterDataHandler)
   1.568 +#define processingInstructionHandler \
   1.569 +        (parser->m_processingInstructionHandler)
   1.570 +#define commentHandler (parser->m_commentHandler)
   1.571 +#define startCdataSectionHandler \
   1.572 +        (parser->m_startCdataSectionHandler)
   1.573 +#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
   1.574 +#define defaultHandler (parser->m_defaultHandler)
   1.575 +#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
   1.576 +#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
   1.577 +#define unparsedEntityDeclHandler \
   1.578 +        (parser->m_unparsedEntityDeclHandler)
   1.579 +#define notationDeclHandler (parser->m_notationDeclHandler)
   1.580 +#define startNamespaceDeclHandler \
   1.581 +        (parser->m_startNamespaceDeclHandler)
   1.582 +#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
   1.583 +#define notStandaloneHandler (parser->m_notStandaloneHandler)
   1.584 +#define externalEntityRefHandler \
   1.585 +        (parser->m_externalEntityRefHandler)
   1.586 +#define externalEntityRefHandlerArg \
   1.587 +        (parser->m_externalEntityRefHandlerArg)
   1.588 +#define internalEntityRefHandler \
   1.589 +        (parser->m_internalEntityRefHandler)
   1.590 +#define skippedEntityHandler (parser->m_skippedEntityHandler)
   1.591 +#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
   1.592 +#define elementDeclHandler (parser->m_elementDeclHandler)
   1.593 +#define attlistDeclHandler (parser->m_attlistDeclHandler)
   1.594 +#define entityDeclHandler (parser->m_entityDeclHandler)
   1.595 +#define xmlDeclHandler (parser->m_xmlDeclHandler)
   1.596 +#define encoding (parser->m_encoding)
   1.597 +#define initEncoding (parser->m_initEncoding)
   1.598 +#define internalEncoding (parser->m_internalEncoding)
   1.599 +#define unknownEncodingMem (parser->m_unknownEncodingMem)
   1.600 +#define unknownEncodingData (parser->m_unknownEncodingData)
   1.601 +#define unknownEncodingHandlerData \
   1.602 +  (parser->m_unknownEncodingHandlerData)
   1.603 +#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
   1.604 +#define protocolEncodingName (parser->m_protocolEncodingName)
   1.605 +#define ns (parser->m_ns)
   1.606 +#define ns_triplets (parser->m_ns_triplets)
   1.607 +#define prologState (parser->m_prologState)
   1.608 +#define processor (parser->m_processor)
   1.609 +#define errorCode (parser->m_errorCode)
   1.610 +#define eventPtr (parser->m_eventPtr)
   1.611 +#define eventEndPtr (parser->m_eventEndPtr)
   1.612 +#define positionPtr (parser->m_positionPtr)
   1.613 +#define position (parser->m_position)
   1.614 +#define openInternalEntities (parser->m_openInternalEntities)
   1.615 +#define freeInternalEntities (parser->m_freeInternalEntities)
   1.616 +#define defaultExpandInternalEntities \
   1.617 +        (parser->m_defaultExpandInternalEntities)
   1.618 +#define tagLevel (parser->m_tagLevel)
   1.619 +#define buffer (parser->m_buffer)
   1.620 +#define bufferPtr (parser->m_bufferPtr)
   1.621 +#define bufferEnd (parser->m_bufferEnd)
   1.622 +#define parseEndByteIndex (parser->m_parseEndByteIndex)
   1.623 +#define parseEndPtr (parser->m_parseEndPtr)
   1.624 +#define bufferLim (parser->m_bufferLim)
   1.625 +#define dataBuf (parser->m_dataBuf)
   1.626 +#define dataBufEnd (parser->m_dataBufEnd)
   1.627 +#define _dtd (parser->m_dtd)
   1.628 +#define curBase (parser->m_curBase)
   1.629 +#define declEntity (parser->m_declEntity)
   1.630 +#define doctypeName (parser->m_doctypeName)
   1.631 +#define doctypeSysid (parser->m_doctypeSysid)
   1.632 +#define doctypePubid (parser->m_doctypePubid)
   1.633 +#define declAttributeType (parser->m_declAttributeType)
   1.634 +#define declNotationName (parser->m_declNotationName)
   1.635 +#define declNotationPublicId (parser->m_declNotationPublicId)
   1.636 +#define declElementType (parser->m_declElementType)
   1.637 +#define declAttributeId (parser->m_declAttributeId)
   1.638 +#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
   1.639 +#define declAttributeIsId (parser->m_declAttributeIsId)
   1.640 +#define freeTagList (parser->m_freeTagList)
   1.641 +#define freeBindingList (parser->m_freeBindingList)
   1.642 +#define inheritedBindings (parser->m_inheritedBindings)
   1.643 +#define tagStack (parser->m_tagStack)
   1.644 +#define atts (parser->m_atts)
   1.645 +#define attsSize (parser->m_attsSize)
   1.646 +#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
   1.647 +#define idAttIndex (parser->m_idAttIndex)
   1.648 +#define nsAtts (parser->m_nsAtts)
   1.649 +#define nsAttsVersion (parser->m_nsAttsVersion)
   1.650 +#define nsAttsPower (parser->m_nsAttsPower)
   1.651 +#define tempPool (parser->m_tempPool)
   1.652 +#define temp2Pool (parser->m_temp2Pool)
   1.653 +#define groupConnector (parser->m_groupConnector)
   1.654 +#define groupSize (parser->m_groupSize)
   1.655 +#define namespaceSeparator (parser->m_namespaceSeparator)
   1.656 +#define parentParser (parser->m_parentParser)
   1.657 +#define ps_parsing (parser->m_parsingStatus.parsing)
   1.658 +#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
   1.659 +#ifdef XML_DTD
   1.660 +#define isParamEntity (parser->m_isParamEntity)
   1.661 +#define useForeignDTD (parser->m_useForeignDTD)
   1.662 +#define paramEntityParsing (parser->m_paramEntityParsing)
   1.663 +#endif /* XML_DTD */
   1.664 +/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
   1.665 +#define mismatch (parser->m_mismatch)
   1.666 +/* END MOZILLA CHANGE */
   1.667 +
   1.668 +/* BEGIN MOZILLA CHANGE (unused API) */
   1.669 +#if 0
   1.670 +XML_Parser XMLCALL
   1.671 +XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
   1.672 +{
   1.673 +  XML_Char tmp[2];
   1.674 +  *tmp = nsSep;
   1.675 +  return XML_ParserCreate_MM(encodingName, NULL, tmp);
   1.676 +}
   1.677 +#endif
   1.678 +/* END MOZILLA CHANGE */
   1.679 +
   1.680 +static const XML_Char implicitContext[] = {
   1.681 +  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
   1.682 +  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
   1.683 +  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
   1.684 +  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
   1.685 +};
   1.686 +
   1.687 +XML_Parser XMLCALL
   1.688 +XML_ParserCreate_MM(const XML_Char *encodingName,
   1.689 +                    const XML_Memory_Handling_Suite *memsuite,
   1.690 +                    const XML_Char *nameSep)
   1.691 +{
   1.692 +  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
   1.693 +  if (parser != NULL && ns) {
   1.694 +    /* implicit context only set for root parser, since child
   1.695 +       parsers (i.e. external entity parsers) will inherit it
   1.696 +    */
   1.697 +    if (!setContext(parser, implicitContext)) {
   1.698 +      XML_ParserFree(parser);
   1.699 +      return NULL;
   1.700 +    }
   1.701 +  }
   1.702 +  return parser;
   1.703 +}
   1.704 +
   1.705 +static XML_Parser
   1.706 +parserCreate(const XML_Char *encodingName,
   1.707 +             const XML_Memory_Handling_Suite *memsuite,
   1.708 +             const XML_Char *nameSep,
   1.709 +             DTD *dtd)
   1.710 +{
   1.711 +  XML_Parser parser;
   1.712 +
   1.713 +  if (memsuite) {
   1.714 +    XML_Memory_Handling_Suite *mtemp;
   1.715 +    parser = (XML_Parser)
   1.716 +      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
   1.717 +    if (parser != NULL) {
   1.718 +      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
   1.719 +      mtemp->malloc_fcn = memsuite->malloc_fcn;
   1.720 +      mtemp->realloc_fcn = memsuite->realloc_fcn;
   1.721 +      mtemp->free_fcn = memsuite->free_fcn;
   1.722 +    }
   1.723 +  }
   1.724 +  else {
   1.725 +    XML_Memory_Handling_Suite *mtemp;
   1.726 +    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
   1.727 +    if (parser != NULL) {
   1.728 +      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
   1.729 +      mtemp->malloc_fcn = malloc;
   1.730 +      mtemp->realloc_fcn = realloc;
   1.731 +      mtemp->free_fcn = free;
   1.732 +    }
   1.733 +  }
   1.734 +
   1.735 +  if (!parser)
   1.736 +    return parser;
   1.737 +
   1.738 +  buffer = NULL;
   1.739 +  bufferLim = NULL;
   1.740 +
   1.741 +  attsSize = INIT_ATTS_SIZE;
   1.742 +  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
   1.743 +  if (atts == NULL) {
   1.744 +    FREE(parser);
   1.745 +    return NULL;
   1.746 +  }
   1.747 +  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
   1.748 +  if (dataBuf == NULL) {
   1.749 +    FREE(atts);
   1.750 +    FREE(parser);
   1.751 +    return NULL;
   1.752 +  }
   1.753 +  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
   1.754 +
   1.755 +  if (dtd)
   1.756 +    _dtd = dtd;
   1.757 +  else {
   1.758 +    _dtd = dtdCreate(&parser->m_mem);
   1.759 +    if (_dtd == NULL) {
   1.760 +      FREE(dataBuf);
   1.761 +      FREE(atts);
   1.762 +      FREE(parser);
   1.763 +      return NULL;
   1.764 +    }
   1.765 +  }
   1.766 +
   1.767 +  freeBindingList = NULL;
   1.768 +  freeTagList = NULL;
   1.769 +  freeInternalEntities = NULL;
   1.770 +
   1.771 +  groupSize = 0;
   1.772 +  groupConnector = NULL;
   1.773 +
   1.774 +  unknownEncodingHandler = NULL;
   1.775 +  unknownEncodingHandlerData = NULL;
   1.776 +
   1.777 +  namespaceSeparator = '!';
   1.778 +  ns = XML_FALSE;
   1.779 +  ns_triplets = XML_FALSE;
   1.780 +
   1.781 +  nsAtts = NULL;
   1.782 +  nsAttsVersion = 0;
   1.783 +  nsAttsPower = 0;
   1.784 +
   1.785 +  poolInit(&tempPool, &(parser->m_mem));
   1.786 +  poolInit(&temp2Pool, &(parser->m_mem));
   1.787 +  parserInit(parser, encodingName);
   1.788 +
   1.789 +  if (encodingName && !protocolEncodingName) {
   1.790 +    XML_ParserFree(parser);
   1.791 +    return NULL;
   1.792 +  }
   1.793 +
   1.794 +  if (nameSep) {
   1.795 +    ns = XML_TRUE;
   1.796 +    internalEncoding = XmlGetInternalEncodingNS();
   1.797 +    namespaceSeparator = *nameSep;
   1.798 +  }
   1.799 +  else {
   1.800 +    internalEncoding = XmlGetInternalEncoding();
   1.801 +  }
   1.802 +
   1.803 +/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
   1.804 +  mismatch = NULL;
   1.805 +/* END MOZILLA CHANGE */
   1.806 +
   1.807 +  return parser;
   1.808 +}
   1.809 +
   1.810 +static void
   1.811 +parserInit(XML_Parser parser, const XML_Char *encodingName)
   1.812 +{
   1.813 +  processor = prologInitProcessor;
   1.814 +  XmlPrologStateInit(&prologState);
   1.815 +  protocolEncodingName = (encodingName != NULL
   1.816 +                          ? poolCopyString(&tempPool, encodingName)
   1.817 +                          : NULL);
   1.818 +  curBase = NULL;
   1.819 +  XmlInitEncoding(&initEncoding, &encoding, 0);
   1.820 +  userData = NULL;
   1.821 +  handlerArg = NULL;
   1.822 +  startElementHandler = NULL;
   1.823 +  endElementHandler = NULL;
   1.824 +  characterDataHandler = NULL;
   1.825 +  processingInstructionHandler = NULL;
   1.826 +  commentHandler = NULL;
   1.827 +  startCdataSectionHandler = NULL;
   1.828 +  endCdataSectionHandler = NULL;
   1.829 +  defaultHandler = NULL;
   1.830 +  startDoctypeDeclHandler = NULL;
   1.831 +  endDoctypeDeclHandler = NULL;
   1.832 +  unparsedEntityDeclHandler = NULL;
   1.833 +  notationDeclHandler = NULL;
   1.834 +  startNamespaceDeclHandler = NULL;
   1.835 +  endNamespaceDeclHandler = NULL;
   1.836 +  notStandaloneHandler = NULL;
   1.837 +  externalEntityRefHandler = NULL;
   1.838 +  externalEntityRefHandlerArg = parser;
   1.839 +  skippedEntityHandler = NULL;
   1.840 +  elementDeclHandler = NULL;
   1.841 +  attlistDeclHandler = NULL;
   1.842 +  entityDeclHandler = NULL;
   1.843 +  xmlDeclHandler = NULL;
   1.844 +  bufferPtr = buffer;
   1.845 +  bufferEnd = buffer;
   1.846 +  parseEndByteIndex = 0;
   1.847 +  parseEndPtr = NULL;
   1.848 +  declElementType = NULL;
   1.849 +  declAttributeId = NULL;
   1.850 +  declEntity = NULL;
   1.851 +  doctypeName = NULL;
   1.852 +  doctypeSysid = NULL;
   1.853 +  doctypePubid = NULL;
   1.854 +  declAttributeType = NULL;
   1.855 +  declNotationName = NULL;
   1.856 +  declNotationPublicId = NULL;
   1.857 +  declAttributeIsCdata = XML_FALSE;
   1.858 +  declAttributeIsId = XML_FALSE;
   1.859 +  memset(&position, 0, sizeof(POSITION));
   1.860 +  errorCode = XML_ERROR_NONE;
   1.861 +  eventPtr = NULL;
   1.862 +  eventEndPtr = NULL;
   1.863 +  positionPtr = NULL;
   1.864 +  openInternalEntities = NULL;
   1.865 +  defaultExpandInternalEntities = XML_TRUE;
   1.866 +  tagLevel = 0;
   1.867 +  tagStack = NULL;
   1.868 +  inheritedBindings = NULL;
   1.869 +  nSpecifiedAtts = 0;
   1.870 +  unknownEncodingMem = NULL;
   1.871 +  unknownEncodingRelease = NULL;
   1.872 +  unknownEncodingData = NULL;
   1.873 +  parentParser = NULL;
   1.874 +  ps_parsing = XML_INITIALIZED;
   1.875 +#ifdef XML_DTD
   1.876 +  isParamEntity = XML_FALSE;
   1.877 +  useForeignDTD = XML_FALSE;
   1.878 +  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
   1.879 +#endif
   1.880 +}
   1.881 +
   1.882 +/* moves list of bindings to freeBindingList */
   1.883 +static void FASTCALL
   1.884 +moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
   1.885 +{
   1.886 +  while (bindings) {
   1.887 +    BINDING *b = bindings;
   1.888 +    bindings = bindings->nextTagBinding;
   1.889 +    b->nextTagBinding = freeBindingList;
   1.890 +    freeBindingList = b;
   1.891 +  }
   1.892 +}
   1.893 +
   1.894 +/* BEGIN MOZILLA CHANGE (unused API) */
   1.895 +#if 0
   1.896 +XML_Bool XMLCALL
   1.897 +XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
   1.898 +{
   1.899 +  TAG *tStk;
   1.900 +  OPEN_INTERNAL_ENTITY *openEntityList;
   1.901 +  if (parentParser)
   1.902 +    return XML_FALSE;
   1.903 +  /* move tagStack to freeTagList */
   1.904 +  tStk = tagStack;
   1.905 +  while (tStk) {
   1.906 +    TAG *tag = tStk;
   1.907 +    tStk = tStk->parent;
   1.908 +    tag->parent = freeTagList;
   1.909 +    moveToFreeBindingList(parser, tag->bindings);
   1.910 +    tag->bindings = NULL;
   1.911 +    freeTagList = tag;
   1.912 +  }
   1.913 +  /* move openInternalEntities to freeInternalEntities */
   1.914 +  openEntityList = openInternalEntities;
   1.915 +  while (openEntityList) {
   1.916 +    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
   1.917 +    openEntityList = openEntity->next;
   1.918 +    openEntity->next = freeInternalEntities;
   1.919 +    freeInternalEntities = openEntity;
   1.920 +  }
   1.921 +  moveToFreeBindingList(parser, inheritedBindings);
   1.922 +  FREE(unknownEncodingMem);
   1.923 +  if (unknownEncodingRelease)
   1.924 +    unknownEncodingRelease(unknownEncodingData);
   1.925 +  poolClear(&tempPool);
   1.926 +  poolClear(&temp2Pool);
   1.927 +  parserInit(parser, encodingName);
   1.928 +  dtdReset(_dtd, &parser->m_mem);
   1.929 +  return setContext(parser, implicitContext);
   1.930 +}
   1.931 +
   1.932 +enum XML_Status XMLCALL
   1.933 +XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
   1.934 +{
   1.935 +  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
   1.936 +     XXX There's no way for the caller to determine which of the
   1.937 +     XXX possible error cases caused the XML_STATUS_ERROR return.
   1.938 +  */
   1.939 +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
   1.940 +    return XML_STATUS_ERROR;
   1.941 +  if (encodingName == NULL)
   1.942 +    protocolEncodingName = NULL;
   1.943 +  else {
   1.944 +    protocolEncodingName = poolCopyString(&tempPool, encodingName);
   1.945 +    if (!protocolEncodingName)
   1.946 +      return XML_STATUS_ERROR;
   1.947 +  }
   1.948 +  return XML_STATUS_OK;
   1.949 +}
   1.950 +#endif
   1.951 +/* END MOZILLA CHANGE */
   1.952 +
   1.953 +XML_Parser XMLCALL
   1.954 +XML_ExternalEntityParserCreate(XML_Parser oldParser,
   1.955 +                               const XML_Char *context,
   1.956 +                               const XML_Char *encodingName)
   1.957 +{
   1.958 +  XML_Parser parser = oldParser;
   1.959 +  DTD *newDtd = NULL;
   1.960 +  DTD *oldDtd = _dtd;
   1.961 +  XML_StartElementHandler oldStartElementHandler = startElementHandler;
   1.962 +  XML_EndElementHandler oldEndElementHandler = endElementHandler;
   1.963 +  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
   1.964 +  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
   1.965 +      = processingInstructionHandler;
   1.966 +  XML_CommentHandler oldCommentHandler = commentHandler;
   1.967 +  XML_StartCdataSectionHandler oldStartCdataSectionHandler
   1.968 +      = startCdataSectionHandler;
   1.969 +  XML_EndCdataSectionHandler oldEndCdataSectionHandler
   1.970 +      = endCdataSectionHandler;
   1.971 +  XML_DefaultHandler oldDefaultHandler = defaultHandler;
   1.972 +  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
   1.973 +      = unparsedEntityDeclHandler;
   1.974 +  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
   1.975 +  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
   1.976 +      = startNamespaceDeclHandler;
   1.977 +  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
   1.978 +      = endNamespaceDeclHandler;
   1.979 +  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
   1.980 +  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
   1.981 +      = externalEntityRefHandler;
   1.982 +  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
   1.983 +  XML_UnknownEncodingHandler oldUnknownEncodingHandler
   1.984 +      = unknownEncodingHandler;
   1.985 +  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
   1.986 +  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
   1.987 +  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
   1.988 +  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
   1.989 +  ELEMENT_TYPE * oldDeclElementType = declElementType;
   1.990 +
   1.991 +  void *oldUserData = userData;
   1.992 +  void *oldHandlerArg = handlerArg;
   1.993 +  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
   1.994 +  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
   1.995 +#ifdef XML_DTD
   1.996 +  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
   1.997 +  int oldInEntityValue = prologState.inEntityValue;
   1.998 +#endif
   1.999 +  XML_Bool oldns_triplets = ns_triplets;
  1.1000 +
  1.1001 +#ifdef XML_DTD
  1.1002 +  if (!context)
  1.1003 +    newDtd = oldDtd;
  1.1004 +#endif /* XML_DTD */
  1.1005 +
  1.1006 +  /* Note that the magical uses of the pre-processor to make field
  1.1007 +     access look more like C++ require that `parser' be overwritten
  1.1008 +     here.  This makes this function more painful to follow than it
  1.1009 +     would be otherwise.
  1.1010 +  */
  1.1011 +  if (ns) {
  1.1012 +    XML_Char tmp[2];
  1.1013 +    *tmp = namespaceSeparator;
  1.1014 +    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
  1.1015 +  }
  1.1016 +  else {
  1.1017 +    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
  1.1018 +  }
  1.1019 +
  1.1020 +  if (!parser)
  1.1021 +    return NULL;
  1.1022 +
  1.1023 +  startElementHandler = oldStartElementHandler;
  1.1024 +  endElementHandler = oldEndElementHandler;
  1.1025 +  characterDataHandler = oldCharacterDataHandler;
  1.1026 +  processingInstructionHandler = oldProcessingInstructionHandler;
  1.1027 +  commentHandler = oldCommentHandler;
  1.1028 +  startCdataSectionHandler = oldStartCdataSectionHandler;
  1.1029 +  endCdataSectionHandler = oldEndCdataSectionHandler;
  1.1030 +  defaultHandler = oldDefaultHandler;
  1.1031 +  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
  1.1032 +  notationDeclHandler = oldNotationDeclHandler;
  1.1033 +  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
  1.1034 +  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
  1.1035 +  notStandaloneHandler = oldNotStandaloneHandler;
  1.1036 +  externalEntityRefHandler = oldExternalEntityRefHandler;
  1.1037 +  skippedEntityHandler = oldSkippedEntityHandler;
  1.1038 +  unknownEncodingHandler = oldUnknownEncodingHandler;
  1.1039 +  elementDeclHandler = oldElementDeclHandler;
  1.1040 +  attlistDeclHandler = oldAttlistDeclHandler;
  1.1041 +  entityDeclHandler = oldEntityDeclHandler;
  1.1042 +  xmlDeclHandler = oldXmlDeclHandler;
  1.1043 +  declElementType = oldDeclElementType;
  1.1044 +  userData = oldUserData;
  1.1045 +  if (oldUserData == oldHandlerArg)
  1.1046 +    handlerArg = userData;
  1.1047 +  else
  1.1048 +    handlerArg = parser;
  1.1049 +  if (oldExternalEntityRefHandlerArg != oldParser)
  1.1050 +    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
  1.1051 +  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
  1.1052 +  ns_triplets = oldns_triplets;
  1.1053 +  parentParser = oldParser;
  1.1054 +#ifdef XML_DTD
  1.1055 +  paramEntityParsing = oldParamEntityParsing;
  1.1056 +  prologState.inEntityValue = oldInEntityValue;
  1.1057 +  if (context) {
  1.1058 +#endif /* XML_DTD */
  1.1059 +    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
  1.1060 +      || !setContext(parser, context)) {
  1.1061 +      XML_ParserFree(parser);
  1.1062 +      return NULL;
  1.1063 +    }
  1.1064 +    processor = externalEntityInitProcessor;
  1.1065 +#ifdef XML_DTD
  1.1066 +  }
  1.1067 +  else {
  1.1068 +    /* The DTD instance referenced by _dtd is shared between the document's
  1.1069 +       root parser and external PE parsers, therefore one does not need to
  1.1070 +       call setContext. In addition, one also *must* not call setContext,
  1.1071 +       because this would overwrite existing prefix->binding pointers in
  1.1072 +       _dtd with ones that get destroyed with the external PE parser.
  1.1073 +       This would leave those prefixes with dangling pointers.
  1.1074 +    */
  1.1075 +    isParamEntity = XML_TRUE;
  1.1076 +    XmlPrologStateInitExternalEntity(&prologState);
  1.1077 +    processor = externalParEntInitProcessor;
  1.1078 +  }
  1.1079 +#endif /* XML_DTD */
  1.1080 +  return parser;
  1.1081 +}
  1.1082 +
  1.1083 +static void FASTCALL
  1.1084 +destroyBindings(BINDING *bindings, XML_Parser parser)
  1.1085 +{
  1.1086 +  for (;;) {
  1.1087 +    BINDING *b = bindings;
  1.1088 +    if (!b)
  1.1089 +      break;
  1.1090 +    bindings = b->nextTagBinding;
  1.1091 +    FREE(b->uri);
  1.1092 +    FREE(b);
  1.1093 +  }
  1.1094 +}
  1.1095 +
  1.1096 +void XMLCALL
  1.1097 +XML_ParserFree(XML_Parser parser)
  1.1098 +{
  1.1099 +  TAG *tagList;
  1.1100 +  OPEN_INTERNAL_ENTITY *entityList;
  1.1101 +  if (parser == NULL)
  1.1102 +    return;
  1.1103 +  /* free tagStack and freeTagList */
  1.1104 +  tagList = tagStack;
  1.1105 +  for (;;) {
  1.1106 +    TAG *p;
  1.1107 +    if (tagList == NULL) {
  1.1108 +      if (freeTagList == NULL)
  1.1109 +        break;
  1.1110 +      tagList = freeTagList;
  1.1111 +      freeTagList = NULL;
  1.1112 +    }
  1.1113 +    p = tagList;
  1.1114 +    tagList = tagList->parent;
  1.1115 +    FREE(p->buf);
  1.1116 +    destroyBindings(p->bindings, parser);
  1.1117 +    FREE(p);
  1.1118 +  }
  1.1119 +  /* free openInternalEntities and freeInternalEntities */
  1.1120 +  entityList = openInternalEntities;
  1.1121 +  for (;;) {
  1.1122 +    OPEN_INTERNAL_ENTITY *openEntity;
  1.1123 +    if (entityList == NULL) {
  1.1124 +      if (freeInternalEntities == NULL)
  1.1125 +        break;
  1.1126 +      entityList = freeInternalEntities;
  1.1127 +      freeInternalEntities = NULL;
  1.1128 +    }
  1.1129 +    openEntity = entityList;
  1.1130 +    entityList = entityList->next;
  1.1131 +    FREE(openEntity);
  1.1132 +  }
  1.1133 +
  1.1134 +  destroyBindings(freeBindingList, parser);
  1.1135 +  destroyBindings(inheritedBindings, parser);
  1.1136 +  poolDestroy(&tempPool);
  1.1137 +  poolDestroy(&temp2Pool);
  1.1138 +#ifdef XML_DTD
  1.1139 +  /* external parameter entity parsers share the DTD structure
  1.1140 +     parser->m_dtd with the root parser, so we must not destroy it
  1.1141 +  */
  1.1142 +  if (!isParamEntity && _dtd)
  1.1143 +#else
  1.1144 +  if (_dtd)
  1.1145 +#endif /* XML_DTD */
  1.1146 +    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
  1.1147 +  FREE((void *)atts);
  1.1148 +  FREE(groupConnector);
  1.1149 +  FREE(buffer);
  1.1150 +  FREE(dataBuf);
  1.1151 +  FREE(nsAtts);
  1.1152 +  FREE(unknownEncodingMem);
  1.1153 +  if (unknownEncodingRelease)
  1.1154 +    unknownEncodingRelease(unknownEncodingData);
  1.1155 +  FREE(parser);
  1.1156 +}
  1.1157 +
  1.1158 +void XMLCALL
  1.1159 +XML_UseParserAsHandlerArg(XML_Parser parser)
  1.1160 +{
  1.1161 +  handlerArg = parser;
  1.1162 +}
  1.1163 +
  1.1164 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1165 +#if 0
  1.1166 +enum XML_Error XMLCALL
  1.1167 +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
  1.1168 +{
  1.1169 +#ifdef XML_DTD
  1.1170 +  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  1.1171 +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
  1.1172 +    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
  1.1173 +  useForeignDTD = useDTD;
  1.1174 +  return XML_ERROR_NONE;
  1.1175 +#else
  1.1176 +  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
  1.1177 +#endif
  1.1178 +}
  1.1179 +#endif
  1.1180 +/* END MOZILLA CHANGE */
  1.1181 +
  1.1182 +void XMLCALL
  1.1183 +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
  1.1184 +{
  1.1185 +  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  1.1186 +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
  1.1187 +    return;
  1.1188 +  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
  1.1189 +}
  1.1190 +
  1.1191 +void XMLCALL
  1.1192 +XML_SetUserData(XML_Parser parser, void *p)
  1.1193 +{
  1.1194 +  if (handlerArg == userData)
  1.1195 +    handlerArg = userData = p;
  1.1196 +  else
  1.1197 +    userData = p;
  1.1198 +}
  1.1199 +
  1.1200 +enum XML_Status XMLCALL
  1.1201 +XML_SetBase(XML_Parser parser, const XML_Char *p)
  1.1202 +{
  1.1203 +  if (p) {
  1.1204 +    p = poolCopyString(&_dtd->pool, p);
  1.1205 +    if (!p)
  1.1206 +      return XML_STATUS_ERROR;
  1.1207 +    curBase = p;
  1.1208 +  }
  1.1209 +  else
  1.1210 +    curBase = NULL;
  1.1211 +  return XML_STATUS_OK;
  1.1212 +}
  1.1213 +
  1.1214 +const XML_Char * XMLCALL
  1.1215 +XML_GetBase(XML_Parser parser)
  1.1216 +{
  1.1217 +  return curBase;
  1.1218 +}
  1.1219 +
  1.1220 +int XMLCALL
  1.1221 +XML_GetSpecifiedAttributeCount(XML_Parser parser)
  1.1222 +{
  1.1223 +  return nSpecifiedAtts;
  1.1224 +}
  1.1225 +
  1.1226 +int XMLCALL
  1.1227 +XML_GetIdAttributeIndex(XML_Parser parser)
  1.1228 +{
  1.1229 +  return idAttIndex;
  1.1230 +}
  1.1231 +
  1.1232 +void XMLCALL
  1.1233 +XML_SetElementHandler(XML_Parser parser,
  1.1234 +                      XML_StartElementHandler start,
  1.1235 +                      XML_EndElementHandler end)
  1.1236 +{
  1.1237 +  startElementHandler = start;
  1.1238 +  endElementHandler = end;
  1.1239 +}
  1.1240 +
  1.1241 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1242 +#if 0
  1.1243 +void XMLCALL
  1.1244 +XML_SetStartElementHandler(XML_Parser parser,
  1.1245 +                           XML_StartElementHandler start) {
  1.1246 +  startElementHandler = start;
  1.1247 +}
  1.1248 +
  1.1249 +void XMLCALL
  1.1250 +XML_SetEndElementHandler(XML_Parser parser,
  1.1251 +                         XML_EndElementHandler end) {
  1.1252 +  endElementHandler = end;
  1.1253 +}
  1.1254 +#endif
  1.1255 +/* END MOZILLA CHANGE */
  1.1256 +
  1.1257 +void XMLCALL
  1.1258 +XML_SetCharacterDataHandler(XML_Parser parser,
  1.1259 +                            XML_CharacterDataHandler handler)
  1.1260 +{
  1.1261 +  characterDataHandler = handler;
  1.1262 +}
  1.1263 +
  1.1264 +void XMLCALL
  1.1265 +XML_SetProcessingInstructionHandler(XML_Parser parser,
  1.1266 +                                    XML_ProcessingInstructionHandler handler)
  1.1267 +{
  1.1268 +  processingInstructionHandler = handler;
  1.1269 +}
  1.1270 +
  1.1271 +void XMLCALL
  1.1272 +XML_SetCommentHandler(XML_Parser parser,
  1.1273 +                      XML_CommentHandler handler)
  1.1274 +{
  1.1275 +  commentHandler = handler;
  1.1276 +}
  1.1277 +
  1.1278 +void XMLCALL
  1.1279 +XML_SetCdataSectionHandler(XML_Parser parser,
  1.1280 +                           XML_StartCdataSectionHandler start,
  1.1281 +                           XML_EndCdataSectionHandler end)
  1.1282 +{
  1.1283 +  startCdataSectionHandler = start;
  1.1284 +  endCdataSectionHandler = end;
  1.1285 +}
  1.1286 +
  1.1287 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1288 +#if 0
  1.1289 +void XMLCALL
  1.1290 +XML_SetStartCdataSectionHandler(XML_Parser parser,
  1.1291 +                                XML_StartCdataSectionHandler start) {
  1.1292 +  startCdataSectionHandler = start;
  1.1293 +}
  1.1294 +
  1.1295 +void XMLCALL
  1.1296 +XML_SetEndCdataSectionHandler(XML_Parser parser,
  1.1297 +                              XML_EndCdataSectionHandler end) {
  1.1298 +  endCdataSectionHandler = end;
  1.1299 +}
  1.1300 +
  1.1301 +void XMLCALL
  1.1302 +XML_SetDefaultHandler(XML_Parser parser,
  1.1303 +                      XML_DefaultHandler handler)
  1.1304 +{
  1.1305 +  defaultHandler = handler;
  1.1306 +  defaultExpandInternalEntities = XML_FALSE;
  1.1307 +}
  1.1308 +#endif
  1.1309 +/* END MOZILLA CHANGE */
  1.1310 +
  1.1311 +void XMLCALL
  1.1312 +XML_SetDefaultHandlerExpand(XML_Parser parser,
  1.1313 +                            XML_DefaultHandler handler)
  1.1314 +{
  1.1315 +  defaultHandler = handler;
  1.1316 +  defaultExpandInternalEntities = XML_TRUE;
  1.1317 +}
  1.1318 +
  1.1319 +void XMLCALL
  1.1320 +XML_SetDoctypeDeclHandler(XML_Parser parser,
  1.1321 +                          XML_StartDoctypeDeclHandler start,
  1.1322 +                          XML_EndDoctypeDeclHandler end)
  1.1323 +{
  1.1324 +  startDoctypeDeclHandler = start;
  1.1325 +  endDoctypeDeclHandler = end;
  1.1326 +}
  1.1327 +
  1.1328 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1329 +#if 0
  1.1330 +void XMLCALL
  1.1331 +XML_SetStartDoctypeDeclHandler(XML_Parser parser,
  1.1332 +                               XML_StartDoctypeDeclHandler start) {
  1.1333 +  startDoctypeDeclHandler = start;
  1.1334 +}
  1.1335 +
  1.1336 +void XMLCALL
  1.1337 +XML_SetEndDoctypeDeclHandler(XML_Parser parser,
  1.1338 +                             XML_EndDoctypeDeclHandler end) {
  1.1339 +  endDoctypeDeclHandler = end;
  1.1340 +}
  1.1341 +#endif
  1.1342 +/* END MOZILLA CHANGE */
  1.1343 +
  1.1344 +void XMLCALL
  1.1345 +XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
  1.1346 +                                 XML_UnparsedEntityDeclHandler handler)
  1.1347 +{
  1.1348 +  unparsedEntityDeclHandler = handler;
  1.1349 +}
  1.1350 +
  1.1351 +void XMLCALL
  1.1352 +XML_SetNotationDeclHandler(XML_Parser parser,
  1.1353 +                           XML_NotationDeclHandler handler)
  1.1354 +{
  1.1355 +  notationDeclHandler = handler;
  1.1356 +}
  1.1357 +
  1.1358 +void XMLCALL
  1.1359 +XML_SetNamespaceDeclHandler(XML_Parser parser,
  1.1360 +                            XML_StartNamespaceDeclHandler start,
  1.1361 +                            XML_EndNamespaceDeclHandler end)
  1.1362 +{
  1.1363 +  startNamespaceDeclHandler = start;
  1.1364 +  endNamespaceDeclHandler = end;
  1.1365 +}
  1.1366 +
  1.1367 +
  1.1368 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1369 +#if 0
  1.1370 +void XMLCALL
  1.1371 +XML_SetStartNamespaceDeclHandler(XML_Parser parser,
  1.1372 +                                 XML_StartNamespaceDeclHandler start) {
  1.1373 +  startNamespaceDeclHandler = start;
  1.1374 +}
  1.1375 +
  1.1376 +void XMLCALL
  1.1377 +XML_SetEndNamespaceDeclHandler(XML_Parser parser,
  1.1378 +                               XML_EndNamespaceDeclHandler end) {
  1.1379 +  endNamespaceDeclHandler = end;
  1.1380 +}
  1.1381 +
  1.1382 +void XMLCALL
  1.1383 +XML_SetNotStandaloneHandler(XML_Parser parser,
  1.1384 +                            XML_NotStandaloneHandler handler)
  1.1385 +{
  1.1386 +  notStandaloneHandler = handler;
  1.1387 +}
  1.1388 +#endif
  1.1389 +/* END MOZILLA CHANGE */
  1.1390 +
  1.1391 +void XMLCALL
  1.1392 +XML_SetExternalEntityRefHandler(XML_Parser parser,
  1.1393 +                                XML_ExternalEntityRefHandler handler)
  1.1394 +{
  1.1395 +  externalEntityRefHandler = handler;
  1.1396 +}
  1.1397 +
  1.1398 +void XMLCALL
  1.1399 +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
  1.1400 +{
  1.1401 +  if (arg)
  1.1402 +    externalEntityRefHandlerArg = (XML_Parser)arg;
  1.1403 +  else
  1.1404 +    externalEntityRefHandlerArg = parser;
  1.1405 +}
  1.1406 +
  1.1407 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1408 +#if 0
  1.1409 +void XMLCALL
  1.1410 +XML_SetSkippedEntityHandler(XML_Parser parser,
  1.1411 +                            XML_SkippedEntityHandler handler)
  1.1412 +{
  1.1413 +  skippedEntityHandler = handler;
  1.1414 +}
  1.1415 +
  1.1416 +void XMLCALL
  1.1417 +XML_SetUnknownEncodingHandler(XML_Parser parser,
  1.1418 +                              XML_UnknownEncodingHandler handler,
  1.1419 +                              void *data)
  1.1420 +{
  1.1421 +  unknownEncodingHandler = handler;
  1.1422 +  unknownEncodingHandlerData = data;
  1.1423 +}
  1.1424 +
  1.1425 +void XMLCALL
  1.1426 +XML_SetElementDeclHandler(XML_Parser parser,
  1.1427 +                          XML_ElementDeclHandler eldecl)
  1.1428 +{
  1.1429 +  elementDeclHandler = eldecl;
  1.1430 +}
  1.1431 +
  1.1432 +void XMLCALL
  1.1433 +XML_SetAttlistDeclHandler(XML_Parser parser,
  1.1434 +                          XML_AttlistDeclHandler attdecl)
  1.1435 +{
  1.1436 +  attlistDeclHandler = attdecl;
  1.1437 +}
  1.1438 +
  1.1439 +void XMLCALL
  1.1440 +XML_SetEntityDeclHandler(XML_Parser parser,
  1.1441 +                         XML_EntityDeclHandler handler)
  1.1442 +{
  1.1443 +  entityDeclHandler = handler;
  1.1444 +}
  1.1445 +#endif
  1.1446 +/* END MOZILLA CHANGE */
  1.1447 +
  1.1448 +void XMLCALL
  1.1449 +XML_SetXmlDeclHandler(XML_Parser parser,
  1.1450 +                      XML_XmlDeclHandler handler) {
  1.1451 +  xmlDeclHandler = handler;
  1.1452 +}
  1.1453 +
  1.1454 +int XMLCALL
  1.1455 +XML_SetParamEntityParsing(XML_Parser parser,
  1.1456 +                          enum XML_ParamEntityParsing peParsing)
  1.1457 +{
  1.1458 +  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  1.1459 +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
  1.1460 +    return 0;
  1.1461 +#ifdef XML_DTD
  1.1462 +  paramEntityParsing = peParsing;
  1.1463 +  return 1;
  1.1464 +#else
  1.1465 +  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
  1.1466 +#endif
  1.1467 +}
  1.1468 +
  1.1469 +enum XML_Status XMLCALL
  1.1470 +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
  1.1471 +{
  1.1472 +  switch (ps_parsing) {
  1.1473 +  case XML_SUSPENDED:
  1.1474 +    errorCode = XML_ERROR_SUSPENDED;
  1.1475 +    return XML_STATUS_ERROR;
  1.1476 +  case XML_FINISHED:
  1.1477 +    errorCode = XML_ERROR_FINISHED;
  1.1478 +    return XML_STATUS_ERROR;
  1.1479 +  default:
  1.1480 +    ps_parsing = XML_PARSING;
  1.1481 +  }
  1.1482 +
  1.1483 +  if (len == 0) {
  1.1484 +    ps_finalBuffer = (XML_Bool)isFinal;
  1.1485 +    if (!isFinal)
  1.1486 +      return XML_STATUS_OK;
  1.1487 +    positionPtr = bufferPtr;
  1.1488 +    parseEndPtr = bufferEnd;
  1.1489 +
  1.1490 +    /* If data are left over from last buffer, and we now know that these
  1.1491 +       data are the final chunk of input, then we have to check them again
  1.1492 +       to detect errors based on that fact.
  1.1493 +    */
  1.1494 +    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
  1.1495 +
  1.1496 +    if (errorCode == XML_ERROR_NONE) {
  1.1497 +      switch (ps_parsing) {
  1.1498 +      case XML_SUSPENDED:
  1.1499 +        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  1.1500 +        positionPtr = bufferPtr;
  1.1501 +        return XML_STATUS_SUSPENDED;
  1.1502 +      case XML_INITIALIZED: 
  1.1503 +      case XML_PARSING:
  1.1504 +        ps_parsing = XML_FINISHED;
  1.1505 +        /* fall through */
  1.1506 +      default:
  1.1507 +        return XML_STATUS_OK;
  1.1508 +      }
  1.1509 +    }
  1.1510 +    eventEndPtr = eventPtr;
  1.1511 +    processor = errorProcessor;
  1.1512 +    return XML_STATUS_ERROR;
  1.1513 +  }
  1.1514 +#ifndef XML_CONTEXT_BYTES
  1.1515 +  else if (bufferPtr == bufferEnd) {
  1.1516 +    const char *end;
  1.1517 +    int nLeftOver;
  1.1518 +/* BEGIN MOZILLA CHANGE (|result| has type XML_Status, not XML_Error) */
  1.1519 +    enum XML_Status result;
  1.1520 +/* END MOZILLA CHANGE */
  1.1521 +    parseEndByteIndex += len;
  1.1522 +    positionPtr = s;
  1.1523 +    ps_finalBuffer = (XML_Bool)isFinal;
  1.1524 +
  1.1525 +    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
  1.1526 +
  1.1527 +    if (errorCode != XML_ERROR_NONE) {
  1.1528 +      eventEndPtr = eventPtr;
  1.1529 +      processor = errorProcessor;
  1.1530 +      return XML_STATUS_ERROR;
  1.1531 +    }
  1.1532 +    else {
  1.1533 +      switch (ps_parsing) {
  1.1534 +      case XML_SUSPENDED:
  1.1535 +        result = XML_STATUS_SUSPENDED;
  1.1536 +        break;
  1.1537 +      case XML_INITIALIZED:
  1.1538 +      case XML_PARSING:
  1.1539 +/* BEGIN MOZILLA CHANGE (always initialize result) */
  1.1540 +#if 0
  1.1541 +        result = XML_STATUS_OK;
  1.1542 +        if (isFinal) {
  1.1543 +          ps_parsing = XML_FINISHED;
  1.1544 +          return result;
  1.1545 +        }
  1.1546 +#else
  1.1547 +        if (isFinal) {
  1.1548 +          ps_parsing = XML_FINISHED;
  1.1549 +          return XML_STATUS_OK;
  1.1550 +        }
  1.1551 +      /* fall through */
  1.1552 +      default:
  1.1553 +        result = XML_STATUS_OK;
  1.1554 +#endif
  1.1555 +/* END MOZILLA CHANGE */
  1.1556 +      }
  1.1557 +    }
  1.1558 +
  1.1559 +    XmlUpdatePosition(encoding, positionPtr, end, &position);
  1.1560 +    nLeftOver = s + len - end;
  1.1561 +    if (nLeftOver) {
  1.1562 +      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
  1.1563 +        /* FIXME avoid integer overflow */
  1.1564 +        char *temp;
  1.1565 +        temp = (buffer == NULL
  1.1566 +                ? (char *)MALLOC(len * 2)
  1.1567 +                : (char *)REALLOC(buffer, len * 2));
  1.1568 +        if (temp == NULL) {
  1.1569 +          errorCode = XML_ERROR_NO_MEMORY;
  1.1570 +          return XML_STATUS_ERROR;
  1.1571 +        }
  1.1572 +        buffer = temp;
  1.1573 +        if (!buffer) {
  1.1574 +          errorCode = XML_ERROR_NO_MEMORY;
  1.1575 +          eventPtr = eventEndPtr = NULL;
  1.1576 +          processor = errorProcessor;
  1.1577 +          return XML_STATUS_ERROR;
  1.1578 +        }
  1.1579 +        bufferLim = buffer + len * 2;
  1.1580 +      }
  1.1581 +      memcpy(buffer, end, nLeftOver);
  1.1582 +    }
  1.1583 +    bufferPtr = buffer;
  1.1584 +    bufferEnd = buffer + nLeftOver;
  1.1585 +    positionPtr = bufferPtr;
  1.1586 +    parseEndPtr = bufferEnd;
  1.1587 +    eventPtr = bufferPtr;
  1.1588 +    eventEndPtr = bufferPtr;
  1.1589 +    return result;
  1.1590 +  }
  1.1591 +#endif  /* not defined XML_CONTEXT_BYTES */
  1.1592 +  else {
  1.1593 +    void *buff = XML_GetBuffer(parser, len);
  1.1594 +    if (buff == NULL)
  1.1595 +      return XML_STATUS_ERROR;
  1.1596 +    else {
  1.1597 +      memcpy(buff, s, len);
  1.1598 +      return XML_ParseBuffer(parser, len, isFinal);
  1.1599 +    }
  1.1600 +  }
  1.1601 +}
  1.1602 +
  1.1603 +enum XML_Status XMLCALL
  1.1604 +XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
  1.1605 +{
  1.1606 +  const char *start;
  1.1607 +  enum XML_Status result = XML_STATUS_OK;
  1.1608 +
  1.1609 +  switch (ps_parsing) {
  1.1610 +  case XML_SUSPENDED:
  1.1611 +    errorCode = XML_ERROR_SUSPENDED;
  1.1612 +    return XML_STATUS_ERROR;
  1.1613 +  case XML_FINISHED:
  1.1614 +    errorCode = XML_ERROR_FINISHED;
  1.1615 +    return XML_STATUS_ERROR;
  1.1616 +  default:
  1.1617 +    ps_parsing = XML_PARSING;
  1.1618 +  }
  1.1619 +
  1.1620 +  start = bufferPtr;
  1.1621 +  positionPtr = start;
  1.1622 +  bufferEnd += len;
  1.1623 +  parseEndPtr = bufferEnd;
  1.1624 +  parseEndByteIndex += len;
  1.1625 +  ps_finalBuffer = (XML_Bool)isFinal;
  1.1626 +
  1.1627 +  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
  1.1628 +
  1.1629 +  if (errorCode != XML_ERROR_NONE) {
  1.1630 +    eventEndPtr = eventPtr;
  1.1631 +    processor = errorProcessor;
  1.1632 +    return XML_STATUS_ERROR;
  1.1633 +  }
  1.1634 +  else {
  1.1635 +    switch (ps_parsing) {
  1.1636 +    case XML_SUSPENDED:
  1.1637 +      result = XML_STATUS_SUSPENDED;
  1.1638 +      break;
  1.1639 +    case XML_INITIALIZED: 
  1.1640 +    case XML_PARSING:
  1.1641 +      if (isFinal) {
  1.1642 +        ps_parsing = XML_FINISHED;
  1.1643 +        return result;
  1.1644 +      }
  1.1645 +    default: ;  /* should not happen */
  1.1646 +    }
  1.1647 +  }
  1.1648 +
  1.1649 +  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  1.1650 +  positionPtr = bufferPtr;
  1.1651 +  return result;
  1.1652 +}
  1.1653 +
  1.1654 +void * XMLCALL
  1.1655 +XML_GetBuffer(XML_Parser parser, int len)
  1.1656 +{
  1.1657 +  switch (ps_parsing) {
  1.1658 +  case XML_SUSPENDED:
  1.1659 +    errorCode = XML_ERROR_SUSPENDED;
  1.1660 +    return NULL;
  1.1661 +  case XML_FINISHED:
  1.1662 +    errorCode = XML_ERROR_FINISHED;
  1.1663 +    return NULL;
  1.1664 +  default: ;
  1.1665 +  }
  1.1666 +
  1.1667 +  if (len > bufferLim - bufferEnd) {
  1.1668 +    /* FIXME avoid integer overflow */
  1.1669 +    int neededSize = len + (int)(bufferEnd - bufferPtr);
  1.1670 +#ifdef XML_CONTEXT_BYTES
  1.1671 +    int keep = (int)(bufferPtr - buffer);
  1.1672 +
  1.1673 +    if (keep > XML_CONTEXT_BYTES)
  1.1674 +      keep = XML_CONTEXT_BYTES;
  1.1675 +    neededSize += keep;
  1.1676 +#endif  /* defined XML_CONTEXT_BYTES */
  1.1677 +    if (neededSize  <= bufferLim - buffer) {
  1.1678 +#ifdef XML_CONTEXT_BYTES
  1.1679 +      if (keep < bufferPtr - buffer) {
  1.1680 +        int offset = (int)(bufferPtr - buffer) - keep;
  1.1681 +        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
  1.1682 +        bufferEnd -= offset;
  1.1683 +        bufferPtr -= offset;
  1.1684 +      }
  1.1685 +#else
  1.1686 +      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
  1.1687 +      bufferEnd = buffer + (bufferEnd - bufferPtr);
  1.1688 +      bufferPtr = buffer;
  1.1689 +#endif  /* not defined XML_CONTEXT_BYTES */
  1.1690 +    }
  1.1691 +    else {
  1.1692 +      char *newBuf;
  1.1693 +      int bufferSize = (int)(bufferLim - bufferPtr);
  1.1694 +      if (bufferSize == 0)
  1.1695 +        bufferSize = INIT_BUFFER_SIZE;
  1.1696 +      do {
  1.1697 +        bufferSize *= 2;
  1.1698 +      } while (bufferSize < neededSize);
  1.1699 +      newBuf = (char *)MALLOC(bufferSize);
  1.1700 +      if (newBuf == 0) {
  1.1701 +        errorCode = XML_ERROR_NO_MEMORY;
  1.1702 +        return NULL;
  1.1703 +      }
  1.1704 +      bufferLim = newBuf + bufferSize;
  1.1705 +#ifdef XML_CONTEXT_BYTES
  1.1706 +      if (bufferPtr) {
  1.1707 +        int keep = (int)(bufferPtr - buffer);
  1.1708 +        if (keep > XML_CONTEXT_BYTES)
  1.1709 +          keep = XML_CONTEXT_BYTES;
  1.1710 +        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
  1.1711 +        FREE(buffer);
  1.1712 +        buffer = newBuf;
  1.1713 +        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
  1.1714 +        bufferPtr = buffer + keep;
  1.1715 +      }
  1.1716 +      else {
  1.1717 +        bufferEnd = newBuf + (bufferEnd - bufferPtr);
  1.1718 +        bufferPtr = buffer = newBuf;
  1.1719 +      }
  1.1720 +#else
  1.1721 +      if (bufferPtr) {
  1.1722 +        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
  1.1723 +        FREE(buffer);
  1.1724 +      }
  1.1725 +      bufferEnd = newBuf + (bufferEnd - bufferPtr);
  1.1726 +      bufferPtr = buffer = newBuf;
  1.1727 +#endif  /* not defined XML_CONTEXT_BYTES */
  1.1728 +    }
  1.1729 +  }
  1.1730 +  return bufferEnd;
  1.1731 +}
  1.1732 +
  1.1733 +enum XML_Status XMLCALL
  1.1734 +XML_StopParser(XML_Parser parser, XML_Bool resumable)
  1.1735 +{
  1.1736 +  switch (ps_parsing) {
  1.1737 +  case XML_SUSPENDED:
  1.1738 +    if (resumable) {
  1.1739 +      errorCode = XML_ERROR_SUSPENDED;
  1.1740 +      return XML_STATUS_ERROR;
  1.1741 +    }
  1.1742 +    ps_parsing = XML_FINISHED;
  1.1743 +    break;
  1.1744 +  case XML_FINISHED:
  1.1745 +    errorCode = XML_ERROR_FINISHED;
  1.1746 +    return XML_STATUS_ERROR;
  1.1747 +  default:
  1.1748 +    if (resumable) {
  1.1749 +#ifdef XML_DTD
  1.1750 +      if (isParamEntity) {
  1.1751 +        errorCode = XML_ERROR_SUSPEND_PE;
  1.1752 +        return XML_STATUS_ERROR;
  1.1753 +      }
  1.1754 +#endif
  1.1755 +      ps_parsing = XML_SUSPENDED;
  1.1756 +    }
  1.1757 +    else
  1.1758 +      ps_parsing = XML_FINISHED;
  1.1759 +  }
  1.1760 +  return XML_STATUS_OK;
  1.1761 +}
  1.1762 +
  1.1763 +enum XML_Status XMLCALL
  1.1764 +XML_ResumeParser(XML_Parser parser)
  1.1765 +{
  1.1766 +  enum XML_Status result = XML_STATUS_OK;
  1.1767 +
  1.1768 +  if (ps_parsing != XML_SUSPENDED) {
  1.1769 +    errorCode = XML_ERROR_NOT_SUSPENDED;
  1.1770 +    return XML_STATUS_ERROR;
  1.1771 +  }
  1.1772 +  ps_parsing = XML_PARSING;
  1.1773 +
  1.1774 +  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
  1.1775 +
  1.1776 +  if (errorCode != XML_ERROR_NONE) {
  1.1777 +    eventEndPtr = eventPtr;
  1.1778 +    processor = errorProcessor;
  1.1779 +    return XML_STATUS_ERROR;
  1.1780 +  }
  1.1781 +  else {
  1.1782 +    switch (ps_parsing) {
  1.1783 +    case XML_SUSPENDED:
  1.1784 +      result = XML_STATUS_SUSPENDED;
  1.1785 +      break;
  1.1786 +    case XML_INITIALIZED: 
  1.1787 +    case XML_PARSING:
  1.1788 +      if (ps_finalBuffer) {
  1.1789 +        ps_parsing = XML_FINISHED;
  1.1790 +        return result;
  1.1791 +      }
  1.1792 +    default: ;
  1.1793 +    }
  1.1794 +  }
  1.1795 +
  1.1796 +  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  1.1797 +  positionPtr = bufferPtr;
  1.1798 +/* BEGIN MOZILLA CHANGE (always set eventPtr/eventEndPtr) */
  1.1799 +  eventPtr = bufferPtr;
  1.1800 +  eventEndPtr = bufferPtr;
  1.1801 +/* END MOZILLA CHANGE */
  1.1802 +  return result;
  1.1803 +}
  1.1804 +
  1.1805 +void XMLCALL
  1.1806 +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
  1.1807 +{
  1.1808 +  assert(status != NULL);
  1.1809 +  *status = parser->m_parsingStatus;
  1.1810 +}
  1.1811 +
  1.1812 +enum XML_Error XMLCALL
  1.1813 +XML_GetErrorCode(XML_Parser parser)
  1.1814 +{
  1.1815 +  return errorCode;
  1.1816 +}
  1.1817 +
  1.1818 +XML_Index XMLCALL
  1.1819 +XML_GetCurrentByteIndex(XML_Parser parser)
  1.1820 +{
  1.1821 +  if (eventPtr)
  1.1822 +    return parseEndByteIndex - (parseEndPtr - eventPtr);
  1.1823 +/* BEGIN MOZILLA CHANGE (fix XML_GetCurrentByteIndex) */
  1.1824 +#if 0
  1.1825 +  return -1;
  1.1826 +#else
  1.1827 +  return parseEndByteIndex;
  1.1828 +#endif
  1.1829 +/* END MOZILLA CHANGE */
  1.1830 +}
  1.1831 +
  1.1832 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1833 +#if 0
  1.1834 +int XMLCALL
  1.1835 +XML_GetCurrentByteCount(XML_Parser parser)
  1.1836 +{
  1.1837 +  if (eventEndPtr && eventPtr)
  1.1838 +    return (int)(eventEndPtr - eventPtr);
  1.1839 +  return 0;
  1.1840 +}
  1.1841 +
  1.1842 +const char * XMLCALL
  1.1843 +XML_GetInputContext(XML_Parser parser, int *offset, int *size)
  1.1844 +{
  1.1845 +#ifdef XML_CONTEXT_BYTES
  1.1846 +  if (eventPtr && buffer) {
  1.1847 +    *offset = (int)(eventPtr - buffer);
  1.1848 +    *size   = (int)(bufferEnd - buffer);
  1.1849 +    return buffer;
  1.1850 +  }
  1.1851 +#endif /* defined XML_CONTEXT_BYTES */
  1.1852 +  return (char *) 0;
  1.1853 +}
  1.1854 +#endif
  1.1855 +/* END MOZILLA CHANGE */
  1.1856 +
  1.1857 +XML_Size XMLCALL
  1.1858 +XML_GetCurrentLineNumber(XML_Parser parser)
  1.1859 +{
  1.1860 +  if (eventPtr && eventPtr >= positionPtr) {
  1.1861 +    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
  1.1862 +    positionPtr = eventPtr;
  1.1863 +  }
  1.1864 +  return position.lineNumber + 1;
  1.1865 +}
  1.1866 +
  1.1867 +XML_Size XMLCALL
  1.1868 +XML_GetCurrentColumnNumber(XML_Parser parser)
  1.1869 +{
  1.1870 +  if (eventPtr && eventPtr >= positionPtr) {
  1.1871 +    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
  1.1872 +    positionPtr = eventPtr;
  1.1873 +  }
  1.1874 +  return position.columnNumber;
  1.1875 +}
  1.1876 +
  1.1877 +/* BEGIN MOZILLA CHANGE (unused API) */
  1.1878 +#if 0
  1.1879 +void XMLCALL
  1.1880 +XML_FreeContentModel(XML_Parser parser, XML_Content *model)
  1.1881 +{
  1.1882 +  FREE(model);
  1.1883 +}
  1.1884 +
  1.1885 +void * XMLCALL
  1.1886 +XML_MemMalloc(XML_Parser parser, size_t size)
  1.1887 +{
  1.1888 +  return MALLOC(size);
  1.1889 +}
  1.1890 +
  1.1891 +void * XMLCALL
  1.1892 +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
  1.1893 +{
  1.1894 +  return REALLOC(ptr, size);
  1.1895 +}
  1.1896 +
  1.1897 +void XMLCALL
  1.1898 +XML_MemFree(XML_Parser parser, void *ptr)
  1.1899 +{
  1.1900 +  FREE(ptr);
  1.1901 +}
  1.1902 +
  1.1903 +void XMLCALL
  1.1904 +XML_DefaultCurrent(XML_Parser parser)
  1.1905 +{
  1.1906 +  if (defaultHandler) {
  1.1907 +    if (openInternalEntities)
  1.1908 +      reportDefault(parser,
  1.1909 +                    internalEncoding,
  1.1910 +                    openInternalEntities->internalEventPtr,
  1.1911 +                    openInternalEntities->internalEventEndPtr);
  1.1912 +    else
  1.1913 +      reportDefault(parser, encoding, eventPtr, eventEndPtr);
  1.1914 +  }
  1.1915 +}
  1.1916 +
  1.1917 +const XML_LChar * XMLCALL
  1.1918 +XML_ExpatVersion(void) {
  1.1919 +
  1.1920 +  /* V1 is used to string-ize the version number. However, it would
  1.1921 +     string-ize the actual version macro *names* unless we get them
  1.1922 +     substituted before being passed to V1. CPP is defined to expand
  1.1923 +     a macro, then rescan for more expansions. Thus, we use V2 to expand
  1.1924 +     the version macros, then CPP will expand the resulting V1() macro
  1.1925 +     with the correct numerals. */
  1.1926 +  /* ### I'm assuming cpp is portable in this respect... */
  1.1927 +
  1.1928 +#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
  1.1929 +#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
  1.1930 +
  1.1931 +  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
  1.1932 +
  1.1933 +#undef V1
  1.1934 +#undef V2
  1.1935 +}
  1.1936 +
  1.1937 +XML_Expat_Version XMLCALL
  1.1938 +XML_ExpatVersionInfo(void)
  1.1939 +{
  1.1940 +  XML_Expat_Version version;
  1.1941 +
  1.1942 +  version.major = XML_MAJOR_VERSION;
  1.1943 +  version.minor = XML_MINOR_VERSION;
  1.1944 +  version.micro = XML_MICRO_VERSION;
  1.1945 +
  1.1946 +  return version;
  1.1947 +}
  1.1948 +
  1.1949 +const XML_Feature * XMLCALL
  1.1950 +XML_GetFeatureList(void)
  1.1951 +{
  1.1952 +  static const XML_Feature features[] = {
  1.1953 +    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
  1.1954 +     sizeof(XML_Char)},
  1.1955 +    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
  1.1956 +     sizeof(XML_LChar)},
  1.1957 +#ifdef XML_UNICODE
  1.1958 +    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
  1.1959 +#endif
  1.1960 +#ifdef XML_UNICODE_WCHAR_T
  1.1961 +    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
  1.1962 +#endif
  1.1963 +#ifdef XML_DTD
  1.1964 +    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
  1.1965 +#endif
  1.1966 +#ifdef XML_CONTEXT_BYTES
  1.1967 +    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
  1.1968 +     XML_CONTEXT_BYTES},
  1.1969 +#endif
  1.1970 +#ifdef XML_MIN_SIZE
  1.1971 +    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
  1.1972 +#endif
  1.1973 +#ifdef XML_NS
  1.1974 +    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
  1.1975 +#endif
  1.1976 +    {XML_FEATURE_END,              NULL, 0}
  1.1977 +  };
  1.1978 +
  1.1979 +  return features;
  1.1980 +}
  1.1981 +#endif
  1.1982 +/* END MOZILLA CHANGE */
  1.1983 +
  1.1984 +/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
  1.1985 +const XML_Char * XMLCALL
  1.1986 +MOZ_XML_GetMismatchedTag(XML_Parser parser)
  1.1987 +{
  1.1988 +  return mismatch;
  1.1989 +}
  1.1990 +/* END MOZILLA CHANGE */
  1.1991 +
  1.1992 +/* Initially tag->rawName always points into the parse buffer;
  1.1993 +   for those TAG instances opened while the current parse buffer was
  1.1994 +   processed, and not yet closed, we need to store tag->rawName in a more
  1.1995 +   permanent location, since the parse buffer is about to be discarded.
  1.1996 +*/
  1.1997 +static XML_Bool
  1.1998 +storeRawNames(XML_Parser parser)
  1.1999 +{
  1.2000 +  TAG *tag = tagStack;
  1.2001 +  while (tag) {
  1.2002 +    int bufSize;
  1.2003 +    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
  1.2004 +    char *rawNameBuf = tag->buf + nameLen;
  1.2005 +    /* Stop if already stored.  Since tagStack is a stack, we can stop
  1.2006 +       at the first entry that has already been copied; everything
  1.2007 +       below it in the stack is already been accounted for in a
  1.2008 +       previous call to this function.
  1.2009 +    */
  1.2010 +    if (tag->rawName == rawNameBuf)
  1.2011 +      break;
  1.2012 +    /* For re-use purposes we need to ensure that the
  1.2013 +       size of tag->buf is a multiple of sizeof(XML_Char).
  1.2014 +    */
  1.2015 +    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
  1.2016 +    if (bufSize > tag->bufEnd - tag->buf) {
  1.2017 +      char *temp = (char *)REALLOC(tag->buf, bufSize);
  1.2018 +      if (temp == NULL)
  1.2019 +        return XML_FALSE;
  1.2020 +      /* if tag->name.str points to tag->buf (only when namespace
  1.2021 +         processing is off) then we have to update it
  1.2022 +      */
  1.2023 +      if (tag->name.str == (XML_Char *)tag->buf)
  1.2024 +        tag->name.str = (XML_Char *)temp;
  1.2025 +      /* if tag->name.localPart is set (when namespace processing is on)
  1.2026 +         then update it as well, since it will always point into tag->buf
  1.2027 +      */
  1.2028 +      if (tag->name.localPart)
  1.2029 +        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
  1.2030 +                                                  (XML_Char *)tag->buf);
  1.2031 +      tag->buf = temp;
  1.2032 +      tag->bufEnd = temp + bufSize;
  1.2033 +      rawNameBuf = temp + nameLen;
  1.2034 +    }
  1.2035 +    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
  1.2036 +    tag->rawName = rawNameBuf;
  1.2037 +    tag = tag->parent;
  1.2038 +  }
  1.2039 +  return XML_TRUE;
  1.2040 +}
  1.2041 +
  1.2042 +static enum XML_Error PTRCALL
  1.2043 +contentProcessor(XML_Parser parser,
  1.2044 +                 const char *start,
  1.2045 +                 const char *end,
  1.2046 +                 const char **endPtr)
  1.2047 +{
  1.2048 +  enum XML_Error result = doContent(parser, 0, encoding, start, end, 
  1.2049 +                                    endPtr, (XML_Bool)!ps_finalBuffer);
  1.2050 +  if (result == XML_ERROR_NONE) {
  1.2051 +    if (!storeRawNames(parser))
  1.2052 +      return XML_ERROR_NO_MEMORY;
  1.2053 +  }
  1.2054 +  return result;
  1.2055 +}
  1.2056 +
  1.2057 +static enum XML_Error PTRCALL
  1.2058 +externalEntityInitProcessor(XML_Parser parser,
  1.2059 +                            const char *start,
  1.2060 +                            const char *end,
  1.2061 +                            const char **endPtr)
  1.2062 +{
  1.2063 +  enum XML_Error result = initializeEncoding(parser);
  1.2064 +  if (result != XML_ERROR_NONE)
  1.2065 +    return result;
  1.2066 +  processor = externalEntityInitProcessor2;
  1.2067 +  return externalEntityInitProcessor2(parser, start, end, endPtr);
  1.2068 +}
  1.2069 +
  1.2070 +static enum XML_Error PTRCALL
  1.2071 +externalEntityInitProcessor2(XML_Parser parser,
  1.2072 +                             const char *start,
  1.2073 +                             const char *end,
  1.2074 +                             const char **endPtr)
  1.2075 +{
  1.2076 +  const char *next = start; /* XmlContentTok doesn't always set the last arg */
  1.2077 +  int tok = XmlContentTok(encoding, start, end, &next);
  1.2078 +  switch (tok) {
  1.2079 +  case XML_TOK_BOM:
  1.2080 +    /* If we are at the end of the buffer, this would cause the next stage,
  1.2081 +       i.e. externalEntityInitProcessor3, to pass control directly to
  1.2082 +       doContent (by detecting XML_TOK_NONE) without processing any xml text
  1.2083 +       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
  1.2084 +    */
  1.2085 +    if (next == end && !ps_finalBuffer) {
  1.2086 +      *endPtr = next;
  1.2087 +      return XML_ERROR_NONE;
  1.2088 +    }
  1.2089 +    start = next;
  1.2090 +    break;
  1.2091 +  case XML_TOK_PARTIAL:
  1.2092 +    if (!ps_finalBuffer) {
  1.2093 +      *endPtr = start;
  1.2094 +      return XML_ERROR_NONE;
  1.2095 +    }
  1.2096 +    eventPtr = start;
  1.2097 +    return XML_ERROR_UNCLOSED_TOKEN;
  1.2098 +  case XML_TOK_PARTIAL_CHAR:
  1.2099 +    if (!ps_finalBuffer) {
  1.2100 +      *endPtr = start;
  1.2101 +      return XML_ERROR_NONE;
  1.2102 +    }
  1.2103 +    eventPtr = start;
  1.2104 +    return XML_ERROR_PARTIAL_CHAR;
  1.2105 +  }
  1.2106 +  processor = externalEntityInitProcessor3;
  1.2107 +  return externalEntityInitProcessor3(parser, start, end, endPtr);
  1.2108 +}
  1.2109 +
  1.2110 +static enum XML_Error PTRCALL
  1.2111 +externalEntityInitProcessor3(XML_Parser parser,
  1.2112 +                             const char *start,
  1.2113 +                             const char *end,
  1.2114 +                             const char **endPtr)
  1.2115 +{
  1.2116 +  int tok;
  1.2117 +  const char *next = start; /* XmlContentTok doesn't always set the last arg */
  1.2118 +  eventPtr = start;
  1.2119 +  tok = XmlContentTok(encoding, start, end, &next);
  1.2120 +  eventEndPtr = next;
  1.2121 +
  1.2122 +  switch (tok) {
  1.2123 +  case XML_TOK_XML_DECL:
  1.2124 +    {
  1.2125 +      enum XML_Error result;
  1.2126 +      result = processXmlDecl(parser, 1, start, next);
  1.2127 +      if (result != XML_ERROR_NONE)
  1.2128 +        return result;
  1.2129 +      switch (ps_parsing) {
  1.2130 +      case XML_SUSPENDED: 
  1.2131 +        *endPtr = next;
  1.2132 +        return XML_ERROR_NONE;
  1.2133 +      case XML_FINISHED:
  1.2134 +        return XML_ERROR_ABORTED;
  1.2135 +      default:
  1.2136 +        start = next;
  1.2137 +      }
  1.2138 +    }
  1.2139 +    break;
  1.2140 +  case XML_TOK_PARTIAL:
  1.2141 +    if (!ps_finalBuffer) {
  1.2142 +      *endPtr = start;
  1.2143 +      return XML_ERROR_NONE;
  1.2144 +    }
  1.2145 +    return XML_ERROR_UNCLOSED_TOKEN;
  1.2146 +  case XML_TOK_PARTIAL_CHAR:
  1.2147 +    if (!ps_finalBuffer) {
  1.2148 +      *endPtr = start;
  1.2149 +      return XML_ERROR_NONE;
  1.2150 +    }
  1.2151 +    return XML_ERROR_PARTIAL_CHAR;
  1.2152 +  }
  1.2153 +  processor = externalEntityContentProcessor;
  1.2154 +  tagLevel = 1;
  1.2155 +  return externalEntityContentProcessor(parser, start, end, endPtr);
  1.2156 +}
  1.2157 +
  1.2158 +static enum XML_Error PTRCALL
  1.2159 +externalEntityContentProcessor(XML_Parser parser,
  1.2160 +                               const char *start,
  1.2161 +                               const char *end,
  1.2162 +                               const char **endPtr)
  1.2163 +{
  1.2164 +  enum XML_Error result = doContent(parser, 1, encoding, start, end, 
  1.2165 +                                    endPtr, (XML_Bool)!ps_finalBuffer);
  1.2166 +  if (result == XML_ERROR_NONE) {
  1.2167 +    if (!storeRawNames(parser))
  1.2168 +      return XML_ERROR_NO_MEMORY;
  1.2169 +  }
  1.2170 +  return result;
  1.2171 +}
  1.2172 +
  1.2173 +static enum XML_Error
  1.2174 +doContent(XML_Parser parser,
  1.2175 +          int startTagLevel,
  1.2176 +          const ENCODING *enc,
  1.2177 +          const char *s,
  1.2178 +          const char *end,
  1.2179 +          const char **nextPtr,
  1.2180 +          XML_Bool haveMore)
  1.2181 +{
  1.2182 +  /* save one level of indirection */
  1.2183 +  DTD * const dtd = _dtd;  
  1.2184 +
  1.2185 +  const char **eventPP;
  1.2186 +  const char **eventEndPP;
  1.2187 +  if (enc == encoding) {
  1.2188 +    eventPP = &eventPtr;
  1.2189 +    eventEndPP = &eventEndPtr;
  1.2190 +  }
  1.2191 +  else {
  1.2192 +    eventPP = &(openInternalEntities->internalEventPtr);
  1.2193 +    eventEndPP = &(openInternalEntities->internalEventEndPtr);
  1.2194 +  }
  1.2195 +  *eventPP = s;
  1.2196 +
  1.2197 +  for (;;) {
  1.2198 +    const char *next = s; /* XmlContentTok doesn't always set the last arg */
  1.2199 +    int tok = XmlContentTok(enc, s, end, &next);
  1.2200 +    *eventEndPP = next;
  1.2201 +    switch (tok) {
  1.2202 +    case XML_TOK_TRAILING_CR:
  1.2203 +      if (haveMore) {
  1.2204 +        *nextPtr = s;
  1.2205 +        return XML_ERROR_NONE;
  1.2206 +      }
  1.2207 +      *eventEndPP = end;
  1.2208 +      if (characterDataHandler) {
  1.2209 +        XML_Char c = 0xA;
  1.2210 +        characterDataHandler(handlerArg, &c, 1);
  1.2211 +      }
  1.2212 +      else if (defaultHandler)
  1.2213 +        reportDefault(parser, enc, s, end);
  1.2214 +      /* We are at the end of the final buffer, should we check for 
  1.2215 +         XML_SUSPENDED, XML_FINISHED? 
  1.2216 +      */
  1.2217 +      if (startTagLevel == 0)
  1.2218 +        return XML_ERROR_NO_ELEMENTS;
  1.2219 +      if (tagLevel != startTagLevel)
  1.2220 +        return XML_ERROR_ASYNC_ENTITY;
  1.2221 +      *nextPtr = end;
  1.2222 +      return XML_ERROR_NONE;
  1.2223 +    case XML_TOK_NONE:
  1.2224 +      if (haveMore) {
  1.2225 +        *nextPtr = s;
  1.2226 +        return XML_ERROR_NONE;
  1.2227 +      }
  1.2228 +      if (startTagLevel > 0) {
  1.2229 +        if (tagLevel != startTagLevel)
  1.2230 +          return XML_ERROR_ASYNC_ENTITY;
  1.2231 +        *nextPtr = s;
  1.2232 +        return XML_ERROR_NONE;
  1.2233 +      }
  1.2234 +      return XML_ERROR_NO_ELEMENTS;
  1.2235 +    case XML_TOK_INVALID:
  1.2236 +      *eventPP = next;
  1.2237 +      return XML_ERROR_INVALID_TOKEN;
  1.2238 +    case XML_TOK_PARTIAL:
  1.2239 +      if (haveMore) {
  1.2240 +        *nextPtr = s;
  1.2241 +        return XML_ERROR_NONE;
  1.2242 +      }
  1.2243 +      return XML_ERROR_UNCLOSED_TOKEN;
  1.2244 +    case XML_TOK_PARTIAL_CHAR:
  1.2245 +      if (haveMore) {
  1.2246 +        *nextPtr = s;
  1.2247 +        return XML_ERROR_NONE;
  1.2248 +      }
  1.2249 +      return XML_ERROR_PARTIAL_CHAR;
  1.2250 +    case XML_TOK_ENTITY_REF:
  1.2251 +      {
  1.2252 +        const XML_Char *name;
  1.2253 +        ENTITY *entity;
  1.2254 +        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
  1.2255 +                                              s + enc->minBytesPerChar,
  1.2256 +                                              next - enc->minBytesPerChar);
  1.2257 +        if (ch) {
  1.2258 +          if (characterDataHandler)
  1.2259 +            characterDataHandler(handlerArg, &ch, 1);
  1.2260 +          else if (defaultHandler)
  1.2261 +            reportDefault(parser, enc, s, next);
  1.2262 +          break;
  1.2263 +        }
  1.2264 +        name = poolStoreString(&dtd->pool, enc,
  1.2265 +                                s + enc->minBytesPerChar,
  1.2266 +                                next - enc->minBytesPerChar);
  1.2267 +        if (!name)
  1.2268 +          return XML_ERROR_NO_MEMORY;
  1.2269 +        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
  1.2270 +        poolDiscard(&dtd->pool);
  1.2271 +        /* First, determine if a check for an existing declaration is needed;
  1.2272 +           if yes, check that the entity exists, and that it is internal,
  1.2273 +           otherwise call the skipped entity or default handler.
  1.2274 +        */
  1.2275 +        if (!dtd->hasParamEntityRefs || dtd->standalone) {
  1.2276 +          if (!entity)
  1.2277 +            return XML_ERROR_UNDEFINED_ENTITY;
  1.2278 +          else if (!entity->is_internal)
  1.2279 +            return XML_ERROR_ENTITY_DECLARED_IN_PE;
  1.2280 +        }
  1.2281 +        else if (!entity) {
  1.2282 +          if (skippedEntityHandler)
  1.2283 +            skippedEntityHandler(handlerArg, name, 0);
  1.2284 +/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=35984) */
  1.2285 +#if 0
  1.2286 +          else if (defaultHandler)
  1.2287 +            reportDefault(parser, enc, s, next);
  1.2288 +          break;
  1.2289 +#else
  1.2290 +          return XML_ERROR_UNDEFINED_ENTITY;
  1.2291 +#endif
  1.2292 +/* END MOZILLA CHANGE */
  1.2293 +        }
  1.2294 +        if (entity->open)
  1.2295 +          return XML_ERROR_RECURSIVE_ENTITY_REF;
  1.2296 +        if (entity->notation)
  1.2297 +          return XML_ERROR_BINARY_ENTITY_REF;
  1.2298 +        if (entity->textPtr) {
  1.2299 +          enum XML_Error result;
  1.2300 +          if (!defaultExpandInternalEntities) {
  1.2301 +            if (skippedEntityHandler)
  1.2302 +              skippedEntityHandler(handlerArg, entity->name, 0);
  1.2303 +            else if (defaultHandler)
  1.2304 +              reportDefault(parser, enc, s, next);
  1.2305 +            break;
  1.2306 +          }
  1.2307 +          result = processInternalEntity(parser, entity, XML_FALSE);
  1.2308 +          if (result != XML_ERROR_NONE)
  1.2309 +            return result;
  1.2310 +        }
  1.2311 +        else if (externalEntityRefHandler) {
  1.2312 +          const XML_Char *context;
  1.2313 +          entity->open = XML_TRUE;
  1.2314 +          context = getContext(parser);
  1.2315 +          entity->open = XML_FALSE;
  1.2316 +          if (!context)
  1.2317 +            return XML_ERROR_NO_MEMORY;
  1.2318 +          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1.2319 +                                        context,
  1.2320 +                                        entity->base,
  1.2321 +                                        entity->systemId,
  1.2322 +                                        entity->publicId))
  1.2323 +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1.2324 +          poolDiscard(&tempPool);
  1.2325 +        }
  1.2326 +        else if (defaultHandler)
  1.2327 +          reportDefault(parser, enc, s, next);
  1.2328 +        break;
  1.2329 +      }
  1.2330 +    case XML_TOK_START_TAG_NO_ATTS:
  1.2331 +      /* fall through */
  1.2332 +    case XML_TOK_START_TAG_WITH_ATTS:
  1.2333 +      {
  1.2334 +        TAG *tag;
  1.2335 +        enum XML_Error result;
  1.2336 +        XML_Char *toPtr;
  1.2337 +        if (freeTagList) {
  1.2338 +          tag = freeTagList;
  1.2339 +          freeTagList = freeTagList->parent;
  1.2340 +        }
  1.2341 +        else {
  1.2342 +          tag = (TAG *)MALLOC(sizeof(TAG));
  1.2343 +          if (!tag)
  1.2344 +            return XML_ERROR_NO_MEMORY;
  1.2345 +          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
  1.2346 +          if (!tag->buf) {
  1.2347 +            FREE(tag);
  1.2348 +            return XML_ERROR_NO_MEMORY;
  1.2349 +          }
  1.2350 +          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
  1.2351 +        }
  1.2352 +        tag->bindings = NULL;
  1.2353 +        tag->parent = tagStack;
  1.2354 +        tagStack = tag;
  1.2355 +        tag->name.localPart = NULL;
  1.2356 +        tag->name.prefix = NULL;
  1.2357 +        tag->rawName = s + enc->minBytesPerChar;
  1.2358 +        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
  1.2359 +        ++tagLevel;
  1.2360 +        {
  1.2361 +          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
  1.2362 +          const char *fromPtr = tag->rawName;
  1.2363 +          toPtr = (XML_Char *)tag->buf;
  1.2364 +          for (;;) {
  1.2365 +            int bufSize;
  1.2366 +            int convLen;
  1.2367 +            XmlConvert(enc,
  1.2368 +                       &fromPtr, rawNameEnd,
  1.2369 +                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
  1.2370 +            convLen = (int)(toPtr - (XML_Char *)tag->buf);
  1.2371 +            if (fromPtr == rawNameEnd) {
  1.2372 +              tag->name.strLen = convLen;
  1.2373 +              break;
  1.2374 +            }
  1.2375 +            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
  1.2376 +            {
  1.2377 +              char *temp = (char *)REALLOC(tag->buf, bufSize);
  1.2378 +              if (temp == NULL)
  1.2379 +                return XML_ERROR_NO_MEMORY;
  1.2380 +              tag->buf = temp;
  1.2381 +              tag->bufEnd = temp + bufSize;
  1.2382 +              toPtr = (XML_Char *)temp + convLen;
  1.2383 +            }
  1.2384 +          }
  1.2385 +        }
  1.2386 +        tag->name.str = (XML_Char *)tag->buf;
  1.2387 +        *toPtr = XML_T('\0');
  1.2388 +        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
  1.2389 +        if (result)
  1.2390 +          return result;
  1.2391 +        if (startElementHandler)
  1.2392 +          startElementHandler(handlerArg, tag->name.str,
  1.2393 +                              (const XML_Char **)atts);
  1.2394 +        else if (defaultHandler)
  1.2395 +          reportDefault(parser, enc, s, next);
  1.2396 +        poolClear(&tempPool);
  1.2397 +        break;
  1.2398 +      }
  1.2399 +    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
  1.2400 +      /* fall through */
  1.2401 +    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
  1.2402 +      {
  1.2403 +        const char *rawName = s + enc->minBytesPerChar;
  1.2404 +        enum XML_Error result;
  1.2405 +        BINDING *bindings = NULL;
  1.2406 +        XML_Bool noElmHandlers = XML_TRUE;
  1.2407 +        TAG_NAME name;
  1.2408 +        name.str = poolStoreString(&tempPool, enc, rawName,
  1.2409 +                                   rawName + XmlNameLength(enc, rawName));
  1.2410 +        if (!name.str)
  1.2411 +          return XML_ERROR_NO_MEMORY;
  1.2412 +        poolFinish(&tempPool);
  1.2413 +        result = storeAtts(parser, enc, s, &name, &bindings);
  1.2414 +        if (result)
  1.2415 +          return result;
  1.2416 +        poolFinish(&tempPool);
  1.2417 +        if (startElementHandler) {
  1.2418 +          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
  1.2419 +          noElmHandlers = XML_FALSE;
  1.2420 +        }
  1.2421 +        if (endElementHandler) {
  1.2422 +          if (startElementHandler)
  1.2423 +            *eventPP = *eventEndPP;
  1.2424 +          endElementHandler(handlerArg, name.str);
  1.2425 +          noElmHandlers = XML_FALSE;
  1.2426 +        }
  1.2427 +        if (noElmHandlers && defaultHandler)
  1.2428 +          reportDefault(parser, enc, s, next);
  1.2429 +        poolClear(&tempPool);
  1.2430 +        while (bindings) {
  1.2431 +          BINDING *b = bindings;
  1.2432 +          if (endNamespaceDeclHandler)
  1.2433 +            endNamespaceDeclHandler(handlerArg, b->prefix->name);
  1.2434 +          bindings = bindings->nextTagBinding;
  1.2435 +          b->nextTagBinding = freeBindingList;
  1.2436 +          freeBindingList = b;
  1.2437 +          b->prefix->binding = b->prevPrefixBinding;
  1.2438 +        }
  1.2439 +      }
  1.2440 +      if (tagLevel == 0)
  1.2441 +        return epilogProcessor(parser, next, end, nextPtr);
  1.2442 +      break;
  1.2443 +    case XML_TOK_END_TAG:
  1.2444 +      if (tagLevel == startTagLevel)
  1.2445 +        return XML_ERROR_ASYNC_ENTITY;
  1.2446 +      else {
  1.2447 +        int len;
  1.2448 +        const char *rawName;
  1.2449 +        TAG *tag = tagStack;
  1.2450 +        tagStack = tag->parent;
  1.2451 +        tag->parent = freeTagList;
  1.2452 +        freeTagList = tag;
  1.2453 +        rawName = s + enc->minBytesPerChar*2;
  1.2454 +        len = XmlNameLength(enc, rawName);
  1.2455 +        if (len != tag->rawNameLength
  1.2456 +            || memcmp(tag->rawName, rawName, len) != 0) {
  1.2457 +/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
  1.2458 +	  /* This code is copied from the |if (endElementHandler)| block below */
  1.2459 +          const XML_Char *localPart;
  1.2460 +          const XML_Char *prefix;
  1.2461 +          XML_Char *uri;
  1.2462 +          localPart = tag->name.localPart;
  1.2463 +          if (ns && localPart) {
  1.2464 +            /* localPart and prefix may have been overwritten in
  1.2465 +               tag->name.str, since this points to the binding->uri
  1.2466 +               buffer which gets re-used; so we have to add them again
  1.2467 +            */
  1.2468 +            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
  1.2469 +            /* don't need to check for space - already done in storeAtts() */
  1.2470 +            while (*localPart) *uri++ = *localPart++;
  1.2471 +            prefix = (XML_Char *)tag->name.prefix;
  1.2472 +            if (ns_triplets && prefix) {
  1.2473 +              *uri++ = namespaceSeparator;
  1.2474 +              while (*prefix) *uri++ = *prefix++;
  1.2475 +             }
  1.2476 +            *uri = XML_T('\0');
  1.2477 +          }
  1.2478 +          mismatch = tag->name.str;
  1.2479 +/* END MOZILLA CHANGE */
  1.2480 +          *eventPP = rawName;
  1.2481 +          return XML_ERROR_TAG_MISMATCH;
  1.2482 +        }
  1.2483 +        --tagLevel;
  1.2484 +        if (endElementHandler) {
  1.2485 +          const XML_Char *localPart;
  1.2486 +          const XML_Char *prefix;
  1.2487 +          XML_Char *uri;
  1.2488 +          localPart = tag->name.localPart;
  1.2489 +          if (ns && localPart) {
  1.2490 +            /* localPart and prefix may have been overwritten in
  1.2491 +               tag->name.str, since this points to the binding->uri
  1.2492 +               buffer which gets re-used; so we have to add them again
  1.2493 +            */
  1.2494 +            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
  1.2495 +            /* don't need to check for space - already done in storeAtts() */
  1.2496 +            while (*localPart) *uri++ = *localPart++;
  1.2497 +            prefix = (XML_Char *)tag->name.prefix;
  1.2498 +            if (ns_triplets && prefix) {
  1.2499 +              *uri++ = namespaceSeparator;
  1.2500 +              while (*prefix) *uri++ = *prefix++;
  1.2501 +             }
  1.2502 +            *uri = XML_T('\0');
  1.2503 +          }
  1.2504 +          endElementHandler(handlerArg, tag->name.str);
  1.2505 +        }
  1.2506 +        else if (defaultHandler)
  1.2507 +          reportDefault(parser, enc, s, next);
  1.2508 +        while (tag->bindings) {
  1.2509 +          BINDING *b = tag->bindings;
  1.2510 +          if (endNamespaceDeclHandler)
  1.2511 +            endNamespaceDeclHandler(handlerArg, b->prefix->name);
  1.2512 +          tag->bindings = tag->bindings->nextTagBinding;
  1.2513 +          b->nextTagBinding = freeBindingList;
  1.2514 +          freeBindingList = b;
  1.2515 +          b->prefix->binding = b->prevPrefixBinding;
  1.2516 +        }
  1.2517 +        if (tagLevel == 0)
  1.2518 +          return epilogProcessor(parser, next, end, nextPtr);
  1.2519 +      }
  1.2520 +      break;
  1.2521 +    case XML_TOK_CHAR_REF:
  1.2522 +      {
  1.2523 +        int n = XmlCharRefNumber(enc, s);
  1.2524 +        if (n < 0)
  1.2525 +          return XML_ERROR_BAD_CHAR_REF;
  1.2526 +        if (characterDataHandler) {
  1.2527 +          XML_Char buf[XML_ENCODE_MAX];
  1.2528 +          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
  1.2529 +        }
  1.2530 +        else if (defaultHandler)
  1.2531 +          reportDefault(parser, enc, s, next);
  1.2532 +      }
  1.2533 +      break;
  1.2534 +    case XML_TOK_XML_DECL:
  1.2535 +      return XML_ERROR_MISPLACED_XML_PI;
  1.2536 +    case XML_TOK_DATA_NEWLINE:
  1.2537 +      if (characterDataHandler) {
  1.2538 +        XML_Char c = 0xA;
  1.2539 +        characterDataHandler(handlerArg, &c, 1);
  1.2540 +      }
  1.2541 +      else if (defaultHandler)
  1.2542 +        reportDefault(parser, enc, s, next);
  1.2543 +      break;
  1.2544 +    case XML_TOK_CDATA_SECT_OPEN:
  1.2545 +      {
  1.2546 +        enum XML_Error result;
  1.2547 +        if (startCdataSectionHandler)
  1.2548 +          startCdataSectionHandler(handlerArg);
  1.2549 +#if 0
  1.2550 +        /* Suppose you doing a transformation on a document that involves
  1.2551 +           changing only the character data.  You set up a defaultHandler
  1.2552 +           and a characterDataHandler.  The defaultHandler simply copies
  1.2553 +           characters through.  The characterDataHandler does the
  1.2554 +           transformation and writes the characters out escaping them as
  1.2555 +           necessary.  This case will fail to work if we leave out the
  1.2556 +           following two lines (because & and < inside CDATA sections will
  1.2557 +           be incorrectly escaped).
  1.2558 +
  1.2559 +           However, now we have a start/endCdataSectionHandler, so it seems
  1.2560 +           easier to let the user deal with this.
  1.2561 +        */
  1.2562 +        else if (characterDataHandler)
  1.2563 +          characterDataHandler(handlerArg, dataBuf, 0);
  1.2564 +#endif
  1.2565 +        else if (defaultHandler)
  1.2566 +          reportDefault(parser, enc, s, next);
  1.2567 +        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
  1.2568 +        if (result != XML_ERROR_NONE)
  1.2569 +          return result;
  1.2570 +        else if (!next) {
  1.2571 +          processor = cdataSectionProcessor;
  1.2572 +          return result;
  1.2573 +        }
  1.2574 +      }
  1.2575 +      break;
  1.2576 +    case XML_TOK_TRAILING_RSQB:
  1.2577 +      if (haveMore) {
  1.2578 +        *nextPtr = s;
  1.2579 +        return XML_ERROR_NONE;
  1.2580 +      }
  1.2581 +      if (characterDataHandler) {
  1.2582 +        if (MUST_CONVERT(enc, s)) {
  1.2583 +          ICHAR *dataPtr = (ICHAR *)dataBuf;
  1.2584 +          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
  1.2585 +          characterDataHandler(handlerArg, dataBuf,
  1.2586 +                               (int)(dataPtr - (ICHAR *)dataBuf));
  1.2587 +        }
  1.2588 +        else
  1.2589 +          characterDataHandler(handlerArg,
  1.2590 +                               (XML_Char *)s,
  1.2591 +                               (int)((XML_Char *)end - (XML_Char *)s));
  1.2592 +      }
  1.2593 +      else if (defaultHandler)
  1.2594 +        reportDefault(parser, enc, s, end);
  1.2595 +      /* We are at the end of the final buffer, should we check for 
  1.2596 +         XML_SUSPENDED, XML_FINISHED? 
  1.2597 +      */
  1.2598 +      if (startTagLevel == 0) {
  1.2599 +        *eventPP = end;
  1.2600 +        return XML_ERROR_NO_ELEMENTS;
  1.2601 +      }
  1.2602 +      if (tagLevel != startTagLevel) {
  1.2603 +        *eventPP = end;
  1.2604 +        return XML_ERROR_ASYNC_ENTITY;
  1.2605 +      }
  1.2606 +      *nextPtr = end;
  1.2607 +      return XML_ERROR_NONE;
  1.2608 +    case XML_TOK_DATA_CHARS:
  1.2609 +      if (characterDataHandler) {
  1.2610 +        if (MUST_CONVERT(enc, s)) {
  1.2611 +          for (;;) {
  1.2612 +            ICHAR *dataPtr = (ICHAR *)dataBuf;
  1.2613 +            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
  1.2614 +            *eventEndPP = s;
  1.2615 +            characterDataHandler(handlerArg, dataBuf,
  1.2616 +                                 (int)(dataPtr - (ICHAR *)dataBuf));
  1.2617 +            if (s == next)
  1.2618 +              break;
  1.2619 +            *eventPP = s;
  1.2620 +          }
  1.2621 +        }
  1.2622 +        else
  1.2623 +          characterDataHandler(handlerArg,
  1.2624 +                               (XML_Char *)s,
  1.2625 +                               (int)((XML_Char *)next - (XML_Char *)s));
  1.2626 +      }
  1.2627 +      else if (defaultHandler)
  1.2628 +        reportDefault(parser, enc, s, next);
  1.2629 +      break;
  1.2630 +    case XML_TOK_PI:
  1.2631 +      if (!reportProcessingInstruction(parser, enc, s, next))
  1.2632 +        return XML_ERROR_NO_MEMORY;
  1.2633 +      break;
  1.2634 +    case XML_TOK_COMMENT:
  1.2635 +      if (!reportComment(parser, enc, s, next))
  1.2636 +        return XML_ERROR_NO_MEMORY;
  1.2637 +      break;
  1.2638 +    default:
  1.2639 +      if (defaultHandler)
  1.2640 +        reportDefault(parser, enc, s, next);
  1.2641 +      break;
  1.2642 +    }
  1.2643 +    *eventPP = s = next;
  1.2644 +    switch (ps_parsing) {
  1.2645 +    case XML_SUSPENDED: 
  1.2646 +      *nextPtr = next;
  1.2647 +      return XML_ERROR_NONE;
  1.2648 +    case XML_FINISHED:
  1.2649 +      return XML_ERROR_ABORTED;
  1.2650 +    default: ;
  1.2651 +    }
  1.2652 +  }
  1.2653 +  /* not reached */
  1.2654 +}
  1.2655 +
  1.2656 +/* Precondition: all arguments must be non-NULL;
  1.2657 +   Purpose:
  1.2658 +   - normalize attributes
  1.2659 +   - check attributes for well-formedness
  1.2660 +   - generate namespace aware attribute names (URI, prefix)
  1.2661 +   - build list of attributes for startElementHandler
  1.2662 +   - default attributes
  1.2663 +   - process namespace declarations (check and report them)
  1.2664 +   - generate namespace aware element name (URI, prefix)
  1.2665 +*/
  1.2666 +static enum XML_Error
  1.2667 +storeAtts(XML_Parser parser, const ENCODING *enc,
  1.2668 +          const char *attStr, TAG_NAME *tagNamePtr,
  1.2669 +          BINDING **bindingsPtr)
  1.2670 +{
  1.2671 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.2672 +  ELEMENT_TYPE *elementType;
  1.2673 +  int nDefaultAtts;
  1.2674 +  const XML_Char **appAtts;   /* the attribute list for the application */
  1.2675 +  int attIndex = 0;
  1.2676 +  int prefixLen;
  1.2677 +  int i;
  1.2678 +  int n;
  1.2679 +  XML_Char *uri;
  1.2680 +  int nPrefixes = 0;
  1.2681 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2682 +  int nXMLNSDeclarations = 0;
  1.2683 +/* END MOZILLA CHANGE */
  1.2684 +  BINDING *binding;
  1.2685 +  const XML_Char *localPart;
  1.2686 +
  1.2687 +  /* lookup the element type name */
  1.2688 +  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
  1.2689 +  if (!elementType) {
  1.2690 +    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
  1.2691 +    if (!name)
  1.2692 +      return XML_ERROR_NO_MEMORY;
  1.2693 +    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
  1.2694 +                                         sizeof(ELEMENT_TYPE));
  1.2695 +    if (!elementType)
  1.2696 +      return XML_ERROR_NO_MEMORY;
  1.2697 +    if (ns && !setElementTypePrefix(parser, elementType))
  1.2698 +      return XML_ERROR_NO_MEMORY;
  1.2699 +  }
  1.2700 +  nDefaultAtts = elementType->nDefaultAtts;
  1.2701 +
  1.2702 +  /* get the attributes from the tokenizer */
  1.2703 +  n = XmlGetAttributes(enc, attStr, attsSize, atts);
  1.2704 +  if (n + nDefaultAtts > attsSize) {
  1.2705 +    int oldAttsSize = attsSize;
  1.2706 +    ATTRIBUTE *temp;
  1.2707 +    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
  1.2708 +    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
  1.2709 +    if (temp == NULL)
  1.2710 +      return XML_ERROR_NO_MEMORY;
  1.2711 +    atts = temp;
  1.2712 +    if (n > oldAttsSize)
  1.2713 +      XmlGetAttributes(enc, attStr, n, atts);
  1.2714 +  }
  1.2715 +
  1.2716 +  appAtts = (const XML_Char **)atts;
  1.2717 +  for (i = 0; i < n; i++) {
  1.2718 +    /* add the name and value to the attribute list */
  1.2719 +    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
  1.2720 +                                         atts[i].name
  1.2721 +                                         + XmlNameLength(enc, atts[i].name));
  1.2722 +    if (!attId)
  1.2723 +      return XML_ERROR_NO_MEMORY;
  1.2724 +    /* Detect duplicate attributes by their QNames. This does not work when
  1.2725 +       namespace processing is turned on and different prefixes for the same
  1.2726 +       namespace are used. For this case we have a check further down.
  1.2727 +    */
  1.2728 +    if ((attId->name)[-1]) {
  1.2729 +      if (enc == encoding)
  1.2730 +        eventPtr = atts[i].name;
  1.2731 +      return XML_ERROR_DUPLICATE_ATTRIBUTE;
  1.2732 +    }
  1.2733 +    (attId->name)[-1] = 1;
  1.2734 +    appAtts[attIndex++] = attId->name;
  1.2735 +    if (!atts[i].normalized) {
  1.2736 +      enum XML_Error result;
  1.2737 +      XML_Bool isCdata = XML_TRUE;
  1.2738 +
  1.2739 +      /* figure out whether declared as other than CDATA */
  1.2740 +      if (attId->maybeTokenized) {
  1.2741 +        int j;
  1.2742 +        for (j = 0; j < nDefaultAtts; j++) {
  1.2743 +          if (attId == elementType->defaultAtts[j].id) {
  1.2744 +            isCdata = elementType->defaultAtts[j].isCdata;
  1.2745 +            break;
  1.2746 +          }
  1.2747 +        }
  1.2748 +      }
  1.2749 +
  1.2750 +      /* normalize the attribute value */
  1.2751 +      result = storeAttributeValue(parser, enc, isCdata,
  1.2752 +                                   atts[i].valuePtr, atts[i].valueEnd,
  1.2753 +                                   &tempPool);
  1.2754 +      if (result)
  1.2755 +        return result;
  1.2756 +      appAtts[attIndex] = poolStart(&tempPool);
  1.2757 +      poolFinish(&tempPool);
  1.2758 +    }
  1.2759 +    else {
  1.2760 +      /* the value did not need normalizing */
  1.2761 +      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
  1.2762 +                                          atts[i].valueEnd);
  1.2763 +      if (appAtts[attIndex] == 0)
  1.2764 +        return XML_ERROR_NO_MEMORY;
  1.2765 +      poolFinish(&tempPool);
  1.2766 +    }
  1.2767 +    /* handle prefixed attribute names */
  1.2768 +    if (attId->prefix) {
  1.2769 +      if (attId->xmlns) {
  1.2770 +        /* deal with namespace declarations here */
  1.2771 +        enum XML_Error result = addBinding(parser, attId->prefix, attId,
  1.2772 +                                           appAtts[attIndex], bindingsPtr);
  1.2773 +        if (result)
  1.2774 +          return result;
  1.2775 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2776 +#if 0
  1.2777 +        --attIndex;
  1.2778 +#else
  1.2779 +        attIndex++;
  1.2780 +        nXMLNSDeclarations++;
  1.2781 +        (attId->name)[-1] = 3;
  1.2782 +#endif
  1.2783 +/* END MOZILLA CHANGE */
  1.2784 +      }
  1.2785 +      else {
  1.2786 +        /* deal with other prefixed names later */
  1.2787 +        attIndex++;
  1.2788 +        nPrefixes++;
  1.2789 +        (attId->name)[-1] = 2;
  1.2790 +      }
  1.2791 +    }
  1.2792 +    else
  1.2793 +      attIndex++;
  1.2794 +  }
  1.2795 +
  1.2796 +  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
  1.2797 +  nSpecifiedAtts = attIndex;
  1.2798 +  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
  1.2799 +    for (i = 0; i < attIndex; i += 2)
  1.2800 +      if (appAtts[i] == elementType->idAtt->name) {
  1.2801 +        idAttIndex = i;
  1.2802 +        break;
  1.2803 +      }
  1.2804 +  }
  1.2805 +  else
  1.2806 +    idAttIndex = -1;
  1.2807 +
  1.2808 +  /* do attribute defaulting */
  1.2809 +  for (i = 0; i < nDefaultAtts; i++) {
  1.2810 +    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
  1.2811 +    if (!(da->id->name)[-1] && da->value) {
  1.2812 +      if (da->id->prefix) {
  1.2813 +        if (da->id->xmlns) {
  1.2814 +          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
  1.2815 +                                             da->value, bindingsPtr);
  1.2816 +          if (result)
  1.2817 +            return result;
  1.2818 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2819 +          (da->id->name)[-1] = 3;
  1.2820 +          nXMLNSDeclarations++;
  1.2821 +          appAtts[attIndex++] = da->id->name;
  1.2822 +          appAtts[attIndex++] = da->value;
  1.2823 +/* END MOZILLA CHANGE */
  1.2824 +        }
  1.2825 +        else {
  1.2826 +          (da->id->name)[-1] = 2;
  1.2827 +          nPrefixes++;
  1.2828 +          appAtts[attIndex++] = da->id->name;
  1.2829 +          appAtts[attIndex++] = da->value;
  1.2830 +        }
  1.2831 +      }
  1.2832 +      else {
  1.2833 +        (da->id->name)[-1] = 1;
  1.2834 +        appAtts[attIndex++] = da->id->name;
  1.2835 +        appAtts[attIndex++] = da->value;
  1.2836 +      }
  1.2837 +    }
  1.2838 +  }
  1.2839 +  appAtts[attIndex] = 0;
  1.2840 +
  1.2841 +  /* expand prefixed attribute names, check for duplicates,
  1.2842 +     and clear flags that say whether attributes were specified */
  1.2843 +  i = 0;
  1.2844 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2845 +#if 0
  1.2846 +  if (nPrefixes) {
  1.2847 +#else
  1.2848 +  if (nPrefixes || nXMLNSDeclarations) {
  1.2849 +#endif
  1.2850 +/* END MOZILLA CHANGE */
  1.2851 +    int j;  /* hash table index */
  1.2852 +    unsigned long version = nsAttsVersion;
  1.2853 +    int nsAttsSize = (int)1 << nsAttsPower;
  1.2854 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2855 +    if (nPrefixes) {
  1.2856 +/* END MOZILLA CHANGE */
  1.2857 +    /* size of hash table must be at least 2 * (# of prefixed attributes) */
  1.2858 +    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
  1.2859 +      NS_ATT *temp;
  1.2860 +      /* hash table size must also be a power of 2 and >= 8 */
  1.2861 +      while (nPrefixes >> nsAttsPower++);
  1.2862 +      if (nsAttsPower < 3)
  1.2863 +        nsAttsPower = 3;
  1.2864 +      nsAttsSize = (int)1 << nsAttsPower;
  1.2865 +      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
  1.2866 +      if (!temp)
  1.2867 +        return XML_ERROR_NO_MEMORY;
  1.2868 +      nsAtts = temp;
  1.2869 +      version = 0;  /* force re-initialization of nsAtts hash table */
  1.2870 +    }
  1.2871 +    /* using a version flag saves us from initializing nsAtts every time */
  1.2872 +    if (!version) {  /* initialize version flags when version wraps around */
  1.2873 +      version = INIT_ATTS_VERSION;
  1.2874 +      for (j = nsAttsSize; j != 0; )
  1.2875 +        nsAtts[--j].version = version;
  1.2876 +    }
  1.2877 +    nsAttsVersion = --version;
  1.2878 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2879 +    }
  1.2880 +/* END MOZILLA CHANGE */
  1.2881 +
  1.2882 +    /* expand prefixed names and check for duplicates */
  1.2883 +    for (; i < attIndex; i += 2) {
  1.2884 +      const XML_Char *s = appAtts[i];
  1.2885 +      if (s[-1] == 2) {  /* prefixed */
  1.2886 +        ATTRIBUTE_ID *id;
  1.2887 +        const BINDING *b;
  1.2888 +        unsigned long uriHash = 0;
  1.2889 +        ((XML_Char *)s)[-1] = 0;  /* clear flag */
  1.2890 +        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
  1.2891 +        b = id->prefix->binding;
  1.2892 +        if (!b)
  1.2893 +          return XML_ERROR_UNBOUND_PREFIX;
  1.2894 +
  1.2895 +        /* as we expand the name we also calculate its hash value */
  1.2896 +        for (j = 0; j < b->uriLen; j++) {
  1.2897 +          const XML_Char c = b->uri[j];
  1.2898 +          if (!poolAppendChar(&tempPool, c))
  1.2899 +            return XML_ERROR_NO_MEMORY;
  1.2900 +          uriHash = CHAR_HASH(uriHash, c);
  1.2901 +        }
  1.2902 +        while (*s++ != XML_T(':'))
  1.2903 +          ;
  1.2904 +        do {  /* copies null terminator */
  1.2905 +          const XML_Char c = *s;
  1.2906 +          if (!poolAppendChar(&tempPool, *s))
  1.2907 +            return XML_ERROR_NO_MEMORY;
  1.2908 +          uriHash = CHAR_HASH(uriHash, c);
  1.2909 +        } while (*s++);
  1.2910 +
  1.2911 +        { /* Check hash table for duplicate of expanded name (uriName).
  1.2912 +             Derived from code in lookup(HASH_TABLE *table, ...).
  1.2913 +          */
  1.2914 +          unsigned char step = 0;
  1.2915 +          unsigned long mask = nsAttsSize - 1;
  1.2916 +          j = uriHash & mask;  /* index into hash table */
  1.2917 +          while (nsAtts[j].version == version) {
  1.2918 +            /* for speed we compare stored hash values first */
  1.2919 +            if (uriHash == nsAtts[j].hash) {
  1.2920 +              const XML_Char *s1 = poolStart(&tempPool);
  1.2921 +              const XML_Char *s2 = nsAtts[j].uriName;
  1.2922 +              /* s1 is null terminated, but not s2 */
  1.2923 +              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
  1.2924 +              if (*s1 == 0)
  1.2925 +                return XML_ERROR_DUPLICATE_ATTRIBUTE;
  1.2926 +            }
  1.2927 +            if (!step)
  1.2928 +              step = PROBE_STEP(uriHash, mask, nsAttsPower);
  1.2929 +            j < step ? (j += nsAttsSize - step) : (j -= step);
  1.2930 +          }
  1.2931 +        }
  1.2932 +
  1.2933 +        if (ns_triplets) {  /* append namespace separator and prefix */
  1.2934 +          tempPool.ptr[-1] = namespaceSeparator;
  1.2935 +          s = b->prefix->name;
  1.2936 +          do {
  1.2937 +            if (!poolAppendChar(&tempPool, *s))
  1.2938 +              return XML_ERROR_NO_MEMORY;
  1.2939 +          } while (*s++);
  1.2940 +        }
  1.2941 +
  1.2942 +        /* store expanded name in attribute list */
  1.2943 +        s = poolStart(&tempPool);
  1.2944 +        poolFinish(&tempPool);
  1.2945 +        appAtts[i] = s;
  1.2946 +
  1.2947 +        /* fill empty slot with new version, uriName and hash value */
  1.2948 +        nsAtts[j].version = version;
  1.2949 +        nsAtts[j].hash = uriHash;
  1.2950 +        nsAtts[j].uriName = s;
  1.2951 +
  1.2952 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2953 +#if 0
  1.2954 +        if (!--nPrefixes)
  1.2955 +#else
  1.2956 +        if (!--nPrefixes && !nXMLNSDeclarations) {
  1.2957 +#endif
  1.2958 +/* END MOZILLA CHANGE */
  1.2959 +          i += 2;
  1.2960 +          break;
  1.2961 +        }
  1.2962 +      }
  1.2963 +/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
  1.2964 +      else if (s[-1] == 3) { /* xmlns attribute */
  1.2965 +        static const XML_Char xmlnsNamespace[] = {
  1.2966 +          'h', 't', 't', 'p', ':', '/', '/',
  1.2967 +          'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
  1.2968 +          '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
  1.2969 +        };
  1.2970 +        static const XML_Char xmlnsPrefix[] = {
  1.2971 +          'x', 'm', 'l', 'n', 's', '\0'
  1.2972 +        };
  1.2973 +        XML_Bool appendXMLNS = XML_TRUE;
  1.2974 +
  1.2975 +        ((XML_Char *)s)[-1] = 0;  /* clear flag */
  1.2976 +        if (!poolAppendString(&tempPool, xmlnsNamespace)
  1.2977 +            || !poolAppendChar(&tempPool, namespaceSeparator))
  1.2978 +          return XML_ERROR_NO_MEMORY;
  1.2979 +        s += sizeof(xmlnsPrefix) / sizeof(xmlnsPrefix[0]) - 1;
  1.2980 +        if (*s == XML_T(':')) {
  1.2981 +          ++s;
  1.2982 +          do {  /* copies null terminator */
  1.2983 +            if (!poolAppendChar(&tempPool, *s))
  1.2984 +              return XML_ERROR_NO_MEMORY;
  1.2985 +          } while (*s++);
  1.2986 +          if (ns_triplets) { /* append namespace separator and prefix */
  1.2987 +            tempPool.ptr[-1] = namespaceSeparator;
  1.2988 +            if (!poolAppendString(&tempPool, xmlnsPrefix)
  1.2989 +                || !poolAppendChar(&tempPool, '\0'))
  1.2990 +              return XML_ERROR_NO_MEMORY;
  1.2991 +          }
  1.2992 +        }
  1.2993 +        else {
  1.2994 +          /* xlmns attribute without a prefix. */
  1.2995 +          if (!poolAppendString(&tempPool, xmlnsPrefix)
  1.2996 +              || !poolAppendChar(&tempPool, '\0'))
  1.2997 +            return XML_ERROR_NO_MEMORY;
  1.2998 +        }
  1.2999 +
  1.3000 +        /* store expanded name in attribute list */
  1.3001 +        s = poolStart(&tempPool);
  1.3002 +        poolFinish(&tempPool);
  1.3003 +        appAtts[i] = s;
  1.3004 +
  1.3005 +        if (!--nXMLNSDeclarations && !nPrefixes) {
  1.3006 +          i += 2;
  1.3007 +          break;
  1.3008 +        }
  1.3009 +      }
  1.3010 +/* END MOZILLA CHANGE */
  1.3011 +      else  /* not prefixed */
  1.3012 +        ((XML_Char *)s)[-1] = 0;  /* clear flag */
  1.3013 +    }
  1.3014 +  }
  1.3015 +  /* clear flags for the remaining attributes */
  1.3016 +  for (; i < attIndex; i += 2)
  1.3017 +    ((XML_Char *)(appAtts[i]))[-1] = 0;
  1.3018 +  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
  1.3019 +    binding->attId->name[-1] = 0;
  1.3020 +
  1.3021 +  if (!ns)
  1.3022 +    return XML_ERROR_NONE;
  1.3023 +
  1.3024 +  /* expand the element type name */
  1.3025 +  if (elementType->prefix) {
  1.3026 +    binding = elementType->prefix->binding;
  1.3027 +    if (!binding)
  1.3028 +      return XML_ERROR_UNBOUND_PREFIX;
  1.3029 +    localPart = tagNamePtr->str;
  1.3030 +    while (*localPart++ != XML_T(':'))
  1.3031 +      ;
  1.3032 +  }
  1.3033 +  else if (dtd->defaultPrefix.binding) {
  1.3034 +    binding = dtd->defaultPrefix.binding;
  1.3035 +    localPart = tagNamePtr->str;
  1.3036 +  }
  1.3037 +  else
  1.3038 +    return XML_ERROR_NONE;
  1.3039 +  prefixLen = 0;
  1.3040 +  if (ns_triplets && binding->prefix->name) {
  1.3041 +    for (; binding->prefix->name[prefixLen++];)
  1.3042 +      ;  /* prefixLen includes null terminator */
  1.3043 +  }
  1.3044 +  tagNamePtr->localPart = localPart;
  1.3045 +  tagNamePtr->uriLen = binding->uriLen;
  1.3046 +  tagNamePtr->prefix = binding->prefix->name;
  1.3047 +  tagNamePtr->prefixLen = prefixLen;
  1.3048 +  for (i = 0; localPart[i++];)
  1.3049 +    ;  /* i includes null terminator */
  1.3050 +  n = i + binding->uriLen + prefixLen;
  1.3051 +  if (n > binding->uriAlloc) {
  1.3052 +    TAG *p;
  1.3053 +    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
  1.3054 +    if (!uri)
  1.3055 +      return XML_ERROR_NO_MEMORY;
  1.3056 +    binding->uriAlloc = n + EXPAND_SPARE;
  1.3057 +    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
  1.3058 +    for (p = tagStack; p; p = p->parent)
  1.3059 +      if (p->name.str == binding->uri)
  1.3060 +        p->name.str = uri;
  1.3061 +    FREE(binding->uri);
  1.3062 +    binding->uri = uri;
  1.3063 +  }
  1.3064 +  /* if namespaceSeparator != '\0' then uri includes it already */
  1.3065 +  uri = binding->uri + binding->uriLen;
  1.3066 +  memcpy(uri, localPart, i * sizeof(XML_Char));
  1.3067 +  /* we always have a namespace separator between localPart and prefix */
  1.3068 +  if (prefixLen) {
  1.3069 +    uri += i - 1;
  1.3070 +    *uri = namespaceSeparator;  /* replace null terminator */
  1.3071 +    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
  1.3072 +  }
  1.3073 +  tagNamePtr->str = binding->uri;
  1.3074 +  return XML_ERROR_NONE;
  1.3075 +}
  1.3076 +
  1.3077 +/* addBinding() overwrites the value of prefix->binding without checking.
  1.3078 +   Therefore one must keep track of the old value outside of addBinding().
  1.3079 +*/
  1.3080 +static enum XML_Error
  1.3081 +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
  1.3082 +           const XML_Char *uri, BINDING **bindingsPtr)
  1.3083 +{
  1.3084 +  static const XML_Char xmlNamespace[] = {
  1.3085 +    'h', 't', 't', 'p', ':', '/', '/',
  1.3086 +    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
  1.3087 +    'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
  1.3088 +    'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
  1.3089 +  };
  1.3090 +  static const int xmlLen = 
  1.3091 +    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
  1.3092 +  static const XML_Char xmlnsNamespace[] = {
  1.3093 +    'h', 't', 't', 'p', ':', '/', '/',
  1.3094 +    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
  1.3095 +    '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
  1.3096 +  };
  1.3097 +  static const int xmlnsLen = 
  1.3098 +    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
  1.3099 +
  1.3100 +  XML_Bool mustBeXML = XML_FALSE;
  1.3101 +  XML_Bool isXML = XML_TRUE;
  1.3102 +  XML_Bool isXMLNS = XML_TRUE;
  1.3103 +  
  1.3104 +  BINDING *b;
  1.3105 +  int len;
  1.3106 +
  1.3107 +  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
  1.3108 +  if (*uri == XML_T('\0') && prefix->name)
  1.3109 +    return XML_ERROR_UNDECLARING_PREFIX;
  1.3110 +
  1.3111 +  if (prefix->name
  1.3112 +      && prefix->name[0] == XML_T('x')
  1.3113 +      && prefix->name[1] == XML_T('m')
  1.3114 +      && prefix->name[2] == XML_T('l')) {
  1.3115 +
  1.3116 +    /* Not allowed to bind xmlns */
  1.3117 +    if (prefix->name[3] == XML_T('n')
  1.3118 +        && prefix->name[4] == XML_T('s')
  1.3119 +        && prefix->name[5] == XML_T('\0'))
  1.3120 +      return XML_ERROR_RESERVED_PREFIX_XMLNS;
  1.3121 +
  1.3122 +    if (prefix->name[3] == XML_T('\0'))
  1.3123 +      mustBeXML = XML_TRUE;
  1.3124 +  }
  1.3125 +
  1.3126 +  for (len = 0; uri[len]; len++) {
  1.3127 +    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
  1.3128 +      isXML = XML_FALSE;
  1.3129 +
  1.3130 +    if (!mustBeXML && isXMLNS 
  1.3131 +        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
  1.3132 +      isXMLNS = XML_FALSE;
  1.3133 +  }
  1.3134 +  isXML = isXML && len == xmlLen;
  1.3135 +  isXMLNS = isXMLNS && len == xmlnsLen;
  1.3136 +
  1.3137 +  if (mustBeXML != isXML)
  1.3138 +    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
  1.3139 +                     : XML_ERROR_RESERVED_NAMESPACE_URI;
  1.3140 +
  1.3141 +  if (isXMLNS)
  1.3142 +    return XML_ERROR_RESERVED_NAMESPACE_URI;
  1.3143 +
  1.3144 +  if (namespaceSeparator)
  1.3145 +    len++;
  1.3146 +  if (freeBindingList) {
  1.3147 +    b = freeBindingList;
  1.3148 +    if (len > b->uriAlloc) {
  1.3149 +      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
  1.3150 +                          sizeof(XML_Char) * (len + EXPAND_SPARE));
  1.3151 +      if (temp == NULL)
  1.3152 +        return XML_ERROR_NO_MEMORY;
  1.3153 +      b->uri = temp;
  1.3154 +      b->uriAlloc = len + EXPAND_SPARE;
  1.3155 +    }
  1.3156 +    freeBindingList = b->nextTagBinding;
  1.3157 +  }
  1.3158 +  else {
  1.3159 +    b = (BINDING *)MALLOC(sizeof(BINDING));
  1.3160 +    if (!b)
  1.3161 +      return XML_ERROR_NO_MEMORY;
  1.3162 +    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
  1.3163 +    if (!b->uri) {
  1.3164 +      FREE(b);
  1.3165 +      return XML_ERROR_NO_MEMORY;
  1.3166 +    }
  1.3167 +    b->uriAlloc = len + EXPAND_SPARE;
  1.3168 +  }
  1.3169 +  b->uriLen = len;
  1.3170 +  memcpy(b->uri, uri, len * sizeof(XML_Char));
  1.3171 +  if (namespaceSeparator)
  1.3172 +    b->uri[len - 1] = namespaceSeparator;
  1.3173 +  b->prefix = prefix;
  1.3174 +  b->attId = attId;
  1.3175 +  b->prevPrefixBinding = prefix->binding;
  1.3176 +  /* NULL binding when default namespace undeclared */
  1.3177 +  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
  1.3178 +    prefix->binding = NULL;
  1.3179 +  else
  1.3180 +    prefix->binding = b;
  1.3181 +  b->nextTagBinding = *bindingsPtr;
  1.3182 +  *bindingsPtr = b;
  1.3183 +  /* if attId == NULL then we are not starting a namespace scope */
  1.3184 +  if (attId && startNamespaceDeclHandler)
  1.3185 +    startNamespaceDeclHandler(handlerArg, prefix->name,
  1.3186 +                              prefix->binding ? uri : 0);
  1.3187 +  return XML_ERROR_NONE;
  1.3188 +}
  1.3189 +
  1.3190 +/* The idea here is to avoid using stack for each CDATA section when
  1.3191 +   the whole file is parsed with one call.
  1.3192 +*/
  1.3193 +static enum XML_Error PTRCALL
  1.3194 +cdataSectionProcessor(XML_Parser parser,
  1.3195 +                      const char *start,
  1.3196 +                      const char *end,
  1.3197 +                      const char **endPtr)
  1.3198 +{
  1.3199 +  enum XML_Error result = doCdataSection(parser, encoding, &start, end,
  1.3200 +                                         endPtr, (XML_Bool)!ps_finalBuffer);
  1.3201 +  if (result != XML_ERROR_NONE)
  1.3202 +    return result;
  1.3203 +  if (start) {
  1.3204 +    if (parentParser) {  /* we are parsing an external entity */
  1.3205 +      processor = externalEntityContentProcessor;
  1.3206 +      return externalEntityContentProcessor(parser, start, end, endPtr);
  1.3207 +    }
  1.3208 +    else {
  1.3209 +      processor = contentProcessor;
  1.3210 +      return contentProcessor(parser, start, end, endPtr);
  1.3211 +    }
  1.3212 +  }
  1.3213 +  return result;
  1.3214 +}
  1.3215 +
  1.3216 +/* startPtr gets set to non-null if the section is closed, and to null if
  1.3217 +   the section is not yet closed.
  1.3218 +*/
  1.3219 +static enum XML_Error
  1.3220 +doCdataSection(XML_Parser parser,
  1.3221 +               const ENCODING *enc,
  1.3222 +               const char **startPtr,
  1.3223 +               const char *end,
  1.3224 +               const char **nextPtr,
  1.3225 +               XML_Bool haveMore)
  1.3226 +{
  1.3227 +  const char *s = *startPtr;
  1.3228 +  const char **eventPP;
  1.3229 +  const char **eventEndPP;
  1.3230 +  if (enc == encoding) {
  1.3231 +    eventPP = &eventPtr;
  1.3232 +    *eventPP = s;
  1.3233 +    eventEndPP = &eventEndPtr;
  1.3234 +  }
  1.3235 +  else {
  1.3236 +    eventPP = &(openInternalEntities->internalEventPtr);
  1.3237 +    eventEndPP = &(openInternalEntities->internalEventEndPtr);
  1.3238 +  }
  1.3239 +  *eventPP = s;
  1.3240 +  *startPtr = NULL;
  1.3241 +
  1.3242 +  for (;;) {
  1.3243 +    const char *next;
  1.3244 +    int tok = XmlCdataSectionTok(enc, s, end, &next);
  1.3245 +    *eventEndPP = next;
  1.3246 +    switch (tok) {
  1.3247 +    case XML_TOK_CDATA_SECT_CLOSE:
  1.3248 +      if (endCdataSectionHandler)
  1.3249 +        endCdataSectionHandler(handlerArg);
  1.3250 +#if 0
  1.3251 +      /* see comment under XML_TOK_CDATA_SECT_OPEN */
  1.3252 +      else if (characterDataHandler)
  1.3253 +        characterDataHandler(handlerArg, dataBuf, 0);
  1.3254 +#endif
  1.3255 +      else if (defaultHandler)
  1.3256 +        reportDefault(parser, enc, s, next);
  1.3257 +      *startPtr = next;
  1.3258 +      *nextPtr = next;
  1.3259 +      if (ps_parsing == XML_FINISHED)
  1.3260 +        return XML_ERROR_ABORTED;
  1.3261 +      else
  1.3262 +        return XML_ERROR_NONE;
  1.3263 +    case XML_TOK_DATA_NEWLINE:
  1.3264 +      if (characterDataHandler) {
  1.3265 +        XML_Char c = 0xA;
  1.3266 +        characterDataHandler(handlerArg, &c, 1);
  1.3267 +      }
  1.3268 +      else if (defaultHandler)
  1.3269 +        reportDefault(parser, enc, s, next);
  1.3270 +      break;
  1.3271 +    case XML_TOK_DATA_CHARS:
  1.3272 +      if (characterDataHandler) {
  1.3273 +        if (MUST_CONVERT(enc, s)) {
  1.3274 +          for (;;) {
  1.3275 +            ICHAR *dataPtr = (ICHAR *)dataBuf;
  1.3276 +            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
  1.3277 +            *eventEndPP = next;
  1.3278 +            characterDataHandler(handlerArg, dataBuf,
  1.3279 +                                 (int)(dataPtr - (ICHAR *)dataBuf));
  1.3280 +            if (s == next)
  1.3281 +              break;
  1.3282 +            *eventPP = s;
  1.3283 +          }
  1.3284 +        }
  1.3285 +        else
  1.3286 +          characterDataHandler(handlerArg,
  1.3287 +                               (XML_Char *)s,
  1.3288 +                               (int)((XML_Char *)next - (XML_Char *)s));
  1.3289 +      }
  1.3290 +      else if (defaultHandler)
  1.3291 +        reportDefault(parser, enc, s, next);
  1.3292 +      break;
  1.3293 +    case XML_TOK_INVALID:
  1.3294 +      *eventPP = next;
  1.3295 +      return XML_ERROR_INVALID_TOKEN;
  1.3296 +    case XML_TOK_PARTIAL_CHAR:
  1.3297 +      if (haveMore) {
  1.3298 +        *nextPtr = s;
  1.3299 +        return XML_ERROR_NONE;
  1.3300 +      }
  1.3301 +      return XML_ERROR_PARTIAL_CHAR;
  1.3302 +    case XML_TOK_PARTIAL:
  1.3303 +    case XML_TOK_NONE:
  1.3304 +      if (haveMore) {
  1.3305 +        *nextPtr = s;
  1.3306 +        return XML_ERROR_NONE;
  1.3307 +      }
  1.3308 +      return XML_ERROR_UNCLOSED_CDATA_SECTION;
  1.3309 +    default:
  1.3310 +      *eventPP = next;
  1.3311 +      return XML_ERROR_UNEXPECTED_STATE;
  1.3312 +    }
  1.3313 +
  1.3314 +    *eventPP = s = next;
  1.3315 +    switch (ps_parsing) {
  1.3316 +    case XML_SUSPENDED:
  1.3317 +      *nextPtr = next;
  1.3318 +      return XML_ERROR_NONE;
  1.3319 +    case XML_FINISHED:
  1.3320 +      return XML_ERROR_ABORTED;
  1.3321 +    default: ;
  1.3322 +    }
  1.3323 +  }
  1.3324 +  /* not reached */
  1.3325 +}
  1.3326 +
  1.3327 +#ifdef XML_DTD
  1.3328 +
  1.3329 +/* The idea here is to avoid using stack for each IGNORE section when
  1.3330 +   the whole file is parsed with one call.
  1.3331 +*/
  1.3332 +static enum XML_Error PTRCALL
  1.3333 +ignoreSectionProcessor(XML_Parser parser,
  1.3334 +                       const char *start,
  1.3335 +                       const char *end,
  1.3336 +                       const char **endPtr)
  1.3337 +{
  1.3338 +  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
  1.3339 +                                          endPtr, (XML_Bool)!ps_finalBuffer);
  1.3340 +  if (result != XML_ERROR_NONE)
  1.3341 +    return result;
  1.3342 +  if (start) {
  1.3343 +    processor = prologProcessor;
  1.3344 +    return prologProcessor(parser, start, end, endPtr);
  1.3345 +  }
  1.3346 +  return result;
  1.3347 +}
  1.3348 +
  1.3349 +/* startPtr gets set to non-null is the section is closed, and to null
  1.3350 +   if the section is not yet closed.
  1.3351 +*/
  1.3352 +static enum XML_Error
  1.3353 +doIgnoreSection(XML_Parser parser,
  1.3354 +                const ENCODING *enc,
  1.3355 +                const char **startPtr,
  1.3356 +                const char *end,
  1.3357 +                const char **nextPtr,
  1.3358 +                XML_Bool haveMore)
  1.3359 +{
  1.3360 +  const char *next;
  1.3361 +  int tok;
  1.3362 +  const char *s = *startPtr;
  1.3363 +  const char **eventPP;
  1.3364 +  const char **eventEndPP;
  1.3365 +  if (enc == encoding) {
  1.3366 +    eventPP = &eventPtr;
  1.3367 +    *eventPP = s;
  1.3368 +    eventEndPP = &eventEndPtr;
  1.3369 +  }
  1.3370 +  else {
  1.3371 +    eventPP = &(openInternalEntities->internalEventPtr);
  1.3372 +    eventEndPP = &(openInternalEntities->internalEventEndPtr);
  1.3373 +  }
  1.3374 +  *eventPP = s;
  1.3375 +  *startPtr = NULL;
  1.3376 +  tok = XmlIgnoreSectionTok(enc, s, end, &next);
  1.3377 +  *eventEndPP = next;
  1.3378 +  switch (tok) {
  1.3379 +  case XML_TOK_IGNORE_SECT:
  1.3380 +    if (defaultHandler)
  1.3381 +      reportDefault(parser, enc, s, next);
  1.3382 +    *startPtr = next;
  1.3383 +    *nextPtr = next;
  1.3384 +    if (ps_parsing == XML_FINISHED)
  1.3385 +      return XML_ERROR_ABORTED;
  1.3386 +    else
  1.3387 +      return XML_ERROR_NONE;
  1.3388 +  case XML_TOK_INVALID:
  1.3389 +    *eventPP = next;
  1.3390 +    return XML_ERROR_INVALID_TOKEN;
  1.3391 +  case XML_TOK_PARTIAL_CHAR:
  1.3392 +    if (haveMore) {
  1.3393 +      *nextPtr = s;
  1.3394 +      return XML_ERROR_NONE;
  1.3395 +    }
  1.3396 +    return XML_ERROR_PARTIAL_CHAR;
  1.3397 +  case XML_TOK_PARTIAL:
  1.3398 +  case XML_TOK_NONE:
  1.3399 +    if (haveMore) {
  1.3400 +      *nextPtr = s;
  1.3401 +      return XML_ERROR_NONE;
  1.3402 +    }
  1.3403 +    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
  1.3404 +  default:
  1.3405 +    *eventPP = next;
  1.3406 +    return XML_ERROR_UNEXPECTED_STATE;
  1.3407 +  }
  1.3408 +  /* not reached */
  1.3409 +}
  1.3410 +
  1.3411 +#endif /* XML_DTD */
  1.3412 +
  1.3413 +static enum XML_Error
  1.3414 +initializeEncoding(XML_Parser parser)
  1.3415 +{
  1.3416 +  const char *s;
  1.3417 +#ifdef XML_UNICODE
  1.3418 +  char encodingBuf[128];
  1.3419 +  if (!protocolEncodingName)
  1.3420 +    s = NULL;
  1.3421 +  else {
  1.3422 +    int i;
  1.3423 +    for (i = 0; protocolEncodingName[i]; i++) {
  1.3424 +      if (i == sizeof(encodingBuf) - 1
  1.3425 +          || (protocolEncodingName[i] & ~0x7f) != 0) {
  1.3426 +        encodingBuf[0] = '\0';
  1.3427 +        break;
  1.3428 +      }
  1.3429 +      encodingBuf[i] = (char)protocolEncodingName[i];
  1.3430 +    }
  1.3431 +    encodingBuf[i] = '\0';
  1.3432 +    s = encodingBuf;
  1.3433 +  }
  1.3434 +#else
  1.3435 +  s = protocolEncodingName;
  1.3436 +#endif
  1.3437 +  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
  1.3438 +    return XML_ERROR_NONE;
  1.3439 +  return handleUnknownEncoding(parser, protocolEncodingName);
  1.3440 +}
  1.3441 +
  1.3442 +static enum XML_Error
  1.3443 +processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
  1.3444 +               const char *s, const char *next)
  1.3445 +{
  1.3446 +  const char *encodingName = NULL;
  1.3447 +  const XML_Char *storedEncName = NULL;
  1.3448 +  const ENCODING *newEncoding = NULL;
  1.3449 +  const char *version = NULL;
  1.3450 +  const char *versionend;
  1.3451 +  const XML_Char *storedversion = NULL;
  1.3452 +  int standalone = -1;
  1.3453 +  if (!(ns
  1.3454 +        ? XmlParseXmlDeclNS
  1.3455 +        : XmlParseXmlDecl)(isGeneralTextEntity,
  1.3456 +                           encoding,
  1.3457 +                           s,
  1.3458 +                           next,
  1.3459 +                           &eventPtr,
  1.3460 +                           &version,
  1.3461 +                           &versionend,
  1.3462 +                           &encodingName,
  1.3463 +                           &newEncoding,
  1.3464 +                           &standalone)) {
  1.3465 +    if (isGeneralTextEntity)
  1.3466 +      return XML_ERROR_TEXT_DECL;
  1.3467 +    else
  1.3468 +      return XML_ERROR_XML_DECL;
  1.3469 +  }
  1.3470 +  if (!isGeneralTextEntity && standalone == 1) {
  1.3471 +    _dtd->standalone = XML_TRUE;
  1.3472 +#ifdef XML_DTD
  1.3473 +    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
  1.3474 +      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  1.3475 +#endif /* XML_DTD */
  1.3476 +  }
  1.3477 +  if (xmlDeclHandler) {
  1.3478 +    if (encodingName != NULL) {
  1.3479 +      storedEncName = poolStoreString(&temp2Pool,
  1.3480 +                                      encoding,
  1.3481 +                                      encodingName,
  1.3482 +                                      encodingName
  1.3483 +                                      + XmlNameLength(encoding, encodingName));
  1.3484 +      if (!storedEncName)
  1.3485 +              return XML_ERROR_NO_MEMORY;
  1.3486 +      poolFinish(&temp2Pool);
  1.3487 +    }
  1.3488 +    if (version) {
  1.3489 +      storedversion = poolStoreString(&temp2Pool,
  1.3490 +                                      encoding,
  1.3491 +                                      version,
  1.3492 +                                      versionend - encoding->minBytesPerChar);
  1.3493 +      if (!storedversion)
  1.3494 +        return XML_ERROR_NO_MEMORY;
  1.3495 +    }
  1.3496 +    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
  1.3497 +  }
  1.3498 +  else if (defaultHandler)
  1.3499 +    reportDefault(parser, encoding, s, next);
  1.3500 +  if (protocolEncodingName == NULL) {
  1.3501 +    if (newEncoding) {
  1.3502 +      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
  1.3503 +        eventPtr = encodingName;
  1.3504 +        return XML_ERROR_INCORRECT_ENCODING;
  1.3505 +      }
  1.3506 +      encoding = newEncoding;
  1.3507 +    }
  1.3508 +    else if (encodingName) {
  1.3509 +      enum XML_Error result;
  1.3510 +      if (!storedEncName) {
  1.3511 +        storedEncName = poolStoreString(
  1.3512 +          &temp2Pool, encoding, encodingName,
  1.3513 +          encodingName + XmlNameLength(encoding, encodingName));
  1.3514 +        if (!storedEncName)
  1.3515 +          return XML_ERROR_NO_MEMORY;
  1.3516 +      }
  1.3517 +      result = handleUnknownEncoding(parser, storedEncName);
  1.3518 +      poolClear(&temp2Pool);
  1.3519 +      if (result == XML_ERROR_UNKNOWN_ENCODING)
  1.3520 +        eventPtr = encodingName;
  1.3521 +      return result;
  1.3522 +    }
  1.3523 +  }
  1.3524 +
  1.3525 +  if (storedEncName || storedversion)
  1.3526 +    poolClear(&temp2Pool);
  1.3527 +
  1.3528 +  return XML_ERROR_NONE;
  1.3529 +}
  1.3530 +
  1.3531 +static enum XML_Error
  1.3532 +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
  1.3533 +{
  1.3534 +  if (unknownEncodingHandler) {
  1.3535 +    XML_Encoding info;
  1.3536 +    int i;
  1.3537 +    for (i = 0; i < 256; i++)
  1.3538 +      info.map[i] = -1;
  1.3539 +    info.convert = NULL;
  1.3540 +    info.data = NULL;
  1.3541 +    info.release = NULL;
  1.3542 +    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
  1.3543 +                               &info)) {
  1.3544 +      ENCODING *enc;
  1.3545 +      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
  1.3546 +      if (!unknownEncodingMem) {
  1.3547 +        if (info.release)
  1.3548 +          info.release(info.data);
  1.3549 +        return XML_ERROR_NO_MEMORY;
  1.3550 +      }
  1.3551 +      enc = (ns
  1.3552 +             ? XmlInitUnknownEncodingNS
  1.3553 +             : XmlInitUnknownEncoding)(unknownEncodingMem,
  1.3554 +                                       info.map,
  1.3555 +                                       info.convert,
  1.3556 +                                       info.data);
  1.3557 +      if (enc) {
  1.3558 +        unknownEncodingData = info.data;
  1.3559 +        unknownEncodingRelease = info.release;
  1.3560 +        encoding = enc;
  1.3561 +        return XML_ERROR_NONE;
  1.3562 +      }
  1.3563 +    }
  1.3564 +    if (info.release != NULL)
  1.3565 +      info.release(info.data);
  1.3566 +  }
  1.3567 +  return XML_ERROR_UNKNOWN_ENCODING;
  1.3568 +}
  1.3569 +
  1.3570 +static enum XML_Error PTRCALL
  1.3571 +prologInitProcessor(XML_Parser parser,
  1.3572 +                    const char *s,
  1.3573 +                    const char *end,
  1.3574 +                    const char **nextPtr)
  1.3575 +{
  1.3576 +  enum XML_Error result = initializeEncoding(parser);
  1.3577 +  if (result != XML_ERROR_NONE)
  1.3578 +    return result;
  1.3579 +  processor = prologProcessor;
  1.3580 +  return prologProcessor(parser, s, end, nextPtr);
  1.3581 +}
  1.3582 +
  1.3583 +#ifdef XML_DTD
  1.3584 +
  1.3585 +static enum XML_Error PTRCALL
  1.3586 +externalParEntInitProcessor(XML_Parser parser,
  1.3587 +                            const char *s,
  1.3588 +                            const char *end,
  1.3589 +                            const char **nextPtr)
  1.3590 +{
  1.3591 +  enum XML_Error result = initializeEncoding(parser);
  1.3592 +  if (result != XML_ERROR_NONE)
  1.3593 +    return result;
  1.3594 +
  1.3595 +  /* we know now that XML_Parse(Buffer) has been called,
  1.3596 +     so we consider the external parameter entity read */
  1.3597 +  _dtd->paramEntityRead = XML_TRUE;
  1.3598 +
  1.3599 +  if (prologState.inEntityValue) {
  1.3600 +    processor = entityValueInitProcessor;
  1.3601 +    return entityValueInitProcessor(parser, s, end, nextPtr);
  1.3602 +  }
  1.3603 +  else {
  1.3604 +    processor = externalParEntProcessor;
  1.3605 +    return externalParEntProcessor(parser, s, end, nextPtr);
  1.3606 +  }
  1.3607 +}
  1.3608 +
  1.3609 +static enum XML_Error PTRCALL
  1.3610 +entityValueInitProcessor(XML_Parser parser,
  1.3611 +                         const char *s,
  1.3612 +                         const char *end,
  1.3613 +                         const char **nextPtr)
  1.3614 +{
  1.3615 +  int tok;
  1.3616 +  const char *start = s;
  1.3617 +  const char *next = start;
  1.3618 +  eventPtr = start;
  1.3619 +
  1.3620 +  for (;;) {  
  1.3621 +    tok = XmlPrologTok(encoding, start, end, &next);
  1.3622 +    eventEndPtr = next;
  1.3623 +    if (tok <= 0) {
  1.3624 +      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
  1.3625 +        *nextPtr = s;
  1.3626 +        return XML_ERROR_NONE;
  1.3627 +      }
  1.3628 +      switch (tok) {
  1.3629 +      case XML_TOK_INVALID:
  1.3630 +        return XML_ERROR_INVALID_TOKEN;
  1.3631 +      case XML_TOK_PARTIAL:
  1.3632 +        return XML_ERROR_UNCLOSED_TOKEN;
  1.3633 +      case XML_TOK_PARTIAL_CHAR:
  1.3634 +        return XML_ERROR_PARTIAL_CHAR;
  1.3635 +      case XML_TOK_NONE:   /* start == end */
  1.3636 +      default:
  1.3637 +        break;
  1.3638 +      }
  1.3639 +      /* found end of entity value - can store it now */
  1.3640 +      return storeEntityValue(parser, encoding, s, end);
  1.3641 +    }
  1.3642 +    else if (tok == XML_TOK_XML_DECL) {
  1.3643 +      enum XML_Error result;
  1.3644 +      result = processXmlDecl(parser, 0, start, next);
  1.3645 +      if (result != XML_ERROR_NONE)
  1.3646 +        return result;
  1.3647 +      switch (ps_parsing) {
  1.3648 +      case XML_SUSPENDED: 
  1.3649 +        *nextPtr = next;
  1.3650 +        return XML_ERROR_NONE;
  1.3651 +      case XML_FINISHED:
  1.3652 +        return XML_ERROR_ABORTED;
  1.3653 +      default:
  1.3654 +        *nextPtr = next;
  1.3655 +      }
  1.3656 +      /* stop scanning for text declaration - we found one */
  1.3657 +      processor = entityValueProcessor;
  1.3658 +      return entityValueProcessor(parser, next, end, nextPtr);
  1.3659 +    }
  1.3660 +    /* If we are at the end of the buffer, this would cause XmlPrologTok to
  1.3661 +       return XML_TOK_NONE on the next call, which would then cause the
  1.3662 +       function to exit with *nextPtr set to s - that is what we want for other
  1.3663 +       tokens, but not for the BOM - we would rather like to skip it;
  1.3664 +       then, when this routine is entered the next time, XmlPrologTok will
  1.3665 +       return XML_TOK_INVALID, since the BOM is still in the buffer
  1.3666 +    */
  1.3667 +    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
  1.3668 +      *nextPtr = next;
  1.3669 +      return XML_ERROR_NONE;
  1.3670 +    }
  1.3671 +    start = next;
  1.3672 +    eventPtr = start;
  1.3673 +  }
  1.3674 +}
  1.3675 +
  1.3676 +static enum XML_Error PTRCALL
  1.3677 +externalParEntProcessor(XML_Parser parser,
  1.3678 +                        const char *s,
  1.3679 +                        const char *end,
  1.3680 +                        const char **nextPtr)
  1.3681 +{
  1.3682 +  const char *next = s;
  1.3683 +  int tok;
  1.3684 +
  1.3685 +  tok = XmlPrologTok(encoding, s, end, &next);
  1.3686 +  if (tok <= 0) {
  1.3687 +    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
  1.3688 +      *nextPtr = s;
  1.3689 +      return XML_ERROR_NONE;
  1.3690 +    }
  1.3691 +    switch (tok) {
  1.3692 +    case XML_TOK_INVALID:
  1.3693 +      return XML_ERROR_INVALID_TOKEN;
  1.3694 +    case XML_TOK_PARTIAL:
  1.3695 +      return XML_ERROR_UNCLOSED_TOKEN;
  1.3696 +    case XML_TOK_PARTIAL_CHAR:
  1.3697 +      return XML_ERROR_PARTIAL_CHAR;
  1.3698 +    case XML_TOK_NONE:   /* start == end */
  1.3699 +    default:
  1.3700 +      break;
  1.3701 +    }
  1.3702 +  }
  1.3703 +  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
  1.3704 +     However, when parsing an external subset, doProlog will not accept a BOM
  1.3705 +     as valid, and report a syntax error, so we have to skip the BOM
  1.3706 +  */
  1.3707 +  else if (tok == XML_TOK_BOM) {
  1.3708 +    s = next;
  1.3709 +    tok = XmlPrologTok(encoding, s, end, &next);
  1.3710 +  }
  1.3711 +
  1.3712 +  processor = prologProcessor;
  1.3713 +  return doProlog(parser, encoding, s, end, tok, next, 
  1.3714 +                  nextPtr, (XML_Bool)!ps_finalBuffer);
  1.3715 +}
  1.3716 +
  1.3717 +static enum XML_Error PTRCALL
  1.3718 +entityValueProcessor(XML_Parser parser,
  1.3719 +                     const char *s,
  1.3720 +                     const char *end,
  1.3721 +                     const char **nextPtr)
  1.3722 +{
  1.3723 +  const char *start = s;
  1.3724 +  const char *next = s;
  1.3725 +  const ENCODING *enc = encoding;
  1.3726 +  int tok;
  1.3727 +
  1.3728 +  for (;;) {
  1.3729 +    tok = XmlPrologTok(enc, start, end, &next);
  1.3730 +    if (tok <= 0) {
  1.3731 +      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
  1.3732 +        *nextPtr = s;
  1.3733 +        return XML_ERROR_NONE;
  1.3734 +      }
  1.3735 +      switch (tok) {
  1.3736 +      case XML_TOK_INVALID:
  1.3737 +        return XML_ERROR_INVALID_TOKEN;
  1.3738 +      case XML_TOK_PARTIAL:
  1.3739 +        return XML_ERROR_UNCLOSED_TOKEN;
  1.3740 +      case XML_TOK_PARTIAL_CHAR:
  1.3741 +        return XML_ERROR_PARTIAL_CHAR;
  1.3742 +      case XML_TOK_NONE:   /* start == end */
  1.3743 +      default:
  1.3744 +        break;
  1.3745 +      }
  1.3746 +      /* found end of entity value - can store it now */
  1.3747 +      return storeEntityValue(parser, enc, s, end);
  1.3748 +    }
  1.3749 +    start = next;
  1.3750 +  }
  1.3751 +}
  1.3752 +
  1.3753 +#endif /* XML_DTD */
  1.3754 +
  1.3755 +static enum XML_Error PTRCALL
  1.3756 +prologProcessor(XML_Parser parser,
  1.3757 +                const char *s,
  1.3758 +                const char *end,
  1.3759 +                const char **nextPtr)
  1.3760 +{
  1.3761 +  const char *next = s;
  1.3762 +  int tok = XmlPrologTok(encoding, s, end, &next);
  1.3763 +  return doProlog(parser, encoding, s, end, tok, next, 
  1.3764 +                  nextPtr, (XML_Bool)!ps_finalBuffer);
  1.3765 +}
  1.3766 +
  1.3767 +static enum XML_Error
  1.3768 +doProlog(XML_Parser parser,
  1.3769 +         const ENCODING *enc,
  1.3770 +         const char *s,
  1.3771 +         const char *end,
  1.3772 +         int tok,
  1.3773 +         const char *next,
  1.3774 +         const char **nextPtr,
  1.3775 +         XML_Bool haveMore)
  1.3776 +{
  1.3777 +#ifdef XML_DTD
  1.3778 +  static const XML_Char externalSubsetName[] = { '#' , '\0' };
  1.3779 +#endif /* XML_DTD */
  1.3780 +  static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
  1.3781 +  static const XML_Char atypeID[] = { 'I', 'D', '\0' };
  1.3782 +  static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
  1.3783 +  static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
  1.3784 +  static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
  1.3785 +  static const XML_Char atypeENTITIES[] =
  1.3786 +      { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
  1.3787 +  static const XML_Char atypeNMTOKEN[] = {
  1.3788 +      'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
  1.3789 +  static const XML_Char atypeNMTOKENS[] = {
  1.3790 +      'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
  1.3791 +  static const XML_Char notationPrefix[] = {
  1.3792 +      'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
  1.3793 +  static const XML_Char enumValueSep[] = { '|', '\0' };
  1.3794 +  static const XML_Char enumValueStart[] = { '(', '\0' };
  1.3795 +
  1.3796 +  /* save one level of indirection */
  1.3797 +  DTD * const dtd = _dtd; 
  1.3798 +
  1.3799 +  const char **eventPP;
  1.3800 +  const char **eventEndPP;
  1.3801 +  enum XML_Content_Quant quant;
  1.3802 +
  1.3803 +  if (enc == encoding) {
  1.3804 +    eventPP = &eventPtr;
  1.3805 +    eventEndPP = &eventEndPtr;
  1.3806 +  }
  1.3807 +  else {
  1.3808 +    eventPP = &(openInternalEntities->internalEventPtr);
  1.3809 +    eventEndPP = &(openInternalEntities->internalEventEndPtr);
  1.3810 +  }
  1.3811 +
  1.3812 +  for (;;) {
  1.3813 +    int role;
  1.3814 +    XML_Bool handleDefault = XML_TRUE;
  1.3815 +    *eventPP = s;
  1.3816 +    *eventEndPP = next;
  1.3817 +    if (tok <= 0) {
  1.3818 +      if (haveMore && tok != XML_TOK_INVALID) {
  1.3819 +        *nextPtr = s;
  1.3820 +        return XML_ERROR_NONE;
  1.3821 +      }
  1.3822 +      switch (tok) {
  1.3823 +      case XML_TOK_INVALID:
  1.3824 +        *eventPP = next;
  1.3825 +        return XML_ERROR_INVALID_TOKEN;
  1.3826 +      case XML_TOK_PARTIAL:
  1.3827 +        return XML_ERROR_UNCLOSED_TOKEN;
  1.3828 +      case XML_TOK_PARTIAL_CHAR:
  1.3829 +        return XML_ERROR_PARTIAL_CHAR;
  1.3830 +      case XML_TOK_NONE:
  1.3831 +#ifdef XML_DTD
  1.3832 +        /* for internal PE NOT referenced between declarations */
  1.3833 +        if (enc != encoding && !openInternalEntities->betweenDecl) {
  1.3834 +          *nextPtr = s;
  1.3835 +          return XML_ERROR_NONE;
  1.3836 +        }
  1.3837 +        /* WFC: PE Between Declarations - must check that PE contains
  1.3838 +           complete markup, not only for external PEs, but also for
  1.3839 +           internal PEs if the reference occurs between declarations.
  1.3840 +        */
  1.3841 +        if (isParamEntity || enc != encoding) {
  1.3842 +          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
  1.3843 +              == XML_ROLE_ERROR)
  1.3844 +            return XML_ERROR_INCOMPLETE_PE;
  1.3845 +          *nextPtr = s;
  1.3846 +          return XML_ERROR_NONE;
  1.3847 +        }
  1.3848 +#endif /* XML_DTD */
  1.3849 +        return XML_ERROR_NO_ELEMENTS;
  1.3850 +      default:
  1.3851 +        tok = -tok;
  1.3852 +        next = end;
  1.3853 +        break;
  1.3854 +      }
  1.3855 +    }
  1.3856 +    role = XmlTokenRole(&prologState, tok, s, next, enc);
  1.3857 +    switch (role) {
  1.3858 +    case XML_ROLE_XML_DECL:
  1.3859 +      {
  1.3860 +        enum XML_Error result = processXmlDecl(parser, 0, s, next);
  1.3861 +        if (result != XML_ERROR_NONE)
  1.3862 +          return result;
  1.3863 +        enc = encoding;
  1.3864 +        handleDefault = XML_FALSE;
  1.3865 +      }
  1.3866 +      break;
  1.3867 +    case XML_ROLE_DOCTYPE_NAME:
  1.3868 +      if (startDoctypeDeclHandler) {
  1.3869 +        doctypeName = poolStoreString(&tempPool, enc, s, next);
  1.3870 +        if (!doctypeName)
  1.3871 +          return XML_ERROR_NO_MEMORY;
  1.3872 +        poolFinish(&tempPool);
  1.3873 +        doctypePubid = NULL;
  1.3874 +        handleDefault = XML_FALSE;
  1.3875 +      }
  1.3876 +      doctypeSysid = NULL; /* always initialize to NULL */
  1.3877 +      break;
  1.3878 +    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
  1.3879 +      if (startDoctypeDeclHandler) {
  1.3880 +        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
  1.3881 +                                doctypePubid, 1);
  1.3882 +        doctypeName = NULL;
  1.3883 +        poolClear(&tempPool);
  1.3884 +        handleDefault = XML_FALSE;
  1.3885 +      }
  1.3886 +      break;
  1.3887 +#ifdef XML_DTD
  1.3888 +    case XML_ROLE_TEXT_DECL:
  1.3889 +      {
  1.3890 +        enum XML_Error result = processXmlDecl(parser, 1, s, next);
  1.3891 +        if (result != XML_ERROR_NONE)
  1.3892 +          return result;
  1.3893 +        enc = encoding;
  1.3894 +        handleDefault = XML_FALSE;
  1.3895 +      }
  1.3896 +      break;
  1.3897 +#endif /* XML_DTD */
  1.3898 +    case XML_ROLE_DOCTYPE_PUBLIC_ID:
  1.3899 +#ifdef XML_DTD
  1.3900 +      useForeignDTD = XML_FALSE;
  1.3901 +      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
  1.3902 +                                    externalSubsetName,
  1.3903 +                                    sizeof(ENTITY));
  1.3904 +      if (!declEntity)
  1.3905 +        return XML_ERROR_NO_MEMORY;
  1.3906 +#endif /* XML_DTD */
  1.3907 +      dtd->hasParamEntityRefs = XML_TRUE;
  1.3908 +      if (startDoctypeDeclHandler) {
  1.3909 +        if (!XmlIsPublicId(enc, s, next, eventPP))
  1.3910 +          return XML_ERROR_PUBLICID;
  1.3911 +        doctypePubid = poolStoreString(&tempPool, enc,
  1.3912 +                                       s + enc->minBytesPerChar,
  1.3913 +                                       next - enc->minBytesPerChar);
  1.3914 +        if (!doctypePubid)
  1.3915 +          return XML_ERROR_NO_MEMORY;
  1.3916 +        normalizePublicId((XML_Char *)doctypePubid);
  1.3917 +        poolFinish(&tempPool);
  1.3918 +        handleDefault = XML_FALSE;
  1.3919 +        goto alreadyChecked;
  1.3920 +      }
  1.3921 +      /* fall through */
  1.3922 +    case XML_ROLE_ENTITY_PUBLIC_ID:
  1.3923 +      if (!XmlIsPublicId(enc, s, next, eventPP))
  1.3924 +        return XML_ERROR_PUBLICID;
  1.3925 +    alreadyChecked:
  1.3926 +      if (dtd->keepProcessing && declEntity) {
  1.3927 +        XML_Char *tem = poolStoreString(&dtd->pool,
  1.3928 +                                        enc,
  1.3929 +                                        s + enc->minBytesPerChar,
  1.3930 +                                        next - enc->minBytesPerChar);
  1.3931 +        if (!tem)
  1.3932 +          return XML_ERROR_NO_MEMORY;
  1.3933 +        normalizePublicId(tem);
  1.3934 +        declEntity->publicId = tem;
  1.3935 +        poolFinish(&dtd->pool);
  1.3936 +        if (entityDeclHandler)
  1.3937 +          handleDefault = XML_FALSE;
  1.3938 +      }
  1.3939 +      break;
  1.3940 +    case XML_ROLE_DOCTYPE_CLOSE:
  1.3941 +      if (doctypeName) {
  1.3942 +        startDoctypeDeclHandler(handlerArg, doctypeName,
  1.3943 +                                doctypeSysid, doctypePubid, 0);
  1.3944 +        poolClear(&tempPool);
  1.3945 +        handleDefault = XML_FALSE;
  1.3946 +      }
  1.3947 +      /* doctypeSysid will be non-NULL in the case of a previous
  1.3948 +         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
  1.3949 +         was not set, indicating an external subset
  1.3950 +      */
  1.3951 +#ifdef XML_DTD
  1.3952 +      if (doctypeSysid || useForeignDTD) {
  1.3953 +        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
  1.3954 +        dtd->hasParamEntityRefs = XML_TRUE;
  1.3955 +        if (paramEntityParsing && externalEntityRefHandler) {
  1.3956 +          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
  1.3957 +                                            externalSubsetName,
  1.3958 +                                            sizeof(ENTITY));
  1.3959 +          if (!entity)
  1.3960 +            return XML_ERROR_NO_MEMORY;
  1.3961 +          if (useForeignDTD)
  1.3962 +            entity->base = curBase;
  1.3963 +          dtd->paramEntityRead = XML_FALSE;
  1.3964 +          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1.3965 +                                        0,
  1.3966 +                                        entity->base,
  1.3967 +                                        entity->systemId,
  1.3968 +                                        entity->publicId))
  1.3969 +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1.3970 +          if (dtd->paramEntityRead) {
  1.3971 +            if (!dtd->standalone && 
  1.3972 +                notStandaloneHandler && 
  1.3973 +                !notStandaloneHandler(handlerArg))
  1.3974 +              return XML_ERROR_NOT_STANDALONE;
  1.3975 +          }
  1.3976 +          /* if we didn't read the foreign DTD then this means that there
  1.3977 +             is no external subset and we must reset dtd->hasParamEntityRefs
  1.3978 +          */
  1.3979 +          else if (!doctypeSysid)
  1.3980 +            dtd->hasParamEntityRefs = hadParamEntityRefs;
  1.3981 +          /* end of DTD - no need to update dtd->keepProcessing */
  1.3982 +        }
  1.3983 +        useForeignDTD = XML_FALSE;
  1.3984 +      }
  1.3985 +#endif /* XML_DTD */
  1.3986 +      if (endDoctypeDeclHandler) {
  1.3987 +        endDoctypeDeclHandler(handlerArg);
  1.3988 +        handleDefault = XML_FALSE;
  1.3989 +      }
  1.3990 +      break;
  1.3991 +    case XML_ROLE_INSTANCE_START:
  1.3992 +#ifdef XML_DTD
  1.3993 +      /* if there is no DOCTYPE declaration then now is the
  1.3994 +         last chance to read the foreign DTD
  1.3995 +      */
  1.3996 +      if (useForeignDTD) {
  1.3997 +        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
  1.3998 +        dtd->hasParamEntityRefs = XML_TRUE;
  1.3999 +        if (paramEntityParsing && externalEntityRefHandler) {
  1.4000 +          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
  1.4001 +                                            externalSubsetName,
  1.4002 +                                            sizeof(ENTITY));
  1.4003 +          if (!entity)
  1.4004 +            return XML_ERROR_NO_MEMORY;
  1.4005 +          entity->base = curBase;
  1.4006 +          dtd->paramEntityRead = XML_FALSE;
  1.4007 +          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1.4008 +                                        0,
  1.4009 +                                        entity->base,
  1.4010 +                                        entity->systemId,
  1.4011 +                                        entity->publicId))
  1.4012 +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1.4013 +          if (dtd->paramEntityRead) {
  1.4014 +            if (!dtd->standalone &&
  1.4015 +                notStandaloneHandler &&
  1.4016 +                !notStandaloneHandler(handlerArg))
  1.4017 +              return XML_ERROR_NOT_STANDALONE;
  1.4018 +          }
  1.4019 +          /* if we didn't read the foreign DTD then this means that there
  1.4020 +             is no external subset and we must reset dtd->hasParamEntityRefs
  1.4021 +          */
  1.4022 +          else
  1.4023 +            dtd->hasParamEntityRefs = hadParamEntityRefs;
  1.4024 +          /* end of DTD - no need to update dtd->keepProcessing */
  1.4025 +        }
  1.4026 +      }
  1.4027 +#endif /* XML_DTD */
  1.4028 +      processor = contentProcessor;
  1.4029 +      return contentProcessor(parser, s, end, nextPtr);
  1.4030 +    case XML_ROLE_ATTLIST_ELEMENT_NAME:
  1.4031 +      declElementType = getElementType(parser, enc, s, next);
  1.4032 +      if (!declElementType)
  1.4033 +        return XML_ERROR_NO_MEMORY;
  1.4034 +      goto checkAttListDeclHandler;
  1.4035 +    case XML_ROLE_ATTRIBUTE_NAME:
  1.4036 +      declAttributeId = getAttributeId(parser, enc, s, next);
  1.4037 +      if (!declAttributeId)
  1.4038 +        return XML_ERROR_NO_MEMORY;
  1.4039 +      declAttributeIsCdata = XML_FALSE;
  1.4040 +      declAttributeType = NULL;
  1.4041 +      declAttributeIsId = XML_FALSE;
  1.4042 +      goto checkAttListDeclHandler;
  1.4043 +    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
  1.4044 +      declAttributeIsCdata = XML_TRUE;
  1.4045 +      declAttributeType = atypeCDATA;
  1.4046 +      goto checkAttListDeclHandler;
  1.4047 +    case XML_ROLE_ATTRIBUTE_TYPE_ID:
  1.4048 +      declAttributeIsId = XML_TRUE;
  1.4049 +      declAttributeType = atypeID;
  1.4050 +      goto checkAttListDeclHandler;
  1.4051 +    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
  1.4052 +      declAttributeType = atypeIDREF;
  1.4053 +      goto checkAttListDeclHandler;
  1.4054 +    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
  1.4055 +      declAttributeType = atypeIDREFS;
  1.4056 +      goto checkAttListDeclHandler;
  1.4057 +    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
  1.4058 +      declAttributeType = atypeENTITY;
  1.4059 +      goto checkAttListDeclHandler;
  1.4060 +    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
  1.4061 +      declAttributeType = atypeENTITIES;
  1.4062 +      goto checkAttListDeclHandler;
  1.4063 +    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
  1.4064 +      declAttributeType = atypeNMTOKEN;
  1.4065 +      goto checkAttListDeclHandler;
  1.4066 +    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
  1.4067 +      declAttributeType = atypeNMTOKENS;
  1.4068 +    checkAttListDeclHandler:
  1.4069 +      if (dtd->keepProcessing && attlistDeclHandler)
  1.4070 +        handleDefault = XML_FALSE;
  1.4071 +      break;
  1.4072 +    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
  1.4073 +    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
  1.4074 +      if (dtd->keepProcessing && attlistDeclHandler) {
  1.4075 +        const XML_Char *prefix;
  1.4076 +        if (declAttributeType) {
  1.4077 +          prefix = enumValueSep;
  1.4078 +        }
  1.4079 +        else {
  1.4080 +          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
  1.4081 +                    ? notationPrefix
  1.4082 +                    : enumValueStart);
  1.4083 +        }
  1.4084 +        if (!poolAppendString(&tempPool, prefix))
  1.4085 +          return XML_ERROR_NO_MEMORY;
  1.4086 +        if (!poolAppend(&tempPool, enc, s, next))
  1.4087 +          return XML_ERROR_NO_MEMORY;
  1.4088 +        declAttributeType = tempPool.start;
  1.4089 +        handleDefault = XML_FALSE;
  1.4090 +      }
  1.4091 +      break;
  1.4092 +    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
  1.4093 +    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
  1.4094 +      if (dtd->keepProcessing) {
  1.4095 +        if (!defineAttribute(declElementType, declAttributeId,
  1.4096 +                             declAttributeIsCdata, declAttributeIsId,
  1.4097 +                             0, parser))
  1.4098 +          return XML_ERROR_NO_MEMORY;
  1.4099 +        if (attlistDeclHandler && declAttributeType) {
  1.4100 +          if (*declAttributeType == XML_T('(')
  1.4101 +              || (*declAttributeType == XML_T('N')
  1.4102 +                  && declAttributeType[1] == XML_T('O'))) {
  1.4103 +            /* Enumerated or Notation type */
  1.4104 +            if (!poolAppendChar(&tempPool, XML_T(')'))
  1.4105 +                || !poolAppendChar(&tempPool, XML_T('\0')))
  1.4106 +              return XML_ERROR_NO_MEMORY;
  1.4107 +            declAttributeType = tempPool.start;
  1.4108 +            poolFinish(&tempPool);
  1.4109 +          }
  1.4110 +          *eventEndPP = s;
  1.4111 +          attlistDeclHandler(handlerArg, declElementType->name,
  1.4112 +                             declAttributeId->name, declAttributeType,
  1.4113 +                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
  1.4114 +          poolClear(&tempPool);
  1.4115 +          handleDefault = XML_FALSE;
  1.4116 +        }
  1.4117 +      }
  1.4118 +      break;
  1.4119 +    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
  1.4120 +    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
  1.4121 +      if (dtd->keepProcessing) {
  1.4122 +        const XML_Char *attVal;
  1.4123 +        enum XML_Error result =
  1.4124 +          storeAttributeValue(parser, enc, declAttributeIsCdata,
  1.4125 +                              s + enc->minBytesPerChar,
  1.4126 +                              next - enc->minBytesPerChar,
  1.4127 +                              &dtd->pool);
  1.4128 +        if (result)
  1.4129 +          return result;
  1.4130 +        attVal = poolStart(&dtd->pool);
  1.4131 +        poolFinish(&dtd->pool);
  1.4132 +        /* ID attributes aren't allowed to have a default */
  1.4133 +        if (!defineAttribute(declElementType, declAttributeId,
  1.4134 +                             declAttributeIsCdata, XML_FALSE, attVal, parser))
  1.4135 +          return XML_ERROR_NO_MEMORY;
  1.4136 +        if (attlistDeclHandler && declAttributeType) {
  1.4137 +          if (*declAttributeType == XML_T('(')
  1.4138 +              || (*declAttributeType == XML_T('N')
  1.4139 +                  && declAttributeType[1] == XML_T('O'))) {
  1.4140 +            /* Enumerated or Notation type */
  1.4141 +            if (!poolAppendChar(&tempPool, XML_T(')'))
  1.4142 +                || !poolAppendChar(&tempPool, XML_T('\0')))
  1.4143 +              return XML_ERROR_NO_MEMORY;
  1.4144 +            declAttributeType = tempPool.start;
  1.4145 +            poolFinish(&tempPool);
  1.4146 +          }
  1.4147 +          *eventEndPP = s;
  1.4148 +          attlistDeclHandler(handlerArg, declElementType->name,
  1.4149 +                             declAttributeId->name, declAttributeType,
  1.4150 +                             attVal,
  1.4151 +                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
  1.4152 +          poolClear(&tempPool);
  1.4153 +          handleDefault = XML_FALSE;
  1.4154 +        }
  1.4155 +      }
  1.4156 +      break;
  1.4157 +    case XML_ROLE_ENTITY_VALUE:
  1.4158 +      if (dtd->keepProcessing) {
  1.4159 +        enum XML_Error result = storeEntityValue(parser, enc,
  1.4160 +                                            s + enc->minBytesPerChar,
  1.4161 +                                            next - enc->minBytesPerChar);
  1.4162 +        if (declEntity) {
  1.4163 +          declEntity->textPtr = poolStart(&dtd->entityValuePool);
  1.4164 +          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
  1.4165 +          poolFinish(&dtd->entityValuePool);
  1.4166 +          if (entityDeclHandler) {
  1.4167 +            *eventEndPP = s;
  1.4168 +            entityDeclHandler(handlerArg,
  1.4169 +                              declEntity->name,
  1.4170 +                              declEntity->is_param,
  1.4171 +                              declEntity->textPtr,
  1.4172 +                              declEntity->textLen,
  1.4173 +                              curBase, 0, 0, 0);
  1.4174 +            handleDefault = XML_FALSE;
  1.4175 +          }
  1.4176 +        }
  1.4177 +        else
  1.4178 +          poolDiscard(&dtd->entityValuePool);
  1.4179 +        if (result != XML_ERROR_NONE)
  1.4180 +          return result;
  1.4181 +      }
  1.4182 +      break;
  1.4183 +    case XML_ROLE_DOCTYPE_SYSTEM_ID:
  1.4184 +#ifdef XML_DTD
  1.4185 +      useForeignDTD = XML_FALSE;
  1.4186 +#endif /* XML_DTD */
  1.4187 +      dtd->hasParamEntityRefs = XML_TRUE;
  1.4188 +      if (startDoctypeDeclHandler) {
  1.4189 +        doctypeSysid = poolStoreString(&tempPool, enc,
  1.4190 +                                       s + enc->minBytesPerChar,
  1.4191 +                                       next - enc->minBytesPerChar);
  1.4192 +        if (doctypeSysid == NULL)
  1.4193 +          return XML_ERROR_NO_MEMORY;
  1.4194 +        poolFinish(&tempPool);
  1.4195 +        handleDefault = XML_FALSE;
  1.4196 +      }
  1.4197 +#ifdef XML_DTD
  1.4198 +      else
  1.4199 +        /* use externalSubsetName to make doctypeSysid non-NULL
  1.4200 +           for the case where no startDoctypeDeclHandler is set */
  1.4201 +        doctypeSysid = externalSubsetName;
  1.4202 +#endif /* XML_DTD */
  1.4203 +      if (!dtd->standalone
  1.4204 +#ifdef XML_DTD
  1.4205 +          && !paramEntityParsing
  1.4206 +#endif /* XML_DTD */
  1.4207 +          && notStandaloneHandler
  1.4208 +          && !notStandaloneHandler(handlerArg))
  1.4209 +        return XML_ERROR_NOT_STANDALONE;
  1.4210 +#ifndef XML_DTD
  1.4211 +      break;
  1.4212 +#else /* XML_DTD */
  1.4213 +      if (!declEntity) {
  1.4214 +        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
  1.4215 +                                      externalSubsetName,
  1.4216 +                                      sizeof(ENTITY));
  1.4217 +        if (!declEntity)
  1.4218 +          return XML_ERROR_NO_MEMORY;
  1.4219 +        declEntity->publicId = NULL;
  1.4220 +      }
  1.4221 +      /* fall through */
  1.4222 +#endif /* XML_DTD */
  1.4223 +    case XML_ROLE_ENTITY_SYSTEM_ID:
  1.4224 +      if (dtd->keepProcessing && declEntity) {
  1.4225 +        declEntity->systemId = poolStoreString(&dtd->pool, enc,
  1.4226 +                                               s + enc->minBytesPerChar,
  1.4227 +                                               next - enc->minBytesPerChar);
  1.4228 +        if (!declEntity->systemId)
  1.4229 +          return XML_ERROR_NO_MEMORY;
  1.4230 +        declEntity->base = curBase;
  1.4231 +        poolFinish(&dtd->pool);
  1.4232 +        if (entityDeclHandler)
  1.4233 +          handleDefault = XML_FALSE;
  1.4234 +      }
  1.4235 +      break;
  1.4236 +    case XML_ROLE_ENTITY_COMPLETE:
  1.4237 +      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
  1.4238 +        *eventEndPP = s;
  1.4239 +        entityDeclHandler(handlerArg,
  1.4240 +                          declEntity->name,
  1.4241 +                          declEntity->is_param,
  1.4242 +                          0,0,
  1.4243 +                          declEntity->base,
  1.4244 +                          declEntity->systemId,
  1.4245 +                          declEntity->publicId,
  1.4246 +                          0);
  1.4247 +        handleDefault = XML_FALSE;
  1.4248 +      }
  1.4249 +      break;
  1.4250 +    case XML_ROLE_ENTITY_NOTATION_NAME:
  1.4251 +      if (dtd->keepProcessing && declEntity) {
  1.4252 +        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
  1.4253 +        if (!declEntity->notation)
  1.4254 +          return XML_ERROR_NO_MEMORY;
  1.4255 +        poolFinish(&dtd->pool);
  1.4256 +        if (unparsedEntityDeclHandler) {
  1.4257 +          *eventEndPP = s;
  1.4258 +          unparsedEntityDeclHandler(handlerArg,
  1.4259 +                                    declEntity->name,
  1.4260 +                                    declEntity->base,
  1.4261 +                                    declEntity->systemId,
  1.4262 +                                    declEntity->publicId,
  1.4263 +                                    declEntity->notation);
  1.4264 +          handleDefault = XML_FALSE;
  1.4265 +        }
  1.4266 +        else if (entityDeclHandler) {
  1.4267 +          *eventEndPP = s;
  1.4268 +          entityDeclHandler(handlerArg,
  1.4269 +                            declEntity->name,
  1.4270 +                            0,0,0,
  1.4271 +                            declEntity->base,
  1.4272 +                            declEntity->systemId,
  1.4273 +                            declEntity->publicId,
  1.4274 +                            declEntity->notation);
  1.4275 +          handleDefault = XML_FALSE;
  1.4276 +        }
  1.4277 +      }
  1.4278 +      break;
  1.4279 +    case XML_ROLE_GENERAL_ENTITY_NAME:
  1.4280 +      {
  1.4281 +        if (XmlPredefinedEntityName(enc, s, next)) {
  1.4282 +          declEntity = NULL;
  1.4283 +          break;
  1.4284 +        }
  1.4285 +        if (dtd->keepProcessing) {
  1.4286 +          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
  1.4287 +          if (!name)
  1.4288 +            return XML_ERROR_NO_MEMORY;
  1.4289 +          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
  1.4290 +                                        sizeof(ENTITY));
  1.4291 +          if (!declEntity)
  1.4292 +            return XML_ERROR_NO_MEMORY;
  1.4293 +          if (declEntity->name != name) {
  1.4294 +            poolDiscard(&dtd->pool);
  1.4295 +            declEntity = NULL;
  1.4296 +          }
  1.4297 +          else {
  1.4298 +            poolFinish(&dtd->pool);
  1.4299 +            declEntity->publicId = NULL;
  1.4300 +            declEntity->is_param = XML_FALSE;
  1.4301 +            /* if we have a parent parser or are reading an internal parameter
  1.4302 +               entity, then the entity declaration is not considered "internal"
  1.4303 +            */
  1.4304 +            declEntity->is_internal = !(parentParser || openInternalEntities);
  1.4305 +            if (entityDeclHandler)
  1.4306 +              handleDefault = XML_FALSE;
  1.4307 +          }
  1.4308 +        }
  1.4309 +        else {
  1.4310 +          poolDiscard(&dtd->pool);
  1.4311 +          declEntity = NULL;
  1.4312 +        }
  1.4313 +      }
  1.4314 +      break;
  1.4315 +    case XML_ROLE_PARAM_ENTITY_NAME:
  1.4316 +#ifdef XML_DTD
  1.4317 +      if (dtd->keepProcessing) {
  1.4318 +        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
  1.4319 +        if (!name)
  1.4320 +          return XML_ERROR_NO_MEMORY;
  1.4321 +        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
  1.4322 +                                           name, sizeof(ENTITY));
  1.4323 +        if (!declEntity)
  1.4324 +          return XML_ERROR_NO_MEMORY;
  1.4325 +        if (declEntity->name != name) {
  1.4326 +          poolDiscard(&dtd->pool);
  1.4327 +          declEntity = NULL;
  1.4328 +        }
  1.4329 +        else {
  1.4330 +          poolFinish(&dtd->pool);
  1.4331 +          declEntity->publicId = NULL;
  1.4332 +          declEntity->is_param = XML_TRUE;
  1.4333 +          /* if we have a parent parser or are reading an internal parameter
  1.4334 +             entity, then the entity declaration is not considered "internal"
  1.4335 +          */
  1.4336 +          declEntity->is_internal = !(parentParser || openInternalEntities);
  1.4337 +          if (entityDeclHandler)
  1.4338 +            handleDefault = XML_FALSE;
  1.4339 +        }
  1.4340 +      }
  1.4341 +      else {
  1.4342 +        poolDiscard(&dtd->pool);
  1.4343 +        declEntity = NULL;
  1.4344 +      }
  1.4345 +#else /* not XML_DTD */
  1.4346 +      declEntity = NULL;
  1.4347 +#endif /* XML_DTD */
  1.4348 +      break;
  1.4349 +    case XML_ROLE_NOTATION_NAME:
  1.4350 +      declNotationPublicId = NULL;
  1.4351 +      declNotationName = NULL;
  1.4352 +      if (notationDeclHandler) {
  1.4353 +        declNotationName = poolStoreString(&tempPool, enc, s, next);
  1.4354 +        if (!declNotationName)
  1.4355 +          return XML_ERROR_NO_MEMORY;
  1.4356 +        poolFinish(&tempPool);
  1.4357 +        handleDefault = XML_FALSE;
  1.4358 +      }
  1.4359 +      break;
  1.4360 +    case XML_ROLE_NOTATION_PUBLIC_ID:
  1.4361 +      if (!XmlIsPublicId(enc, s, next, eventPP))
  1.4362 +        return XML_ERROR_PUBLICID;
  1.4363 +      if (declNotationName) {  /* means notationDeclHandler != NULL */
  1.4364 +        XML_Char *tem = poolStoreString(&tempPool,
  1.4365 +                                        enc,
  1.4366 +                                        s + enc->minBytesPerChar,
  1.4367 +                                        next - enc->minBytesPerChar);
  1.4368 +        if (!tem)
  1.4369 +          return XML_ERROR_NO_MEMORY;
  1.4370 +        normalizePublicId(tem);
  1.4371 +        declNotationPublicId = tem;
  1.4372 +        poolFinish(&tempPool);
  1.4373 +        handleDefault = XML_FALSE;
  1.4374 +      }
  1.4375 +      break;
  1.4376 +    case XML_ROLE_NOTATION_SYSTEM_ID:
  1.4377 +      if (declNotationName && notationDeclHandler) {
  1.4378 +        const XML_Char *systemId
  1.4379 +          = poolStoreString(&tempPool, enc,
  1.4380 +                            s + enc->minBytesPerChar,
  1.4381 +                            next - enc->minBytesPerChar);
  1.4382 +        if (!systemId)
  1.4383 +          return XML_ERROR_NO_MEMORY;
  1.4384 +        *eventEndPP = s;
  1.4385 +        notationDeclHandler(handlerArg,
  1.4386 +                            declNotationName,
  1.4387 +                            curBase,
  1.4388 +                            systemId,
  1.4389 +                            declNotationPublicId);
  1.4390 +        handleDefault = XML_FALSE;
  1.4391 +      }
  1.4392 +      poolClear(&tempPool);
  1.4393 +      break;
  1.4394 +    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
  1.4395 +      if (declNotationPublicId && notationDeclHandler) {
  1.4396 +        *eventEndPP = s;
  1.4397 +        notationDeclHandler(handlerArg,
  1.4398 +                            declNotationName,
  1.4399 +                            curBase,
  1.4400 +                            0,
  1.4401 +                            declNotationPublicId);
  1.4402 +        handleDefault = XML_FALSE;
  1.4403 +      }
  1.4404 +      poolClear(&tempPool);
  1.4405 +      break;
  1.4406 +    case XML_ROLE_ERROR:
  1.4407 +      switch (tok) {
  1.4408 +      case XML_TOK_PARAM_ENTITY_REF:
  1.4409 +        /* PE references in internal subset are
  1.4410 +           not allowed within declarations. */  
  1.4411 +        return XML_ERROR_PARAM_ENTITY_REF;
  1.4412 +      case XML_TOK_XML_DECL:
  1.4413 +        return XML_ERROR_MISPLACED_XML_PI;
  1.4414 +      default:
  1.4415 +        return XML_ERROR_SYNTAX;
  1.4416 +      }
  1.4417 +#ifdef XML_DTD
  1.4418 +    case XML_ROLE_IGNORE_SECT:
  1.4419 +      {
  1.4420 +        enum XML_Error result;
  1.4421 +        if (defaultHandler)
  1.4422 +          reportDefault(parser, enc, s, next);
  1.4423 +        handleDefault = XML_FALSE;
  1.4424 +        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
  1.4425 +        if (result != XML_ERROR_NONE)
  1.4426 +          return result;
  1.4427 +        else if (!next) {
  1.4428 +          processor = ignoreSectionProcessor;
  1.4429 +          return result;
  1.4430 +        }
  1.4431 +      }
  1.4432 +      break;
  1.4433 +#endif /* XML_DTD */
  1.4434 +    case XML_ROLE_GROUP_OPEN:
  1.4435 +      if (prologState.level >= groupSize) {
  1.4436 +        if (groupSize) {
  1.4437 +          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
  1.4438 +          if (temp == NULL)
  1.4439 +            return XML_ERROR_NO_MEMORY;
  1.4440 +          groupConnector = temp;
  1.4441 +          if (dtd->scaffIndex) {
  1.4442 +            int *temp = (int *)REALLOC(dtd->scaffIndex,
  1.4443 +                          groupSize * sizeof(int));
  1.4444 +            if (temp == NULL)
  1.4445 +              return XML_ERROR_NO_MEMORY;
  1.4446 +            dtd->scaffIndex = temp;
  1.4447 +          }
  1.4448 +        }
  1.4449 +        else {
  1.4450 +          groupConnector = (char *)MALLOC(groupSize = 32);
  1.4451 +          if (!groupConnector)
  1.4452 +            return XML_ERROR_NO_MEMORY;
  1.4453 +        }
  1.4454 +      }
  1.4455 +      groupConnector[prologState.level] = 0;
  1.4456 +      if (dtd->in_eldecl) {
  1.4457 +        int myindex = nextScaffoldPart(parser);
  1.4458 +        if (myindex < 0)
  1.4459 +          return XML_ERROR_NO_MEMORY;
  1.4460 +        dtd->scaffIndex[dtd->scaffLevel] = myindex;
  1.4461 +        dtd->scaffLevel++;
  1.4462 +        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
  1.4463 +        if (elementDeclHandler)
  1.4464 +          handleDefault = XML_FALSE;
  1.4465 +      }
  1.4466 +      break;
  1.4467 +    case XML_ROLE_GROUP_SEQUENCE:
  1.4468 +      if (groupConnector[prologState.level] == '|')
  1.4469 +        return XML_ERROR_SYNTAX;
  1.4470 +      groupConnector[prologState.level] = ',';
  1.4471 +      if (dtd->in_eldecl && elementDeclHandler)
  1.4472 +        handleDefault = XML_FALSE;
  1.4473 +      break;
  1.4474 +    case XML_ROLE_GROUP_CHOICE:
  1.4475 +      if (groupConnector[prologState.level] == ',')
  1.4476 +        return XML_ERROR_SYNTAX;
  1.4477 +      if (dtd->in_eldecl
  1.4478 +          && !groupConnector[prologState.level]
  1.4479 +          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  1.4480 +              != XML_CTYPE_MIXED)
  1.4481 +          ) {
  1.4482 +        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  1.4483 +            = XML_CTYPE_CHOICE;
  1.4484 +        if (elementDeclHandler)
  1.4485 +          handleDefault = XML_FALSE;
  1.4486 +      }
  1.4487 +      groupConnector[prologState.level] = '|';
  1.4488 +      break;
  1.4489 +    case XML_ROLE_PARAM_ENTITY_REF:
  1.4490 +#ifdef XML_DTD
  1.4491 +    case XML_ROLE_INNER_PARAM_ENTITY_REF:
  1.4492 +      dtd->hasParamEntityRefs = XML_TRUE;
  1.4493 +      if (!paramEntityParsing)
  1.4494 +        dtd->keepProcessing = dtd->standalone;
  1.4495 +      else {
  1.4496 +        const XML_Char *name;
  1.4497 +        ENTITY *entity;
  1.4498 +        name = poolStoreString(&dtd->pool, enc,
  1.4499 +                                s + enc->minBytesPerChar,
  1.4500 +                                next - enc->minBytesPerChar);
  1.4501 +        if (!name)
  1.4502 +          return XML_ERROR_NO_MEMORY;
  1.4503 +        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
  1.4504 +        poolDiscard(&dtd->pool);
  1.4505 +        /* first, determine if a check for an existing declaration is needed;
  1.4506 +           if yes, check that the entity exists, and that it is internal,
  1.4507 +           otherwise call the skipped entity handler
  1.4508 +        */
  1.4509 +        if (prologState.documentEntity &&
  1.4510 +            (dtd->standalone
  1.4511 +             ? !openInternalEntities
  1.4512 +             : !dtd->hasParamEntityRefs)) {
  1.4513 +          if (!entity)
  1.4514 +            return XML_ERROR_UNDEFINED_ENTITY;
  1.4515 +          else if (!entity->is_internal)
  1.4516 +            return XML_ERROR_ENTITY_DECLARED_IN_PE;
  1.4517 +        }
  1.4518 +        else if (!entity) {
  1.4519 +          dtd->keepProcessing = dtd->standalone;
  1.4520 +          /* cannot report skipped entities in declarations */
  1.4521 +          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
  1.4522 +            skippedEntityHandler(handlerArg, name, 1);
  1.4523 +            handleDefault = XML_FALSE;
  1.4524 +          }
  1.4525 +          break;
  1.4526 +        }
  1.4527 +        if (entity->open)
  1.4528 +          return XML_ERROR_RECURSIVE_ENTITY_REF;
  1.4529 +        if (entity->textPtr) {
  1.4530 +          enum XML_Error result;
  1.4531 +          XML_Bool betweenDecl = 
  1.4532 +            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
  1.4533 +          result = processInternalEntity(parser, entity, betweenDecl);
  1.4534 +          if (result != XML_ERROR_NONE)
  1.4535 +            return result;
  1.4536 +          handleDefault = XML_FALSE;
  1.4537 +          break;
  1.4538 +        }
  1.4539 +        if (externalEntityRefHandler) {
  1.4540 +          dtd->paramEntityRead = XML_FALSE;
  1.4541 +          entity->open = XML_TRUE;
  1.4542 +          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1.4543 +/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=191482) */
  1.4544 +#if 0
  1.4545 +                                        0,
  1.4546 +#else
  1.4547 +                                        entity->name,
  1.4548 +#endif
  1.4549 +/* END MOZILLA CHANGE */
  1.4550 +                                        entity->base,
  1.4551 +                                        entity->systemId,
  1.4552 +                                        entity->publicId)) {
  1.4553 +            entity->open = XML_FALSE;
  1.4554 +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1.4555 +          }
  1.4556 +          entity->open = XML_FALSE;
  1.4557 +          handleDefault = XML_FALSE;
  1.4558 +          if (!dtd->paramEntityRead) {
  1.4559 +            dtd->keepProcessing = dtd->standalone;
  1.4560 +            break;
  1.4561 +          }
  1.4562 +        }
  1.4563 +        else {
  1.4564 +          dtd->keepProcessing = dtd->standalone;
  1.4565 +          break;
  1.4566 +        }
  1.4567 +      }
  1.4568 +#endif /* XML_DTD */
  1.4569 +      if (!dtd->standalone &&
  1.4570 +          notStandaloneHandler &&
  1.4571 +          !notStandaloneHandler(handlerArg))
  1.4572 +        return XML_ERROR_NOT_STANDALONE;
  1.4573 +      break;
  1.4574 +
  1.4575 +    /* Element declaration stuff */
  1.4576 +
  1.4577 +    case XML_ROLE_ELEMENT_NAME:
  1.4578 +      if (elementDeclHandler) {
  1.4579 +        declElementType = getElementType(parser, enc, s, next);
  1.4580 +        if (!declElementType)
  1.4581 +          return XML_ERROR_NO_MEMORY;
  1.4582 +        dtd->scaffLevel = 0;
  1.4583 +        dtd->scaffCount = 0;
  1.4584 +        dtd->in_eldecl = XML_TRUE;
  1.4585 +        handleDefault = XML_FALSE;
  1.4586 +      }
  1.4587 +      break;
  1.4588 +
  1.4589 +    case XML_ROLE_CONTENT_ANY:
  1.4590 +    case XML_ROLE_CONTENT_EMPTY:
  1.4591 +      if (dtd->in_eldecl) {
  1.4592 +        if (elementDeclHandler) {
  1.4593 +          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
  1.4594 +          if (!content)
  1.4595 +            return XML_ERROR_NO_MEMORY;
  1.4596 +          content->quant = XML_CQUANT_NONE;
  1.4597 +          content->name = NULL;
  1.4598 +          content->numchildren = 0;
  1.4599 +          content->children = NULL;
  1.4600 +          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
  1.4601 +                           XML_CTYPE_ANY :
  1.4602 +                           XML_CTYPE_EMPTY);
  1.4603 +          *eventEndPP = s;
  1.4604 +          elementDeclHandler(handlerArg, declElementType->name, content);
  1.4605 +          handleDefault = XML_FALSE;
  1.4606 +        }
  1.4607 +        dtd->in_eldecl = XML_FALSE;
  1.4608 +      }
  1.4609 +      break;
  1.4610 +
  1.4611 +    case XML_ROLE_CONTENT_PCDATA:
  1.4612 +      if (dtd->in_eldecl) {
  1.4613 +        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  1.4614 +            = XML_CTYPE_MIXED;
  1.4615 +        if (elementDeclHandler)
  1.4616 +          handleDefault = XML_FALSE;
  1.4617 +      }
  1.4618 +      break;
  1.4619 +
  1.4620 +    case XML_ROLE_CONTENT_ELEMENT:
  1.4621 +      quant = XML_CQUANT_NONE;
  1.4622 +      goto elementContent;
  1.4623 +    case XML_ROLE_CONTENT_ELEMENT_OPT:
  1.4624 +      quant = XML_CQUANT_OPT;
  1.4625 +      goto elementContent;
  1.4626 +    case XML_ROLE_CONTENT_ELEMENT_REP:
  1.4627 +      quant = XML_CQUANT_REP;
  1.4628 +      goto elementContent;
  1.4629 +    case XML_ROLE_CONTENT_ELEMENT_PLUS:
  1.4630 +      quant = XML_CQUANT_PLUS;
  1.4631 +    elementContent:
  1.4632 +      if (dtd->in_eldecl) {
  1.4633 +        ELEMENT_TYPE *el;
  1.4634 +        const XML_Char *name;
  1.4635 +        int nameLen;
  1.4636 +        const char *nxt = (quant == XML_CQUANT_NONE
  1.4637 +                           ? next
  1.4638 +                           : next - enc->minBytesPerChar);
  1.4639 +        int myindex = nextScaffoldPart(parser);
  1.4640 +        if (myindex < 0)
  1.4641 +          return XML_ERROR_NO_MEMORY;
  1.4642 +        dtd->scaffold[myindex].type = XML_CTYPE_NAME;
  1.4643 +        dtd->scaffold[myindex].quant = quant;
  1.4644 +        el = getElementType(parser, enc, s, nxt);
  1.4645 +        if (!el)
  1.4646 +          return XML_ERROR_NO_MEMORY;
  1.4647 +        name = el->name;
  1.4648 +        dtd->scaffold[myindex].name = name;
  1.4649 +        nameLen = 0;
  1.4650 +        for (; name[nameLen++]; );
  1.4651 +        dtd->contentStringLen +=  nameLen;
  1.4652 +        if (elementDeclHandler)
  1.4653 +          handleDefault = XML_FALSE;
  1.4654 +      }
  1.4655 +      break;
  1.4656 +
  1.4657 +    case XML_ROLE_GROUP_CLOSE:
  1.4658 +      quant = XML_CQUANT_NONE;
  1.4659 +      goto closeGroup;
  1.4660 +    case XML_ROLE_GROUP_CLOSE_OPT:
  1.4661 +      quant = XML_CQUANT_OPT;
  1.4662 +      goto closeGroup;
  1.4663 +    case XML_ROLE_GROUP_CLOSE_REP:
  1.4664 +      quant = XML_CQUANT_REP;
  1.4665 +      goto closeGroup;
  1.4666 +    case XML_ROLE_GROUP_CLOSE_PLUS:
  1.4667 +      quant = XML_CQUANT_PLUS;
  1.4668 +    closeGroup:
  1.4669 +      if (dtd->in_eldecl) {
  1.4670 +        if (elementDeclHandler)
  1.4671 +          handleDefault = XML_FALSE;
  1.4672 +        dtd->scaffLevel--;
  1.4673 +        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
  1.4674 +        if (dtd->scaffLevel == 0) {
  1.4675 +          if (!handleDefault) {
  1.4676 +            XML_Content *model = build_model(parser);
  1.4677 +            if (!model)
  1.4678 +              return XML_ERROR_NO_MEMORY;
  1.4679 +            *eventEndPP = s;
  1.4680 +            elementDeclHandler(handlerArg, declElementType->name, model);
  1.4681 +          }
  1.4682 +          dtd->in_eldecl = XML_FALSE;
  1.4683 +          dtd->contentStringLen = 0;
  1.4684 +        }
  1.4685 +      }
  1.4686 +      break;
  1.4687 +      /* End element declaration stuff */
  1.4688 +
  1.4689 +    case XML_ROLE_PI:
  1.4690 +      if (!reportProcessingInstruction(parser, enc, s, next))
  1.4691 +        return XML_ERROR_NO_MEMORY;
  1.4692 +      handleDefault = XML_FALSE;
  1.4693 +      break;
  1.4694 +    case XML_ROLE_COMMENT:
  1.4695 +      if (!reportComment(parser, enc, s, next))
  1.4696 +        return XML_ERROR_NO_MEMORY;
  1.4697 +      handleDefault = XML_FALSE;
  1.4698 +      break;
  1.4699 +    case XML_ROLE_NONE:
  1.4700 +      switch (tok) {
  1.4701 +      case XML_TOK_BOM:
  1.4702 +        handleDefault = XML_FALSE;
  1.4703 +        break;
  1.4704 +      }
  1.4705 +      break;
  1.4706 +    case XML_ROLE_DOCTYPE_NONE:
  1.4707 +      if (startDoctypeDeclHandler)
  1.4708 +        handleDefault = XML_FALSE;
  1.4709 +      break;
  1.4710 +    case XML_ROLE_ENTITY_NONE:
  1.4711 +      if (dtd->keepProcessing && entityDeclHandler)
  1.4712 +        handleDefault = XML_FALSE;
  1.4713 +      break;
  1.4714 +    case XML_ROLE_NOTATION_NONE:
  1.4715 +      if (notationDeclHandler)
  1.4716 +        handleDefault = XML_FALSE;
  1.4717 +      break;
  1.4718 +    case XML_ROLE_ATTLIST_NONE:
  1.4719 +      if (dtd->keepProcessing && attlistDeclHandler)
  1.4720 +        handleDefault = XML_FALSE;
  1.4721 +      break;
  1.4722 +    case XML_ROLE_ELEMENT_NONE:
  1.4723 +      if (elementDeclHandler)
  1.4724 +        handleDefault = XML_FALSE;
  1.4725 +      break;
  1.4726 +    } /* end of big switch */
  1.4727 +
  1.4728 +    if (handleDefault && defaultHandler)
  1.4729 +      reportDefault(parser, enc, s, next);
  1.4730 +
  1.4731 +    switch (ps_parsing) {
  1.4732 +    case XML_SUSPENDED: 
  1.4733 +      *nextPtr = next;
  1.4734 +      return XML_ERROR_NONE;
  1.4735 +    case XML_FINISHED:
  1.4736 +      return XML_ERROR_ABORTED;
  1.4737 +    default:
  1.4738 +      s = next;
  1.4739 +      tok = XmlPrologTok(enc, s, end, &next);
  1.4740 +    }
  1.4741 +  }
  1.4742 +  /* not reached */
  1.4743 +}
  1.4744 +
  1.4745 +static enum XML_Error PTRCALL
  1.4746 +epilogProcessor(XML_Parser parser,
  1.4747 +                const char *s,
  1.4748 +                const char *end,
  1.4749 +                const char **nextPtr)
  1.4750 +{
  1.4751 +  processor = epilogProcessor;
  1.4752 +  eventPtr = s;
  1.4753 +  for (;;) {
  1.4754 +    const char *next = NULL;
  1.4755 +    int tok = XmlPrologTok(encoding, s, end, &next);
  1.4756 +    eventEndPtr = next;
  1.4757 +    switch (tok) {
  1.4758 +    /* report partial linebreak - it might be the last token */
  1.4759 +    case -XML_TOK_PROLOG_S:
  1.4760 +      if (defaultHandler) {
  1.4761 +        reportDefault(parser, encoding, s, next);
  1.4762 +        if (ps_parsing == XML_FINISHED)
  1.4763 +          return XML_ERROR_ABORTED;
  1.4764 +      }
  1.4765 +      *nextPtr = next;
  1.4766 +      return XML_ERROR_NONE;
  1.4767 +    case XML_TOK_NONE:
  1.4768 +      *nextPtr = s;
  1.4769 +      return XML_ERROR_NONE;
  1.4770 +    case XML_TOK_PROLOG_S:
  1.4771 +      if (defaultHandler)
  1.4772 +        reportDefault(parser, encoding, s, next);
  1.4773 +      break;
  1.4774 +    case XML_TOK_PI:
  1.4775 +      if (!reportProcessingInstruction(parser, encoding, s, next))
  1.4776 +        return XML_ERROR_NO_MEMORY;
  1.4777 +      break;
  1.4778 +    case XML_TOK_COMMENT:
  1.4779 +      if (!reportComment(parser, encoding, s, next))
  1.4780 +        return XML_ERROR_NO_MEMORY;
  1.4781 +      break;
  1.4782 +    case XML_TOK_INVALID:
  1.4783 +      eventPtr = next;
  1.4784 +      return XML_ERROR_INVALID_TOKEN;
  1.4785 +    case XML_TOK_PARTIAL:
  1.4786 +      if (!ps_finalBuffer) {
  1.4787 +        *nextPtr = s;
  1.4788 +        return XML_ERROR_NONE;
  1.4789 +      }
  1.4790 +      return XML_ERROR_UNCLOSED_TOKEN;
  1.4791 +    case XML_TOK_PARTIAL_CHAR:
  1.4792 +      if (!ps_finalBuffer) {
  1.4793 +        *nextPtr = s;
  1.4794 +        return XML_ERROR_NONE;
  1.4795 +      }
  1.4796 +      return XML_ERROR_PARTIAL_CHAR;
  1.4797 +    default:
  1.4798 +      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
  1.4799 +    }
  1.4800 +    eventPtr = s = next;
  1.4801 +    switch (ps_parsing) {
  1.4802 +    case XML_SUSPENDED: 
  1.4803 +      *nextPtr = next;
  1.4804 +      return XML_ERROR_NONE;
  1.4805 +    case XML_FINISHED:
  1.4806 +      return XML_ERROR_ABORTED;
  1.4807 +    default: ;
  1.4808 +    }
  1.4809 +  }
  1.4810 +}
  1.4811 +
  1.4812 +static enum XML_Error
  1.4813 +processInternalEntity(XML_Parser parser, ENTITY *entity,
  1.4814 +                      XML_Bool betweenDecl)
  1.4815 +{
  1.4816 +  const char *textStart, *textEnd;
  1.4817 +  const char *next;
  1.4818 +  enum XML_Error result;
  1.4819 +  OPEN_INTERNAL_ENTITY *openEntity;
  1.4820 +
  1.4821 +  if (freeInternalEntities) {
  1.4822 +    openEntity = freeInternalEntities;
  1.4823 +    freeInternalEntities = openEntity->next;
  1.4824 +  }
  1.4825 +  else {
  1.4826 +    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
  1.4827 +    if (!openEntity)
  1.4828 +      return XML_ERROR_NO_MEMORY;
  1.4829 +  }
  1.4830 +  entity->open = XML_TRUE;
  1.4831 +  entity->processed = 0;
  1.4832 +  openEntity->next = openInternalEntities;
  1.4833 +  openInternalEntities = openEntity;
  1.4834 +  openEntity->entity = entity;
  1.4835 +  openEntity->startTagLevel = tagLevel;
  1.4836 +  openEntity->betweenDecl = betweenDecl;
  1.4837 +  openEntity->internalEventPtr = NULL;
  1.4838 +  openEntity->internalEventEndPtr = NULL;
  1.4839 +  textStart = (char *)entity->textPtr;
  1.4840 +  textEnd = (char *)(entity->textPtr + entity->textLen);
  1.4841 +
  1.4842 +#ifdef XML_DTD
  1.4843 +  if (entity->is_param) {
  1.4844 +    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
  1.4845 +    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
  1.4846 +                      next, &next, XML_FALSE);
  1.4847 +  }
  1.4848 +  else 
  1.4849 +#endif /* XML_DTD */
  1.4850 +    result = doContent(parser, tagLevel, internalEncoding, textStart, 
  1.4851 +                       textEnd, &next, XML_FALSE);
  1.4852 +
  1.4853 +  if (result == XML_ERROR_NONE) {
  1.4854 +    if (textEnd != next && ps_parsing == XML_SUSPENDED) {
  1.4855 +      entity->processed = (int)(next - textStart);
  1.4856 +      processor = internalEntityProcessor;
  1.4857 +    }
  1.4858 +    else {
  1.4859 +      entity->open = XML_FALSE;
  1.4860 +      openInternalEntities = openEntity->next;
  1.4861 +      /* put openEntity back in list of free instances */
  1.4862 +      openEntity->next = freeInternalEntities;
  1.4863 +      freeInternalEntities = openEntity;
  1.4864 +    }
  1.4865 +  }
  1.4866 +  return result;
  1.4867 +}
  1.4868 +
  1.4869 +static enum XML_Error PTRCALL
  1.4870 +internalEntityProcessor(XML_Parser parser,
  1.4871 +                        const char *s,
  1.4872 +                        const char *end,
  1.4873 +                        const char **nextPtr)
  1.4874 +{
  1.4875 +  ENTITY *entity;
  1.4876 +  const char *textStart, *textEnd;
  1.4877 +  const char *next;
  1.4878 +  enum XML_Error result;
  1.4879 +  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
  1.4880 +  if (!openEntity)
  1.4881 +    return XML_ERROR_UNEXPECTED_STATE;
  1.4882 +
  1.4883 +  entity = openEntity->entity;
  1.4884 +  textStart = ((char *)entity->textPtr) + entity->processed;
  1.4885 +  textEnd = (char *)(entity->textPtr + entity->textLen);
  1.4886 +
  1.4887 +#ifdef XML_DTD
  1.4888 +  if (entity->is_param) {
  1.4889 +    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
  1.4890 +    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
  1.4891 +                      next, &next, XML_FALSE);
  1.4892 +  }
  1.4893 +  else
  1.4894 +#endif /* XML_DTD */
  1.4895 +    result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
  1.4896 +                       textStart, textEnd, &next, XML_FALSE);  
  1.4897 +
  1.4898 +  if (result != XML_ERROR_NONE)
  1.4899 +    return result;
  1.4900 +  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
  1.4901 +    entity->processed = (int)(next - (char *)entity->textPtr);
  1.4902 +    return result;
  1.4903 +  }
  1.4904 +  else {
  1.4905 +    entity->open = XML_FALSE;
  1.4906 +    openInternalEntities = openEntity->next;
  1.4907 +    /* put openEntity back in list of free instances */
  1.4908 +    openEntity->next = freeInternalEntities;
  1.4909 +    freeInternalEntities = openEntity;
  1.4910 +  }
  1.4911 +
  1.4912 +#ifdef XML_DTD
  1.4913 +  if (entity->is_param) {
  1.4914 +    int tok;
  1.4915 +    processor = prologProcessor;
  1.4916 +    tok = XmlPrologTok(encoding, s, end, &next);
  1.4917 +    return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
  1.4918 +                    (XML_Bool)!ps_finalBuffer);
  1.4919 +  }
  1.4920 +  else
  1.4921 +#endif /* XML_DTD */
  1.4922 +  {
  1.4923 +    processor = contentProcessor;
  1.4924 +    /* see externalEntityContentProcessor vs contentProcessor */
  1.4925 +    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
  1.4926 +                     nextPtr, (XML_Bool)!ps_finalBuffer); 
  1.4927 +  }  
  1.4928 +}
  1.4929 +
  1.4930 +static enum XML_Error PTRCALL
  1.4931 +errorProcessor(XML_Parser parser,
  1.4932 +               const char *s,
  1.4933 +               const char *end,
  1.4934 +               const char **nextPtr)
  1.4935 +{
  1.4936 +  return errorCode;
  1.4937 +}
  1.4938 +
  1.4939 +static enum XML_Error
  1.4940 +storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
  1.4941 +                    const char *ptr, const char *end,
  1.4942 +                    STRING_POOL *pool)
  1.4943 +{
  1.4944 +  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
  1.4945 +                                               end, pool);
  1.4946 +  if (result)
  1.4947 +    return result;
  1.4948 +  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
  1.4949 +    poolChop(pool);
  1.4950 +  if (!poolAppendChar(pool, XML_T('\0')))
  1.4951 +    return XML_ERROR_NO_MEMORY;
  1.4952 +  return XML_ERROR_NONE;
  1.4953 +}
  1.4954 +
  1.4955 +static enum XML_Error
  1.4956 +appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
  1.4957 +                     const char *ptr, const char *end,
  1.4958 +                     STRING_POOL *pool)
  1.4959 +{
  1.4960 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.4961 +  for (;;) {
  1.4962 +    const char *next;
  1.4963 +    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
  1.4964 +    switch (tok) {
  1.4965 +    case XML_TOK_NONE:
  1.4966 +      return XML_ERROR_NONE;
  1.4967 +    case XML_TOK_INVALID:
  1.4968 +      if (enc == encoding)
  1.4969 +        eventPtr = next;
  1.4970 +      return XML_ERROR_INVALID_TOKEN;
  1.4971 +    case XML_TOK_PARTIAL:
  1.4972 +      if (enc == encoding)
  1.4973 +        eventPtr = ptr;
  1.4974 +      return XML_ERROR_INVALID_TOKEN;
  1.4975 +    case XML_TOK_CHAR_REF:
  1.4976 +      {
  1.4977 +        XML_Char buf[XML_ENCODE_MAX];
  1.4978 +        int i;
  1.4979 +        int n = XmlCharRefNumber(enc, ptr);
  1.4980 +        if (n < 0) {
  1.4981 +          if (enc == encoding)
  1.4982 +            eventPtr = ptr;
  1.4983 +          return XML_ERROR_BAD_CHAR_REF;
  1.4984 +        }
  1.4985 +        if (!isCdata
  1.4986 +            && n == 0x20 /* space */
  1.4987 +            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  1.4988 +          break;
  1.4989 +        n = XmlEncode(n, (ICHAR *)buf);
  1.4990 +        if (!n) {
  1.4991 +          if (enc == encoding)
  1.4992 +            eventPtr = ptr;
  1.4993 +          return XML_ERROR_BAD_CHAR_REF;
  1.4994 +        }
  1.4995 +        for (i = 0; i < n; i++) {
  1.4996 +          if (!poolAppendChar(pool, buf[i]))
  1.4997 +            return XML_ERROR_NO_MEMORY;
  1.4998 +        }
  1.4999 +      }
  1.5000 +      break;
  1.5001 +    case XML_TOK_DATA_CHARS:
  1.5002 +      if (!poolAppend(pool, enc, ptr, next))
  1.5003 +        return XML_ERROR_NO_MEMORY;
  1.5004 +      break;
  1.5005 +    case XML_TOK_TRAILING_CR:
  1.5006 +      next = ptr + enc->minBytesPerChar;
  1.5007 +      /* fall through */
  1.5008 +    case XML_TOK_ATTRIBUTE_VALUE_S:
  1.5009 +    case XML_TOK_DATA_NEWLINE:
  1.5010 +      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  1.5011 +        break;
  1.5012 +      if (!poolAppendChar(pool, 0x20))
  1.5013 +        return XML_ERROR_NO_MEMORY;
  1.5014 +      break;
  1.5015 +    case XML_TOK_ENTITY_REF:
  1.5016 +      {
  1.5017 +        const XML_Char *name;
  1.5018 +        ENTITY *entity;
  1.5019 +        char checkEntityDecl;
  1.5020 +        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
  1.5021 +                                              ptr + enc->minBytesPerChar,
  1.5022 +                                              next - enc->minBytesPerChar);
  1.5023 +        if (ch) {
  1.5024 +          if (!poolAppendChar(pool, ch))
  1.5025 +                return XML_ERROR_NO_MEMORY;
  1.5026 +          break;
  1.5027 +        }
  1.5028 +        name = poolStoreString(&temp2Pool, enc,
  1.5029 +                               ptr + enc->minBytesPerChar,
  1.5030 +                               next - enc->minBytesPerChar);
  1.5031 +        if (!name)
  1.5032 +          return XML_ERROR_NO_MEMORY;
  1.5033 +        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
  1.5034 +        poolDiscard(&temp2Pool);
  1.5035 +        /* First, determine if a check for an existing declaration is needed;
  1.5036 +           if yes, check that the entity exists, and that it is internal.
  1.5037 +        */
  1.5038 +        if (pool == &dtd->pool)  /* are we called from prolog? */
  1.5039 +          checkEntityDecl =
  1.5040 +#ifdef XML_DTD
  1.5041 +              prologState.documentEntity &&
  1.5042 +#endif /* XML_DTD */
  1.5043 +              (dtd->standalone
  1.5044 +               ? !openInternalEntities
  1.5045 +               : !dtd->hasParamEntityRefs);
  1.5046 +        else /* if (pool == &tempPool): we are called from content */
  1.5047 +          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
  1.5048 +        if (checkEntityDecl) {
  1.5049 +          if (!entity)
  1.5050 +            return XML_ERROR_UNDEFINED_ENTITY;
  1.5051 +          else if (!entity->is_internal)
  1.5052 +            return XML_ERROR_ENTITY_DECLARED_IN_PE;
  1.5053 +        }
  1.5054 +        else if (!entity) {
  1.5055 +          /* Cannot report skipped entity here - see comments on
  1.5056 +             skippedEntityHandler.
  1.5057 +          if (skippedEntityHandler)
  1.5058 +            skippedEntityHandler(handlerArg, name, 0);
  1.5059 +          */
  1.5060 +          /* Cannot call the default handler because this would be
  1.5061 +             out of sync with the call to the startElementHandler.
  1.5062 +          if ((pool == &tempPool) && defaultHandler)
  1.5063 +            reportDefault(parser, enc, ptr, next);
  1.5064 +          */
  1.5065 +/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=35984) */
  1.5066 +#if 0
  1.5067 +          break;
  1.5068 +#else
  1.5069 +          return XML_ERROR_UNDEFINED_ENTITY;
  1.5070 +#endif
  1.5071 +/* END MOZILLA CHANGE */
  1.5072 +        }
  1.5073 +        if (entity->open) {
  1.5074 +          if (enc == encoding)
  1.5075 +            eventPtr = ptr;
  1.5076 +          return XML_ERROR_RECURSIVE_ENTITY_REF;
  1.5077 +        }
  1.5078 +        if (entity->notation) {
  1.5079 +          if (enc == encoding)
  1.5080 +            eventPtr = ptr;
  1.5081 +          return XML_ERROR_BINARY_ENTITY_REF;
  1.5082 +        }
  1.5083 +        if (!entity->textPtr) {
  1.5084 +          if (enc == encoding)
  1.5085 +            eventPtr = ptr;
  1.5086 +              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
  1.5087 +        }
  1.5088 +        else {
  1.5089 +          enum XML_Error result;
  1.5090 +          const XML_Char *textEnd = entity->textPtr + entity->textLen;
  1.5091 +          entity->open = XML_TRUE;
  1.5092 +          result = appendAttributeValue(parser, internalEncoding, isCdata,
  1.5093 +                                        (char *)entity->textPtr,
  1.5094 +                                        (char *)textEnd, pool);
  1.5095 +          entity->open = XML_FALSE;
  1.5096 +          if (result)
  1.5097 +            return result;
  1.5098 +        }
  1.5099 +      }
  1.5100 +      break;
  1.5101 +    default:
  1.5102 +      if (enc == encoding)
  1.5103 +        eventPtr = ptr;
  1.5104 +      return XML_ERROR_UNEXPECTED_STATE;
  1.5105 +    }
  1.5106 +    ptr = next;
  1.5107 +  }
  1.5108 +  /* not reached */
  1.5109 +}
  1.5110 +
  1.5111 +static enum XML_Error
  1.5112 +storeEntityValue(XML_Parser parser,
  1.5113 +                 const ENCODING *enc,
  1.5114 +                 const char *entityTextPtr,
  1.5115 +                 const char *entityTextEnd)
  1.5116 +{
  1.5117 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.5118 +  STRING_POOL *pool = &(dtd->entityValuePool);
  1.5119 +  enum XML_Error result = XML_ERROR_NONE;
  1.5120 +#ifdef XML_DTD
  1.5121 +  int oldInEntityValue = prologState.inEntityValue;
  1.5122 +  prologState.inEntityValue = 1;
  1.5123 +#endif /* XML_DTD */
  1.5124 +  /* never return Null for the value argument in EntityDeclHandler,
  1.5125 +     since this would indicate an external entity; therefore we
  1.5126 +     have to make sure that entityValuePool.start is not null */
  1.5127 +  if (!pool->blocks) {
  1.5128 +    if (!poolGrow(pool))
  1.5129 +      return XML_ERROR_NO_MEMORY;
  1.5130 +  }
  1.5131 +
  1.5132 +  for (;;) {
  1.5133 +    const char *next;
  1.5134 +    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
  1.5135 +    switch (tok) {
  1.5136 +    case XML_TOK_PARAM_ENTITY_REF:
  1.5137 +#ifdef XML_DTD
  1.5138 +      if (isParamEntity || enc != encoding) {
  1.5139 +        const XML_Char *name;
  1.5140 +        ENTITY *entity;
  1.5141 +        name = poolStoreString(&tempPool, enc,
  1.5142 +                               entityTextPtr + enc->minBytesPerChar,
  1.5143 +                               next - enc->minBytesPerChar);
  1.5144 +        if (!name) {
  1.5145 +          result = XML_ERROR_NO_MEMORY;
  1.5146 +          goto endEntityValue;
  1.5147 +        }
  1.5148 +        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
  1.5149 +        poolDiscard(&tempPool);
  1.5150 +        if (!entity) {
  1.5151 +          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
  1.5152 +          /* cannot report skipped entity here - see comments on
  1.5153 +             skippedEntityHandler
  1.5154 +          if (skippedEntityHandler)
  1.5155 +            skippedEntityHandler(handlerArg, name, 0);
  1.5156 +          */
  1.5157 +          dtd->keepProcessing = dtd->standalone;
  1.5158 +          goto endEntityValue;
  1.5159 +        }
  1.5160 +        if (entity->open) {
  1.5161 +          if (enc == encoding)
  1.5162 +            eventPtr = entityTextPtr;
  1.5163 +          result = XML_ERROR_RECURSIVE_ENTITY_REF;
  1.5164 +          goto endEntityValue;
  1.5165 +        }
  1.5166 +        if (entity->systemId) {
  1.5167 +          if (externalEntityRefHandler) {
  1.5168 +            dtd->paramEntityRead = XML_FALSE;
  1.5169 +            entity->open = XML_TRUE;
  1.5170 +            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1.5171 +                                          0,
  1.5172 +                                          entity->base,
  1.5173 +                                          entity->systemId,
  1.5174 +                                          entity->publicId)) {
  1.5175 +              entity->open = XML_FALSE;
  1.5176 +              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1.5177 +              goto endEntityValue;
  1.5178 +            }
  1.5179 +            entity->open = XML_FALSE;
  1.5180 +            if (!dtd->paramEntityRead)
  1.5181 +              dtd->keepProcessing = dtd->standalone;
  1.5182 +          }
  1.5183 +          else
  1.5184 +            dtd->keepProcessing = dtd->standalone;
  1.5185 +        }
  1.5186 +        else {
  1.5187 +          entity->open = XML_TRUE;
  1.5188 +          result = storeEntityValue(parser,
  1.5189 +                                    internalEncoding,
  1.5190 +                                    (char *)entity->textPtr,
  1.5191 +                                    (char *)(entity->textPtr
  1.5192 +                                             + entity->textLen));
  1.5193 +          entity->open = XML_FALSE;
  1.5194 +          if (result)
  1.5195 +            goto endEntityValue;
  1.5196 +        }
  1.5197 +        break;
  1.5198 +      }
  1.5199 +#endif /* XML_DTD */
  1.5200 +      /* In the internal subset, PE references are not legal
  1.5201 +         within markup declarations, e.g entity values in this case. */
  1.5202 +      eventPtr = entityTextPtr;
  1.5203 +      result = XML_ERROR_PARAM_ENTITY_REF;
  1.5204 +      goto endEntityValue;
  1.5205 +    case XML_TOK_NONE:
  1.5206 +      result = XML_ERROR_NONE;
  1.5207 +      goto endEntityValue;
  1.5208 +    case XML_TOK_ENTITY_REF:
  1.5209 +    case XML_TOK_DATA_CHARS:
  1.5210 +      if (!poolAppend(pool, enc, entityTextPtr, next)) {
  1.5211 +        result = XML_ERROR_NO_MEMORY;
  1.5212 +        goto endEntityValue;
  1.5213 +      }
  1.5214 +      break;
  1.5215 +    case XML_TOK_TRAILING_CR:
  1.5216 +      next = entityTextPtr + enc->minBytesPerChar;
  1.5217 +      /* fall through */
  1.5218 +    case XML_TOK_DATA_NEWLINE:
  1.5219 +      if (pool->end == pool->ptr && !poolGrow(pool)) {
  1.5220 +              result = XML_ERROR_NO_MEMORY;
  1.5221 +        goto endEntityValue;
  1.5222 +      }
  1.5223 +      *(pool->ptr)++ = 0xA;
  1.5224 +      break;
  1.5225 +    case XML_TOK_CHAR_REF:
  1.5226 +      {
  1.5227 +        XML_Char buf[XML_ENCODE_MAX];
  1.5228 +        int i;
  1.5229 +        int n = XmlCharRefNumber(enc, entityTextPtr);
  1.5230 +        if (n < 0) {
  1.5231 +          if (enc == encoding)
  1.5232 +            eventPtr = entityTextPtr;
  1.5233 +          result = XML_ERROR_BAD_CHAR_REF;
  1.5234 +          goto endEntityValue;
  1.5235 +        }
  1.5236 +        n = XmlEncode(n, (ICHAR *)buf);
  1.5237 +        if (!n) {
  1.5238 +          if (enc == encoding)
  1.5239 +            eventPtr = entityTextPtr;
  1.5240 +          result = XML_ERROR_BAD_CHAR_REF;
  1.5241 +          goto endEntityValue;
  1.5242 +        }
  1.5243 +        for (i = 0; i < n; i++) {
  1.5244 +          if (pool->end == pool->ptr && !poolGrow(pool)) {
  1.5245 +            result = XML_ERROR_NO_MEMORY;
  1.5246 +            goto endEntityValue;
  1.5247 +          }
  1.5248 +          *(pool->ptr)++ = buf[i];
  1.5249 +        }
  1.5250 +      }
  1.5251 +      break;
  1.5252 +    case XML_TOK_PARTIAL:
  1.5253 +      if (enc == encoding)
  1.5254 +        eventPtr = entityTextPtr;
  1.5255 +      result = XML_ERROR_INVALID_TOKEN;
  1.5256 +      goto endEntityValue;
  1.5257 +    case XML_TOK_INVALID:
  1.5258 +      if (enc == encoding)
  1.5259 +        eventPtr = next;
  1.5260 +      result = XML_ERROR_INVALID_TOKEN;
  1.5261 +      goto endEntityValue;
  1.5262 +    default:
  1.5263 +      if (enc == encoding)
  1.5264 +        eventPtr = entityTextPtr;
  1.5265 +      result = XML_ERROR_UNEXPECTED_STATE;
  1.5266 +      goto endEntityValue;
  1.5267 +    }
  1.5268 +    entityTextPtr = next;
  1.5269 +  }
  1.5270 +endEntityValue:
  1.5271 +#ifdef XML_DTD
  1.5272 +  prologState.inEntityValue = oldInEntityValue;
  1.5273 +#endif /* XML_DTD */
  1.5274 +  return result;
  1.5275 +}
  1.5276 +
  1.5277 +static void FASTCALL
  1.5278 +normalizeLines(XML_Char *s)
  1.5279 +{
  1.5280 +  XML_Char *p;
  1.5281 +  for (;; s++) {
  1.5282 +    if (*s == XML_T('\0'))
  1.5283 +      return;
  1.5284 +    if (*s == 0xD)
  1.5285 +      break;
  1.5286 +  }
  1.5287 +  p = s;
  1.5288 +  do {
  1.5289 +    if (*s == 0xD) {
  1.5290 +      *p++ = 0xA;
  1.5291 +      if (*++s == 0xA)
  1.5292 +        s++;
  1.5293 +    }
  1.5294 +    else
  1.5295 +      *p++ = *s++;
  1.5296 +  } while (*s);
  1.5297 +  *p = XML_T('\0');
  1.5298 +}
  1.5299 +
  1.5300 +static int
  1.5301 +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
  1.5302 +                            const char *start, const char *end)
  1.5303 +{
  1.5304 +  const XML_Char *target;
  1.5305 +  XML_Char *data;
  1.5306 +  const char *tem;
  1.5307 +  if (!processingInstructionHandler) {
  1.5308 +    if (defaultHandler)
  1.5309 +      reportDefault(parser, enc, start, end);
  1.5310 +    return 1;
  1.5311 +  }
  1.5312 +  start += enc->minBytesPerChar * 2;
  1.5313 +  tem = start + XmlNameLength(enc, start);
  1.5314 +  target = poolStoreString(&tempPool, enc, start, tem);
  1.5315 +  if (!target)
  1.5316 +    return 0;
  1.5317 +  poolFinish(&tempPool);
  1.5318 +  data = poolStoreString(&tempPool, enc,
  1.5319 +                        XmlSkipS(enc, tem),
  1.5320 +                        end - enc->minBytesPerChar*2);
  1.5321 +  if (!data)
  1.5322 +    return 0;
  1.5323 +  normalizeLines(data);
  1.5324 +  processingInstructionHandler(handlerArg, target, data);
  1.5325 +  poolClear(&tempPool);
  1.5326 +  return 1;
  1.5327 +}
  1.5328 +
  1.5329 +static int
  1.5330 +reportComment(XML_Parser parser, const ENCODING *enc,
  1.5331 +              const char *start, const char *end)
  1.5332 +{
  1.5333 +  XML_Char *data;
  1.5334 +  if (!commentHandler) {
  1.5335 +    if (defaultHandler)
  1.5336 +      reportDefault(parser, enc, start, end);
  1.5337 +    return 1;
  1.5338 +  }
  1.5339 +  data = poolStoreString(&tempPool,
  1.5340 +                         enc,
  1.5341 +                         start + enc->minBytesPerChar * 4,
  1.5342 +                         end - enc->minBytesPerChar * 3);
  1.5343 +  if (!data)
  1.5344 +    return 0;
  1.5345 +  normalizeLines(data);
  1.5346 +  commentHandler(handlerArg, data);
  1.5347 +  poolClear(&tempPool);
  1.5348 +  return 1;
  1.5349 +}
  1.5350 +
  1.5351 +static void
  1.5352 +reportDefault(XML_Parser parser, const ENCODING *enc,
  1.5353 +              const char *s, const char *end)
  1.5354 +{
  1.5355 +  if (MUST_CONVERT(enc, s)) {
  1.5356 +    const char **eventPP;
  1.5357 +    const char **eventEndPP;
  1.5358 +    if (enc == encoding) {
  1.5359 +      eventPP = &eventPtr;
  1.5360 +      eventEndPP = &eventEndPtr;
  1.5361 +    }
  1.5362 +    else {
  1.5363 +      eventPP = &(openInternalEntities->internalEventPtr);
  1.5364 +      eventEndPP = &(openInternalEntities->internalEventEndPtr);
  1.5365 +    }
  1.5366 +    do {
  1.5367 +      ICHAR *dataPtr = (ICHAR *)dataBuf;
  1.5368 +      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
  1.5369 +      *eventEndPP = s;
  1.5370 +      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
  1.5371 +      *eventPP = s;
  1.5372 +    } while (s != end);
  1.5373 +  }
  1.5374 +  else
  1.5375 +    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
  1.5376 +}
  1.5377 +
  1.5378 +
  1.5379 +static int
  1.5380 +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
  1.5381 +                XML_Bool isId, const XML_Char *value, XML_Parser parser)
  1.5382 +{
  1.5383 +  DEFAULT_ATTRIBUTE *att;
  1.5384 +  if (value || isId) {
  1.5385 +    /* The handling of default attributes gets messed up if we have
  1.5386 +       a default which duplicates a non-default. */
  1.5387 +    int i;
  1.5388 +    for (i = 0; i < type->nDefaultAtts; i++)
  1.5389 +      if (attId == type->defaultAtts[i].id)
  1.5390 +        return 1;
  1.5391 +    if (isId && !type->idAtt && !attId->xmlns)
  1.5392 +      type->idAtt = attId;
  1.5393 +  }
  1.5394 +  if (type->nDefaultAtts == type->allocDefaultAtts) {
  1.5395 +    if (type->allocDefaultAtts == 0) {
  1.5396 +      type->allocDefaultAtts = 8;
  1.5397 +      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
  1.5398 +                            * sizeof(DEFAULT_ATTRIBUTE));
  1.5399 +      if (!type->defaultAtts)
  1.5400 +        return 0;
  1.5401 +    }
  1.5402 +    else {
  1.5403 +      DEFAULT_ATTRIBUTE *temp;
  1.5404 +      int count = type->allocDefaultAtts * 2;
  1.5405 +      temp = (DEFAULT_ATTRIBUTE *)
  1.5406 +        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
  1.5407 +      if (temp == NULL)
  1.5408 +        return 0;
  1.5409 +      type->allocDefaultAtts = count;
  1.5410 +      type->defaultAtts = temp;
  1.5411 +    }
  1.5412 +  }
  1.5413 +  att = type->defaultAtts + type->nDefaultAtts;
  1.5414 +  att->id = attId;
  1.5415 +  att->value = value;
  1.5416 +  att->isCdata = isCdata;
  1.5417 +  if (!isCdata)
  1.5418 +    attId->maybeTokenized = XML_TRUE;
  1.5419 +  type->nDefaultAtts += 1;
  1.5420 +  return 1;
  1.5421 +}
  1.5422 +
  1.5423 +static int
  1.5424 +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
  1.5425 +{
  1.5426 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.5427 +  const XML_Char *name;
  1.5428 +  for (name = elementType->name; *name; name++) {
  1.5429 +    if (*name == XML_T(':')) {
  1.5430 +      PREFIX *prefix;
  1.5431 +      const XML_Char *s;
  1.5432 +      for (s = elementType->name; s != name; s++) {
  1.5433 +        if (!poolAppendChar(&dtd->pool, *s))
  1.5434 +          return 0;
  1.5435 +      }
  1.5436 +      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
  1.5437 +        return 0;
  1.5438 +      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
  1.5439 +                                sizeof(PREFIX));
  1.5440 +      if (!prefix)
  1.5441 +        return 0;
  1.5442 +      if (prefix->name == poolStart(&dtd->pool))
  1.5443 +        poolFinish(&dtd->pool);
  1.5444 +      else
  1.5445 +        poolDiscard(&dtd->pool);
  1.5446 +      elementType->prefix = prefix;
  1.5447 +
  1.5448 +    }
  1.5449 +  }
  1.5450 +  return 1;
  1.5451 +}
  1.5452 +
  1.5453 +static ATTRIBUTE_ID *
  1.5454 +getAttributeId(XML_Parser parser, const ENCODING *enc,
  1.5455 +               const char *start, const char *end)
  1.5456 +{
  1.5457 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.5458 +  ATTRIBUTE_ID *id;
  1.5459 +  const XML_Char *name;
  1.5460 +  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
  1.5461 +    return NULL;
  1.5462 +  name = poolStoreString(&dtd->pool, enc, start, end);
  1.5463 +  if (!name)
  1.5464 +    return NULL;
  1.5465 +  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
  1.5466 +  ++name;
  1.5467 +  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
  1.5468 +  if (!id)
  1.5469 +    return NULL;
  1.5470 +  if (id->name != name)
  1.5471 +    poolDiscard(&dtd->pool);
  1.5472 +  else {
  1.5473 +    poolFinish(&dtd->pool);
  1.5474 +    if (!ns)
  1.5475 +      ;
  1.5476 +    else if (name[0] == XML_T('x')
  1.5477 +        && name[1] == XML_T('m')
  1.5478 +        && name[2] == XML_T('l')
  1.5479 +        && name[3] == XML_T('n')
  1.5480 +        && name[4] == XML_T('s')
  1.5481 +        && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
  1.5482 +      if (name[5] == XML_T('\0'))
  1.5483 +        id->prefix = &dtd->defaultPrefix;
  1.5484 +      else
  1.5485 +        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
  1.5486 +      id->xmlns = XML_TRUE;
  1.5487 +    }
  1.5488 +    else {
  1.5489 +      int i;
  1.5490 +      for (i = 0; name[i]; i++) {
  1.5491 +        /* attributes without prefix are *not* in the default namespace */
  1.5492 +        if (name[i] == XML_T(':')) {
  1.5493 +          int j;
  1.5494 +          for (j = 0; j < i; j++) {
  1.5495 +            if (!poolAppendChar(&dtd->pool, name[j]))
  1.5496 +              return NULL;
  1.5497 +          }
  1.5498 +          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
  1.5499 +            return NULL;
  1.5500 +          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
  1.5501 +                                        sizeof(PREFIX));
  1.5502 +          if (id->prefix->name == poolStart(&dtd->pool))
  1.5503 +            poolFinish(&dtd->pool);
  1.5504 +          else
  1.5505 +            poolDiscard(&dtd->pool);
  1.5506 +          break;
  1.5507 +        }
  1.5508 +      }
  1.5509 +    }
  1.5510 +  }
  1.5511 +  return id;
  1.5512 +}
  1.5513 +
  1.5514 +#define CONTEXT_SEP XML_T('\f')
  1.5515 +
  1.5516 +static const XML_Char *
  1.5517 +getContext(XML_Parser parser)
  1.5518 +{
  1.5519 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.5520 +  HASH_TABLE_ITER iter;
  1.5521 +  XML_Bool needSep = XML_FALSE;
  1.5522 +
  1.5523 +  if (dtd->defaultPrefix.binding) {
  1.5524 +    int i;
  1.5525 +    int len;
  1.5526 +    if (!poolAppendChar(&tempPool, XML_T('=')))
  1.5527 +      return NULL;
  1.5528 +    len = dtd->defaultPrefix.binding->uriLen;
  1.5529 +    if (namespaceSeparator)
  1.5530 +      len--;
  1.5531 +    for (i = 0; i < len; i++)
  1.5532 +      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
  1.5533 +        return NULL;
  1.5534 +    needSep = XML_TRUE;
  1.5535 +  }
  1.5536 +
  1.5537 +  hashTableIterInit(&iter, &(dtd->prefixes));
  1.5538 +  for (;;) {
  1.5539 +    int i;
  1.5540 +    int len;
  1.5541 +    const XML_Char *s;
  1.5542 +    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
  1.5543 +    if (!prefix)
  1.5544 +      break;
  1.5545 +    if (!prefix->binding)
  1.5546 +      continue;
  1.5547 +    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
  1.5548 +      return NULL;
  1.5549 +    for (s = prefix->name; *s; s++)
  1.5550 +      if (!poolAppendChar(&tempPool, *s))
  1.5551 +        return NULL;
  1.5552 +    if (!poolAppendChar(&tempPool, XML_T('=')))
  1.5553 +      return NULL;
  1.5554 +    len = prefix->binding->uriLen;
  1.5555 +    if (namespaceSeparator)
  1.5556 +      len--;
  1.5557 +    for (i = 0; i < len; i++)
  1.5558 +      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
  1.5559 +        return NULL;
  1.5560 +    needSep = XML_TRUE;
  1.5561 +  }
  1.5562 +
  1.5563 +
  1.5564 +  hashTableIterInit(&iter, &(dtd->generalEntities));
  1.5565 +  for (;;) {
  1.5566 +    const XML_Char *s;
  1.5567 +    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
  1.5568 +    if (!e)
  1.5569 +      break;
  1.5570 +    if (!e->open)
  1.5571 +      continue;
  1.5572 +    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
  1.5573 +      return NULL;
  1.5574 +    for (s = e->name; *s; s++)
  1.5575 +      if (!poolAppendChar(&tempPool, *s))
  1.5576 +        return 0;
  1.5577 +    needSep = XML_TRUE;
  1.5578 +  }
  1.5579 +
  1.5580 +  if (!poolAppendChar(&tempPool, XML_T('\0')))
  1.5581 +    return NULL;
  1.5582 +  return tempPool.start;
  1.5583 +}
  1.5584 +
  1.5585 +static XML_Bool
  1.5586 +setContext(XML_Parser parser, const XML_Char *context)
  1.5587 +{
  1.5588 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.5589 +  const XML_Char *s = context;
  1.5590 +
  1.5591 +  while (*context != XML_T('\0')) {
  1.5592 +    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
  1.5593 +      ENTITY *e;
  1.5594 +      if (!poolAppendChar(&tempPool, XML_T('\0')))
  1.5595 +        return XML_FALSE;
  1.5596 +      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
  1.5597 +      if (e)
  1.5598 +        e->open = XML_TRUE;
  1.5599 +      if (*s != XML_T('\0'))
  1.5600 +        s++;
  1.5601 +      context = s;
  1.5602 +      poolDiscard(&tempPool);
  1.5603 +    }
  1.5604 +    else if (*s == XML_T('=')) {
  1.5605 +      PREFIX *prefix;
  1.5606 +      if (poolLength(&tempPool) == 0)
  1.5607 +        prefix = &dtd->defaultPrefix;
  1.5608 +      else {
  1.5609 +        if (!poolAppendChar(&tempPool, XML_T('\0')))
  1.5610 +          return XML_FALSE;
  1.5611 +        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
  1.5612 +                                  sizeof(PREFIX));
  1.5613 +        if (!prefix)
  1.5614 +          return XML_FALSE;
  1.5615 +        if (prefix->name == poolStart(&tempPool)) {
  1.5616 +          prefix->name = poolCopyString(&dtd->pool, prefix->name);
  1.5617 +          if (!prefix->name)
  1.5618 +            return XML_FALSE;
  1.5619 +        }
  1.5620 +        poolDiscard(&tempPool);
  1.5621 +      }
  1.5622 +      for (context = s + 1;
  1.5623 +           *context != CONTEXT_SEP && *context != XML_T('\0');
  1.5624 +           context++)
  1.5625 +        if (!poolAppendChar(&tempPool, *context))
  1.5626 +          return XML_FALSE;
  1.5627 +      if (!poolAppendChar(&tempPool, XML_T('\0')))
  1.5628 +        return XML_FALSE;
  1.5629 +      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
  1.5630 +                     &inheritedBindings) != XML_ERROR_NONE)
  1.5631 +        return XML_FALSE;
  1.5632 +      poolDiscard(&tempPool);
  1.5633 +      if (*context != XML_T('\0'))
  1.5634 +        ++context;
  1.5635 +      s = context;
  1.5636 +    }
  1.5637 +    else {
  1.5638 +      if (!poolAppendChar(&tempPool, *s))
  1.5639 +        return XML_FALSE;
  1.5640 +      s++;
  1.5641 +    }
  1.5642 +  }
  1.5643 +  return XML_TRUE;
  1.5644 +}
  1.5645 +
  1.5646 +static void FASTCALL
  1.5647 +normalizePublicId(XML_Char *publicId)
  1.5648 +{
  1.5649 +  XML_Char *p = publicId;
  1.5650 +  XML_Char *s;
  1.5651 +  for (s = publicId; *s; s++) {
  1.5652 +    switch (*s) {
  1.5653 +    case 0x20:
  1.5654 +    case 0xD:
  1.5655 +    case 0xA:
  1.5656 +      if (p != publicId && p[-1] != 0x20)
  1.5657 +        *p++ = 0x20;
  1.5658 +      break;
  1.5659 +    default:
  1.5660 +      *p++ = *s;
  1.5661 +    }
  1.5662 +  }
  1.5663 +  if (p != publicId && p[-1] == 0x20)
  1.5664 +    --p;
  1.5665 +  *p = XML_T('\0');
  1.5666 +}
  1.5667 +
  1.5668 +static DTD *
  1.5669 +dtdCreate(const XML_Memory_Handling_Suite *ms)
  1.5670 +{
  1.5671 +  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
  1.5672 +  if (p == NULL)
  1.5673 +    return p;
  1.5674 +  poolInit(&(p->pool), ms);
  1.5675 +  poolInit(&(p->entityValuePool), ms);
  1.5676 +  hashTableInit(&(p->generalEntities), ms);
  1.5677 +  hashTableInit(&(p->elementTypes), ms);
  1.5678 +  hashTableInit(&(p->attributeIds), ms);
  1.5679 +  hashTableInit(&(p->prefixes), ms);
  1.5680 +#ifdef XML_DTD
  1.5681 +  p->paramEntityRead = XML_FALSE;
  1.5682 +  hashTableInit(&(p->paramEntities), ms);
  1.5683 +#endif /* XML_DTD */
  1.5684 +  p->defaultPrefix.name = NULL;
  1.5685 +  p->defaultPrefix.binding = NULL;
  1.5686 +
  1.5687 +  p->in_eldecl = XML_FALSE;
  1.5688 +  p->scaffIndex = NULL;
  1.5689 +  p->scaffold = NULL;
  1.5690 +  p->scaffLevel = 0;
  1.5691 +  p->scaffSize = 0;
  1.5692 +  p->scaffCount = 0;
  1.5693 +  p->contentStringLen = 0;
  1.5694 +
  1.5695 +  p->keepProcessing = XML_TRUE;
  1.5696 +  p->hasParamEntityRefs = XML_FALSE;
  1.5697 +  p->standalone = XML_FALSE;
  1.5698 +  return p;
  1.5699 +}
  1.5700 +
  1.5701 +static void
  1.5702 +dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
  1.5703 +{
  1.5704 +  HASH_TABLE_ITER iter;
  1.5705 +  hashTableIterInit(&iter, &(p->elementTypes));
  1.5706 +  for (;;) {
  1.5707 +    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  1.5708 +    if (!e)
  1.5709 +      break;
  1.5710 +    if (e->allocDefaultAtts != 0)
  1.5711 +      ms->free_fcn(e->defaultAtts);
  1.5712 +  }
  1.5713 +  hashTableClear(&(p->generalEntities));
  1.5714 +#ifdef XML_DTD
  1.5715 +  p->paramEntityRead = XML_FALSE;
  1.5716 +  hashTableClear(&(p->paramEntities));
  1.5717 +#endif /* XML_DTD */
  1.5718 +  hashTableClear(&(p->elementTypes));
  1.5719 +  hashTableClear(&(p->attributeIds));
  1.5720 +  hashTableClear(&(p->prefixes));
  1.5721 +  poolClear(&(p->pool));
  1.5722 +  poolClear(&(p->entityValuePool));
  1.5723 +  p->defaultPrefix.name = NULL;
  1.5724 +  p->defaultPrefix.binding = NULL;
  1.5725 +
  1.5726 +  p->in_eldecl = XML_FALSE;
  1.5727 +
  1.5728 +  ms->free_fcn(p->scaffIndex);
  1.5729 +  p->scaffIndex = NULL;
  1.5730 +  ms->free_fcn(p->scaffold);
  1.5731 +  p->scaffold = NULL;
  1.5732 +
  1.5733 +  p->scaffLevel = 0;
  1.5734 +  p->scaffSize = 0;
  1.5735 +  p->scaffCount = 0;
  1.5736 +  p->contentStringLen = 0;
  1.5737 +
  1.5738 +  p->keepProcessing = XML_TRUE;
  1.5739 +  p->hasParamEntityRefs = XML_FALSE;
  1.5740 +  p->standalone = XML_FALSE;
  1.5741 +}
  1.5742 +
  1.5743 +static void
  1.5744 +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
  1.5745 +{
  1.5746 +  HASH_TABLE_ITER iter;
  1.5747 +  hashTableIterInit(&iter, &(p->elementTypes));
  1.5748 +  for (;;) {
  1.5749 +    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  1.5750 +    if (!e)
  1.5751 +      break;
  1.5752 +    if (e->allocDefaultAtts != 0)
  1.5753 +      ms->free_fcn(e->defaultAtts);
  1.5754 +  }
  1.5755 +  hashTableDestroy(&(p->generalEntities));
  1.5756 +#ifdef XML_DTD
  1.5757 +  hashTableDestroy(&(p->paramEntities));
  1.5758 +#endif /* XML_DTD */
  1.5759 +  hashTableDestroy(&(p->elementTypes));
  1.5760 +  hashTableDestroy(&(p->attributeIds));
  1.5761 +  hashTableDestroy(&(p->prefixes));
  1.5762 +  poolDestroy(&(p->pool));
  1.5763 +  poolDestroy(&(p->entityValuePool));
  1.5764 +  if (isDocEntity) {
  1.5765 +    ms->free_fcn(p->scaffIndex);
  1.5766 +    ms->free_fcn(p->scaffold);
  1.5767 +  }
  1.5768 +  ms->free_fcn(p);
  1.5769 +}
  1.5770 +
  1.5771 +/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
  1.5772 +   The new DTD has already been initialized.
  1.5773 +*/
  1.5774 +static int
  1.5775 +dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
  1.5776 +{
  1.5777 +  HASH_TABLE_ITER iter;
  1.5778 +
  1.5779 +  /* Copy the prefix table. */
  1.5780 +
  1.5781 +  hashTableIterInit(&iter, &(oldDtd->prefixes));
  1.5782 +  for (;;) {
  1.5783 +    const XML_Char *name;
  1.5784 +    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
  1.5785 +    if (!oldP)
  1.5786 +      break;
  1.5787 +    name = poolCopyString(&(newDtd->pool), oldP->name);
  1.5788 +    if (!name)
  1.5789 +      return 0;
  1.5790 +    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
  1.5791 +      return 0;
  1.5792 +  }
  1.5793 +
  1.5794 +  hashTableIterInit(&iter, &(oldDtd->attributeIds));
  1.5795 +
  1.5796 +  /* Copy the attribute id table. */
  1.5797 +
  1.5798 +  for (;;) {
  1.5799 +    ATTRIBUTE_ID *newA;
  1.5800 +    const XML_Char *name;
  1.5801 +    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
  1.5802 +
  1.5803 +    if (!oldA)
  1.5804 +      break;
  1.5805 +    /* Remember to allocate the scratch byte before the name. */
  1.5806 +    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
  1.5807 +      return 0;
  1.5808 +    name = poolCopyString(&(newDtd->pool), oldA->name);
  1.5809 +    if (!name)
  1.5810 +      return 0;
  1.5811 +    ++name;
  1.5812 +    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
  1.5813 +                                  sizeof(ATTRIBUTE_ID));
  1.5814 +    if (!newA)
  1.5815 +      return 0;
  1.5816 +    newA->maybeTokenized = oldA->maybeTokenized;
  1.5817 +    if (oldA->prefix) {
  1.5818 +      newA->xmlns = oldA->xmlns;
  1.5819 +      if (oldA->prefix == &oldDtd->defaultPrefix)
  1.5820 +        newA->prefix = &newDtd->defaultPrefix;
  1.5821 +      else
  1.5822 +        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
  1.5823 +                                        oldA->prefix->name, 0);
  1.5824 +    }
  1.5825 +  }
  1.5826 +
  1.5827 +  /* Copy the element type table. */
  1.5828 +
  1.5829 +  hashTableIterInit(&iter, &(oldDtd->elementTypes));
  1.5830 +
  1.5831 +  for (;;) {
  1.5832 +    int i;
  1.5833 +    ELEMENT_TYPE *newE;
  1.5834 +    const XML_Char *name;
  1.5835 +    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  1.5836 +    if (!oldE)
  1.5837 +      break;
  1.5838 +    name = poolCopyString(&(newDtd->pool), oldE->name);
  1.5839 +    if (!name)
  1.5840 +      return 0;
  1.5841 +    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
  1.5842 +                                  sizeof(ELEMENT_TYPE));
  1.5843 +    if (!newE)
  1.5844 +      return 0;
  1.5845 +    if (oldE->nDefaultAtts) {
  1.5846 +      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
  1.5847 +          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
  1.5848 +      if (!newE->defaultAtts) {
  1.5849 +        ms->free_fcn(newE);
  1.5850 +        return 0;
  1.5851 +      }
  1.5852 +    }
  1.5853 +    if (oldE->idAtt)
  1.5854 +      newE->idAtt = (ATTRIBUTE_ID *)
  1.5855 +          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
  1.5856 +    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
  1.5857 +    if (oldE->prefix)
  1.5858 +      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
  1.5859 +                                      oldE->prefix->name, 0);
  1.5860 +    for (i = 0; i < newE->nDefaultAtts; i++) {
  1.5861 +      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
  1.5862 +          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
  1.5863 +      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
  1.5864 +      if (oldE->defaultAtts[i].value) {
  1.5865 +        newE->defaultAtts[i].value
  1.5866 +            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
  1.5867 +        if (!newE->defaultAtts[i].value)
  1.5868 +          return 0;
  1.5869 +      }
  1.5870 +      else
  1.5871 +        newE->defaultAtts[i].value = NULL;
  1.5872 +    }
  1.5873 +  }
  1.5874 +
  1.5875 +  /* Copy the entity tables. */
  1.5876 +  if (!copyEntityTable(&(newDtd->generalEntities),
  1.5877 +                       &(newDtd->pool),
  1.5878 +                       &(oldDtd->generalEntities)))
  1.5879 +      return 0;
  1.5880 +
  1.5881 +#ifdef XML_DTD
  1.5882 +  if (!copyEntityTable(&(newDtd->paramEntities),
  1.5883 +                       &(newDtd->pool),
  1.5884 +                       &(oldDtd->paramEntities)))
  1.5885 +      return 0;
  1.5886 +  newDtd->paramEntityRead = oldDtd->paramEntityRead;
  1.5887 +#endif /* XML_DTD */
  1.5888 +
  1.5889 +  newDtd->keepProcessing = oldDtd->keepProcessing;
  1.5890 +  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
  1.5891 +  newDtd->standalone = oldDtd->standalone;
  1.5892 +
  1.5893 +  /* Don't want deep copying for scaffolding */
  1.5894 +  newDtd->in_eldecl = oldDtd->in_eldecl;
  1.5895 +  newDtd->scaffold = oldDtd->scaffold;
  1.5896 +  newDtd->contentStringLen = oldDtd->contentStringLen;
  1.5897 +  newDtd->scaffSize = oldDtd->scaffSize;
  1.5898 +  newDtd->scaffLevel = oldDtd->scaffLevel;
  1.5899 +  newDtd->scaffIndex = oldDtd->scaffIndex;
  1.5900 +
  1.5901 +  return 1;
  1.5902 +}  /* End dtdCopy */
  1.5903 +
  1.5904 +static int
  1.5905 +copyEntityTable(HASH_TABLE *newTable,
  1.5906 +                STRING_POOL *newPool,
  1.5907 +                const HASH_TABLE *oldTable)
  1.5908 +{
  1.5909 +  HASH_TABLE_ITER iter;
  1.5910 +  const XML_Char *cachedOldBase = NULL;
  1.5911 +  const XML_Char *cachedNewBase = NULL;
  1.5912 +
  1.5913 +  hashTableIterInit(&iter, oldTable);
  1.5914 +
  1.5915 +  for (;;) {
  1.5916 +    ENTITY *newE;
  1.5917 +    const XML_Char *name;
  1.5918 +    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
  1.5919 +    if (!oldE)
  1.5920 +      break;
  1.5921 +    name = poolCopyString(newPool, oldE->name);
  1.5922 +    if (!name)
  1.5923 +      return 0;
  1.5924 +    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
  1.5925 +    if (!newE)
  1.5926 +      return 0;
  1.5927 +    if (oldE->systemId) {
  1.5928 +      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
  1.5929 +      if (!tem)
  1.5930 +        return 0;
  1.5931 +      newE->systemId = tem;
  1.5932 +      if (oldE->base) {
  1.5933 +        if (oldE->base == cachedOldBase)
  1.5934 +          newE->base = cachedNewBase;
  1.5935 +        else {
  1.5936 +          cachedOldBase = oldE->base;
  1.5937 +          tem = poolCopyString(newPool, cachedOldBase);
  1.5938 +          if (!tem)
  1.5939 +            return 0;
  1.5940 +          cachedNewBase = newE->base = tem;
  1.5941 +        }
  1.5942 +      }
  1.5943 +      if (oldE->publicId) {
  1.5944 +        tem = poolCopyString(newPool, oldE->publicId);
  1.5945 +        if (!tem)
  1.5946 +          return 0;
  1.5947 +        newE->publicId = tem;
  1.5948 +      }
  1.5949 +    }
  1.5950 +    else {
  1.5951 +      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
  1.5952 +                                            oldE->textLen);
  1.5953 +      if (!tem)
  1.5954 +        return 0;
  1.5955 +      newE->textPtr = tem;
  1.5956 +      newE->textLen = oldE->textLen;
  1.5957 +    }
  1.5958 +    if (oldE->notation) {
  1.5959 +      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
  1.5960 +      if (!tem)
  1.5961 +        return 0;
  1.5962 +      newE->notation = tem;
  1.5963 +    }
  1.5964 +    newE->is_param = oldE->is_param;
  1.5965 +    newE->is_internal = oldE->is_internal;
  1.5966 +  }
  1.5967 +  return 1;
  1.5968 +}
  1.5969 +
  1.5970 +#define INIT_POWER 6
  1.5971 +
  1.5972 +static XML_Bool FASTCALL
  1.5973 +keyeq(KEY s1, KEY s2)
  1.5974 +{
  1.5975 +  for (; *s1 == *s2; s1++, s2++)
  1.5976 +    if (*s1 == 0)
  1.5977 +      return XML_TRUE;
  1.5978 +  return XML_FALSE;
  1.5979 +}
  1.5980 +
  1.5981 +static unsigned long FASTCALL
  1.5982 +hash(KEY s)
  1.5983 +{
  1.5984 +  unsigned long h = 0;
  1.5985 +  while (*s)
  1.5986 +    h = CHAR_HASH(h, *s++);
  1.5987 +  return h;
  1.5988 +}
  1.5989 +
  1.5990 +static NAMED *
  1.5991 +lookup(HASH_TABLE *table, KEY name, size_t createSize)
  1.5992 +{
  1.5993 +  size_t i;
  1.5994 +  if (table->size == 0) {
  1.5995 +    size_t tsize;
  1.5996 +    if (!createSize)
  1.5997 +      return NULL;
  1.5998 +    table->power = INIT_POWER;
  1.5999 +    /* table->size is a power of 2 */
  1.6000 +    table->size = (size_t)1 << INIT_POWER;
  1.6001 +    tsize = table->size * sizeof(NAMED *);
  1.6002 +    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
  1.6003 +    if (!table->v) {
  1.6004 +      table->size = 0;
  1.6005 +      return NULL;
  1.6006 +    }
  1.6007 +    memset(table->v, 0, tsize);
  1.6008 +    i = hash(name) & ((unsigned long)table->size - 1);
  1.6009 +  }
  1.6010 +  else {
  1.6011 +    unsigned long h = hash(name);
  1.6012 +    unsigned long mask = (unsigned long)table->size - 1;
  1.6013 +    unsigned char step = 0;
  1.6014 +    i = h & mask;
  1.6015 +    while (table->v[i]) {
  1.6016 +      if (keyeq(name, table->v[i]->name))
  1.6017 +        return table->v[i];
  1.6018 +      if (!step)
  1.6019 +        step = PROBE_STEP(h, mask, table->power);
  1.6020 +      i < step ? (i += table->size - step) : (i -= step);
  1.6021 +    }
  1.6022 +    if (!createSize)
  1.6023 +      return NULL;
  1.6024 +
  1.6025 +    /* check for overflow (table is half full) */
  1.6026 +    if (table->used >> (table->power - 1)) {
  1.6027 +      unsigned char newPower = table->power + 1;
  1.6028 +      size_t newSize = (size_t)1 << newPower;
  1.6029 +      unsigned long newMask = (unsigned long)newSize - 1;
  1.6030 +      size_t tsize = newSize * sizeof(NAMED *);
  1.6031 +      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
  1.6032 +      if (!newV)
  1.6033 +        return NULL;
  1.6034 +      memset(newV, 0, tsize);
  1.6035 +      for (i = 0; i < table->size; i++)
  1.6036 +        if (table->v[i]) {
  1.6037 +          unsigned long newHash = hash(table->v[i]->name);
  1.6038 +          size_t j = newHash & newMask;
  1.6039 +          step = 0;
  1.6040 +          while (newV[j]) {
  1.6041 +            if (!step)
  1.6042 +              step = PROBE_STEP(newHash, newMask, newPower);
  1.6043 +            j < step ? (j += newSize - step) : (j -= step);
  1.6044 +          }
  1.6045 +          newV[j] = table->v[i];
  1.6046 +        }
  1.6047 +      table->mem->free_fcn(table->v);
  1.6048 +      table->v = newV;
  1.6049 +      table->power = newPower;
  1.6050 +      table->size = newSize;
  1.6051 +      i = h & newMask;
  1.6052 +      step = 0;
  1.6053 +      while (table->v[i]) {
  1.6054 +        if (!step)
  1.6055 +          step = PROBE_STEP(h, newMask, newPower);
  1.6056 +        i < step ? (i += newSize - step) : (i -= step);
  1.6057 +      }
  1.6058 +    }
  1.6059 +  }
  1.6060 +  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
  1.6061 +  if (!table->v[i])
  1.6062 +    return NULL;
  1.6063 +  memset(table->v[i], 0, createSize);
  1.6064 +  table->v[i]->name = name;
  1.6065 +  (table->used)++;
  1.6066 +  return table->v[i];
  1.6067 +}
  1.6068 +
  1.6069 +static void FASTCALL
  1.6070 +hashTableClear(HASH_TABLE *table)
  1.6071 +{
  1.6072 +  size_t i;
  1.6073 +  for (i = 0; i < table->size; i++) {
  1.6074 +    table->mem->free_fcn(table->v[i]);
  1.6075 +    table->v[i] = NULL;
  1.6076 +  }
  1.6077 +  table->used = 0;
  1.6078 +}
  1.6079 +
  1.6080 +static void FASTCALL
  1.6081 +hashTableDestroy(HASH_TABLE *table)
  1.6082 +{
  1.6083 +  size_t i;
  1.6084 +  for (i = 0; i < table->size; i++)
  1.6085 +    table->mem->free_fcn(table->v[i]);
  1.6086 +  table->mem->free_fcn(table->v);
  1.6087 +}
  1.6088 +
  1.6089 +static void FASTCALL
  1.6090 +hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
  1.6091 +{
  1.6092 +  p->power = 0;
  1.6093 +  p->size = 0;
  1.6094 +  p->used = 0;
  1.6095 +  p->v = NULL;
  1.6096 +  p->mem = ms;
  1.6097 +}
  1.6098 +
  1.6099 +static void FASTCALL
  1.6100 +hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
  1.6101 +{
  1.6102 +  iter->p = table->v;
  1.6103 +  iter->end = iter->p + table->size;
  1.6104 +}
  1.6105 +
  1.6106 +static NAMED * FASTCALL
  1.6107 +hashTableIterNext(HASH_TABLE_ITER *iter)
  1.6108 +{
  1.6109 +  while (iter->p != iter->end) {
  1.6110 +    NAMED *tem = *(iter->p)++;
  1.6111 +    if (tem)
  1.6112 +      return tem;
  1.6113 +  }
  1.6114 +  return NULL;
  1.6115 +}
  1.6116 +
  1.6117 +static void FASTCALL
  1.6118 +poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
  1.6119 +{
  1.6120 +  pool->blocks = NULL;
  1.6121 +  pool->freeBlocks = NULL;
  1.6122 +  pool->start = NULL;
  1.6123 +  pool->ptr = NULL;
  1.6124 +  pool->end = NULL;
  1.6125 +  pool->mem = ms;
  1.6126 +}
  1.6127 +
  1.6128 +static void FASTCALL
  1.6129 +poolClear(STRING_POOL *pool)
  1.6130 +{
  1.6131 +  if (!pool->freeBlocks)
  1.6132 +    pool->freeBlocks = pool->blocks;
  1.6133 +  else {
  1.6134 +    BLOCK *p = pool->blocks;
  1.6135 +    while (p) {
  1.6136 +      BLOCK *tem = p->next;
  1.6137 +      p->next = pool->freeBlocks;
  1.6138 +      pool->freeBlocks = p;
  1.6139 +      p = tem;
  1.6140 +    }
  1.6141 +  }
  1.6142 +  pool->blocks = NULL;
  1.6143 +  pool->start = NULL;
  1.6144 +  pool->ptr = NULL;
  1.6145 +  pool->end = NULL;
  1.6146 +}
  1.6147 +
  1.6148 +static void FASTCALL
  1.6149 +poolDestroy(STRING_POOL *pool)
  1.6150 +{
  1.6151 +  BLOCK *p = pool->blocks;
  1.6152 +  while (p) {
  1.6153 +    BLOCK *tem = p->next;
  1.6154 +    pool->mem->free_fcn(p);
  1.6155 +    p = tem;
  1.6156 +  }
  1.6157 +  p = pool->freeBlocks;
  1.6158 +  while (p) {
  1.6159 +    BLOCK *tem = p->next;
  1.6160 +    pool->mem->free_fcn(p);
  1.6161 +    p = tem;
  1.6162 +  }
  1.6163 +}
  1.6164 +
  1.6165 +static XML_Char *
  1.6166 +poolAppend(STRING_POOL *pool, const ENCODING *enc,
  1.6167 +           const char *ptr, const char *end)
  1.6168 +{
  1.6169 +  if (!pool->ptr && !poolGrow(pool))
  1.6170 +    return NULL;
  1.6171 +  for (;;) {
  1.6172 +    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
  1.6173 +    if (ptr == end)
  1.6174 +      break;
  1.6175 +    if (!poolGrow(pool))
  1.6176 +      return NULL;
  1.6177 +  }
  1.6178 +  return pool->start;
  1.6179 +}
  1.6180 +
  1.6181 +static const XML_Char * FASTCALL
  1.6182 +poolCopyString(STRING_POOL *pool, const XML_Char *s)
  1.6183 +{
  1.6184 +  do {
  1.6185 +    if (!poolAppendChar(pool, *s))
  1.6186 +      return NULL;
  1.6187 +  } while (*s++);
  1.6188 +  s = pool->start;
  1.6189 +  poolFinish(pool);
  1.6190 +  return s;
  1.6191 +}
  1.6192 +
  1.6193 +static const XML_Char *
  1.6194 +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
  1.6195 +{
  1.6196 +  if (!pool->ptr && !poolGrow(pool))
  1.6197 +    return NULL;
  1.6198 +  for (; n > 0; --n, s++) {
  1.6199 +    if (!poolAppendChar(pool, *s))
  1.6200 +      return NULL;
  1.6201 +  }
  1.6202 +  s = pool->start;
  1.6203 +  poolFinish(pool);
  1.6204 +  return s;
  1.6205 +}
  1.6206 +
  1.6207 +static const XML_Char * FASTCALL
  1.6208 +poolAppendString(STRING_POOL *pool, const XML_Char *s)
  1.6209 +{
  1.6210 +  while (*s) {
  1.6211 +    if (!poolAppendChar(pool, *s))
  1.6212 +      return NULL;
  1.6213 +    s++;
  1.6214 +  }
  1.6215 +  return pool->start;
  1.6216 +}
  1.6217 +
  1.6218 +static XML_Char *
  1.6219 +poolStoreString(STRING_POOL *pool, const ENCODING *enc,
  1.6220 +                const char *ptr, const char *end)
  1.6221 +{
  1.6222 +  if (!poolAppend(pool, enc, ptr, end))
  1.6223 +    return NULL;
  1.6224 +  if (pool->ptr == pool->end && !poolGrow(pool))
  1.6225 +    return NULL;
  1.6226 +  *(pool->ptr)++ = 0;
  1.6227 +  return pool->start;
  1.6228 +}
  1.6229 +
  1.6230 +static XML_Bool FASTCALL
  1.6231 +poolGrow(STRING_POOL *pool)
  1.6232 +{
  1.6233 +  if (pool->freeBlocks) {
  1.6234 +    if (pool->start == 0) {
  1.6235 +      pool->blocks = pool->freeBlocks;
  1.6236 +      pool->freeBlocks = pool->freeBlocks->next;
  1.6237 +      pool->blocks->next = NULL;
  1.6238 +      pool->start = pool->blocks->s;
  1.6239 +      pool->end = pool->start + pool->blocks->size;
  1.6240 +      pool->ptr = pool->start;
  1.6241 +      return XML_TRUE;
  1.6242 +    }
  1.6243 +    if (pool->end - pool->start < pool->freeBlocks->size) {
  1.6244 +      BLOCK *tem = pool->freeBlocks->next;
  1.6245 +      pool->freeBlocks->next = pool->blocks;
  1.6246 +      pool->blocks = pool->freeBlocks;
  1.6247 +      pool->freeBlocks = tem;
  1.6248 +      memcpy(pool->blocks->s, pool->start,
  1.6249 +             (pool->end - pool->start) * sizeof(XML_Char));
  1.6250 +      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  1.6251 +      pool->start = pool->blocks->s;
  1.6252 +      pool->end = pool->start + pool->blocks->size;
  1.6253 +      return XML_TRUE;
  1.6254 +    }
  1.6255 +  }
  1.6256 +  if (pool->blocks && pool->start == pool->blocks->s) {
  1.6257 +    int blockSize = (int)(pool->end - pool->start)*2;
  1.6258 +    pool->blocks = (BLOCK *)
  1.6259 +      pool->mem->realloc_fcn(pool->blocks,
  1.6260 +                             (offsetof(BLOCK, s)
  1.6261 +                              + blockSize * sizeof(XML_Char)));
  1.6262 +    if (pool->blocks == NULL)
  1.6263 +      return XML_FALSE;
  1.6264 +    pool->blocks->size = blockSize;
  1.6265 +    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  1.6266 +    pool->start = pool->blocks->s;
  1.6267 +    pool->end = pool->start + blockSize;
  1.6268 +  }
  1.6269 +  else {
  1.6270 +    BLOCK *tem;
  1.6271 +    int blockSize = (int)(pool->end - pool->start);
  1.6272 +    if (blockSize < INIT_BLOCK_SIZE)
  1.6273 +      blockSize = INIT_BLOCK_SIZE;
  1.6274 +    else
  1.6275 +      blockSize *= 2;
  1.6276 +    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
  1.6277 +                                        + blockSize * sizeof(XML_Char));
  1.6278 +    if (!tem)
  1.6279 +      return XML_FALSE;
  1.6280 +    tem->size = blockSize;
  1.6281 +    tem->next = pool->blocks;
  1.6282 +    pool->blocks = tem;
  1.6283 +    if (pool->ptr != pool->start)
  1.6284 +      memcpy(tem->s, pool->start,
  1.6285 +             (pool->ptr - pool->start) * sizeof(XML_Char));
  1.6286 +    pool->ptr = tem->s + (pool->ptr - pool->start);
  1.6287 +    pool->start = tem->s;
  1.6288 +    pool->end = tem->s + blockSize;
  1.6289 +  }
  1.6290 +  return XML_TRUE;
  1.6291 +}
  1.6292 +
  1.6293 +static int FASTCALL
  1.6294 +nextScaffoldPart(XML_Parser parser)
  1.6295 +{
  1.6296 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.6297 +  CONTENT_SCAFFOLD * me;
  1.6298 +  int next;
  1.6299 +
  1.6300 +  if (!dtd->scaffIndex) {
  1.6301 +    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
  1.6302 +    if (!dtd->scaffIndex)
  1.6303 +      return -1;
  1.6304 +    dtd->scaffIndex[0] = 0;
  1.6305 +  }
  1.6306 +
  1.6307 +  if (dtd->scaffCount >= dtd->scaffSize) {
  1.6308 +    CONTENT_SCAFFOLD *temp;
  1.6309 +    if (dtd->scaffold) {
  1.6310 +      temp = (CONTENT_SCAFFOLD *)
  1.6311 +        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
  1.6312 +      if (temp == NULL)
  1.6313 +        return -1;
  1.6314 +      dtd->scaffSize *= 2;
  1.6315 +    }
  1.6316 +    else {
  1.6317 +      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
  1.6318 +                                        * sizeof(CONTENT_SCAFFOLD));
  1.6319 +      if (temp == NULL)
  1.6320 +        return -1;
  1.6321 +      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
  1.6322 +    }
  1.6323 +    dtd->scaffold = temp;
  1.6324 +  }
  1.6325 +  next = dtd->scaffCount++;
  1.6326 +  me = &dtd->scaffold[next];
  1.6327 +  if (dtd->scaffLevel) {
  1.6328 +    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
  1.6329 +    if (parent->lastchild) {
  1.6330 +      dtd->scaffold[parent->lastchild].nextsib = next;
  1.6331 +    }
  1.6332 +    if (!parent->childcnt)
  1.6333 +      parent->firstchild = next;
  1.6334 +    parent->lastchild = next;
  1.6335 +    parent->childcnt++;
  1.6336 +  }
  1.6337 +  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
  1.6338 +  return next;
  1.6339 +}
  1.6340 +
  1.6341 +static void
  1.6342 +build_node(XML_Parser parser,
  1.6343 +           int src_node,
  1.6344 +           XML_Content *dest,
  1.6345 +           XML_Content **contpos,
  1.6346 +           XML_Char **strpos)
  1.6347 +{
  1.6348 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.6349 +  dest->type = dtd->scaffold[src_node].type;
  1.6350 +  dest->quant = dtd->scaffold[src_node].quant;
  1.6351 +  if (dest->type == XML_CTYPE_NAME) {
  1.6352 +    const XML_Char *src;
  1.6353 +    dest->name = *strpos;
  1.6354 +    src = dtd->scaffold[src_node].name;
  1.6355 +    for (;;) {
  1.6356 +      *(*strpos)++ = *src;
  1.6357 +      if (!*src)
  1.6358 +        break;
  1.6359 +      src++;
  1.6360 +    }
  1.6361 +    dest->numchildren = 0;
  1.6362 +    dest->children = NULL;
  1.6363 +  }
  1.6364 +  else {
  1.6365 +    unsigned int i;
  1.6366 +    int cn;
  1.6367 +    dest->numchildren = dtd->scaffold[src_node].childcnt;
  1.6368 +    dest->children = *contpos;
  1.6369 +    *contpos += dest->numchildren;
  1.6370 +    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
  1.6371 +         i < dest->numchildren;
  1.6372 +         i++, cn = dtd->scaffold[cn].nextsib) {
  1.6373 +      build_node(parser, cn, &(dest->children[i]), contpos, strpos);
  1.6374 +    }
  1.6375 +    dest->name = NULL;
  1.6376 +  }
  1.6377 +}
  1.6378 +
  1.6379 +static XML_Content *
  1.6380 +build_model (XML_Parser parser)
  1.6381 +{
  1.6382 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.6383 +  XML_Content *ret;
  1.6384 +  XML_Content *cpos;
  1.6385 +  XML_Char * str;
  1.6386 +  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
  1.6387 +                   + (dtd->contentStringLen * sizeof(XML_Char)));
  1.6388 +
  1.6389 +  ret = (XML_Content *)MALLOC(allocsize);
  1.6390 +  if (!ret)
  1.6391 +    return NULL;
  1.6392 +
  1.6393 +  str =  (XML_Char *) (&ret[dtd->scaffCount]);
  1.6394 +  cpos = &ret[1];
  1.6395 +
  1.6396 +  build_node(parser, 0, ret, &cpos, &str);
  1.6397 +  return ret;
  1.6398 +}
  1.6399 +
  1.6400 +static ELEMENT_TYPE *
  1.6401 +getElementType(XML_Parser parser,
  1.6402 +               const ENCODING *enc,
  1.6403 +               const char *ptr,
  1.6404 +               const char *end)
  1.6405 +{
  1.6406 +  DTD * const dtd = _dtd;  /* save one level of indirection */
  1.6407 +  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
  1.6408 +  ELEMENT_TYPE *ret;
  1.6409 +
  1.6410 +  if (!name)
  1.6411 +    return NULL;
  1.6412 +  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
  1.6413 +  if (!ret)
  1.6414 +    return NULL;
  1.6415 +  if (ret->name != name)
  1.6416 +    poolDiscard(&dtd->pool);
  1.6417 +  else {
  1.6418 +    poolFinish(&dtd->pool);
  1.6419 +    if (!setElementTypePrefix(parser, ret))
  1.6420 +      return NULL;
  1.6421 +  }
  1.6422 +  return ret;
  1.6423 +}

mercurial