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