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