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