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