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