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