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