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