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