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