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