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