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