Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
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 {
212  enum XML_Content_Type type;
213  enum XML_Content_Quant quant;
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 {
1283  startElementHandler = start;
1284  endElementHandler = end;
1285 }
1286 
1287 void XMLCALL
1289  XML_StartElementHandler start) {
1290  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 {
1325  startCdataSectionHandler = start;
1326  endCdataSectionHandler = end;
1327 }
1328 
1329 void XMLCALL
1331  XML_StartCdataSectionHandler start) {
1332  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 {
1362  startDoctypeDeclHandler = start;
1363  endDoctypeDeclHandler = end;
1364 }
1365 
1366 void XMLCALL
1368  XML_StartDoctypeDeclHandler start) {
1369  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 {
1397  startNamespaceDeclHandler = start;
1399 }
1400 
1401 void XMLCALL
1403  XML_StartNamespaceDeclHandler start) {
1404  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;
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 {
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
1863 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
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 {