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