Merge branch 'vendor/EXPAT'
[dragonfly.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 #include <time.h>                       /* time() */
10
11 #define XML_BUILDING_EXPAT 1
12
13 #ifdef COMPILED_FROM_DSP
14 #include "winconfig.h"
15 #elif defined(MACOS_CLASSIC)
16 #include "macconfig.h"
17 #elif defined(__amigaos__)
18 #include "amigaconfig.h"
19 #elif defined(__WATCOMC__)
20 #include "watcomconfig.h"
21 #elif defined(HAVE_EXPAT_CONFIG_H)
22 #include <expat_config.h>
23 #endif /* ndef COMPILED_FROM_DSP */
24
25 #include "ascii.h"
26 #include "expat.h"
27
28 #ifdef XML_UNICODE
29 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30 #define XmlConvert XmlUtf16Convert
31 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
33 #define XmlEncode XmlUtf16Encode
34 /* Using pointer subtraction to convert to integer type. */
35 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
36 typedef unsigned short ICHAR;
37 #else
38 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
39 #define XmlConvert XmlUtf8Convert
40 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
41 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
42 #define XmlEncode XmlUtf8Encode
43 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
44 typedef char ICHAR;
45 #endif
46
47
48 #ifndef XML_NS
49
50 #define XmlInitEncodingNS XmlInitEncoding
51 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
52 #undef XmlGetInternalEncodingNS
53 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
54 #define XmlParseXmlDeclNS XmlParseXmlDecl
55
56 #endif
57
58 #ifdef XML_UNICODE
59
60 #ifdef XML_UNICODE_WCHAR_T
61 #define XML_T(x) (const wchar_t)x
62 #define XML_L(x) L ## x
63 #else
64 #define XML_T(x) (const unsigned short)x
65 #define XML_L(x) x
66 #endif
67
68 #else
69
70 #define XML_T(x) x
71 #define XML_L(x) x
72
73 #endif
74
75 /* Round up n to be a multiple of sz, where sz is a power of 2. */
76 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
77
78 /* Handle the case where memmove() doesn't exist. */
79 #ifndef HAVE_MEMMOVE
80 #ifdef HAVE_BCOPY
81 #define memmove(d,s,l) bcopy((s),(d),(l))
82 #else
83 #error memmove does not exist on this platform, nor is a substitute available
84 #endif /* HAVE_BCOPY */
85 #endif /* HAVE_MEMMOVE */
86
87 #include "internal.h"
88 #include "xmltok.h"
89 #include "xmlrole.h"
90
91 typedef const XML_Char *KEY;
92
93 typedef struct {
94   KEY name;
95 } NAMED;
96
97 typedef struct {
98   NAMED **v;
99   unsigned char power;
100   size_t size;
101   size_t used;
102   const XML_Memory_Handling_Suite *mem;
103 } HASH_TABLE;
104
105 /* Basic character hash algorithm, taken from Python's string hash:
106    h = h * 1000003 ^ character, the constant being a prime number.
107
108 */
109 #ifdef XML_UNICODE
110 #define CHAR_HASH(h, c) \
111   (((h) * 0xF4243) ^ (unsigned short)(c))
112 #else
113 #define CHAR_HASH(h, c) \
114   (((h) * 0xF4243) ^ (unsigned char)(c))
115 #endif
116
117 /* For probing (after a collision) we need a step size relative prime
118    to the hash table size, which is a power of 2. We use double-hashing,
119    since we can calculate a second hash value cheaply by taking those bits
120    of the first hash value that were discarded (masked out) when the table
121    index was calculated: index = hash & mask, where mask = table->size - 1.
122    We limit the maximum step size to table->size / 4 (mask >> 2) and make
123    it odd, since odd numbers are always relative prime to a power of 2.
124 */
125 #define SECOND_HASH(hash, mask, power) \
126   ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
127 #define PROBE_STEP(hash, mask, power) \
128   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
129
130 typedef struct {
131   NAMED **p;
132   NAMED **end;
133 } HASH_TABLE_ITER;
134
135 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
136 #define INIT_DATA_BUF_SIZE 1024
137 #define INIT_ATTS_SIZE 16
138 #define INIT_ATTS_VERSION 0xFFFFFFFF
139 #define INIT_BLOCK_SIZE 1024
140 #define INIT_BUFFER_SIZE 1024
141
142 #define EXPAND_SPARE 24
143
144 typedef struct binding {
145   struct prefix *prefix;
146   struct binding *nextTagBinding;
147   struct binding *prevPrefixBinding;
148   const struct attribute_id *attId;
149   XML_Char *uri;
150   int uriLen;
151   int uriAlloc;
152 } BINDING;
153
154 typedef struct prefix {
155   const XML_Char *name;
156   BINDING *binding;
157 } PREFIX;
158
159 typedef struct {
160   const XML_Char *str;
161   const XML_Char *localPart;
162   const XML_Char *prefix;
163   int strLen;
164   int uriLen;
165   int prefixLen;
166 } TAG_NAME;
167
168 /* TAG represents an open element.
169    The name of the element is stored in both the document and API
170    encodings.  The memory buffer 'buf' is a separately-allocated
171    memory area which stores the name.  During the XML_Parse()/
172    XMLParseBuffer() when the element is open, the memory for the 'raw'
173    version of the name (in the document encoding) is shared with the
174    document buffer.  If the element is open across calls to
175    XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
176    contain the 'raw' name as well.
177
178    A parser re-uses these structures, maintaining a list of allocated
179    TAG objects in a free list.
180 */
181 typedef struct tag {
182   struct tag *parent;           /* parent of this element */
183   const char *rawName;          /* tagName in the original encoding */
184   int rawNameLength;
185   TAG_NAME name;                /* tagName in the API encoding */
186   char *buf;                    /* buffer for name components */
187   char *bufEnd;                 /* end of the buffer */
188   BINDING *bindings;
189 } TAG;
190
191 typedef struct {
192   const XML_Char *name;
193   const XML_Char *textPtr;
194   int textLen;                  /* length in XML_Chars */
195   int processed;                /* # of processed bytes - when suspended */
196   const XML_Char *systemId;
197   const XML_Char *base;
198   const XML_Char *publicId;
199   const XML_Char *notation;
200   XML_Bool open;
201   XML_Bool is_param;
202   XML_Bool is_internal; /* true if declared in internal subset outside PE */
203 } ENTITY;
204
205 typedef struct {
206   enum XML_Content_Type         type;
207   enum XML_Content_Quant        quant;
208   const XML_Char *              name;
209   int                           firstchild;
210   int                           lastchild;
211   int                           childcnt;
212   int                           nextsib;
213 } CONTENT_SCAFFOLD;
214
215 #define INIT_SCAFFOLD_ELEMENTS 32
216
217 typedef struct block {
218   struct block *next;
219   int size;
220   XML_Char s[1];
221 } BLOCK;
222
223 typedef struct {
224   BLOCK *blocks;
225   BLOCK *freeBlocks;
226   const XML_Char *end;
227   XML_Char *ptr;
228   XML_Char *start;
229   const XML_Memory_Handling_Suite *mem;
230 } STRING_POOL;
231
232 /* The XML_Char before the name is used to determine whether
233    an attribute has been specified. */
234 typedef struct attribute_id {
235   XML_Char *name;
236   PREFIX *prefix;
237   XML_Bool maybeTokenized;
238   XML_Bool xmlns;
239 } ATTRIBUTE_ID;
240
241 typedef struct {
242   const ATTRIBUTE_ID *id;
243   XML_Bool isCdata;
244   const XML_Char *value;
245 } DEFAULT_ATTRIBUTE;
246
247 typedef struct {
248   unsigned long version;
249   unsigned long hash;
250   const XML_Char *uriName;
251 } NS_ATT;
252
253 typedef struct {
254   const XML_Char *name;
255   PREFIX *prefix;
256   const ATTRIBUTE_ID *idAtt;
257   int nDefaultAtts;
258   int allocDefaultAtts;
259   DEFAULT_ATTRIBUTE *defaultAtts;
260 } ELEMENT_TYPE;
261
262 typedef struct {
263   HASH_TABLE generalEntities;
264   HASH_TABLE elementTypes;
265   HASH_TABLE attributeIds;
266   HASH_TABLE prefixes;
267   STRING_POOL pool;
268   STRING_POOL entityValuePool;
269   /* false once a parameter entity reference has been skipped */
270   XML_Bool keepProcessing;
271   /* true once an internal or external PE reference has been encountered;
272      this includes the reference to an external subset */
273   XML_Bool hasParamEntityRefs;
274   XML_Bool standalone;
275 #ifdef XML_DTD
276   /* indicates if external PE has been read */
277   XML_Bool paramEntityRead;
278   HASH_TABLE paramEntities;
279 #endif /* XML_DTD */
280   PREFIX defaultPrefix;
281   /* === scaffolding for building content model === */
282   XML_Bool in_eldecl;
283   CONTENT_SCAFFOLD *scaffold;
284   unsigned contentStringLen;
285   unsigned scaffSize;
286   unsigned scaffCount;
287   int scaffLevel;
288   int *scaffIndex;
289 } DTD;
290
291 typedef struct open_internal_entity {
292   const char *internalEventPtr;
293   const char *internalEventEndPtr;
294   struct open_internal_entity *next;
295   ENTITY *entity;
296   int startTagLevel;
297   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
298 } OPEN_INTERNAL_ENTITY;
299
300 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
301                                          const char *start,
302                                          const char *end,
303                                          const char **endPtr);
304
305 static Processor prologProcessor;
306 static Processor prologInitProcessor;
307 static Processor contentProcessor;
308 static Processor cdataSectionProcessor;
309 #ifdef XML_DTD
310 static Processor ignoreSectionProcessor;
311 static Processor externalParEntProcessor;
312 static Processor externalParEntInitProcessor;
313 static Processor entityValueProcessor;
314 static Processor entityValueInitProcessor;
315 #endif /* XML_DTD */
316 static Processor epilogProcessor;
317 static Processor errorProcessor;
318 static Processor externalEntityInitProcessor;
319 static Processor externalEntityInitProcessor2;
320 static Processor externalEntityInitProcessor3;
321 static Processor externalEntityContentProcessor;
322 static Processor internalEntityProcessor;
323
324 static enum XML_Error
325 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
326 static enum XML_Error
327 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
328                const char *s, const char *next);
329 static enum XML_Error
330 initializeEncoding(XML_Parser parser);
331 static enum XML_Error
332 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
333          const char *end, int tok, const char *next, const char **nextPtr,
334          XML_Bool haveMore);
335 static enum XML_Error
336 processInternalEntity(XML_Parser parser, ENTITY *entity,
337                       XML_Bool betweenDecl);
338 static enum XML_Error
339 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
340           const char *start, const char *end, const char **endPtr,
341           XML_Bool haveMore);
342 static enum XML_Error
343 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
344                const char *end, const char **nextPtr, XML_Bool haveMore);
345 #ifdef XML_DTD
346 static enum XML_Error
347 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
348                 const char *end, const char **nextPtr, XML_Bool haveMore);
349 #endif /* XML_DTD */
350
351 static enum XML_Error
352 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
353           TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
354 static enum XML_Error
355 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
356            const XML_Char *uri, BINDING **bindingsPtr);
357 static int
358 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
359                 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
360 static enum XML_Error
361 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
362                     const char *, const char *, STRING_POOL *);
363 static enum XML_Error
364 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
365                      const char *, const char *, STRING_POOL *);
366 static ATTRIBUTE_ID *
367 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
368                const char *end);
369 static int
370 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
371 static enum XML_Error
372 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
373                  const char *end);
374 static int
375 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
376                             const char *start, const char *end);
377 static int
378 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
379               const char *end);
380 static void
381 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
382               const char *end);
383
384 static const XML_Char * getContext(XML_Parser parser);
385 static XML_Bool
386 setContext(XML_Parser parser, const XML_Char *context);
387
388 static void FASTCALL normalizePublicId(XML_Char *s);
389
390 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
391 /* do not call if parentParser != NULL */
392 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
393 static void
394 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
395 static int
396 dtdCopy(XML_Parser oldParser,
397         DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
398 static int
399 copyEntityTable(XML_Parser oldParser,
400                 HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
401 static NAMED *
402 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
403 static void FASTCALL
404 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
405 static void FASTCALL hashTableClear(HASH_TABLE *);
406 static void FASTCALL hashTableDestroy(HASH_TABLE *);
407 static void FASTCALL
408 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
409 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
410
411 static void FASTCALL
412 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
413 static void FASTCALL poolClear(STRING_POOL *);
414 static void FASTCALL poolDestroy(STRING_POOL *);
415 static XML_Char *
416 poolAppend(STRING_POOL *pool, const ENCODING *enc,
417            const char *ptr, const char *end);
418 static XML_Char *
419 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
420                 const char *ptr, const char *end);
421 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
422 static const XML_Char * FASTCALL
423 poolCopyString(STRING_POOL *pool, const XML_Char *s);
424 static const XML_Char *
425 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
426 static const XML_Char * FASTCALL
427 poolAppendString(STRING_POOL *pool, const XML_Char *s);
428
429 static int FASTCALL nextScaffoldPart(XML_Parser parser);
430 static XML_Content * build_model(XML_Parser parser);
431 static ELEMENT_TYPE *
432 getElementType(XML_Parser parser, const ENCODING *enc,
433                const char *ptr, const char *end);
434
435 static unsigned long generate_hash_secret_salt(void);
436 static XML_Bool startParsing(XML_Parser parser);
437
438 static XML_Parser
439 parserCreate(const XML_Char *encodingName,
440              const XML_Memory_Handling_Suite *memsuite,
441              const XML_Char *nameSep,
442              DTD *dtd);
443
444 static void
445 parserInit(XML_Parser parser, const XML_Char *encodingName);
446
447 #define poolStart(pool) ((pool)->start)
448 #define poolEnd(pool) ((pool)->ptr)
449 #define poolLength(pool) ((pool)->ptr - (pool)->start)
450 #define poolChop(pool) ((void)--(pool->ptr))
451 #define poolLastChar(pool) (((pool)->ptr)[-1])
452 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
453 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
454 #define poolAppendChar(pool, c) \
455   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
456    ? 0 \
457    : ((*((pool)->ptr)++ = c), 1))
458
459 struct XML_ParserStruct {
460   /* The first member must be userData so that the XML_GetUserData
461      macro works. */
462   void *m_userData;
463   void *m_handlerArg;
464   char *m_buffer;
465   const XML_Memory_Handling_Suite m_mem;
466   /* first character to be parsed */
467   const char *m_bufferPtr;
468   /* past last character to be parsed */
469   char *m_bufferEnd;
470   /* allocated end of buffer */
471   const char *m_bufferLim;
472   XML_Index m_parseEndByteIndex;
473   const char *m_parseEndPtr;
474   XML_Char *m_dataBuf;
475   XML_Char *m_dataBufEnd;
476   XML_StartElementHandler m_startElementHandler;
477   XML_EndElementHandler m_endElementHandler;
478   XML_CharacterDataHandler m_characterDataHandler;
479   XML_ProcessingInstructionHandler m_processingInstructionHandler;
480   XML_CommentHandler m_commentHandler;
481   XML_StartCdataSectionHandler m_startCdataSectionHandler;
482   XML_EndCdataSectionHandler m_endCdataSectionHandler;
483   XML_DefaultHandler m_defaultHandler;
484   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
485   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
486   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
487   XML_NotationDeclHandler m_notationDeclHandler;
488   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
489   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
490   XML_NotStandaloneHandler m_notStandaloneHandler;
491   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
492   XML_Parser m_externalEntityRefHandlerArg;
493   XML_SkippedEntityHandler m_skippedEntityHandler;
494   XML_UnknownEncodingHandler m_unknownEncodingHandler;
495   XML_ElementDeclHandler m_elementDeclHandler;
496   XML_AttlistDeclHandler m_attlistDeclHandler;
497   XML_EntityDeclHandler m_entityDeclHandler;
498   XML_XmlDeclHandler m_xmlDeclHandler;
499   const ENCODING *m_encoding;
500   INIT_ENCODING m_initEncoding;
501   const ENCODING *m_internalEncoding;
502   const XML_Char *m_protocolEncodingName;
503   XML_Bool m_ns;
504   XML_Bool m_ns_triplets;
505   void *m_unknownEncodingMem;
506   void *m_unknownEncodingData;
507   void *m_unknownEncodingHandlerData;
508   void (XMLCALL *m_unknownEncodingRelease)(void *);
509   PROLOG_STATE m_prologState;
510   Processor *m_processor;
511   enum XML_Error m_errorCode;
512   const char *m_eventPtr;
513   const char *m_eventEndPtr;
514   const char *m_positionPtr;
515   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
516   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
517   XML_Bool m_defaultExpandInternalEntities;
518   int m_tagLevel;
519   ENTITY *m_declEntity;
520   const XML_Char *m_doctypeName;
521   const XML_Char *m_doctypeSysid;
522   const XML_Char *m_doctypePubid;
523   const XML_Char *m_declAttributeType;
524   const XML_Char *m_declNotationName;
525   const XML_Char *m_declNotationPublicId;
526   ELEMENT_TYPE *m_declElementType;
527   ATTRIBUTE_ID *m_declAttributeId;
528   XML_Bool m_declAttributeIsCdata;
529   XML_Bool m_declAttributeIsId;
530   DTD *m_dtd;
531   const XML_Char *m_curBase;
532   TAG *m_tagStack;
533   TAG *m_freeTagList;
534   BINDING *m_inheritedBindings;
535   BINDING *m_freeBindingList;
536   int m_attsSize;
537   int m_nSpecifiedAtts;
538   int m_idAttIndex;
539   ATTRIBUTE *m_atts;
540   NS_ATT *m_nsAtts;
541   unsigned long m_nsAttsVersion;
542   unsigned char m_nsAttsPower;
543 #ifdef XML_ATTR_INFO
544   XML_AttrInfo *m_attInfo;
545 #endif
546   POSITION m_position;
547   STRING_POOL m_tempPool;
548   STRING_POOL m_temp2Pool;
549   char *m_groupConnector;
550   unsigned int m_groupSize;
551   XML_Char m_namespaceSeparator;
552   XML_Parser m_parentParser;
553   XML_ParsingStatus m_parsingStatus;
554 #ifdef XML_DTD
555   XML_Bool m_isParamEntity;
556   XML_Bool m_useForeignDTD;
557   enum XML_ParamEntityParsing m_paramEntityParsing;
558 #endif
559   unsigned long m_hash_secret_salt;
560 };
561
562 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
563 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
564 #define FREE(p) (parser->m_mem.free_fcn((p)))
565
566 #define userData (parser->m_userData)
567 #define handlerArg (parser->m_handlerArg)
568 #define startElementHandler (parser->m_startElementHandler)
569 #define endElementHandler (parser->m_endElementHandler)
570 #define characterDataHandler (parser->m_characterDataHandler)
571 #define processingInstructionHandler \
572         (parser->m_processingInstructionHandler)
573 #define commentHandler (parser->m_commentHandler)
574 #define startCdataSectionHandler \
575         (parser->m_startCdataSectionHandler)
576 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
577 #define defaultHandler (parser->m_defaultHandler)
578 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
579 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
580 #define unparsedEntityDeclHandler \
581         (parser->m_unparsedEntityDeclHandler)
582 #define notationDeclHandler (parser->m_notationDeclHandler)
583 #define startNamespaceDeclHandler \
584         (parser->m_startNamespaceDeclHandler)
585 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
586 #define notStandaloneHandler (parser->m_notStandaloneHandler)
587 #define externalEntityRefHandler \
588         (parser->m_externalEntityRefHandler)
589 #define externalEntityRefHandlerArg \
590         (parser->m_externalEntityRefHandlerArg)
591 #define internalEntityRefHandler \
592         (parser->m_internalEntityRefHandler)
593 #define skippedEntityHandler (parser->m_skippedEntityHandler)
594 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
595 #define elementDeclHandler (parser->m_elementDeclHandler)
596 #define attlistDeclHandler (parser->m_attlistDeclHandler)
597 #define entityDeclHandler (parser->m_entityDeclHandler)
598 #define xmlDeclHandler (parser->m_xmlDeclHandler)
599 #define encoding (parser->m_encoding)
600 #define initEncoding (parser->m_initEncoding)
601 #define internalEncoding (parser->m_internalEncoding)
602 #define unknownEncodingMem (parser->m_unknownEncodingMem)
603 #define unknownEncodingData (parser->m_unknownEncodingData)
604 #define unknownEncodingHandlerData \
605   (parser->m_unknownEncodingHandlerData)
606 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
607 #define protocolEncodingName (parser->m_protocolEncodingName)
608 #define ns (parser->m_ns)
609 #define ns_triplets (parser->m_ns_triplets)
610 #define prologState (parser->m_prologState)
611 #define processor (parser->m_processor)
612 #define errorCode (parser->m_errorCode)
613 #define eventPtr (parser->m_eventPtr)
614 #define eventEndPtr (parser->m_eventEndPtr)
615 #define positionPtr (parser->m_positionPtr)
616 #define position (parser->m_position)
617 #define openInternalEntities (parser->m_openInternalEntities)
618 #define freeInternalEntities (parser->m_freeInternalEntities)
619 #define defaultExpandInternalEntities \
620         (parser->m_defaultExpandInternalEntities)
621 #define tagLevel (parser->m_tagLevel)
622 #define buffer (parser->m_buffer)
623 #define bufferPtr (parser->m_bufferPtr)
624 #define bufferEnd (parser->m_bufferEnd)
625 #define parseEndByteIndex (parser->m_parseEndByteIndex)
626 #define parseEndPtr (parser->m_parseEndPtr)
627 #define bufferLim (parser->m_bufferLim)
628 #define dataBuf (parser->m_dataBuf)
629 #define dataBufEnd (parser->m_dataBufEnd)
630 #define _dtd (parser->m_dtd)
631 #define curBase (parser->m_curBase)
632 #define declEntity (parser->m_declEntity)
633 #define doctypeName (parser->m_doctypeName)
634 #define doctypeSysid (parser->m_doctypeSysid)
635 #define doctypePubid (parser->m_doctypePubid)
636 #define declAttributeType (parser->m_declAttributeType)
637 #define declNotationName (parser->m_declNotationName)
638 #define declNotationPublicId (parser->m_declNotationPublicId)
639 #define declElementType (parser->m_declElementType)
640 #define declAttributeId (parser->m_declAttributeId)
641 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
642 #define declAttributeIsId (parser->m_declAttributeIsId)
643 #define freeTagList (parser->m_freeTagList)
644 #define freeBindingList (parser->m_freeBindingList)
645 #define inheritedBindings (parser->m_inheritedBindings)
646 #define tagStack (parser->m_tagStack)
647 #define atts (parser->m_atts)
648 #define attsSize (parser->m_attsSize)
649 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
650 #define idAttIndex (parser->m_idAttIndex)
651 #define nsAtts (parser->m_nsAtts)
652 #define nsAttsVersion (parser->m_nsAttsVersion)
653 #define nsAttsPower (parser->m_nsAttsPower)
654 #define attInfo (parser->m_attInfo)
655 #define tempPool (parser->m_tempPool)
656 #define temp2Pool (parser->m_temp2Pool)
657 #define groupConnector (parser->m_groupConnector)
658 #define groupSize (parser->m_groupSize)
659 #define namespaceSeparator (parser->m_namespaceSeparator)
660 #define parentParser (parser->m_parentParser)
661 #define ps_parsing (parser->m_parsingStatus.parsing)
662 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
663 #ifdef XML_DTD
664 #define isParamEntity (parser->m_isParamEntity)
665 #define useForeignDTD (parser->m_useForeignDTD)
666 #define paramEntityParsing (parser->m_paramEntityParsing)
667 #endif /* XML_DTD */
668 #define hash_secret_salt (parser->m_hash_secret_salt)
669
670 XML_Parser XMLCALL
671 XML_ParserCreate(const XML_Char *encodingName)
672 {
673   return XML_ParserCreate_MM(encodingName, NULL, NULL);
674 }
675
676 XML_Parser XMLCALL
677 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
678 {
679   XML_Char tmp[2];
680   *tmp = nsSep;
681   return XML_ParserCreate_MM(encodingName, NULL, tmp);
682 }
683
684 static const XML_Char implicitContext[] = {
685   ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
686   ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
687   ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
688   ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
689   ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
690   ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
691 };
692
693 static unsigned long
694 generate_hash_secret_salt(void)
695 {
696   unsigned int seed = time(NULL) % UINT_MAX;
697   srand(seed);
698   return rand();
699 }
700
701 static XML_Bool  /* only valid for root parser */
702 startParsing(XML_Parser parser)
703 {
704     /* hash functions must be initialized before setContext() is called */
705     if (hash_secret_salt == 0)
706       hash_secret_salt = generate_hash_secret_salt();
707     if (ns) {
708       /* implicit context only set for root parser, since child
709          parsers (i.e. external entity parsers) will inherit it
710       */
711       return setContext(parser, implicitContext);
712     }
713     return XML_TRUE;
714 }
715
716 XML_Parser XMLCALL
717 XML_ParserCreate_MM(const XML_Char *encodingName,
718                     const XML_Memory_Handling_Suite *memsuite,
719                     const XML_Char *nameSep)
720 {
721   return parserCreate(encodingName, memsuite, nameSep, NULL);
722 }
723
724 static XML_Parser
725 parserCreate(const XML_Char *encodingName,
726              const XML_Memory_Handling_Suite *memsuite,
727              const XML_Char *nameSep,
728              DTD *dtd)
729 {
730   XML_Parser parser;
731
732   if (memsuite) {
733     XML_Memory_Handling_Suite *mtemp;
734     parser = (XML_Parser)
735       memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
736     if (parser != NULL) {
737       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
738       mtemp->malloc_fcn = memsuite->malloc_fcn;
739       mtemp->realloc_fcn = memsuite->realloc_fcn;
740       mtemp->free_fcn = memsuite->free_fcn;
741     }
742   }
743   else {
744     XML_Memory_Handling_Suite *mtemp;
745     parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
746     if (parser != NULL) {
747       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
748       mtemp->malloc_fcn = malloc;
749       mtemp->realloc_fcn = realloc;
750       mtemp->free_fcn = free;
751     }
752   }
753
754   if (!parser)
755     return parser;
756
757   buffer = NULL;
758   bufferLim = NULL;
759
760   attsSize = INIT_ATTS_SIZE;
761   atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
762   if (atts == NULL) {
763     FREE(parser);
764     return NULL;
765   }
766 #ifdef XML_ATTR_INFO
767   attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
768   if (attInfo == NULL) {
769     FREE(atts);
770     FREE(parser);
771     return NULL;
772   }
773 #endif
774   dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
775   if (dataBuf == NULL) {
776     FREE(atts);
777 #ifdef XML_ATTR_INFO
778     FREE(attInfo);
779 #endif
780     FREE(parser);
781     return NULL;
782   }
783   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
784
785   if (dtd)
786     _dtd = dtd;
787   else {
788     _dtd = dtdCreate(&parser->m_mem);
789     if (_dtd == NULL) {
790       FREE(dataBuf);
791       FREE(atts);
792 #ifdef XML_ATTR_INFO
793       FREE(attInfo);
794 #endif
795       FREE(parser);
796       return NULL;
797     }
798   }
799
800   freeBindingList = NULL;
801   freeTagList = NULL;
802   freeInternalEntities = NULL;
803
804   groupSize = 0;
805   groupConnector = NULL;
806
807   unknownEncodingHandler = NULL;
808   unknownEncodingHandlerData = NULL;
809
810   namespaceSeparator = ASCII_EXCL;
811   ns = XML_FALSE;
812   ns_triplets = XML_FALSE;
813
814   nsAtts = NULL;
815   nsAttsVersion = 0;
816   nsAttsPower = 0;
817
818   poolInit(&tempPool, &(parser->m_mem));
819   poolInit(&temp2Pool, &(parser->m_mem));
820   parserInit(parser, encodingName);
821
822   if (encodingName && !protocolEncodingName) {
823     XML_ParserFree(parser);
824     return NULL;
825   }
826
827   if (nameSep) {
828     ns = XML_TRUE;
829     internalEncoding = XmlGetInternalEncodingNS();
830     namespaceSeparator = *nameSep;
831   }
832   else {
833     internalEncoding = XmlGetInternalEncoding();
834   }
835
836   return parser;
837 }
838
839 static void
840 parserInit(XML_Parser parser, const XML_Char *encodingName)
841 {
842   processor = prologInitProcessor;
843   XmlPrologStateInit(&prologState);
844   protocolEncodingName = (encodingName != NULL
845                           ? poolCopyString(&tempPool, encodingName)
846                           : NULL);
847   curBase = NULL;
848   XmlInitEncoding(&initEncoding, &encoding, 0);
849   userData = NULL;
850   handlerArg = NULL;
851   startElementHandler = NULL;
852   endElementHandler = NULL;
853   characterDataHandler = NULL;
854   processingInstructionHandler = NULL;
855   commentHandler = NULL;
856   startCdataSectionHandler = NULL;
857   endCdataSectionHandler = NULL;
858   defaultHandler = NULL;
859   startDoctypeDeclHandler = NULL;
860   endDoctypeDeclHandler = NULL;
861   unparsedEntityDeclHandler = NULL;
862   notationDeclHandler = NULL;
863   startNamespaceDeclHandler = NULL;
864   endNamespaceDeclHandler = NULL;
865   notStandaloneHandler = NULL;
866   externalEntityRefHandler = NULL;
867   externalEntityRefHandlerArg = parser;
868   skippedEntityHandler = NULL;
869   elementDeclHandler = NULL;
870   attlistDeclHandler = NULL;
871   entityDeclHandler = NULL;
872   xmlDeclHandler = NULL;
873   bufferPtr = buffer;
874   bufferEnd = buffer;
875   parseEndByteIndex = 0;
876   parseEndPtr = NULL;
877   declElementType = NULL;
878   declAttributeId = NULL;
879   declEntity = NULL;
880   doctypeName = NULL;
881   doctypeSysid = NULL;
882   doctypePubid = NULL;
883   declAttributeType = NULL;
884   declNotationName = NULL;
885   declNotationPublicId = NULL;
886   declAttributeIsCdata = XML_FALSE;
887   declAttributeIsId = XML_FALSE;
888   memset(&position, 0, sizeof(POSITION));
889   errorCode = XML_ERROR_NONE;
890   eventPtr = NULL;
891   eventEndPtr = NULL;
892   positionPtr = NULL;
893   openInternalEntities = NULL;
894   defaultExpandInternalEntities = XML_TRUE;
895   tagLevel = 0;
896   tagStack = NULL;
897   inheritedBindings = NULL;
898   nSpecifiedAtts = 0;
899   unknownEncodingMem = NULL;
900   unknownEncodingRelease = NULL;
901   unknownEncodingData = NULL;
902   parentParser = NULL;
903   ps_parsing = XML_INITIALIZED;
904 #ifdef XML_DTD
905   isParamEntity = XML_FALSE;
906   useForeignDTD = XML_FALSE;
907   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
908 #endif
909   hash_secret_salt = 0;
910 }
911
912 /* moves list of bindings to freeBindingList */
913 static void FASTCALL
914 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
915 {
916   while (bindings) {
917     BINDING *b = bindings;
918     bindings = bindings->nextTagBinding;
919     b->nextTagBinding = freeBindingList;
920     freeBindingList = b;
921   }
922 }
923
924 XML_Bool XMLCALL
925 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
926 {
927   TAG *tStk;
928   OPEN_INTERNAL_ENTITY *openEntityList;
929   if (parentParser)
930     return XML_FALSE;
931   /* move tagStack to freeTagList */
932   tStk = tagStack;
933   while (tStk) {
934     TAG *tag = tStk;
935     tStk = tStk->parent;
936     tag->parent = freeTagList;
937     moveToFreeBindingList(parser, tag->bindings);
938     tag->bindings = NULL;
939     freeTagList = tag;
940   }
941   /* move openInternalEntities to freeInternalEntities */
942   openEntityList = openInternalEntities;
943   while (openEntityList) {
944     OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
945     openEntityList = openEntity->next;
946     openEntity->next = freeInternalEntities;
947     freeInternalEntities = openEntity;
948   }
949   moveToFreeBindingList(parser, inheritedBindings);
950   FREE(unknownEncodingMem);
951   if (unknownEncodingRelease)
952     unknownEncodingRelease(unknownEncodingData);
953   poolClear(&tempPool);
954   poolClear(&temp2Pool);
955   parserInit(parser, encodingName);
956   dtdReset(_dtd, &parser->m_mem);
957   return XML_TRUE;
958 }
959
960 enum XML_Status XMLCALL
961 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
962 {
963   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
964      XXX There's no way for the caller to determine which of the
965      XXX possible error cases caused the XML_STATUS_ERROR return.
966   */
967   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
968     return XML_STATUS_ERROR;
969   if (encodingName == NULL)
970     protocolEncodingName = NULL;
971   else {
972     protocolEncodingName = poolCopyString(&tempPool, encodingName);
973     if (!protocolEncodingName)
974       return XML_STATUS_ERROR;
975   }
976   return XML_STATUS_OK;
977 }
978
979 XML_Parser XMLCALL
980 XML_ExternalEntityParserCreate(XML_Parser oldParser,
981                                const XML_Char *context,
982                                const XML_Char *encodingName)
983 {
984   XML_Parser parser = oldParser;
985   DTD *newDtd = NULL;
986   DTD *oldDtd = _dtd;
987   XML_StartElementHandler oldStartElementHandler = startElementHandler;
988   XML_EndElementHandler oldEndElementHandler = endElementHandler;
989   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
990   XML_ProcessingInstructionHandler oldProcessingInstructionHandler
991       = processingInstructionHandler;
992   XML_CommentHandler oldCommentHandler = commentHandler;
993   XML_StartCdataSectionHandler oldStartCdataSectionHandler
994       = startCdataSectionHandler;
995   XML_EndCdataSectionHandler oldEndCdataSectionHandler
996       = endCdataSectionHandler;
997   XML_DefaultHandler oldDefaultHandler = defaultHandler;
998   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
999       = unparsedEntityDeclHandler;
1000   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
1001   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1002       = startNamespaceDeclHandler;
1003   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1004       = endNamespaceDeclHandler;
1005   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
1006   XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1007       = externalEntityRefHandler;
1008   XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
1009   XML_UnknownEncodingHandler oldUnknownEncodingHandler
1010       = unknownEncodingHandler;
1011   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1012   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1013   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1014   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1015   ELEMENT_TYPE * oldDeclElementType = declElementType;
1016
1017   void *oldUserData = userData;
1018   void *oldHandlerArg = handlerArg;
1019   XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1020   XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1021 #ifdef XML_DTD
1022   enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1023   int oldInEntityValue = prologState.inEntityValue;
1024 #endif
1025   XML_Bool oldns_triplets = ns_triplets;
1026   /* Note that the new parser shares the same hash secret as the old
1027      parser, so that dtdCopy and copyEntityTable can lookup values
1028      from hash tables associated with either parser without us having
1029      to worry which hash secrets each table has.
1030   */
1031   unsigned long oldhash_secret_salt = hash_secret_salt;
1032
1033 #ifdef XML_DTD
1034   if (!context)
1035     newDtd = oldDtd;
1036 #endif /* XML_DTD */
1037
1038   /* Note that the magical uses of the pre-processor to make field
1039      access look more like C++ require that `parser' be overwritten
1040      here.  This makes this function more painful to follow than it
1041      would be otherwise.
1042   */
1043   if (ns) {
1044     XML_Char tmp[2];
1045     *tmp = namespaceSeparator;
1046     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1047   }
1048   else {
1049     parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1050   }
1051
1052   if (!parser)
1053     return NULL;
1054
1055   startElementHandler = oldStartElementHandler;
1056   endElementHandler = oldEndElementHandler;
1057   characterDataHandler = oldCharacterDataHandler;
1058   processingInstructionHandler = oldProcessingInstructionHandler;
1059   commentHandler = oldCommentHandler;
1060   startCdataSectionHandler = oldStartCdataSectionHandler;
1061   endCdataSectionHandler = oldEndCdataSectionHandler;
1062   defaultHandler = oldDefaultHandler;
1063   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1064   notationDeclHandler = oldNotationDeclHandler;
1065   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1066   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1067   notStandaloneHandler = oldNotStandaloneHandler;
1068   externalEntityRefHandler = oldExternalEntityRefHandler;
1069   skippedEntityHandler = oldSkippedEntityHandler;
1070   unknownEncodingHandler = oldUnknownEncodingHandler;
1071   elementDeclHandler = oldElementDeclHandler;
1072   attlistDeclHandler = oldAttlistDeclHandler;
1073   entityDeclHandler = oldEntityDeclHandler;
1074   xmlDeclHandler = oldXmlDeclHandler;
1075   declElementType = oldDeclElementType;
1076   userData = oldUserData;
1077   if (oldUserData == oldHandlerArg)
1078     handlerArg = userData;
1079   else
1080     handlerArg = parser;
1081   if (oldExternalEntityRefHandlerArg != oldParser)
1082     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1083   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1084   ns_triplets = oldns_triplets;
1085   hash_secret_salt = oldhash_secret_salt;
1086   parentParser = oldParser;
1087 #ifdef XML_DTD
1088   paramEntityParsing = oldParamEntityParsing;
1089   prologState.inEntityValue = oldInEntityValue;
1090   if (context) {
1091 #endif /* XML_DTD */
1092     if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
1093       || !setContext(parser, context)) {
1094       XML_ParserFree(parser);
1095       return NULL;
1096     }
1097     processor = externalEntityInitProcessor;
1098 #ifdef XML_DTD
1099   }
1100   else {
1101     /* The DTD instance referenced by _dtd is shared between the document's
1102        root parser and external PE parsers, therefore one does not need to
1103        call setContext. In addition, one also *must* not call setContext,
1104        because this would overwrite existing prefix->binding pointers in
1105        _dtd with ones that get destroyed with the external PE parser.
1106        This would leave those prefixes with dangling pointers.
1107     */
1108     isParamEntity = XML_TRUE;
1109     XmlPrologStateInitExternalEntity(&prologState);
1110     processor = externalParEntInitProcessor;
1111   }
1112 #endif /* XML_DTD */
1113   return parser;
1114 }
1115
1116 static void FASTCALL
1117 destroyBindings(BINDING *bindings, XML_Parser parser)
1118 {
1119   for (;;) {
1120     BINDING *b = bindings;
1121     if (!b)
1122       break;
1123     bindings = b->nextTagBinding;
1124     FREE(b->uri);
1125     FREE(b);
1126   }
1127 }
1128
1129 void XMLCALL
1130 XML_ParserFree(XML_Parser parser)
1131 {
1132   TAG *tagList;
1133   OPEN_INTERNAL_ENTITY *entityList;
1134   if (parser == NULL)
1135     return;
1136   /* free tagStack and freeTagList */
1137   tagList = tagStack;
1138   for (;;) {
1139     TAG *p;
1140     if (tagList == NULL) {
1141       if (freeTagList == NULL)
1142         break;
1143       tagList = freeTagList;
1144       freeTagList = NULL;
1145     }
1146     p = tagList;
1147     tagList = tagList->parent;
1148     FREE(p->buf);
1149     destroyBindings(p->bindings, parser);
1150     FREE(p);
1151   }
1152   /* free openInternalEntities and freeInternalEntities */
1153   entityList = openInternalEntities;
1154   for (;;) {
1155     OPEN_INTERNAL_ENTITY *openEntity;
1156     if (entityList == NULL) {
1157       if (freeInternalEntities == NULL)
1158         break;
1159       entityList = freeInternalEntities;
1160       freeInternalEntities = NULL;
1161     }
1162     openEntity = entityList;
1163     entityList = entityList->next;
1164     FREE(openEntity);
1165   }
1166
1167   destroyBindings(freeBindingList, parser);
1168   destroyBindings(inheritedBindings, parser);
1169   poolDestroy(&tempPool);
1170   poolDestroy(&temp2Pool);
1171 #ifdef XML_DTD
1172   /* external parameter entity parsers share the DTD structure
1173      parser->m_dtd with the root parser, so we must not destroy it
1174   */
1175   if (!isParamEntity && _dtd)
1176 #else
1177   if (_dtd)
1178 #endif /* XML_DTD */
1179     dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1180   FREE((void *)atts);
1181 #ifdef XML_ATTR_INFO
1182   FREE((void *)attInfo);
1183 #endif
1184   FREE(groupConnector);
1185   FREE(buffer);
1186   FREE(dataBuf);
1187   FREE(nsAtts);
1188   FREE(unknownEncodingMem);
1189   if (unknownEncodingRelease)
1190     unknownEncodingRelease(unknownEncodingData);
1191   FREE(parser);
1192 }
1193
1194 void XMLCALL
1195 XML_UseParserAsHandlerArg(XML_Parser parser)
1196 {
1197   handlerArg = parser;
1198 }
1199
1200 enum XML_Error XMLCALL
1201 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1202 {
1203 #ifdef XML_DTD
1204   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1205   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1206     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1207   useForeignDTD = useDTD;
1208   return XML_ERROR_NONE;
1209 #else
1210   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1211 #endif
1212 }
1213
1214 void XMLCALL
1215 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1216 {
1217   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1218   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1219     return;
1220   ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1221 }
1222
1223 void XMLCALL
1224 XML_SetUserData(XML_Parser parser, void *p)
1225 {
1226   if (handlerArg == userData)
1227     handlerArg = userData = p;
1228   else
1229     userData = p;
1230 }
1231
1232 enum XML_Status XMLCALL
1233 XML_SetBase(XML_Parser parser, const XML_Char *p)
1234 {
1235   if (p) {
1236     p = poolCopyString(&_dtd->pool, p);
1237     if (!p)
1238       return XML_STATUS_ERROR;
1239     curBase = p;
1240   }
1241   else
1242     curBase = NULL;
1243   return XML_STATUS_OK;
1244 }
1245
1246 const XML_Char * XMLCALL
1247 XML_GetBase(XML_Parser parser)
1248 {
1249   return curBase;
1250 }
1251
1252 int XMLCALL
1253 XML_GetSpecifiedAttributeCount(XML_Parser parser)
1254 {
1255   return nSpecifiedAtts;
1256 }
1257
1258 int XMLCALL
1259 XML_GetIdAttributeIndex(XML_Parser parser)
1260 {
1261   return idAttIndex;
1262 }
1263
1264 #ifdef XML_ATTR_INFO
1265 const XML_AttrInfo * XMLCALL
1266 XML_GetAttributeInfo(XML_Parser parser)
1267 {
1268   return attInfo;
1269 }
1270 #endif
1271
1272 void XMLCALL
1273 XML_SetElementHandler(XML_Parser parser,
1274                       XML_StartElementHandler start,
1275                       XML_EndElementHandler end)
1276 {
1277   startElementHandler = start;
1278   endElementHandler = end;
1279 }
1280
1281 void XMLCALL
1282 XML_SetStartElementHandler(XML_Parser parser,
1283                            XML_StartElementHandler start) {
1284   startElementHandler = start;
1285 }
1286
1287 void XMLCALL
1288 XML_SetEndElementHandler(XML_Parser parser,
1289                          XML_EndElementHandler end) {
1290   endElementHandler = end;
1291 }
1292
1293 void XMLCALL
1294 XML_SetCharacterDataHandler(XML_Parser parser,
1295                             XML_CharacterDataHandler handler)
1296 {
1297   characterDataHandler = handler;
1298 }
1299
1300 void XMLCALL
1301 XML_SetProcessingInstructionHandler(XML_Parser parser,
1302                                     XML_ProcessingInstructionHandler handler)
1303 {
1304   processingInstructionHandler = handler;
1305 }
1306
1307 void XMLCALL
1308 XML_SetCommentHandler(XML_Parser parser,
1309                       XML_CommentHandler handler)
1310 {
1311   commentHandler = handler;
1312 }
1313
1314 void XMLCALL
1315 XML_SetCdataSectionHandler(XML_Parser parser,
1316                            XML_StartCdataSectionHandler start,
1317                            XML_EndCdataSectionHandler end)
1318 {
1319   startCdataSectionHandler = start;
1320   endCdataSectionHandler = end;
1321 }
1322
1323 void XMLCALL
1324 XML_SetStartCdataSectionHandler(XML_Parser parser,
1325                                 XML_StartCdataSectionHandler start) {
1326   startCdataSectionHandler = start;
1327 }
1328
1329 void XMLCALL
1330 XML_SetEndCdataSectionHandler(XML_Parser parser,
1331                               XML_EndCdataSectionHandler end) {
1332   endCdataSectionHandler = end;
1333 }
1334
1335 void XMLCALL
1336 XML_SetDefaultHandler(XML_Parser parser,
1337                       XML_DefaultHandler handler)
1338 {
1339   defaultHandler = handler;
1340   defaultExpandInternalEntities = XML_FALSE;
1341 }
1342
1343 void XMLCALL
1344 XML_SetDefaultHandlerExpand(XML_Parser parser,
1345                             XML_DefaultHandler handler)
1346 {
1347   defaultHandler = handler;
1348   defaultExpandInternalEntities = XML_TRUE;
1349 }
1350
1351 void XMLCALL
1352 XML_SetDoctypeDeclHandler(XML_Parser parser,
1353                           XML_StartDoctypeDeclHandler start,
1354                           XML_EndDoctypeDeclHandler end)
1355 {
1356   startDoctypeDeclHandler = start;
1357   endDoctypeDeclHandler = end;
1358 }
1359
1360 void XMLCALL
1361 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1362                                XML_StartDoctypeDeclHandler start) {
1363   startDoctypeDeclHandler = start;
1364 }
1365
1366 void XMLCALL
1367 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1368                              XML_EndDoctypeDeclHandler end) {
1369   endDoctypeDeclHandler = end;
1370 }
1371
1372 void XMLCALL
1373 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1374                                  XML_UnparsedEntityDeclHandler handler)
1375 {
1376   unparsedEntityDeclHandler = handler;
1377 }
1378
1379 void XMLCALL
1380 XML_SetNotationDeclHandler(XML_Parser parser,
1381                            XML_NotationDeclHandler handler)
1382 {
1383   notationDeclHandler = handler;
1384 }
1385
1386 void XMLCALL
1387 XML_SetNamespaceDeclHandler(XML_Parser parser,
1388                             XML_StartNamespaceDeclHandler start,
1389                             XML_EndNamespaceDeclHandler end)
1390 {
1391   startNamespaceDeclHandler = start;
1392   endNamespaceDeclHandler = end;
1393 }
1394
1395 void XMLCALL
1396 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1397                                  XML_StartNamespaceDeclHandler start) {
1398   startNamespaceDeclHandler = start;
1399 }
1400
1401 void XMLCALL
1402 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1403                                XML_EndNamespaceDeclHandler end) {
1404   endNamespaceDeclHandler = end;
1405 }
1406
1407 void XMLCALL
1408 XML_SetNotStandaloneHandler(XML_Parser parser,
1409                             XML_NotStandaloneHandler handler)
1410 {
1411   notStandaloneHandler = handler;
1412 }
1413
1414 void XMLCALL
1415 XML_SetExternalEntityRefHandler(XML_Parser parser,
1416                                 XML_ExternalEntityRefHandler handler)
1417 {
1418   externalEntityRefHandler = handler;
1419 }
1420
1421 void XMLCALL
1422 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1423 {
1424   if (arg)
1425     externalEntityRefHandlerArg = (XML_Parser)arg;
1426   else
1427     externalEntityRefHandlerArg = parser;
1428 }
1429
1430 void XMLCALL
1431 XML_SetSkippedEntityHandler(XML_Parser parser,
1432                             XML_SkippedEntityHandler handler)
1433 {
1434   skippedEntityHandler = handler;
1435 }
1436
1437 void XMLCALL
1438 XML_SetUnknownEncodingHandler(XML_Parser parser,
1439                               XML_UnknownEncodingHandler handler,
1440                               void *data)
1441 {
1442   unknownEncodingHandler = handler;
1443   unknownEncodingHandlerData = data;
1444 }
1445
1446 void XMLCALL
1447 XML_SetElementDeclHandler(XML_Parser parser,
1448                           XML_ElementDeclHandler eldecl)
1449 {
1450   elementDeclHandler = eldecl;
1451 }
1452
1453 void XMLCALL
1454 XML_SetAttlistDeclHandler(XML_Parser parser,
1455                           XML_AttlistDeclHandler attdecl)
1456 {
1457   attlistDeclHandler = attdecl;
1458 }
1459
1460 void XMLCALL
1461 XML_SetEntityDeclHandler(XML_Parser parser,
1462                          XML_EntityDeclHandler handler)
1463 {
1464   entityDeclHandler = handler;
1465 }
1466
1467 void XMLCALL
1468 XML_SetXmlDeclHandler(XML_Parser parser,
1469                       XML_XmlDeclHandler handler) {
1470   xmlDeclHandler = handler;
1471 }
1472
1473 int XMLCALL
1474 XML_SetParamEntityParsing(XML_Parser parser,
1475                           enum XML_ParamEntityParsing peParsing)
1476 {
1477   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1478   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1479     return 0;
1480 #ifdef XML_DTD
1481   paramEntityParsing = peParsing;
1482   return 1;
1483 #else
1484   return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1485 #endif
1486 }
1487
1488 int XMLCALL
1489 XML_SetHashSalt(XML_Parser parser,
1490                 unsigned long hash_salt)
1491 {
1492   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1493   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1494     return 0;
1495   hash_secret_salt = hash_salt;
1496   return 1;
1497 }
1498
1499 enum XML_Status XMLCALL
1500 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1501 {
1502   switch (ps_parsing) {
1503   case XML_SUSPENDED:
1504     errorCode = XML_ERROR_SUSPENDED;
1505     return XML_STATUS_ERROR;
1506   case XML_FINISHED:
1507     errorCode = XML_ERROR_FINISHED;
1508     return XML_STATUS_ERROR;
1509   case XML_INITIALIZED:
1510     if (parentParser == NULL && !startParsing(parser)) {
1511       errorCode = XML_ERROR_NO_MEMORY;
1512       return XML_STATUS_ERROR;
1513     }
1514   default:
1515     ps_parsing = XML_PARSING;
1516   }
1517
1518   if (len == 0) {
1519     ps_finalBuffer = (XML_Bool)isFinal;
1520     if (!isFinal)
1521       return XML_STATUS_OK;
1522     positionPtr = bufferPtr;
1523     parseEndPtr = bufferEnd;
1524
1525     /* If data are left over from last buffer, and we now know that these
1526        data are the final chunk of input, then we have to check them again
1527        to detect errors based on that fact.
1528     */
1529     errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1530
1531     if (errorCode == XML_ERROR_NONE) {
1532       switch (ps_parsing) {
1533       case XML_SUSPENDED:
1534         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1535         positionPtr = bufferPtr;
1536         return XML_STATUS_SUSPENDED;
1537       case XML_INITIALIZED:
1538       case XML_PARSING:
1539         ps_parsing = XML_FINISHED;
1540         /* fall through */
1541       default:
1542         return XML_STATUS_OK;
1543       }
1544     }
1545     eventEndPtr = eventPtr;
1546     processor = errorProcessor;
1547     return XML_STATUS_ERROR;
1548   }
1549 #ifndef XML_CONTEXT_BYTES
1550   else if (bufferPtr == bufferEnd) {
1551     const char *end;
1552     int nLeftOver;
1553     enum XML_Error result;
1554     parseEndByteIndex += len;
1555     positionPtr = s;
1556     ps_finalBuffer = (XML_Bool)isFinal;
1557
1558     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1559
1560     if (errorCode != XML_ERROR_NONE) {
1561       eventEndPtr = eventPtr;
1562       processor = errorProcessor;
1563       return XML_STATUS_ERROR;
1564     }
1565     else {
1566       switch (ps_parsing) {
1567       case XML_SUSPENDED:
1568         result = XML_STATUS_SUSPENDED;
1569         break;
1570       case XML_INITIALIZED:
1571       case XML_PARSING:
1572         if (isFinal) {
1573           ps_parsing = XML_FINISHED;
1574           return XML_STATUS_OK;
1575         }
1576       /* fall through */
1577       default:
1578         result = XML_STATUS_OK;
1579       }
1580     }
1581
1582     XmlUpdatePosition(encoding, positionPtr, end, &position);
1583     nLeftOver = s + len - end;
1584     if (nLeftOver) {
1585       if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1586         /* FIXME avoid integer overflow */
1587         char *temp;
1588         temp = (buffer == NULL
1589                 ? (char *)MALLOC(len * 2)
1590                 : (char *)REALLOC(buffer, len * 2));
1591         if (temp == NULL) {
1592           errorCode = XML_ERROR_NO_MEMORY;
1593           eventPtr = eventEndPtr = NULL;
1594           processor = errorProcessor;
1595           return XML_STATUS_ERROR;
1596         }
1597         buffer = temp;
1598         bufferLim = buffer + len * 2;
1599       }
1600       memcpy(buffer, end, nLeftOver);
1601     }
1602     bufferPtr = buffer;
1603     bufferEnd = buffer + nLeftOver;
1604     positionPtr = bufferPtr;
1605     parseEndPtr = bufferEnd;
1606     eventPtr = bufferPtr;
1607     eventEndPtr = bufferPtr;
1608     return result;
1609   }
1610 #endif  /* not defined XML_CONTEXT_BYTES */
1611   else {
1612     void *buff = XML_GetBuffer(parser, len);
1613     if (buff == NULL)
1614       return XML_STATUS_ERROR;
1615     else {
1616       memcpy(buff, s, len);
1617       return XML_ParseBuffer(parser, len, isFinal);
1618     }
1619   }
1620 }
1621
1622 enum XML_Status XMLCALL
1623 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1624 {
1625   const char *start;
1626   enum XML_Status result = XML_STATUS_OK;
1627
1628   switch (ps_parsing) {
1629   case XML_SUSPENDED:
1630     errorCode = XML_ERROR_SUSPENDED;
1631     return XML_STATUS_ERROR;
1632   case XML_FINISHED:
1633     errorCode = XML_ERROR_FINISHED;
1634     return XML_STATUS_ERROR;
1635   case XML_INITIALIZED:
1636     if (parentParser == NULL && !startParsing(parser)) {
1637       errorCode = XML_ERROR_NO_MEMORY;
1638       return XML_STATUS_ERROR;
1639     }
1640   default:
1641     ps_parsing = XML_PARSING;
1642   }
1643
1644   start = bufferPtr;
1645   positionPtr = start;
1646   bufferEnd += len;
1647   parseEndPtr = bufferEnd;
1648   parseEndByteIndex += len;
1649   ps_finalBuffer = (XML_Bool)isFinal;
1650
1651   errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1652
1653   if (errorCode != XML_ERROR_NONE) {
1654     eventEndPtr = eventPtr;
1655     processor = errorProcessor;
1656     return XML_STATUS_ERROR;
1657   }
1658   else {
1659     switch (ps_parsing) {
1660     case XML_SUSPENDED:
1661       result = XML_STATUS_SUSPENDED;
1662       break;
1663     case XML_INITIALIZED:
1664     case XML_PARSING:
1665       if (isFinal) {
1666         ps_parsing = XML_FINISHED;
1667         return result;
1668       }
1669     default: ;  /* should not happen */
1670     }
1671   }
1672
1673   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1674   positionPtr = bufferPtr;
1675   return result;
1676 }
1677
1678 void * XMLCALL
1679 XML_GetBuffer(XML_Parser parser, int len)
1680 {
1681   switch (ps_parsing) {
1682   case XML_SUSPENDED:
1683     errorCode = XML_ERROR_SUSPENDED;
1684     return NULL;
1685   case XML_FINISHED:
1686     errorCode = XML_ERROR_FINISHED;
1687     return NULL;
1688   default: ;
1689   }
1690
1691   if (len > bufferLim - bufferEnd) {
1692     /* FIXME avoid integer overflow */
1693     int neededSize = len + (int)(bufferEnd - bufferPtr);
1694 #ifdef XML_CONTEXT_BYTES
1695     int keep = (int)(bufferPtr - buffer);
1696
1697     if (keep > XML_CONTEXT_BYTES)
1698       keep = XML_CONTEXT_BYTES;
1699     neededSize += keep;
1700 #endif  /* defined XML_CONTEXT_BYTES */
1701     if (neededSize  <= bufferLim - buffer) {
1702 #ifdef XML_CONTEXT_BYTES
1703       if (keep < bufferPtr - buffer) {
1704         int offset = (int)(bufferPtr - buffer) - keep;
1705         memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1706         bufferEnd -= offset;
1707         bufferPtr -= offset;
1708       }
1709 #else
1710       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1711       bufferEnd = buffer + (bufferEnd - bufferPtr);
1712       bufferPtr = buffer;
1713 #endif  /* not defined XML_CONTEXT_BYTES */
1714     }
1715     else {
1716       char *newBuf;
1717       int bufferSize = (int)(bufferLim - bufferPtr);
1718       if (bufferSize == 0)
1719         bufferSize = INIT_BUFFER_SIZE;
1720       do {
1721         bufferSize *= 2;
1722       } while (bufferSize < neededSize);
1723       newBuf = (char *)MALLOC(bufferSize);
1724       if (newBuf == 0) {
1725         errorCode = XML_ERROR_NO_MEMORY;
1726         return NULL;
1727       }
1728       bufferLim = newBuf + bufferSize;
1729 #ifdef XML_CONTEXT_BYTES
1730       if (bufferPtr) {
1731         int keep = (int)(bufferPtr - buffer);
1732         if (keep > XML_CONTEXT_BYTES)
1733           keep = XML_CONTEXT_BYTES;
1734         memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1735         FREE(buffer);
1736         buffer = newBuf;
1737         bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1738         bufferPtr = buffer + keep;
1739       }
1740       else {
1741         bufferEnd = newBuf + (bufferEnd - bufferPtr);
1742         bufferPtr = buffer = newBuf;
1743       }
1744 #else
1745       if (bufferPtr) {
1746         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1747         FREE(buffer);
1748       }
1749       bufferEnd = newBuf + (bufferEnd - bufferPtr);
1750       bufferPtr = buffer = newBuf;
1751 #endif  /* not defined XML_CONTEXT_BYTES */
1752     }
1753     eventPtr = eventEndPtr = NULL;
1754     positionPtr = NULL;
1755   }
1756   return bufferEnd;
1757 }
1758
1759 enum XML_Status XMLCALL
1760 XML_StopParser(XML_Parser parser, XML_Bool resumable)
1761 {
1762   switch (ps_parsing) {
1763   case XML_SUSPENDED:
1764     if (resumable) {
1765       errorCode = XML_ERROR_SUSPENDED;
1766       return XML_STATUS_ERROR;
1767     }
1768     ps_parsing = XML_FINISHED;
1769     break;
1770   case XML_FINISHED:
1771     errorCode = XML_ERROR_FINISHED;
1772     return XML_STATUS_ERROR;
1773   default:
1774     if (resumable) {
1775 #ifdef XML_DTD
1776       if (isParamEntity) {
1777         errorCode = XML_ERROR_SUSPEND_PE;
1778         return XML_STATUS_ERROR;
1779       }
1780 #endif
1781       ps_parsing = XML_SUSPENDED;
1782     }
1783     else
1784       ps_parsing = XML_FINISHED;
1785   }
1786   return XML_STATUS_OK;
1787 }
1788
1789 enum XML_Status XMLCALL
1790 XML_ResumeParser(XML_Parser parser)
1791 {
1792   enum XML_Status result = XML_STATUS_OK;
1793
1794   if (ps_parsing != XML_SUSPENDED) {
1795     errorCode = XML_ERROR_NOT_SUSPENDED;
1796     return XML_STATUS_ERROR;
1797   }
1798   ps_parsing = XML_PARSING;
1799
1800   errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1801
1802   if (errorCode != XML_ERROR_NONE) {
1803     eventEndPtr = eventPtr;
1804     processor = errorProcessor;
1805     return XML_STATUS_ERROR;
1806   }
1807   else {
1808     switch (ps_parsing) {
1809     case XML_SUSPENDED:
1810       result = XML_STATUS_SUSPENDED;
1811       break;
1812     case XML_INITIALIZED:
1813     case XML_PARSING:
1814       if (ps_finalBuffer) {
1815         ps_parsing = XML_FINISHED;
1816         return result;
1817       }
1818     default: ;
1819     }
1820   }
1821
1822   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1823   positionPtr = bufferPtr;
1824   return result;
1825 }
1826
1827 void XMLCALL
1828 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1829 {
1830   assert(status != NULL);
1831   *status = parser->m_parsingStatus;
1832 }
1833
1834 enum XML_Error XMLCALL
1835 XML_GetErrorCode(XML_Parser parser)
1836 {
1837   return errorCode;
1838 }
1839
1840 XML_Index XMLCALL
1841 XML_GetCurrentByteIndex(XML_Parser parser)
1842 {
1843   if (eventPtr)
1844     return parseEndByteIndex - (parseEndPtr - eventPtr);
1845   return -1;
1846 }
1847
1848 int XMLCALL
1849 XML_GetCurrentByteCount(XML_Parser parser)
1850 {
1851   if (eventEndPtr && eventPtr)
1852     return (int)(eventEndPtr - eventPtr);
1853   return 0;
1854 }
1855
1856 const char * XMLCALL
1857 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1858 {
1859 #ifdef XML_CONTEXT_BYTES
1860   if (eventPtr && buffer) {
1861     *offset = (int)(eventPtr - buffer);
1862     *size   = (int)(bufferEnd - buffer);
1863     return buffer;
1864   }
1865 #endif /* defined XML_CONTEXT_BYTES */
1866   return (char *) 0;
1867 }
1868
1869 XML_Size XMLCALL
1870 XML_GetCurrentLineNumber(XML_Parser parser)
1871 {
1872   if (eventPtr && eventPtr >= positionPtr) {
1873     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1874     positionPtr = eventPtr;
1875   }
1876   return position.lineNumber + 1;
1877 }
1878
1879 XML_Size XMLCALL
1880 XML_GetCurrentColumnNumber(XML_Parser parser)
1881 {
1882   if (eventPtr && eventPtr >= positionPtr) {
1883     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1884     positionPtr = eventPtr;
1885   }
1886   return position.columnNumber;
1887 }
1888
1889 void XMLCALL
1890 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1891 {
1892   FREE(model);
1893 }
1894
1895 void * XMLCALL
1896 XML_MemMalloc(XML_Parser parser, size_t size)
1897 {
1898   return MALLOC(size);
1899 }
1900
1901 void * XMLCALL
1902 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1903 {
1904   return REALLOC(ptr, size);
1905 }
1906
1907 void XMLCALL
1908 XML_MemFree(XML_Parser parser, void *ptr)
1909 {
1910   FREE(ptr);
1911 }
1912
1913 void XMLCALL
1914 XML_DefaultCurrent(XML_Parser parser)
1915 {
1916   if (defaultHandler) {
1917     if (openInternalEntities)
1918       reportDefault(parser,
1919                     internalEncoding,
1920                     openInternalEntities->internalEventPtr,
1921                     openInternalEntities->internalEventEndPtr);
1922     else
1923       reportDefault(parser, encoding, eventPtr, eventEndPtr);
1924   }
1925 }
1926
1927 const XML_LChar * XMLCALL
1928 XML_ErrorString(enum XML_Error code)
1929 {
1930   static const XML_LChar* const message[] = {
1931     0,
1932     XML_L("out of memory"),
1933     XML_L("syntax error"),
1934     XML_L("no element found"),
1935     XML_L("not well-formed (invalid token)"),
1936     XML_L("unclosed token"),
1937     XML_L("partial character"),
1938     XML_L("mismatched tag"),
1939     XML_L("duplicate attribute"),
1940     XML_L("junk after document element"),
1941     XML_L("illegal parameter entity reference"),
1942     XML_L("undefined entity"),
1943     XML_L("recursive entity reference"),
1944     XML_L("asynchronous entity"),
1945     XML_L("reference to invalid character number"),
1946     XML_L("reference to binary entity"),
1947     XML_L("reference to external entity in attribute"),
1948     XML_L("XML or text declaration not at start of entity"),
1949     XML_L("unknown encoding"),
1950     XML_L("encoding specified in XML declaration is incorrect"),
1951     XML_L("unclosed CDATA section"),
1952     XML_L("error in processing external entity reference"),
1953     XML_L("document is not standalone"),
1954     XML_L("unexpected parser state - please send a bug report"),
1955     XML_L("entity declared in parameter entity"),
1956     XML_L("requested feature requires XML_DTD support in Expat"),
1957     XML_L("cannot change setting once parsing has begun"),
1958     XML_L("unbound prefix"),
1959     XML_L("must not undeclare prefix"),
1960     XML_L("incomplete markup in parameter entity"),
1961     XML_L("XML declaration not well-formed"),
1962     XML_L("text declaration not well-formed"),
1963     XML_L("illegal character(s) in public id"),
1964     XML_L("parser suspended"),
1965     XML_L("parser not suspended"),
1966     XML_L("parsing aborted"),
1967     XML_L("parsing finished"),
1968     XML_L("cannot suspend in external parameter entity"),
1969     XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1970     XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1971     XML_L("prefix must not be bound to one of the reserved namespace names")
1972   };
1973   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1974     return message[code];
1975   return NULL;
1976 }
1977
1978 const XML_LChar * XMLCALL
1979 XML_ExpatVersion(void) {
1980
1981   /* V1 is used to string-ize the version number. However, it would
1982      string-ize the actual version macro *names* unless we get them
1983      substituted before being passed to V1. CPP is defined to expand
1984      a macro, then rescan for more expansions. Thus, we use V2 to expand
1985      the version macros, then CPP will expand the resulting V1() macro
1986      with the correct numerals. */
1987   /* ### I'm assuming cpp is portable in this respect... */
1988
1989 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1990 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1991
1992   return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1993
1994 #undef V1
1995 #undef V2
1996 }
1997
1998 XML_Expat_Version XMLCALL
1999 XML_ExpatVersionInfo(void)
2000 {
2001   XML_Expat_Version version;
2002
2003   version.major = XML_MAJOR_VERSION;
2004   version.minor = XML_MINOR_VERSION;
2005   version.micro = XML_MICRO_VERSION;
2006
2007   return version;
2008 }
2009
2010 const XML_Feature * XMLCALL
2011 XML_GetFeatureList(void)
2012 {
2013   static const XML_Feature features[] = {
2014     {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
2015      sizeof(XML_Char)},
2016     {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2017      sizeof(XML_LChar)},
2018 #ifdef XML_UNICODE
2019     {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
2020 #endif
2021 #ifdef XML_UNICODE_WCHAR_T
2022     {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
2023 #endif
2024 #ifdef XML_DTD
2025     {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
2026 #endif
2027 #ifdef XML_CONTEXT_BYTES
2028     {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
2029      XML_CONTEXT_BYTES},
2030 #endif
2031 #ifdef XML_MIN_SIZE
2032     {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
2033 #endif
2034 #ifdef XML_NS
2035     {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
2036 #endif
2037 #ifdef XML_LARGE_SIZE
2038     {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
2039 #endif
2040 #ifdef XML_ATTR_INFO
2041     {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
2042 #endif
2043     {XML_FEATURE_END,              NULL, 0}
2044   };
2045
2046   return features;
2047 }
2048
2049 /* Initially tag->rawName always points into the parse buffer;
2050    for those TAG instances opened while the current parse buffer was
2051    processed, and not yet closed, we need to store tag->rawName in a more
2052    permanent location, since the parse buffer is about to be discarded.
2053 */
2054 static XML_Bool
2055 storeRawNames(XML_Parser parser)
2056 {
2057   TAG *tag = tagStack;
2058   while (tag) {
2059     int bufSize;
2060     int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2061     char *rawNameBuf = tag->buf + nameLen;
2062     /* Stop if already stored.  Since tagStack is a stack, we can stop
2063        at the first entry that has already been copied; everything
2064        below it in the stack is already been accounted for in a
2065        previous call to this function.
2066     */
2067     if (tag->rawName == rawNameBuf)
2068       break;
2069     /* For re-use purposes we need to ensure that the
2070        size of tag->buf is a multiple of sizeof(XML_Char).
2071     */
2072     bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2073     if (bufSize > tag->bufEnd - tag->buf) {
2074       char *temp = (char *)REALLOC(tag->buf, bufSize);
2075       if (temp == NULL)
2076         return XML_FALSE;
2077       /* if tag->name.str points to tag->buf (only when namespace
2078          processing is off) then we have to update it
2079       */
2080       if (tag->name.str == (XML_Char *)tag->buf)
2081         tag->name.str = (XML_Char *)temp;
2082       /* if tag->name.localPart is set (when namespace processing is on)
2083          then update it as well, since it will always point into tag->buf
2084       */
2085       if (tag->name.localPart)
2086         tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2087                                                   (XML_Char *)tag->buf);
2088       tag->buf = temp;
2089       tag->bufEnd = temp + bufSize;
2090       rawNameBuf = temp + nameLen;
2091     }
2092     memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2093     tag->rawName = rawNameBuf;
2094     tag = tag->parent;
2095   }
2096   return XML_TRUE;
2097 }
2098
2099 static enum XML_Error PTRCALL
2100 contentProcessor(XML_Parser parser,
2101                  const char *start,
2102                  const char *end,
2103                  const char **endPtr)
2104 {
2105   enum XML_Error result = doContent(parser, 0, encoding, start, end,
2106                                     endPtr, (XML_Bool)!ps_finalBuffer);
2107   if (result == XML_ERROR_NONE) {
2108     if (!storeRawNames(parser))
2109       return XML_ERROR_NO_MEMORY;
2110   }
2111   return result;
2112 }
2113
2114 static enum XML_Error PTRCALL
2115 externalEntityInitProcessor(XML_Parser parser,
2116                             const char *start,
2117                             const char *end,
2118                             const char **endPtr)
2119 {
2120   enum XML_Error result = initializeEncoding(parser);
2121   if (result != XML_ERROR_NONE)
2122     return result;
2123   processor = externalEntityInitProcessor2;
2124   return externalEntityInitProcessor2(parser, start, end, endPtr);
2125 }
2126
2127 static enum XML_Error PTRCALL
2128 externalEntityInitProcessor2(XML_Parser parser,
2129                              const char *start,
2130                              const char *end,
2131                              const char **endPtr)
2132 {
2133   const char *next = start; /* XmlContentTok doesn't always set the last arg */
2134   int tok = XmlContentTok(encoding, start, end, &next);
2135   switch (tok) {
2136   case XML_TOK_BOM:
2137     /* If we are at the end of the buffer, this would cause the next stage,
2138        i.e. externalEntityInitProcessor3, to pass control directly to
2139        doContent (by detecting XML_TOK_NONE) without processing any xml text
2140        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2141     */
2142     if (next == end && !ps_finalBuffer) {
2143       *endPtr = next;
2144       return XML_ERROR_NONE;
2145     }
2146     start = next;
2147     break;
2148   case XML_TOK_PARTIAL:
2149     if (!ps_finalBuffer) {
2150       *endPtr = start;
2151       return XML_ERROR_NONE;
2152     }
2153     eventPtr = start;
2154     return XML_ERROR_UNCLOSED_TOKEN;
2155   case XML_TOK_PARTIAL_CHAR:
2156     if (!ps_finalBuffer) {
2157       *endPtr = start;
2158       return XML_ERROR_NONE;
2159     }
2160     eventPtr = start;
2161     return XML_ERROR_PARTIAL_CHAR;
2162   }
2163   processor = externalEntityInitProcessor3;
2164   return externalEntityInitProcessor3(parser, start, end, endPtr);
2165 }
2166
2167 static enum XML_Error PTRCALL
2168 externalEntityInitProcessor3(XML_Parser parser,
2169                              const char *start,
2170                              const char *end,
2171                              const char **endPtr)
2172 {
2173   int tok;
2174   const char *next = start; /* XmlContentTok doesn't always set the last arg */
2175   eventPtr = start;
2176   tok = XmlContentTok(encoding, start, end, &next);
2177   eventEndPtr = next;
2178
2179   switch (tok) {
2180   case XML_TOK_XML_DECL:
2181     {
2182       enum XML_Error result;
2183       result = processXmlDecl(parser, 1, start, next);
2184       if (result != XML_ERROR_NONE)
2185         return result;
2186       switch (ps_parsing) {
2187       case XML_SUSPENDED:
2188         *endPtr = next;
2189         return XML_ERROR_NONE;
2190       case XML_FINISHED:
2191         return XML_ERROR_ABORTED;
2192       default:
2193         start = next;
2194       }
2195     }
2196     break;
2197   case XML_TOK_PARTIAL:
2198     if (!ps_finalBuffer) {
2199       *endPtr = start;
2200       return XML_ERROR_NONE;
2201     }
2202     return XML_ERROR_UNCLOSED_TOKEN;
2203   case XML_TOK_PARTIAL_CHAR:
2204     if (!ps_finalBuffer) {
2205       *endPtr = start;
2206       return XML_ERROR_NONE;
2207     }
2208     return XML_ERROR_PARTIAL_CHAR;
2209   }
2210   processor = externalEntityContentProcessor;
2211   tagLevel = 1;
2212   return externalEntityContentProcessor(parser, start, end, endPtr);
2213 }
2214
2215 static enum XML_Error PTRCALL
2216 externalEntityContentProcessor(XML_Parser parser,
2217                                const char *start,
2218                                const char *end,
2219                                const char **endPtr)
2220 {
2221   enum XML_Error result = doContent(parser, 1, encoding, start, end,
2222                                     endPtr, (XML_Bool)!ps_finalBuffer);
2223   if (result == XML_ERROR_NONE) {
2224     if (!storeRawNames(parser))
2225       return XML_ERROR_NO_MEMORY;
2226   }
2227   return result;
2228 }
2229
2230 static enum XML_Error
2231 doContent(XML_Parser parser,
2232           int startTagLevel,
2233           const ENCODING *enc,
2234           const char *s,
2235           const char *end,
2236           const char **nextPtr,
2237           XML_Bool haveMore)
2238 {
2239   /* save one level of indirection */
2240   DTD * const dtd = _dtd;
2241
2242   const char **eventPP;
2243   const char **eventEndPP;
2244   if (enc == encoding) {
2245     eventPP = &eventPtr;
2246     eventEndPP = &eventEndPtr;
2247   }
2248   else {
2249     eventPP = &(openInternalEntities->internalEventPtr);
2250     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2251   }
2252   *eventPP = s;
2253
2254   for (;;) {
2255     const char *next = s; /* XmlContentTok doesn't always set the last arg */
2256     int tok = XmlContentTok(enc, s, end, &next);
2257     *eventEndPP = next;
2258     switch (tok) {
2259     case XML_TOK_TRAILING_CR:
2260       if (haveMore) {
2261         *nextPtr = s;
2262         return XML_ERROR_NONE;
2263       }
2264       *eventEndPP = end;
2265       if (characterDataHandler) {
2266         XML_Char c = 0xA;
2267         characterDataHandler(handlerArg, &c, 1);
2268       }
2269       else if (defaultHandler)
2270         reportDefault(parser, enc, s, end);
2271       /* We are at the end of the final buffer, should we check for
2272          XML_SUSPENDED, XML_FINISHED?
2273       */
2274       if (startTagLevel == 0)
2275         return XML_ERROR_NO_ELEMENTS;
2276       if (tagLevel != startTagLevel)
2277         return XML_ERROR_ASYNC_ENTITY;
2278       *nextPtr = end;
2279       return XML_ERROR_NONE;
2280     case XML_TOK_NONE:
2281       if (haveMore) {
2282         *nextPtr = s;
2283         return XML_ERROR_NONE;
2284       }
2285       if (startTagLevel > 0) {
2286         if (tagLevel != startTagLevel)
2287           return XML_ERROR_ASYNC_ENTITY;
2288         *nextPtr = s;
2289         return XML_ERROR_NONE;
2290       }
2291       return XML_ERROR_NO_ELEMENTS;
2292     case XML_TOK_INVALID:
2293       *eventPP = next;
2294       return XML_ERROR_INVALID_TOKEN;
2295     case XML_TOK_PARTIAL:
2296       if (haveMore) {
2297         *nextPtr = s;
2298         return XML_ERROR_NONE;
2299       }
2300       return XML_ERROR_UNCLOSED_TOKEN;
2301     case XML_TOK_PARTIAL_CHAR:
2302       if (haveMore) {
2303         *nextPtr = s;
2304         return XML_ERROR_NONE;
2305       }
2306       return XML_ERROR_PARTIAL_CHAR;
2307     case XML_TOK_ENTITY_REF:
2308       {
2309         const XML_Char *name;
2310         ENTITY *entity;
2311         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2312                                               s + enc->minBytesPerChar,
2313                                               next - enc->minBytesPerChar);
2314         if (ch) {
2315           if (characterDataHandler)
2316             characterDataHandler(handlerArg, &ch, 1);
2317           else if (defaultHandler)
2318             reportDefault(parser, enc, s, next);
2319           break;
2320         }
2321         name = poolStoreString(&dtd->pool, enc,
2322                                 s + enc->minBytesPerChar,
2323                                 next - enc->minBytesPerChar);
2324         if (!name)
2325           return XML_ERROR_NO_MEMORY;
2326         entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2327         poolDiscard(&dtd->pool);
2328         /* First, determine if a check for an existing declaration is needed;
2329            if yes, check that the entity exists, and that it is internal,
2330            otherwise call the skipped entity or default handler.
2331         */
2332         if (!dtd->hasParamEntityRefs || dtd->standalone) {
2333           if (!entity)
2334             return XML_ERROR_UNDEFINED_ENTITY;
2335           else if (!entity->is_internal)
2336             return XML_ERROR_ENTITY_DECLARED_IN_PE;
2337         }
2338         else if (!entity) {
2339           if (skippedEntityHandler)
2340             skippedEntityHandler(handlerArg, name, 0);
2341           else if (defaultHandler)
2342             reportDefault(parser, enc, s, next);
2343           break;
2344         }
2345         if (entity->open)
2346           return XML_ERROR_RECURSIVE_ENTITY_REF;
2347         if (entity->notation)
2348           return XML_ERROR_BINARY_ENTITY_REF;
2349         if (entity->textPtr) {
2350           enum XML_Error result;
2351           if (!defaultExpandInternalEntities) {
2352             if (skippedEntityHandler)
2353               skippedEntityHandler(handlerArg, entity->name, 0);
2354             else if (defaultHandler)
2355               reportDefault(parser, enc, s, next);
2356             break;
2357           }
2358           result = processInternalEntity(parser, entity, XML_FALSE);
2359           if (result != XML_ERROR_NONE)
2360             return result;
2361         }
2362         else if (externalEntityRefHandler) {
2363           const XML_Char *context;
2364           entity->open = XML_TRUE;
2365           context = getContext(parser);
2366           entity->open = XML_FALSE;
2367           if (!context)
2368             return XML_ERROR_NO_MEMORY;
2369           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2370                                         context,
2371                                         entity->base,
2372                                         entity->systemId,
2373                                         entity->publicId))
2374             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2375           poolDiscard(&tempPool);
2376         }
2377         else if (defaultHandler)
2378           reportDefault(parser, enc, s, next);
2379         break;
2380       }
2381     case XML_TOK_START_TAG_NO_ATTS:
2382       /* fall through */
2383     case XML_TOK_START_TAG_WITH_ATTS:
2384       {
2385         TAG *tag;
2386         enum XML_Error result;
2387         XML_Char *toPtr;
2388         if (freeTagList) {
2389           tag = freeTagList;
2390           freeTagList = freeTagList->parent;
2391         }
2392         else {
2393           tag = (TAG *)MALLOC(sizeof(TAG));
2394           if (!tag)
2395             return XML_ERROR_NO_MEMORY;
2396           tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2397           if (!tag->buf) {
2398             FREE(tag);
2399             return XML_ERROR_NO_MEMORY;
2400           }
2401           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2402         }
2403         tag->bindings = NULL;
2404         tag->parent = tagStack;
2405         tagStack = tag;
2406         tag->name.localPart = NULL;
2407         tag->name.prefix = NULL;
2408         tag->rawName = s + enc->minBytesPerChar;
2409         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2410         ++tagLevel;
2411         {
2412           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2413           const char *fromPtr = tag->rawName;
2414           toPtr = (XML_Char *)tag->buf;
2415           for (;;) {
2416             int bufSize;
2417             int convLen;
2418             XmlConvert(enc,
2419                        &fromPtr, rawNameEnd,
2420                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2421             convLen = (int)(toPtr - (XML_Char *)tag->buf);
2422             if (fromPtr == rawNameEnd) {
2423               tag->name.strLen = convLen;
2424               break;
2425             }
2426             bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2427             {
2428               char *temp = (char *)REALLOC(tag->buf, bufSize);
2429               if (temp == NULL)
2430                 return XML_ERROR_NO_MEMORY;
2431               tag->buf = temp;
2432               tag->bufEnd = temp + bufSize;
2433               toPtr = (XML_Char *)temp + convLen;
2434             }
2435           }
2436         }
2437         tag->name.str = (XML_Char *)tag->buf;
2438         *toPtr = XML_T('\0');
2439         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2440         if (result)
2441           return result;
2442         if (startElementHandler)
2443           startElementHandler(handlerArg, tag->name.str,
2444                               (const XML_Char **)atts);
2445         else if (defaultHandler)
2446           reportDefault(parser, enc, s, next);
2447         poolClear(&tempPool);
2448         break;
2449       }
2450     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2451       /* fall through */
2452     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2453       {
2454         const char *rawName = s + enc->minBytesPerChar;
2455         enum XML_Error result;
2456         BINDING *bindings = NULL;
2457         XML_Bool noElmHandlers = XML_TRUE;
2458         TAG_NAME name;
2459         name.str = poolStoreString(&tempPool, enc, rawName,
2460                                    rawName + XmlNameLength(enc, rawName));
2461         if (!name.str)
2462           return XML_ERROR_NO_MEMORY;
2463         poolFinish(&tempPool);
2464         result = storeAtts(parser, enc, s, &name, &bindings);
2465         if (result)
2466           return result;
2467         poolFinish(&tempPool);
2468         if (startElementHandler) {
2469           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2470           noElmHandlers = XML_FALSE;
2471         }
2472         if (endElementHandler) {
2473           if (startElementHandler)
2474             *eventPP = *eventEndPP;
2475           endElementHandler(handlerArg, name.str);
2476           noElmHandlers = XML_FALSE;
2477         }
2478         if (noElmHandlers && defaultHandler)
2479           reportDefault(parser, enc, s, next);
2480         poolClear(&tempPool);
2481         while (bindings) {
2482           BINDING *b = bindings;
2483           if (endNamespaceDeclHandler)
2484             endNamespaceDeclHandler(handlerArg, b->prefix->name);
2485           bindings = bindings->nextTagBinding;
2486           b->nextTagBinding = freeBindingList;
2487           freeBindingList = b;
2488           b->prefix->binding = b->prevPrefixBinding;
2489         }
2490       }
2491       if (tagLevel == 0)
2492         return epilogProcessor(parser, next, end, nextPtr);
2493       break;
2494     case XML_TOK_END_TAG:
2495       if (tagLevel == startTagLevel)
2496         return XML_ERROR_ASYNC_ENTITY;
2497       else {
2498         int len;
2499         const char *rawName;
2500         TAG *tag = tagStack;
2501         tagStack = tag->parent;
2502         tag->parent = freeTagList;
2503         freeTagList = tag;
2504         rawName = s + enc->minBytesPerChar*2;
2505         len = XmlNameLength(enc, rawName);
2506         if (len != tag->rawNameLength
2507             || memcmp(tag->rawName, rawName, len) != 0) {
2508           *eventPP = rawName;
2509           return XML_ERROR_TAG_MISMATCH;
2510         }
2511         --tagLevel;
2512         if (endElementHandler) {
2513           const XML_Char *localPart;
2514           const XML_Char *prefix;
2515           XML_Char *uri;
2516           localPart = tag->name.localPart;
2517           if (ns && localPart) {
2518             /* localPart and prefix may have been overwritten in
2519                tag->name.str, since this points to the binding->uri
2520                buffer which gets re-used; so we have to add them again
2521             */
2522             uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2523             /* don't need to check for space - already done in storeAtts() */
2524             while (*localPart) *uri++ = *localPart++;
2525             prefix = (XML_Char *)tag->name.prefix;
2526             if (ns_triplets && prefix) {
2527               *uri++ = namespaceSeparator;
2528               while (*prefix) *uri++ = *prefix++;
2529              }
2530             *uri = XML_T('\0');
2531           }
2532           endElementHandler(handlerArg, tag->name.str);
2533         }
2534         else if (defaultHandler)
2535           reportDefault(parser, enc, s, next);
2536         while (tag->bindings) {
2537           BINDING *b = tag->bindings;
2538           if (endNamespaceDeclHandler)
2539             endNamespaceDeclHandler(handlerArg, b->prefix->name);
2540           tag->bindings = tag->bindings->nextTagBinding;
2541           b->nextTagBinding = freeBindingList;
2542           freeBindingList = b;
2543           b->prefix->binding = b->prevPrefixBinding;
2544         }
2545         if (tagLevel == 0)
2546           return epilogProcessor(parser, next, end, nextPtr);
2547       }
2548       break;
2549     case XML_TOK_CHAR_REF:
2550       {
2551         int n = XmlCharRefNumber(enc, s);
2552         if (n < 0)
2553           return XML_ERROR_BAD_CHAR_REF;
2554         if (characterDataHandler) {
2555           XML_Char buf[XML_ENCODE_MAX];
2556           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2557         }
2558         else if (defaultHandler)
2559           reportDefault(parser, enc, s, next);
2560       }
2561       break;
2562     case XML_TOK_XML_DECL:
2563       return XML_ERROR_MISPLACED_XML_PI;
2564     case XML_TOK_DATA_NEWLINE:
2565       if (characterDataHandler) {
2566         XML_Char c = 0xA;
2567         characterDataHandler(handlerArg, &c, 1);
2568       }
2569       else if (defaultHandler)
2570         reportDefault(parser, enc, s, next);
2571       break;
2572     case XML_TOK_CDATA_SECT_OPEN:
2573       {
2574         enum XML_Error result;
2575         if (startCdataSectionHandler)
2576           startCdataSectionHandler(handlerArg);
2577 #if 0
2578         /* Suppose you doing a transformation on a document that involves
2579            changing only the character data.  You set up a defaultHandler
2580            and a characterDataHandler.  The defaultHandler simply copies
2581            characters through.  The characterDataHandler does the
2582            transformation and writes the characters out escaping them as
2583            necessary.  This case will fail to work if we leave out the
2584            following two lines (because & and < inside CDATA sections will
2585            be incorrectly escaped).
2586
2587            However, now we have a start/endCdataSectionHandler, so it seems
2588            easier to let the user deal with this.
2589         */
2590         else if (characterDataHandler)
2591           characterDataHandler(handlerArg, dataBuf, 0);
2592 #endif
2593         else if (defaultHandler)
2594           reportDefault(parser, enc, s, next);
2595         result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2596         if (result != XML_ERROR_NONE)
2597           return result;
2598         else if (!next) {
2599           processor = cdataSectionProcessor;
2600           return result;
2601         }
2602       }
2603       break;
2604     case XML_TOK_TRAILING_RSQB:
2605       if (haveMore) {
2606         *nextPtr = s;
2607         return XML_ERROR_NONE;
2608       }
2609       if (characterDataHandler) {
2610         if (MUST_CONVERT(enc, s)) {
2611           ICHAR *dataPtr = (ICHAR *)dataBuf;
2612           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2613           characterDataHandler(handlerArg, dataBuf,
2614                                (int)(dataPtr - (ICHAR *)dataBuf));
2615         }
2616         else
2617           characterDataHandler(handlerArg,
2618                                (XML_Char *)s,
2619                                (int)((XML_Char *)end - (XML_Char *)s));
2620       }
2621       else if (defaultHandler)
2622         reportDefault(parser, enc, s, end);
2623       /* We are at the end of the final buffer, should we check for
2624          XML_SUSPENDED, XML_FINISHED?
2625       */
2626       if (startTagLevel == 0) {
2627         *eventPP = end;
2628         return XML_ERROR_NO_ELEMENTS;
2629       }
2630       if (tagLevel != startTagLevel) {
2631         *eventPP = end;
2632         return XML_ERROR_ASYNC_ENTITY;
2633       }
2634       *nextPtr = end;
2635       return XML_ERROR_NONE;
2636     case XML_TOK_DATA_CHARS:
2637       {
2638         XML_CharacterDataHandler charDataHandler = characterDataHandler;
2639         if (charDataHandler) {
2640           if (MUST_CONVERT(enc, s)) {
2641             for (;;) {
2642               ICHAR *dataPtr = (ICHAR *)dataBuf;
2643               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2644               *eventEndPP = s;
2645               charDataHandler(handlerArg, dataBuf,
2646                               (int)(dataPtr - (ICHAR *)dataBuf));
2647               if (s == next)
2648                 break;
2649               *eventPP = s;
2650             }
2651           }
2652           else
2653             charDataHandler(handlerArg,
2654                             (XML_Char *)s,
2655                             (int)((XML_Char *)next - (XML_Char *)s));
2656         }
2657         else if (defaultHandler)
2658           reportDefault(parser, enc, s, next);
2659       }
2660       break;
2661     case XML_TOK_PI:
2662       if (!reportProcessingInstruction(parser, enc, s, next))
2663         return XML_ERROR_NO_MEMORY;
2664       break;
2665     case XML_TOK_COMMENT:
2666       if (!reportComment(parser, enc, s, next))
2667         return XML_ERROR_NO_MEMORY;
2668       break;
2669     default:
2670       if (defaultHandler)
2671         reportDefault(parser, enc, s, next);
2672       break;
2673     }
2674     *eventPP = s = next;
2675     switch (ps_parsing) {
2676     case XML_SUSPENDED:
2677       *nextPtr = next;
2678       return XML_ERROR_NONE;
2679     case XML_FINISHED:
2680       return XML_ERROR_ABORTED;
2681     default: ;
2682     }
2683   }
2684   /* not reached */
2685 }
2686
2687 /* Precondition: all arguments must be non-NULL;
2688    Purpose:
2689    - normalize attributes
2690    - check attributes for well-formedness
2691    - generate namespace aware attribute names (URI, prefix)
2692    - build list of attributes for startElementHandler
2693    - default attributes
2694    - process namespace declarations (check and report them)
2695    - generate namespace aware element name (URI, prefix)
2696 */
2697 static enum XML_Error
2698 storeAtts(XML_Parser parser, const ENCODING *enc,
2699           const char *attStr, TAG_NAME *tagNamePtr,
2700           BINDING **bindingsPtr)
2701 {
2702   DTD * const dtd = _dtd;  /* save one level of indirection */
2703   ELEMENT_TYPE *elementType;
2704   int nDefaultAtts;
2705   const XML_Char **appAtts;   /* the attribute list for the application */
2706   int attIndex = 0;
2707   int prefixLen;
2708   int i;
2709   int n;
2710   XML_Char *uri;
2711   int nPrefixes = 0;
2712   BINDING *binding;
2713   const XML_Char *localPart;
2714
2715   /* lookup the element type name */
2716   elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
2717   if (!elementType) {
2718     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2719     if (!name)
2720       return XML_ERROR_NO_MEMORY;
2721     elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
2722                                          sizeof(ELEMENT_TYPE));
2723     if (!elementType)
2724       return XML_ERROR_NO_MEMORY;
2725     if (ns && !setElementTypePrefix(parser, elementType))
2726       return XML_ERROR_NO_MEMORY;
2727   }
2728   nDefaultAtts = elementType->nDefaultAtts;
2729
2730   /* get the attributes from the tokenizer */
2731   n = XmlGetAttributes(enc, attStr, attsSize, atts);
2732   if (n + nDefaultAtts > attsSize) {
2733     int oldAttsSize = attsSize;
2734     ATTRIBUTE *temp;
2735 #ifdef XML_ATTR_INFO
2736     XML_AttrInfo *temp2;
2737 #endif
2738     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2739     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2740     if (temp == NULL)
2741       return XML_ERROR_NO_MEMORY;
2742     atts = temp;
2743 #ifdef XML_ATTR_INFO
2744     temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
2745     if (temp2 == NULL)
2746       return XML_ERROR_NO_MEMORY;
2747     attInfo = temp2;
2748 #endif
2749     if (n > oldAttsSize)
2750       XmlGetAttributes(enc, attStr, n, atts);
2751   }
2752
2753   appAtts = (const XML_Char **)atts;
2754   for (i = 0; i < n; i++) {
2755     ATTRIBUTE *currAtt = &atts[i];
2756 #ifdef XML_ATTR_INFO
2757     XML_AttrInfo *currAttInfo = &attInfo[i];
2758 #endif
2759     /* add the name and value to the attribute list */
2760     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2761                                          currAtt->name
2762                                          + XmlNameLength(enc, currAtt->name));
2763     if (!attId)
2764       return XML_ERROR_NO_MEMORY;
2765 #ifdef XML_ATTR_INFO
2766     currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
2767     currAttInfo->nameEnd = currAttInfo->nameStart +
2768                            XmlNameLength(enc, currAtt->name);
2769     currAttInfo->valueStart = parseEndByteIndex -
2770                             (parseEndPtr - currAtt->valuePtr);
2771     currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
2772 #endif
2773     /* Detect duplicate attributes by their QNames. This does not work when
2774        namespace processing is turned on and different prefixes for the same
2775        namespace are used. For this case we have a check further down.
2776     */
2777     if ((attId->name)[-1]) {
2778       if (enc == encoding)
2779         eventPtr = atts[i].name;
2780       return XML_ERROR_DUPLICATE_ATTRIBUTE;
2781     }
2782     (attId->name)[-1] = 1;
2783     appAtts[attIndex++] = attId->name;
2784     if (!atts[i].normalized) {
2785       enum XML_Error result;
2786       XML_Bool isCdata = XML_TRUE;
2787
2788       /* figure out whether declared as other than CDATA */
2789       if (attId->maybeTokenized) {
2790         int j;
2791         for (j = 0; j < nDefaultAtts; j++) {
2792           if (attId == elementType->defaultAtts[j].id) {
2793             isCdata = elementType->defaultAtts[j].isCdata;
2794             break;
2795           }
2796         }
2797       }
2798
2799       /* normalize the attribute value */
2800       result = storeAttributeValue(parser, enc, isCdata,
2801                                    atts[i].valuePtr, atts[i].valueEnd,
2802                                    &tempPool);
2803       if (result)
2804         return result;
2805       appAtts[attIndex] = poolStart(&tempPool);
2806       poolFinish(&tempPool);
2807     }
2808     else {
2809       /* the value did not need normalizing */
2810       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2811                                           atts[i].valueEnd);
2812       if (appAtts[attIndex] == 0)
2813         return XML_ERROR_NO_MEMORY;
2814       poolFinish(&tempPool);
2815     }
2816     /* handle prefixed attribute names */
2817     if (attId->prefix) {
2818       if (attId->xmlns) {
2819         /* deal with namespace declarations here */
2820         enum XML_Error result = addBinding(parser, attId->prefix, attId,
2821                                            appAtts[attIndex], bindingsPtr);
2822         if (result)
2823           return result;
2824         --attIndex;
2825       }
2826       else {
2827         /* deal with other prefixed names later */
2828         attIndex++;
2829         nPrefixes++;
2830         (attId->name)[-1] = 2;
2831       }
2832     }
2833     else
2834       attIndex++;
2835   }
2836
2837   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2838   nSpecifiedAtts = attIndex;
2839   if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2840     for (i = 0; i < attIndex; i += 2)
2841       if (appAtts[i] == elementType->idAtt->name) {
2842         idAttIndex = i;
2843         break;
2844       }
2845   }
2846   else
2847     idAttIndex = -1;
2848
2849   /* do attribute defaulting */
2850   for (i = 0; i < nDefaultAtts; i++) {
2851     const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2852     if (!(da->id->name)[-1] && da->value) {
2853       if (da->id->prefix) {
2854         if (da->id->xmlns) {
2855           enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2856                                              da->value, bindingsPtr);
2857           if (result)
2858             return result;
2859         }
2860         else {
2861           (da->id->name)[-1] = 2;
2862           nPrefixes++;
2863           appAtts[attIndex++] = da->id->name;
2864           appAtts[attIndex++] = da->value;
2865         }
2866       }
2867       else {
2868         (da->id->name)[-1] = 1;
2869         appAtts[attIndex++] = da->id->name;
2870         appAtts[attIndex++] = da->value;
2871       }
2872     }
2873   }
2874   appAtts[attIndex] = 0;
2875
2876   /* expand prefixed attribute names, check for duplicates,
2877      and clear flags that say whether attributes were specified */
2878   i = 0;
2879   if (nPrefixes) {
2880     int j;  /* hash table index */
2881     unsigned long version = nsAttsVersion;
2882     int nsAttsSize = (int)1 << nsAttsPower;
2883     /* size of hash table must be at least 2 * (# of prefixed attributes) */
2884     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
2885       NS_ATT *temp;
2886       /* hash table size must also be a power of 2 and >= 8 */
2887       while (nPrefixes >> nsAttsPower++);
2888       if (nsAttsPower < 3)
2889         nsAttsPower = 3;
2890       nsAttsSize = (int)1 << nsAttsPower;
2891       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2892       if (!temp)
2893         return XML_ERROR_NO_MEMORY;
2894       nsAtts = temp;
2895       version = 0;  /* force re-initialization of nsAtts hash table */
2896     }
2897     /* using a version flag saves us from initializing nsAtts every time */
2898     if (!version) {  /* initialize version flags when version wraps around */
2899       version = INIT_ATTS_VERSION;
2900       for (j = nsAttsSize; j != 0; )
2901         nsAtts[--j].version = version;
2902     }
2903     nsAttsVersion = --version;
2904
2905     /* expand prefixed names and check for duplicates */
2906     for (; i < attIndex; i += 2) {
2907       const XML_Char *s = appAtts[i];
2908       if (s[-1] == 2) {  /* prefixed */
2909         ATTRIBUTE_ID *id;
2910         const BINDING *b;
2911         unsigned long uriHash = hash_secret_salt;
2912         ((XML_Char *)s)[-1] = 0;  /* clear flag */
2913         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
2914         b = id->prefix->binding;
2915         if (!b)
2916           return XML_ERROR_UNBOUND_PREFIX;
2917
2918         /* as we expand the name we also calculate its hash value */
2919         for (j = 0; j < b->uriLen; j++) {
2920           const XML_Char c = b->uri[j];
2921           if (!poolAppendChar(&tempPool, c))
2922             return XML_ERROR_NO_MEMORY;
2923           uriHash = CHAR_HASH(uriHash, c);
2924         }
2925         while (*s++ != XML_T(ASCII_COLON))
2926           ;
2927         do {  /* copies null terminator */
2928           const XML_Char c = *s;
2929           if (!poolAppendChar(&tempPool, *s))
2930             return XML_ERROR_NO_MEMORY;
2931           uriHash = CHAR_HASH(uriHash, c);
2932         } while (*s++);
2933
2934         { /* Check hash table for duplicate of expanded name (uriName).
2935              Derived from code in lookup(parser, HASH_TABLE *table, ...).
2936           */
2937           unsigned char step = 0;
2938           unsigned long mask = nsAttsSize - 1;
2939           j = uriHash & mask;  /* index into hash table */
2940           while (nsAtts[j].version == version) {
2941             /* for speed we compare stored hash values first */
2942             if (uriHash == nsAtts[j].hash) {
2943               const XML_Char *s1 = poolStart(&tempPool);
2944               const XML_Char *s2 = nsAtts[j].uriName;
2945               /* s1 is null terminated, but not s2 */
2946               for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2947               if (*s1 == 0)
2948                 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2949             }
2950             if (!step)
2951               step = PROBE_STEP(uriHash, mask, nsAttsPower);
2952             j < step ? (j += nsAttsSize - step) : (j -= step);
2953           }
2954         }
2955
2956         if (ns_triplets) {  /* append namespace separator and prefix */
2957           tempPool.ptr[-1] = namespaceSeparator;
2958           s = b->prefix->name;
2959           do {
2960             if (!poolAppendChar(&tempPool, *s))
2961               return XML_ERROR_NO_MEMORY;
2962           } while (*s++);
2963         }
2964
2965         /* store expanded name in attribute list */
2966         s = poolStart(&tempPool);
2967         poolFinish(&tempPool);
2968         appAtts[i] = s;
2969
2970         /* fill empty slot with new version, uriName and hash value */
2971         nsAtts[j].version = version;
2972         nsAtts[j].hash = uriHash;
2973         nsAtts[j].uriName = s;
2974
2975         if (!--nPrefixes) {
2976           i += 2;
2977           break;
2978         }
2979       }
2980       else  /* not prefixed */
2981         ((XML_Char *)s)[-1] = 0;  /* clear flag */
2982     }
2983   }
2984   /* clear flags for the remaining attributes */
2985   for (; i < attIndex; i += 2)
2986     ((XML_Char *)(appAtts[i]))[-1] = 0;
2987   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2988     binding->attId->name[-1] = 0;
2989
2990   if (!ns)
2991     return XML_ERROR_NONE;
2992
2993   /* expand the element type name */
2994   if (elementType->prefix) {
2995     binding = elementType->prefix->binding;
2996     if (!binding)
2997       return XML_ERROR_UNBOUND_PREFIX;
2998     localPart = tagNamePtr->str;
2999     while (*localPart++ != XML_T(ASCII_COLON))
3000       ;
3001   }
3002   else if (dtd->defaultPrefix.binding) {
3003     binding = dtd->defaultPrefix.binding;
3004     localPart = tagNamePtr->str;
3005   }
3006   else
3007     return XML_ERROR_NONE;
3008   prefixLen = 0;
3009   if (ns_triplets && binding->prefix->name) {
3010     for (; binding->prefix->name[prefixLen++];)
3011       ;  /* prefixLen includes null terminator */
3012   }
3013   tagNamePtr->localPart = localPart;
3014   tagNamePtr->uriLen = binding->uriLen;
3015   tagNamePtr->prefix = binding->prefix->name;
3016   tagNamePtr->prefixLen = prefixLen;
3017   for (i = 0; localPart[i++];)
3018     ;  /* i includes null terminator */
3019   n = i + binding->uriLen + prefixLen;
3020   if (n > binding->uriAlloc) {
3021     TAG *p;
3022     uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3023     if (!uri)
3024       return XML_ERROR_NO_MEMORY;
3025     binding->uriAlloc = n + EXPAND_SPARE;
3026     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3027     for (p = tagStack; p; p = p->parent)
3028       if (p->name.str == binding->uri)
3029         p->name.str = uri;
3030     FREE(binding->uri);
3031     binding->uri = uri;
3032   }
3033   /* if namespaceSeparator != '\0' then uri includes it already */
3034   uri = binding->uri + binding->uriLen;
3035   memcpy(uri, localPart, i * sizeof(XML_Char));
3036   /* we always have a namespace separator between localPart and prefix */
3037   if (prefixLen) {
3038     uri += i - 1;
3039     *uri = namespaceSeparator;  /* replace null terminator */
3040     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3041   }
3042   tagNamePtr->str = binding->uri;
3043   return XML_ERROR_NONE;
3044 }
3045
3046 /* addBinding() overwrites the value of prefix->binding without checking.
3047    Therefore one must keep track of the old value outside of addBinding().
3048 */
3049 static enum XML_Error
3050 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3051            const XML_Char *uri, BINDING **bindingsPtr)
3052 {
3053   static const XML_Char xmlNamespace[] = {
3054     ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3055     ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3056     ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3057     ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3058     ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3059     ASCII_e, '\0'
3060   };
3061   static const int xmlLen =
3062     (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3063   static const XML_Char xmlnsNamespace[] = {
3064     ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3065     ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3066     ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3067     ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3068     ASCII_SLASH, '\0'
3069   };
3070   static const int xmlnsLen =
3071     (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3072
3073   XML_Bool mustBeXML = XML_FALSE;
3074   XML_Bool isXML = XML_TRUE;
3075   XML_Bool isXMLNS = XML_TRUE;
3076
3077   BINDING *b;
3078   int len;
3079
3080   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3081   if (*uri == XML_T('\0') && prefix->name)
3082     return XML_ERROR_UNDECLARING_PREFIX;
3083
3084   if (prefix->name
3085       && prefix->name[0] == XML_T(ASCII_x)
3086       && prefix->name[1] == XML_T(ASCII_m)
3087       && prefix->name[2] == XML_T(ASCII_l)) {
3088
3089     /* Not allowed to bind xmlns */
3090     if (prefix->name[3] == XML_T(ASCII_n)
3091         && prefix->name[4] == XML_T(ASCII_s)
3092         && prefix->name[5] == XML_T('\0'))
3093       return XML_ERROR_RESERVED_PREFIX_XMLNS;
3094
3095     if (prefix->name[3] == XML_T('\0'))
3096       mustBeXML = XML_TRUE;
3097   }
3098
3099   for (len = 0; uri[len]; len++) {
3100     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3101       isXML = XML_FALSE;
3102
3103     if (!mustBeXML && isXMLNS
3104         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3105       isXMLNS = XML_FALSE;
3106   }
3107   isXML = isXML && len == xmlLen;
3108   isXMLNS = isXMLNS && len == xmlnsLen;
3109
3110   if (mustBeXML != isXML)
3111     return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3112                      : XML_ERROR_RESERVED_NAMESPACE_URI;
3113
3114   if (isXMLNS)
3115     return XML_ERROR_RESERVED_NAMESPACE_URI;
3116
3117   if (namespaceSeparator)
3118     len++;
3119   if (freeBindingList) {
3120     b = freeBindingList;
3121     if (len > b->uriAlloc) {
3122       XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3123                           sizeof(XML_Char) * (len + EXPAND_SPARE));
3124       if (temp == NULL)
3125         return XML_ERROR_NO_MEMORY;
3126       b->uri = temp;
3127       b->uriAlloc = len + EXPAND_SPARE;
3128     }
3129     freeBindingList = b->nextTagBinding;
3130   }
3131   else {
3132     b = (BINDING *)MALLOC(sizeof(BINDING));
3133     if (!b)
3134       return XML_ERROR_NO_MEMORY;
3135     b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3136     if (!b->uri) {
3137       FREE(b);
3138       return XML_ERROR_NO_MEMORY;
3139     }
3140     b->uriAlloc = len + EXPAND_SPARE;
3141   }
3142   b->uriLen = len;
3143   memcpy(b->uri, uri, len * sizeof(XML_Char));
3144   if (namespaceSeparator)
3145     b->uri[len - 1] = namespaceSeparator;
3146   b->prefix = prefix;
3147   b->attId = attId;
3148   b->prevPrefixBinding = prefix->binding;
3149   /* NULL binding when default namespace undeclared */
3150   if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3151     prefix->binding = NULL;
3152   else
3153     prefix->binding = b;
3154   b->nextTagBinding = *bindingsPtr;
3155   *bindingsPtr = b;
3156   /* if attId == NULL then we are not starting a namespace scope */
3157   if (attId && startNamespaceDeclHandler)
3158     startNamespaceDeclHandler(handlerArg, prefix->name,
3159                               prefix->binding ? uri : 0);
3160   return XML_ERROR_NONE;
3161 }
3162
3163 /* The idea here is to avoid using stack for each CDATA section when
3164    the whole file is parsed with one call.
3165 */
3166 static enum XML_Error PTRCALL
3167 cdataSectionProcessor(XML_Parser parser,
3168                       const char *start,
3169                       const char *end,
3170                       const char **endPtr)
3171 {
3172   enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3173                                          endPtr, (XML_Bool)!ps_finalBuffer);
3174   if (result != XML_ERROR_NONE)
3175     return result;
3176   if (start) {
3177     if (parentParser) {  /* we are parsing an external entity */
3178       processor = externalEntityContentProcessor;
3179       return externalEntityContentProcessor(parser, start, end, endPtr);
3180     }
3181     else {
3182       processor = contentProcessor;
3183       return contentProcessor(parser, start, end, endPtr);
3184     }
3185   }
3186   return result;
3187 }
3188
3189 /* startPtr gets set to non-null if the section is closed, and to null if
3190    the section is not yet closed.
3191 */
3192 static enum XML_Error
3193 doCdataSection(XML_Parser parser,
3194                const ENCODING *enc,
3195                const char **startPtr,
3196                const char *end,
3197                const char **nextPtr,
3198                XML_Bool haveMore)
3199 {
3200   const char *s = *startPtr;
3201   const char **eventPP;
3202   const char **eventEndPP;
3203   if (enc == encoding) {
3204     eventPP = &eventPtr;
3205     *eventPP = s;
3206     eventEndPP = &eventEndPtr;
3207   }
3208   else {
3209     eventPP = &(openInternalEntities->internalEventPtr);
3210     eventEndPP = &(openInternalEntities->internalEventEndPtr);
3211   }
3212   *eventPP = s;
3213   *startPtr = NULL;
3214
3215   for (;;) {
3216     const char *next;
3217     int tok = XmlCdataSectionTok(enc, s, end, &next);
3218     *eventEndPP = next;
3219     switch (tok) {
3220     case XML_TOK_CDATA_SECT_CLOSE:
3221       if (endCdataSectionHandler)
3222         endCdataSectionHandler(handlerArg);
3223 #if 0
3224       /* see comment under XML_TOK_CDATA_SECT_OPEN */
3225       else if (characterDataHandler)
3226         characterDataHandler(handlerArg, dataBuf, 0);
3227 #endif
3228       else if (defaultHandler)
3229         reportDefault(parser, enc, s, next);
3230       *startPtr = next;
3231       *nextPtr = next;
3232       if (ps_parsing == XML_FINISHED)
3233         return XML_ERROR_ABORTED;
3234       else
3235         return XML_ERROR_NONE;
3236     case XML_TOK_DATA_NEWLINE:
3237       if (characterDataHandler) {
3238         XML_Char c = 0xA;
3239         characterDataHandler(handlerArg, &c, 1);
3240       }
3241       else if (defaultHandler)
3242         reportDefault(parser, enc, s, next);
3243       break;
3244     case XML_TOK_DATA_CHARS:
3245       {
3246         XML_CharacterDataHandler charDataHandler = characterDataHandler;
3247         if (charDataHandler) {
3248           if (MUST_CONVERT(enc, s)) {
3249             for (;;) {
3250               ICHAR *dataPtr = (ICHAR *)dataBuf;
3251               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3252               *eventEndPP = next;
3253               charDataHandler(handlerArg, dataBuf,
3254                               (int)(dataPtr - (ICHAR *)dataBuf));
3255               if (s == next)
3256                 break;
3257               *eventPP = s;
3258             }
3259           }
3260           else
3261             charDataHandler(handlerArg,
3262                             (XML_Char *)s,
3263                             (int)((XML_Char *)next - (XML_Char *)s));
3264         }
3265         else if (defaultHandler)
3266           reportDefault(parser, enc, s, next);
3267       }
3268       break;
3269     case XML_TOK_INVALID:
3270       *eventPP = next;
3271       return XML_ERROR_INVALID_TOKEN;
3272     case XML_TOK_PARTIAL_CHAR:
3273       if (haveMore) {
3274         *nextPtr = s;
3275         return XML_ERROR_NONE;
3276       }
3277       return XML_ERROR_PARTIAL_CHAR;
3278     case XML_TOK_PARTIAL:
3279     case XML_TOK_NONE:
3280       if (haveMore) {
3281         *nextPtr = s;
3282         return XML_ERROR_NONE;
3283       }
3284       return XML_ERROR_UNCLOSED_CDATA_SECTION;
3285     default:
3286       *eventPP = next;
3287       return XML_ERROR_UNEXPECTED_STATE;
3288     }
3289
3290     *eventPP = s = next;
3291     switch (ps_parsing) {
3292     case XML_SUSPENDED:
3293       *nextPtr = next;
3294       return XML_ERROR_NONE;
3295     case XML_FINISHED:
3296       return XML_ERROR_ABORTED;
3297     default: ;
3298     }
3299   }
3300   /* not reached */
3301 }
3302
3303 #ifdef XML_DTD
3304
3305 /* The idea here is to avoid using stack for each IGNORE section when
3306    the whole file is parsed with one call.
3307 */
3308 static enum XML_Error PTRCALL
3309 ignoreSectionProcessor(XML_Parser parser,
3310                        const char *start,
3311                        const char *end,
3312                        const char **endPtr)
3313 {
3314   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3315                                           endPtr, (XML_Bool)!ps_finalBuffer);
3316   if (result != XML_ERROR_NONE)
3317     return result;
3318   if (start) {
3319     processor = prologProcessor;
3320     return prologProcessor(parser, start, end, endPtr);
3321   }
3322   return result;
3323 }
3324
3325 /* startPtr gets set to non-null is the section is closed, and to null
3326    if the section is not yet closed.
3327 */
3328 static enum XML_Error
3329 doIgnoreSection(XML_Parser parser,
3330                 const ENCODING *enc,
3331                 const char **startPtr,
3332                 const char *end,
3333                 const char **nextPtr,
3334                 XML_Bool haveMore)
3335 {
3336   const char *next;
3337   int tok;
3338   const char *s = *startPtr;
3339   const char **eventPP;
3340   const char **eventEndPP;
3341   if (enc == encoding) {
3342     eventPP = &eventPtr;
3343     *eventPP = s;
3344     eventEndPP = &eventEndPtr;
3345   }
3346   else {
3347     eventPP = &(openInternalEntities->internalEventPtr);
3348     eventEndPP = &(openInternalEntities->internalEventEndPtr);
3349   }
3350   *eventPP = s;
3351   *startPtr = NULL;
3352   tok = XmlIgnoreSectionTok(enc, s, end, &next);
3353   *eventEndPP = next;
3354   switch (tok) {
3355   case XML_TOK_IGNORE_SECT:
3356     if (defaultHandler)
3357       reportDefault(parser, enc, s, next);
3358     *startPtr = next;
3359     *nextPtr = next;
3360     if (ps_parsing == XML_FINISHED)
3361       return XML_ERROR_ABORTED;
3362     else
3363       return XML_ERROR_NONE;
3364   case XML_TOK_INVALID:
3365     *eventPP = next;
3366     return XML_ERROR_INVALID_TOKEN;
3367   case XML_TOK_PARTIAL_CHAR:
3368     if (haveMore) {
3369       *nextPtr = s;
3370       return XML_ERROR_NONE;
3371     }
3372     return XML_ERROR_PARTIAL_CHAR;
3373   case XML_TOK_PARTIAL:
3374   case XML_TOK_NONE:
3375     if (haveMore) {
3376       *nextPtr = s;
3377       return XML_ERROR_NONE;
3378     }
3379     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3380   default:
3381     *eventPP = next;
3382     return XML_ERROR_UNEXPECTED_STATE;
3383   }
3384   /* not reached */
3385 }
3386
3387 #endif /* XML_DTD */
3388
3389 static enum XML_Error
3390 initializeEncoding(XML_Parser parser)
3391 {
3392   const char *s;
3393 #ifdef XML_UNICODE
3394   char encodingBuf[128];
3395   if (!protocolEncodingName)
3396     s = NULL;
3397   else {
3398     int i;
3399     for (i = 0; protocolEncodingName[i]; i++) {
3400       if (i == sizeof(encodingBuf) - 1
3401           || (protocolEncodingName[i] & ~0x7f) != 0) {
3402         encodingBuf[0] = '\0';
3403         break;
3404       }
3405       encodingBuf[i] = (char)protocolEncodingName[i];
3406     }
3407     encodingBuf[i] = '\0';
3408     s = encodingBuf;
3409   }
3410 #else
3411   s = protocolEncodingName;
3412 #endif
3413   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3414     return XML_ERROR_NONE;
3415   return handleUnknownEncoding(parser, protocolEncodingName);
3416 }
3417
3418 static enum XML_Error
3419 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3420                const char *s, const char *next)
3421 {
3422   const char *encodingName = NULL;
3423   const XML_Char *storedEncName = NULL;
3424   const ENCODING *newEncoding = NULL;
3425   const char *version = NULL;
3426   const char *versionend;
3427   const XML_Char *storedversion = NULL;
3428   int standalone = -1;
3429   if (!(ns
3430         ? XmlParseXmlDeclNS
3431         : XmlParseXmlDecl)(isGeneralTextEntity,
3432                            encoding,
3433                            s,
3434                            next,
3435                            &eventPtr,
3436                            &version,
3437                            &versionend,
3438                            &encodingName,
3439                            &newEncoding,
3440                            &standalone)) {
3441     if (isGeneralTextEntity)
3442       return XML_ERROR_TEXT_DECL;
3443     else
3444       return XML_ERROR_XML_DECL;
3445   }
3446   if (!isGeneralTextEntity && standalone == 1) {
3447     _dtd->standalone = XML_TRUE;
3448 #ifdef XML_DTD
3449     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3450       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3451 #endif /* XML_DTD */
3452   }
3453   if (xmlDeclHandler) {
3454     if (encodingName != NULL) {
3455       storedEncName = poolStoreString(&temp2Pool,
3456                                       encoding,
3457                                       encodingName,
3458                                       encodingName
3459                                       + XmlNameLength(encoding, encodingName));
3460       if (!storedEncName)
3461               return XML_ERROR_NO_MEMORY;
3462       poolFinish(&temp2Pool);
3463     }
3464     if (version) {
3465       storedversion = poolStoreString(&temp2Pool,
3466                                       encoding,
3467                                       version,
3468                                       versionend - encoding->minBytesPerChar);
3469       if (!storedversion)
3470         return XML_ERROR_NO_MEMORY;
3471     }
3472     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3473   }
3474   else if (defaultHandler)
3475     reportDefault(parser, encoding, s, next);
3476   if (protocolEncodingName == NULL) {
3477     if (newEncoding) {
3478       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3479         eventPtr = encodingName;
3480         return XML_ERROR_INCORRECT_ENCODING;
3481       }
3482       encoding = newEncoding;
3483     }
3484     else if (encodingName) {
3485       enum XML_Error result;
3486       if (!storedEncName) {
3487         storedEncName = poolStoreString(
3488           &temp2Pool, encoding, encodingName,
3489           encodingName + XmlNameLength(encoding, encodingName));
3490         if (!storedEncName)
3491           return XML_ERROR_NO_MEMORY;
3492       }
3493       result = handleUnknownEncoding(parser, storedEncName);
3494       poolClear(&temp2Pool);
3495       if (result == XML_ERROR_UNKNOWN_ENCODING)
3496         eventPtr = encodingName;
3497       return result;
3498     }
3499   }
3500
3501   if (storedEncName || storedversion)
3502     poolClear(&temp2Pool);
3503
3504   return XML_ERROR_NONE;
3505 }
3506
3507 static enum XML_Error
3508 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3509 {
3510   if (unknownEncodingHandler) {
3511     XML_Encoding info;
3512     int i;
3513     for (i = 0; i < 256; i++)
3514       info.map[i] = -1;
3515     info.convert = NULL;
3516     info.data = NULL;
3517     info.release = NULL;
3518     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3519                                &info)) {
3520       ENCODING *enc;
3521       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3522       if (!unknownEncodingMem) {
3523         if (info.release)
3524           info.release(info.data);
3525         return XML_ERROR_NO_MEMORY;
3526       }
3527       enc = (ns
3528              ? XmlInitUnknownEncodingNS
3529              : XmlInitUnknownEncoding)(unknownEncodingMem,
3530                                        info.map,
3531                                        info.convert,
3532                                        info.data);
3533       if (enc) {
3534         unknownEncodingData = info.data;
3535         unknownEncodingRelease = info.release;
3536         encoding = enc;
3537         return XML_ERROR_NONE;
3538       }
3539     }
3540     if (info.release != NULL)
3541       info.release(info.data);
3542   }
3543   return XML_ERROR_UNKNOWN_ENCODING;
3544 }
3545
3546 static enum XML_Error PTRCALL
3547 prologInitProcessor(XML_Parser parser,
3548                     const char *s,
3549                     const char *end,
3550                     const char **nextPtr)
3551 {
3552   enum XML_Error result = initializeEncoding(parser);
3553   if (result != XML_ERROR_NONE)
3554     return result;
3555   processor = prologProcessor;
3556   return prologProcessor(parser, s, end, nextPtr);
3557 }
3558
3559 #ifdef XML_DTD
3560
3561 static enum XML_Error PTRCALL
3562 externalParEntInitProcessor(XML_Parser parser,
3563                             const char *s,
3564                             const char *end,
3565                             const char **nextPtr)
3566 {
3567   enum XML_Error result = initializeEncoding(parser);
3568   if (result != XML_ERROR_NONE)
3569     return result;
3570
3571   /* we know now that XML_Parse(Buffer) has been called,
3572      so we consider the external parameter entity read */
3573   _dtd->paramEntityRead = XML_TRUE;
3574
3575   if (prologState.inEntityValue) {
3576     processor = entityValueInitProcessor;
3577     return entityValueInitProcessor(parser, s, end, nextPtr);
3578   }
3579   else {
3580     processor = externalParEntProcessor;
3581     return externalParEntProcessor(parser, s, end, nextPtr);
3582   }
3583 }
3584
3585 static enum XML_Error PTRCALL
3586 entityValueInitProcessor(XML_Parser parser,
3587                          const char *s,
3588                          const char *end,
3589                          const char **nextPtr)
3590 {
3591   int tok;
3592   const char *start = s;
3593   const char *next = start;
3594   eventPtr = start;
3595
3596   for (;;) {
3597     tok = XmlPrologTok(encoding, start, end, &next);
3598     eventEndPtr = next;
3599     if (tok <= 0) {
3600       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3601         *nextPtr = s;
3602         return XML_ERROR_NONE;
3603       }
3604       switch (tok) {
3605       case XML_TOK_INVALID:
3606         return XML_ERROR_INVALID_TOKEN;
3607       case XML_TOK_PARTIAL:
3608         return XML_ERROR_UNCLOSED_TOKEN;
3609       case XML_TOK_PARTIAL_CHAR:
3610         return XML_ERROR_PARTIAL_CHAR;
3611       case XML_TOK_NONE:   /* start == end */
3612       default:
3613         break;
3614       }
3615       /* found end of entity value - can store it now */
3616       return storeEntityValue(parser, encoding, s, end);
3617     }
3618     else if (tok == XML_TOK_XML_DECL) {
3619       enum XML_Error result;
3620       result = processXmlDecl(parser, 0, start, next);
3621       if (result != XML_ERROR_NONE)
3622         return result;
3623       switch (ps_parsing) {
3624       case XML_SUSPENDED:
3625         *nextPtr = next;
3626         return XML_ERROR_NONE;
3627       case XML_FINISHED:
3628         return XML_ERROR_ABORTED;
3629       default:
3630         *nextPtr = next;
3631       }
3632       /* stop scanning for text declaration - we found one */
3633       processor = entityValueProcessor;
3634       return entityValueProcessor(parser, next, end, nextPtr);
3635     }
3636     /* If we are at the end of the buffer, this would cause XmlPrologTok to
3637        return XML_TOK_NONE on the next call, which would then cause the
3638        function to exit with *nextPtr set to s - that is what we want for other
3639        tokens, but not for the BOM - we would rather like to skip it;
3640        then, when this routine is entered the next time, XmlPrologTok will
3641        return XML_TOK_INVALID, since the BOM is still in the buffer
3642     */
3643     else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3644       *nextPtr = next;
3645       return XML_ERROR_NONE;
3646     }
3647     start = next;
3648     eventPtr = start;
3649   }
3650 }
3651
3652 static enum XML_Error PTRCALL
3653 externalParEntProcessor(XML_Parser parser,
3654                         const char *s,
3655                         const char *end,
3656                         const char **nextPtr)
3657 {
3658   const char *next = s;
3659   int tok;
3660
3661   tok = XmlPrologTok(encoding, s, end, &next);
3662   if (tok <= 0) {
3663     if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3664       *nextPtr = s;
3665       return XML_ERROR_NONE;
3666     }
3667     switch (tok) {
3668     case XML_TOK_INVALID:
3669       return XML_ERROR_INVALID_TOKEN;
3670     case XML_TOK_PARTIAL:
3671       return XML_ERROR_UNCLOSED_TOKEN;
3672     case XML_TOK_PARTIAL_CHAR:
3673       return XML_ERROR_PARTIAL_CHAR;
3674     case XML_TOK_NONE:   /* start == end */
3675     default:
3676       break;
3677     }
3678   }
3679   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3680      However, when parsing an external subset, doProlog will not accept a BOM
3681      as valid, and report a syntax error, so we have to skip the BOM
3682   */
3683   else if (tok == XML_TOK_BOM) {
3684     s = next;
3685     tok = XmlPrologTok(encoding, s, end, &next);
3686   }
3687
3688   processor = prologProcessor;
3689   return doProlog(parser, encoding, s, end, tok, next,
3690                   nextPtr, (XML_Bool)!ps_finalBuffer);
3691 }
3692
3693 static enum XML_Error PTRCALL
3694 entityValueProcessor(XML_Parser parser,
3695                      const char *s,
3696                      const char *end,
3697                      const char **nextPtr)
3698 {
3699   const char *start = s;
3700   const char *next = s;
3701   const ENCODING *enc = encoding;
3702   int tok;
3703
3704   for (;;) {
3705     tok = XmlPrologTok(enc, start, end, &next);
3706     if (tok <= 0) {
3707       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3708         *nextPtr = s;
3709         return XML_ERROR_NONE;
3710       }
3711       switch (tok) {
3712       case XML_TOK_INVALID:
3713         return XML_ERROR_INVALID_TOKEN;
3714       case XML_TOK_PARTIAL:
3715         return XML_ERROR_UNCLOSED_TOKEN;
3716       case XML_TOK_PARTIAL_CHAR:
3717         return XML_ERROR_PARTIAL_CHAR;
3718       case XML_TOK_NONE:   /* start == end */
3719       default:
3720         break;
3721       }
3722       /* found end of entity value - can store it now */
3723       return storeEntityValue(parser, enc, s, end);
3724     }
3725     start = next;
3726   }
3727 }
3728
3729 #endif /* XML_DTD */
3730
3731 static enum XML_Error PTRCALL
3732 prologProcessor(XML_Parser parser,
3733                 const char *s,
3734                 const char *end,
3735                 const char **nextPtr)
3736 {
3737   const char *next = s;
3738   int tok = XmlPrologTok(encoding, s, end, &next);
3739   return doProlog(parser, encoding, s, end, tok, next,
3740                   nextPtr, (XML_Bool)!ps_finalBuffer);
3741 }
3742
3743 static enum XML_Error
3744 doProlog(XML_Parser parser,
3745          const ENCODING *enc,
3746          const char *s,
3747          const char *end,
3748          int tok,
3749          const char *next,
3750          const char **nextPtr,
3751          XML_Bool haveMore)
3752 {
3753 #ifdef XML_DTD
3754   static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
3755 #endif /* XML_DTD */
3756   static const XML_Char atypeCDATA[] =
3757       { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3758   static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3759   static const XML_Char atypeIDREF[] =
3760       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3761   static const XML_Char atypeIDREFS[] =
3762       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3763   static const XML_Char atypeENTITY[] =
3764       { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3765   static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3766       ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
3767   static const XML_Char atypeNMTOKEN[] = {
3768       ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3769   static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3770       ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3771   static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3772       ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3773   static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3774   static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
3775
3776   /* save one level of indirection */
3777   DTD * const dtd = _dtd;
3778
3779   const char **eventPP;
3780   const char **eventEndPP;
3781   enum XML_Content_Quant quant;
3782
3783   if (enc == encoding) {
3784     eventPP = &eventPtr;
3785     eventEndPP = &eventEndPtr;
3786   }
3787   else {
3788     eventPP = &(openInternalEntities->internalEventPtr);
3789     eventEndPP = &(openInternalEntities->internalEventEndPtr);
3790   }
3791
3792   for (;;) {
3793     int role;
3794     XML_Bool handleDefault = XML_TRUE;
3795     *eventPP = s;
3796     *eventEndPP = next;
3797     if (tok <= 0) {
3798       if (haveMore && tok != XML_TOK_INVALID) {
3799         *nextPtr = s;
3800         return XML_ERROR_NONE;
3801       }
3802       switch (tok) {
3803       case XML_TOK_INVALID:
3804         *eventPP = next;
3805         return XML_ERROR_INVALID_TOKEN;
3806       case XML_TOK_PARTIAL:
3807         return XML_ERROR_UNCLOSED_TOKEN;
3808       case XML_TOK_PARTIAL_CHAR:
3809         return XML_ERROR_PARTIAL_CHAR;
3810       case -XML_TOK_PROLOG_S:
3811         tok = -tok;
3812         break;
3813       case XML_TOK_NONE:
3814 #ifdef XML_DTD
3815         /* for internal PE NOT referenced between declarations */
3816         if (enc != encoding && !openInternalEntities->betweenDecl) {
3817           *nextPtr = s;
3818           return XML_ERROR_NONE;
3819         }
3820         /* WFC: PE Between Declarations - must check that PE contains
3821            complete markup, not only for external PEs, but also for
3822            internal PEs if the reference occurs between declarations.
3823         */
3824         if (isParamEntity || enc != encoding) {
3825           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3826               == XML_ROLE_ERROR)
3827             return XML_ERROR_INCOMPLETE_PE;
3828           *nextPtr = s;
3829           return XML_ERROR_NONE;
3830         }
3831 #endif /* XML_DTD */
3832         return XML_ERROR_NO_ELEMENTS;
3833       default:
3834         tok = -tok;
3835         break;
3836       }
3837     }
3838     role = XmlTokenRole(&prologState, tok, s, next, enc);
3839     switch (role) {
3840     case XML_ROLE_XML_DECL:
3841       {
3842         enum XML_Error result = processXmlDecl(parser, 0, s, next);
3843         if (result != XML_ERROR_NONE)
3844           return result;
3845         enc = encoding;
3846         handleDefault = XML_FALSE;
3847       }
3848       break;
3849     case XML_ROLE_DOCTYPE_NAME:
3850       if (startDoctypeDeclHandler) {
3851         doctypeName = poolStoreString(&tempPool, enc, s, next);
3852         if (!doctypeName)
3853           return XML_ERROR_NO_MEMORY;
3854         poolFinish(&tempPool);
3855         doctypePubid = NULL;
3856         handleDefault = XML_FALSE;
3857       }
3858       doctypeSysid = NULL; /* always initialize to NULL */
3859       break;
3860     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3861       if (startDoctypeDeclHandler) {
3862         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3863                                 doctypePubid, 1);
3864         doctypeName = NULL;
3865         poolClear(&tempPool);
3866         handleDefault = XML_FALSE;
3867       }
3868       break;
3869 #ifdef XML_DTD
3870     case XML_ROLE_TEXT_DECL:
3871       {
3872         enum XML_Error result = processXmlDecl(parser, 1, s, next);
3873         if (result != XML_ERROR_NONE)
3874           return result;
3875         enc = encoding;
3876         handleDefault = XML_FALSE;
3877       }
3878       break;
3879 #endif /* XML_DTD */
3880     case XML_ROLE_DOCTYPE_PUBLIC_ID:
3881 #ifdef XML_DTD
3882       useForeignDTD = XML_FALSE;
3883       declEntity = (ENTITY *)lookup(parser,
3884                                     &dtd->paramEntities,
3885                                     externalSubsetName,
3886                                     sizeof(ENTITY));
3887       if (!declEntity)
3888         return XML_ERROR_NO_MEMORY;
3889 #endif /* XML_DTD */
3890       dtd->hasParamEntityRefs = XML_TRUE;
3891       if (startDoctypeDeclHandler) {
3892         XML_Char *pubId;
3893         if (!XmlIsPublicId(enc, s, next, eventPP))
3894           return XML_ERROR_PUBLICID;
3895         pubId = poolStoreString(&tempPool, enc,
3896                                 s + enc->minBytesPerChar,
3897                                 next - enc->minBytesPerChar);
3898         if (!pubId)
3899           return XML_ERROR_NO_MEMORY;
3900         normalizePublicId(pubId);
3901         poolFinish(&tempPool);
3902         doctypePubid = pubId;
3903         handleDefault = XML_FALSE;
3904         goto alreadyChecked;
3905       }
3906       /* fall through */
3907     case XML_ROLE_ENTITY_PUBLIC_ID:
3908       if (!XmlIsPublicId(enc, s, next, eventPP))
3909         return XML_ERROR_PUBLICID;
3910     alreadyChecked:
3911       if (dtd->keepProcessing && declEntity) {
3912         XML_Char *tem = poolStoreString(&dtd->pool,
3913                                         enc,
3914                                         s + enc->minBytesPerChar,
3915                                         next - enc->minBytesPerChar);
3916         if (!tem)
3917           return XML_ERROR_NO_MEMORY;
3918         normalizePublicId(tem);
3919         declEntity->publicId = tem;
3920         poolFinish(&dtd->pool);
3921         if (entityDeclHandler)
3922           handleDefault = XML_FALSE;
3923       }
3924       break;
3925     case XML_ROLE_DOCTYPE_CLOSE:
3926       if (doctypeName) {
3927         startDoctypeDeclHandler(handlerArg, doctypeName,
3928                                 doctypeSysid, doctypePubid, 0);
3929         poolClear(&tempPool);
3930         handleDefault = XML_FALSE;
3931       }
3932       /* doctypeSysid will be non-NULL in the case of a previous
3933          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3934          was not set, indicating an external subset
3935       */
3936 #ifdef XML_DTD
3937       if (doctypeSysid || useForeignDTD) {
3938         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3939         dtd->hasParamEntityRefs = XML_TRUE;
3940         if (paramEntityParsing && externalEntityRefHandler) {
3941           ENTITY *entity = (ENTITY *)lookup(parser,
3942                                             &dtd->paramEntities,
3943                                             externalSubsetName,
3944                                             sizeof(ENTITY));
3945           if (!entity)
3946             return XML_ERROR_NO_MEMORY;
3947           if (useForeignDTD)
3948             entity->base = curBase;
3949           dtd->paramEntityRead = XML_FALSE;
3950           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3951                                         0,
3952                                         entity->base,
3953                                         entity->systemId,
3954                                         entity->publicId))
3955             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3956           if (dtd->paramEntityRead) {
3957             if (!dtd->standalone &&
3958                 notStandaloneHandler &&
3959                 !notStandaloneHandler(handlerArg))
3960               return XML_ERROR_NOT_STANDALONE;
3961           }
3962           /* if we didn't read the foreign DTD then this means that there
3963              is no external subset and we must reset dtd->hasParamEntityRefs
3964           */
3965           else if (!doctypeSysid)
3966             dtd->hasParamEntityRefs = hadParamEntityRefs;
3967           /* end of DTD - no need to update dtd->keepProcessing */
3968         }
3969         useForeignDTD = XML_FALSE;
3970       }
3971 #endif /* XML_DTD */
3972       if (endDoctypeDeclHandler) {
3973         endDoctypeDeclHandler(handlerArg);
3974         handleDefault = XML_FALSE;
3975       }
3976       break;
3977     case XML_ROLE_INSTANCE_START:
3978 #ifdef XML_DTD
3979       /* if there is no DOCTYPE declaration then now is the
3980          last chance to read the foreign DTD
3981       */
3982       if (useForeignDTD) {
3983         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3984         dtd->hasParamEntityRefs = XML_TRUE;
3985         if (paramEntityParsing && externalEntityRefHandler) {
3986           ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
3987                                             externalSubsetName,
3988                                             sizeof(ENTITY));
3989           if (!entity)
3990             return XML_ERROR_NO_MEMORY;
3991           entity->base = curBase;
3992           dtd->paramEntityRead = XML_FALSE;
3993           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3994                                         0,
3995                                         entity->base,
3996                                         entity->systemId,
3997                                         entity->publicId))
3998             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3999           if (dtd->paramEntityRead) {
4000             if (!dtd->standalone &&
4001                 notStandaloneHandler &&
4002                 !notStandaloneHandler(handlerArg))
4003               return XML_ERROR_NOT_STANDALONE;
4004           }
4005           /* if we didn't read the foreign DTD then this means that there
4006              is no external subset and we must reset dtd->hasParamEntityRefs
4007           */
4008           else
4009             dtd->hasParamEntityRefs = hadParamEntityRefs;
4010           /* end of DTD - no need to update dtd->keepProcessing */
4011         }
4012       }
4013 #endif /* XML_DTD */
4014       processor = contentProcessor;
4015       return contentProcessor(parser, s, end, nextPtr);
4016     case XML_ROLE_ATTLIST_ELEMENT_NAME:
4017       declElementType = getElementType(parser, enc, s, next);
4018       if (!declElementType)
4019         return XML_ERROR_NO_MEMORY;
4020       goto checkAttListDeclHandler;
4021     case XML_ROLE_ATTRIBUTE_NAME:
4022       declAttributeId = getAttributeId(parser, enc, s, next);
4023       if (!declAttributeId)
4024         return XML_ERROR_NO_MEMORY;
4025       declAttributeIsCdata = XML_FALSE;
4026       declAttributeType = NULL;
4027       declAttributeIsId = XML_FALSE;
4028       goto checkAttListDeclHandler;
4029     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4030       declAttributeIsCdata = XML_TRUE;
4031       declAttributeType = atypeCDATA;
4032       goto checkAttListDeclHandler;
4033     case XML_ROLE_ATTRIBUTE_TYPE_ID:
4034       declAttributeIsId = XML_TRUE;
4035       declAttributeType = atypeID;
4036       goto checkAttListDeclHandler;
4037     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4038       declAttributeType = atypeIDREF;
4039       goto checkAttListDeclHandler;
4040     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4041       declAttributeType = atypeIDREFS;
4042       goto checkAttListDeclHandler;
4043     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4044       declAttributeType = atypeENTITY;
4045       goto checkAttListDeclHandler;
4046     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4047       declAttributeType = atypeENTITIES;
4048       goto checkAttListDeclHandler;
4049     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4050       declAttributeType = atypeNMTOKEN;
4051       goto checkAttListDeclHandler;
4052     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4053       declAttributeType = atypeNMTOKENS;
4054     checkAttListDeclHandler:
4055       if (dtd->keepProcessing && attlistDeclHandler)
4056         handleDefault = XML_FALSE;
4057       break;
4058     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4059     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4060       if (dtd->keepProcessing && attlistDeclHandler) {
4061         const XML_Char *prefix;
4062         if (declAttributeType) {
4063           prefix = enumValueSep;
4064         }
4065         else {
4066           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4067                     ? notationPrefix
4068                     : enumValueStart);
4069         }
4070         if (!poolAppendString(&tempPool, prefix))
4071           return XML_ERROR_NO_MEMORY;
4072         if (!poolAppend(&tempPool, enc, s, next))
4073           return XML_ERROR_NO_MEMORY;
4074         declAttributeType = tempPool.start;
4075         handleDefault = XML_FALSE;
4076       }
4077       break;
4078     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4079     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4080       if (dtd->keepProcessing) {
4081         if (!defineAttribute(declElementType, declAttributeId,
4082                              declAttributeIsCdata, declAttributeIsId,
4083                              0, parser))
4084           return XML_ERROR_NO_MEMORY;
4085         if (attlistDeclHandler && declAttributeType) {
4086           if (*declAttributeType == XML_T(ASCII_LPAREN)
4087               || (*declAttributeType == XML_T(ASCII_N)
4088                   && declAttributeType[1] == XML_T(ASCII_O))) {
4089             /* Enumerated or Notation type */
4090             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4091                 || !poolAppendChar(&tempPool, XML_T('\0')))
4092               return XML_ERROR_NO_MEMORY;
4093             declAttributeType = tempPool.start;
4094             poolFinish(&tempPool);
4095           }
4096           *eventEndPP = s;
4097           attlistDeclHandler(handlerArg, declElementType->name,
4098                              declAttributeId->name, declAttributeType,
4099                              0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4100           poolClear(&tempPool);
4101           handleDefault = XML_FALSE;
4102         }
4103       }
4104       break;
4105     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4106     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4107       if (dtd->keepProcessing) {
4108         const XML_Char *attVal;
4109         enum XML_Error result =
4110           storeAttributeValue(parser, enc, declAttributeIsCdata,
4111                               s + enc->minBytesPerChar,
4112                               next - enc->minBytesPerChar,
4113                               &dtd->pool);
4114         if (result)
4115           return result;
4116         attVal = poolStart(&dtd->pool);
4117         poolFinish(&dtd->pool);
4118         /* ID attributes aren't allowed to have a default */
4119         if (!defineAttribute(declElementType, declAttributeId,
4120                              declAttributeIsCdata, XML_FALSE, attVal, parser))
4121           return XML_ERROR_NO_MEMORY;
4122         if (attlistDeclHandler && declAttributeType) {
4123           if (*declAttributeType == XML_T(ASCII_LPAREN)
4124               || (*declAttributeType == XML_T(ASCII_N)
4125                   && declAttributeType[1] == XML_T(ASCII_O))) {
4126             /* Enumerated or Notation type */
4127             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4128                 || !poolAppendChar(&tempPool, XML_T('\0')))
4129               return XML_ERROR_NO_MEMORY;
4130             declAttributeType = tempPool.start;
4131             poolFinish(&tempPool);
4132           }
4133           *eventEndPP = s;
4134           attlistDeclHandler(handlerArg, declElementType->name,
4135                              declAttributeId->name, declAttributeType,
4136                              attVal,
4137                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4138           poolClear(&tempPool);
4139           handleDefault = XML_FALSE;
4140         }
4141       }
4142       break;
4143     case XML_ROLE_ENTITY_VALUE:
4144       if (dtd->keepProcessing) {
4145         enum XML_Error result = storeEntityValue(parser, enc,
4146                                             s + enc->minBytesPerChar,
4147                                             next - enc->minBytesPerChar);
4148         if (declEntity) {
4149           declEntity->textPtr = poolStart(&dtd->entityValuePool);
4150           declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4151           poolFinish(&dtd->entityValuePool);
4152           if (entityDeclHandler) {
4153             *eventEndPP = s;
4154             entityDeclHandler(handlerArg,
4155                               declEntity->name,
4156                               declEntity->is_param,
4157                               declEntity->textPtr,
4158                               declEntity->textLen,
4159                               curBase, 0, 0, 0);
4160             handleDefault = XML_FALSE;
4161           }
4162         }
4163         else
4164           poolDiscard(&dtd->entityValuePool);
4165         if (result != XML_ERROR_NONE)
4166           return result;
4167       }
4168       break;
4169     case XML_ROLE_DOCTYPE_SYSTEM_ID:
4170 #ifdef XML_DTD
4171       useForeignDTD = XML_FALSE;
4172 #endif /* XML_DTD */
4173       dtd->hasParamEntityRefs = XML_TRUE;
4174       if (startDoctypeDeclHandler) {
4175         doctypeSysid = poolStoreString(&tempPool, enc,
4176                                        s + enc->minBytesPerChar,
4177                                        next - enc->minBytesPerChar);
4178         if (doctypeSysid == NULL)
4179           return XML_ERROR_NO_MEMORY;
4180         poolFinish(&tempPool);
4181         handleDefault = XML_FALSE;
4182       }
4183 #ifdef XML_DTD
4184       else
4185         /* use externalSubsetName to make doctypeSysid non-NULL
4186            for the case where no startDoctypeDeclHandler is set */
4187         doctypeSysid = externalSubsetName;
4188 #endif /* XML_DTD */
4189       if (!dtd->standalone
4190 #ifdef XML_DTD
4191           && !paramEntityParsing
4192 #endif /* XML_DTD */
4193           && notStandaloneHandler
4194           && !notStandaloneHandler(handlerArg))
4195         return XML_ERROR_NOT_STANDALONE;
4196 #ifndef XML_DTD
4197       break;
4198 #else /* XML_DTD */
4199       if (!declEntity) {
4200         declEntity = (ENTITY *)lookup(parser,
4201                                       &dtd->paramEntities,
4202                                       externalSubsetName,
4203                                       sizeof(ENTITY));
4204         if (!declEntity)
4205           return XML_ERROR_NO_MEMORY;
4206         declEntity->publicId = NULL;
4207       }
4208       /* fall through */
4209 #endif /* XML_DTD */
4210     case XML_ROLE_ENTITY_SYSTEM_ID:
4211       if (dtd->keepProcessing && declEntity) {
4212         declEntity->systemId = poolStoreString(&dtd->pool, enc,
4213                                                s + enc->minBytesPerChar,
4214                                                next - enc->minBytesPerChar);
4215         if (!declEntity->systemId)
4216           return XML_ERROR_NO_MEMORY;
4217         declEntity->base = curBase;
4218         poolFinish(&dtd->pool);
4219         if (entityDeclHandler)
4220           handleDefault = XML_FALSE;
4221       }
4222       break;
4223     case XML_ROLE_ENTITY_COMPLETE:
4224       if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4225         *eventEndPP = s;
4226         entityDeclHandler(handlerArg,
4227                           declEntity->name,
4228                           declEntity->is_param,
4229                           0,0,
4230                           declEntity->base,
4231                           declEntity->systemId,
4232                           declEntity->publicId,
4233                           0);
4234         handleDefault = XML_FALSE;
4235       }
4236       break;
4237     case XML_ROLE_ENTITY_NOTATION_NAME:
4238       if (dtd->keepProcessing && declEntity) {
4239         declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4240         if (!declEntity->notation)
4241           return XML_ERROR_NO_MEMORY;
4242         poolFinish(&dtd->pool);
4243         if (unparsedEntityDeclHandler) {
4244           *eventEndPP = s;
4245           unparsedEntityDeclHandler(handlerArg,
4246                                     declEntity->name,
4247                                     declEntity->base,
4248                                     declEntity->systemId,
4249                                     declEntity->publicId,
4250                                     declEntity->notation);
4251           handleDefault = XML_FALSE;
4252         }
4253         else if (entityDeclHandler) {
4254           *eventEndPP = s;
4255           entityDeclHandler(handlerArg,
4256                             declEntity->name,
4257                             0,0,0,
4258                             declEntity->base,
4259                             declEntity->systemId,
4260                             declEntity->publicId,
4261                             declEntity->notation);
4262           handleDefault = XML_FALSE;
4263         }
4264       }
4265       break;
4266     case XML_ROLE_GENERAL_ENTITY_NAME:
4267       {
4268         if (XmlPredefinedEntityName(enc, s, next)) {
4269           declEntity = NULL;
4270           break;
4271         }
4272         if (dtd->keepProcessing) {
4273           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4274           if (!name)
4275             return XML_ERROR_NO_MEMORY;
4276           declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
4277                                         sizeof(ENTITY));
4278           if (!declEntity)
4279             return XML_ERROR_NO_MEMORY;
4280           if (declEntity->name != name) {
4281             poolDiscard(&dtd->pool);
4282             declEntity = NULL;
4283           }
4284           else {
4285             poolFinish(&dtd->pool);
4286             declEntity->publicId = NULL;
4287             declEntity->is_param = XML_FALSE;
4288             /* if we have a parent parser or are reading an internal parameter
4289                entity, then the entity declaration is not considered "internal"
4290             */
4291             declEntity->is_internal = !(parentParser || openInternalEntities);
4292             if (entityDeclHandler)
4293               handleDefault = XML_FALSE;
4294           }
4295         }
4296         else {
4297           poolDiscard(&dtd->pool);
4298           declEntity = NULL;
4299         }
4300       }
4301       break;
4302     case XML_ROLE_PARAM_ENTITY_NAME:
4303 #ifdef XML_DTD
4304       if (dtd->keepProcessing) {
4305         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4306         if (!name)
4307           return XML_ERROR_NO_MEMORY;
4308         declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4309                                            name, sizeof(ENTITY));
4310         if (!declEntity)
4311           return XML_ERROR_NO_MEMORY;
4312         if (declEntity->name != name) {
4313           poolDiscard(&dtd->pool);
4314           declEntity = NULL;
4315         }
4316         else {
4317           poolFinish(&dtd->pool);
4318           declEntity->publicId = NULL;
4319           declEntity->is_param = XML_TRUE;
4320           /* if we have a parent parser or are reading an internal parameter
4321              entity, then the entity declaration is not considered "internal"
4322           */
4323           declEntity->is_internal = !(parentParser || openInternalEntities);
4324           if (entityDeclHandler)
4325             handleDefault = XML_FALSE;
4326         }
4327       }
4328       else {
4329         poolDiscard(&dtd->pool);
4330         declEntity = NULL;
4331       }
4332 #else /* not XML_DTD */
4333       declEntity = NULL;
4334 #endif /* XML_DTD */
4335       break;
4336     case XML_ROLE_NOTATION_NAME:
4337       declNotationPublicId = NULL;
4338       declNotationName = NULL;
4339       if (notationDeclHandler) {
4340         declNotationName = poolStoreString(&tempPool, enc, s, next);
4341         if (!declNotationName)
4342           return XML_ERROR_NO_MEMORY;
4343         poolFinish(&tempPool);
4344         handleDefault = XML_FALSE;
4345       }
4346       break;
4347     case XML_ROLE_NOTATION_PUBLIC_ID:
4348       if (!XmlIsPublicId(enc, s, next, eventPP))
4349         return XML_ERROR_PUBLICID;
4350       if (declNotationName) {  /* means notationDeclHandler != NULL */
4351         XML_Char *tem = poolStoreString(&tempPool,
4352                                         enc,
4353                                         s + enc->minBytesPerChar,
4354                                         next - enc->minBytesPerChar);
4355         if (!tem)
4356           return XML_ERROR_NO_MEMORY;
4357         normalizePublicId(tem);
4358         declNotationPublicId = tem;
4359         poolFinish(&tempPool);
4360         handleDefault = XML_FALSE;
4361       }
4362       break;
4363     case XML_ROLE_NOTATION_SYSTEM_ID:
4364       if (declNotationName && notationDeclHandler) {
4365         const XML_Char *systemId
4366           = poolStoreString(&tempPool, enc,
4367                             s + enc->minBytesPerChar,
4368                             next - enc->minBytesPerChar);
4369         if (!systemId)
4370           return XML_ERROR_NO_MEMORY;
4371         *eventEndPP = s;
4372         notationDeclHandler(handlerArg,
4373                             declNotationName,
4374                             curBase,
4375                             systemId,
4376                             declNotationPublicId);
4377         handleDefault = XML_FALSE;
4378       }
4379       poolClear(&tempPool);
4380       break;
4381     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4382       if (declNotationPublicId && notationDeclHandler) {
4383         *eventEndPP = s;
4384         notationDeclHandler(handlerArg,
4385                             declNotationName,
4386                             curBase,
4387                             0,
4388                             declNotationPublicId);
4389         handleDefault = XML_FALSE;
4390       }
4391       poolClear(&tempPool);
4392       break;
4393     case XML_ROLE_ERROR:
4394       switch (tok) {
4395       case XML_TOK_PARAM_ENTITY_REF:
4396         /* PE references in internal subset are
4397            not allowed within declarations. */
4398         return XML_ERROR_PARAM_ENTITY_REF;
4399       case XML_TOK_XML_DECL:
4400         return XML_ERROR_MISPLACED_XML_PI;
4401       default:
4402         return XML_ERROR_SYNTAX;
4403       }
4404 #ifdef XML_DTD
4405     case XML_ROLE_IGNORE_SECT:
4406       {
4407         enum XML_Error result;
4408         if (defaultHandler)
4409           reportDefault(parser, enc, s, next);
4410         handleDefault = XML_FALSE;
4411         result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4412         if (result != XML_ERROR_NONE)
4413           return result;
4414         else if (!next) {
4415           processor = ignoreSectionProcessor;
4416           return result;
4417         }
4418       }
4419       break;
4420 #endif /* XML_DTD */
4421     case XML_ROLE_GROUP_OPEN:
4422       if (prologState.level >= groupSize) {
4423         if (groupSize) {
4424           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4425           if (temp == NULL)
4426             return XML_ERROR_NO_MEMORY;
4427           groupConnector = temp;
4428           if (dtd->scaffIndex) {
4429             int *temp = (int *)REALLOC(dtd->scaffIndex,
4430                           groupSize * sizeof(int));
4431             if (temp == NULL)
4432               return XML_ERROR_NO_MEMORY;
4433             dtd->scaffIndex = temp;
4434           }
4435         }
4436         else {
4437           groupConnector = (char *)MALLOC(groupSize = 32);
4438           if (!groupConnector)
4439             return XML_ERROR_NO_MEMORY;
4440         }