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