]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/expat/lib/xmlparse.c
Temporary fix for link error to ~wxZipOutputStream()
[wxWidgets.git] / src / expat / lib / xmlparse.c
... / ...
CommitLineData
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"
11#include "expat.h"
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 ;
4043 dtd->contentStringLen += nameLen;
4044 if (elementDeclHandler)
4045 handleDefault = XML_FALSE;
4046 }
4047 break;
4048
4049 case XML_ROLE_GROUP_CLOSE:
4050 quant = XML_CQUANT_NONE;
4051 goto closeGroup;
4052 case XML_ROLE_GROUP_CLOSE_OPT:
4053 quant = XML_CQUANT_OPT;
4054 goto closeGroup;
4055 case XML_ROLE_GROUP_CLOSE_REP:
4056 quant = XML_CQUANT_REP;
4057 goto closeGroup;
4058 case XML_ROLE_GROUP_CLOSE_PLUS:
4059 quant = XML_CQUANT_PLUS;
4060 closeGroup:
4061 if (dtd->in_eldecl) {
4062 if (elementDeclHandler)
4063 handleDefault = XML_FALSE;
4064 dtd->scaffLevel--;
4065 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4066 if (dtd->scaffLevel == 0) {
4067 if (!handleDefault) {
4068 XML_Content *model = build_model(parser);
4069 if (!model)
4070 return XML_ERROR_NO_MEMORY;
4071 *eventEndPP = s;
4072 elementDeclHandler(handlerArg, declElementType->name, model);
4073 }
4074 dtd->in_eldecl = XML_FALSE;
4075 dtd->contentStringLen = 0;
4076 }
4077 }
4078 break;
4079 /* End element declaration stuff */
4080
4081 case XML_ROLE_PI:
4082 if (!reportProcessingInstruction(parser, enc, s, next))
4083 return XML_ERROR_NO_MEMORY;
4084 handleDefault = XML_FALSE;
4085 break;
4086 case XML_ROLE_COMMENT:
4087 if (!reportComment(parser, enc, s, next))
4088 return XML_ERROR_NO_MEMORY;
4089 handleDefault = XML_FALSE;
4090 break;
4091 case XML_ROLE_NONE:
4092 switch (tok) {
4093 case XML_TOK_BOM:
4094 handleDefault = XML_FALSE;
4095 break;
4096 }
4097 break;
4098 case XML_ROLE_DOCTYPE_NONE:
4099 if (startDoctypeDeclHandler)
4100 handleDefault = XML_FALSE;
4101 break;
4102 case XML_ROLE_ENTITY_NONE:
4103 if (dtd->keepProcessing && entityDeclHandler)
4104 handleDefault = XML_FALSE;
4105 break;
4106 case XML_ROLE_NOTATION_NONE:
4107 if (notationDeclHandler)
4108 handleDefault = XML_FALSE;
4109 break;
4110 case XML_ROLE_ATTLIST_NONE:
4111 if (dtd->keepProcessing && attlistDeclHandler)
4112 handleDefault = XML_FALSE;
4113 break;
4114 case XML_ROLE_ELEMENT_NONE:
4115 if (elementDeclHandler)
4116 handleDefault = XML_FALSE;
4117 break;
4118 } /* end of big switch */
4119
4120 if (handleDefault && defaultHandler)
4121 reportDefault(parser, enc, s, next);
4122
4123 s = next;
4124 tok = XmlPrologTok(enc, s, end, &next);
4125 }
4126 /* not reached */
4127}
4128
4129static enum XML_Error PTRCALL
4130epilogProcessor(XML_Parser parser,
4131 const char *s,
4132 const char *end,
4133 const char **nextPtr)
4134{
4135 processor = epilogProcessor;
4136 eventPtr = s;
4137 for (;;) {
4138 const char *next = NULL;
4139 int tok = XmlPrologTok(encoding, s, end, &next);
4140 eventEndPtr = next;
4141 switch (tok) {
4142 /* report partial linebreak - it might be the last token */
4143 case -XML_TOK_PROLOG_S:
4144 if (defaultHandler) {
4145 eventEndPtr = next;
4146 reportDefault(parser, encoding, s, next);
4147 }
4148 if (nextPtr)
4149 *nextPtr = next;
4150 return XML_ERROR_NONE;
4151 case XML_TOK_NONE:
4152 if (nextPtr)
4153 *nextPtr = s;
4154 return XML_ERROR_NONE;
4155 case XML_TOK_PROLOG_S:
4156 if (defaultHandler)
4157 reportDefault(parser, encoding, s, next);
4158 break;
4159 case XML_TOK_PI:
4160 if (!reportProcessingInstruction(parser, encoding, s, next))
4161 return XML_ERROR_NO_MEMORY;
4162 break;
4163 case XML_TOK_COMMENT:
4164 if (!reportComment(parser, encoding, s, next))
4165 return XML_ERROR_NO_MEMORY;
4166 break;
4167 case XML_TOK_INVALID:
4168 eventPtr = next;
4169 return XML_ERROR_INVALID_TOKEN;
4170 case XML_TOK_PARTIAL:
4171 if (nextPtr) {
4172 *nextPtr = s;
4173 return XML_ERROR_NONE;
4174 }
4175 return XML_ERROR_UNCLOSED_TOKEN;
4176 case XML_TOK_PARTIAL_CHAR:
4177 if (nextPtr) {
4178 *nextPtr = s;
4179 return XML_ERROR_NONE;
4180 }
4181 return XML_ERROR_PARTIAL_CHAR;
4182 default:
4183 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4184 }
4185 eventPtr = s = next;
4186 }
4187}
4188
4189#ifdef XML_DTD
4190
4191static enum XML_Error
4192processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4193{
4194 const char *s, *end, *next;
4195 int tok;
4196 enum XML_Error result;
4197 OPEN_INTERNAL_ENTITY openEntity;
4198 entity->open = XML_TRUE;
4199 openEntity.next = openInternalEntities;
4200 openInternalEntities = &openEntity;
4201 openEntity.entity = entity;
4202 openEntity.internalEventPtr = NULL;
4203 openEntity.internalEventEndPtr = NULL;
4204 s = (char *)entity->textPtr;
4205 end = (char *)(entity->textPtr + entity->textLen);
4206 tok = XmlPrologTok(internalEncoding, s, end, &next);
4207 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
4208 entity->open = XML_FALSE;
4209 openInternalEntities = openEntity.next;
4210 return result;
4211}
4212
4213#endif /* XML_DTD */
4214
4215static enum XML_Error PTRCALL
4216errorProcessor(XML_Parser parser,
4217 const char *s,
4218 const char *end,
4219 const char **nextPtr)
4220{
4221 return errorCode;
4222}
4223
4224static enum XML_Error
4225storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4226 const char *ptr, const char *end,
4227 STRING_POOL *pool)
4228{
4229 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4230 end, pool);
4231 if (result)
4232 return result;
4233 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4234 poolChop(pool);
4235 if (!poolAppendChar(pool, XML_T('\0')))
4236 return XML_ERROR_NO_MEMORY;
4237 return XML_ERROR_NONE;
4238}
4239
4240static enum XML_Error
4241appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4242 const char *ptr, const char *end,
4243 STRING_POOL *pool)
4244{
4245 DTD * const dtd = _dtd; /* save one level of indirection */
4246 for (;;) {
4247 const char *next;
4248 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4249 switch (tok) {
4250 case XML_TOK_NONE:
4251 return XML_ERROR_NONE;
4252 case XML_TOK_INVALID:
4253 if (enc == encoding)
4254 eventPtr = next;
4255 return XML_ERROR_INVALID_TOKEN;
4256 case XML_TOK_PARTIAL:
4257 if (enc == encoding)
4258 eventPtr = ptr;
4259 return XML_ERROR_INVALID_TOKEN;
4260 case XML_TOK_CHAR_REF:
4261 {
4262 XML_Char buf[XML_ENCODE_MAX];
4263 int i;
4264 int n = XmlCharRefNumber(enc, ptr);
4265 if (n < 0) {
4266 if (enc == encoding)
4267 eventPtr = ptr;
4268 return XML_ERROR_BAD_CHAR_REF;
4269 }
4270 if (!isCdata
4271 && n == 0x20 /* space */
4272 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4273 break;
4274 n = XmlEncode(n, (ICHAR *)buf);
4275 if (!n) {
4276 if (enc == encoding)
4277 eventPtr = ptr;
4278 return XML_ERROR_BAD_CHAR_REF;
4279 }
4280 for (i = 0; i < n; i++) {
4281 if (!poolAppendChar(pool, buf[i]))
4282 return XML_ERROR_NO_MEMORY;
4283 }
4284 }
4285 break;
4286 case XML_TOK_DATA_CHARS:
4287 if (!poolAppend(pool, enc, ptr, next))
4288 return XML_ERROR_NO_MEMORY;
4289 break;
4290 case XML_TOK_TRAILING_CR:
4291 next = ptr + enc->minBytesPerChar;
4292 /* fall through */
4293 case XML_TOK_ATTRIBUTE_VALUE_S:
4294 case XML_TOK_DATA_NEWLINE:
4295 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4296 break;
4297 if (!poolAppendChar(pool, 0x20))
4298 return XML_ERROR_NO_MEMORY;
4299 break;
4300 case XML_TOK_ENTITY_REF:
4301 {
4302 const XML_Char *name;
4303 ENTITY *entity;
4304 char checkEntityDecl;
4305 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4306 ptr + enc->minBytesPerChar,
4307 next - enc->minBytesPerChar);
4308 if (ch) {
4309 if (!poolAppendChar(pool, ch))
4310 return XML_ERROR_NO_MEMORY;
4311 break;
4312 }
4313 name = poolStoreString(&temp2Pool, enc,
4314 ptr + enc->minBytesPerChar,
4315 next - enc->minBytesPerChar);
4316 if (!name)
4317 return XML_ERROR_NO_MEMORY;
4318 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4319 poolDiscard(&temp2Pool);
4320 /* first, determine if a check for an existing declaration is needed;
4321 if yes, check that the entity exists, and that it is internal,
4322 otherwise call the default handler (if called from content)
4323 */
4324 if (pool == &dtd->pool) /* are we called from prolog? */
4325 checkEntityDecl =
4326#ifdef XML_DTD
4327 prologState.documentEntity &&
4328#endif /* XML_DTD */
4329 (dtd->standalone
4330 ? !openInternalEntities
4331 : !dtd->hasParamEntityRefs);
4332 else /* if (pool == &tempPool): we are called from content */
4333 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4334 if (checkEntityDecl) {
4335 if (!entity)
4336 return XML_ERROR_UNDEFINED_ENTITY;
4337 else if (!entity->is_internal)
4338 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4339 }
4340 else if (!entity) {
4341 /* cannot report skipped entity here - see comments on
4342 skippedEntityHandler
4343 if (skippedEntityHandler)
4344 skippedEntityHandler(handlerArg, name, 0);
4345 */
4346 if ((pool == &tempPool) && defaultHandler)
4347 reportDefault(parser, enc, ptr, next);
4348 break;
4349 }
4350 if (entity->open) {
4351 if (enc == encoding)
4352 eventPtr = ptr;
4353 return XML_ERROR_RECURSIVE_ENTITY_REF;
4354 }
4355 if (entity->notation) {
4356 if (enc == encoding)
4357 eventPtr = ptr;
4358 return XML_ERROR_BINARY_ENTITY_REF;
4359 }
4360 if (!entity->textPtr) {
4361 if (enc == encoding)
4362 eventPtr = ptr;
4363 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4364 }
4365 else {
4366 enum XML_Error result;
4367 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4368 entity->open = XML_TRUE;
4369 result = appendAttributeValue(parser, internalEncoding, isCdata,
4370 (char *)entity->textPtr,
4371 (char *)textEnd, pool);
4372 entity->open = XML_FALSE;
4373 if (result)
4374 return result;
4375 }
4376 }
4377 break;
4378 default:
4379 if (enc == encoding)
4380 eventPtr = ptr;
4381 return XML_ERROR_UNEXPECTED_STATE;
4382 }
4383 ptr = next;
4384 }
4385 /* not reached */
4386}
4387
4388static enum XML_Error
4389storeEntityValue(XML_Parser parser,
4390 const ENCODING *enc,
4391 const char *entityTextPtr,
4392 const char *entityTextEnd)
4393{
4394 DTD * const dtd = _dtd; /* save one level of indirection */
4395 STRING_POOL *pool = &(dtd->entityValuePool);
4396 enum XML_Error result = XML_ERROR_NONE;
4397#ifdef XML_DTD
4398 int oldInEntityValue = prologState.inEntityValue;
4399 prologState.inEntityValue = 1;
4400#endif /* XML_DTD */
4401 /* never return Null for the value argument in EntityDeclHandler,
4402 since this would indicate an external entity; therefore we
4403 have to make sure that entityValuePool.start is not null */
4404 if (!pool->blocks) {
4405 if (!poolGrow(pool))
4406 return XML_ERROR_NO_MEMORY;
4407 }
4408
4409 for (;;) {
4410 const char *next;
4411 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4412 switch (tok) {
4413 case XML_TOK_PARAM_ENTITY_REF:
4414#ifdef XML_DTD
4415 if (isParamEntity || enc != encoding) {
4416 const XML_Char *name;
4417 ENTITY *entity;
4418 name = poolStoreString(&tempPool, enc,
4419 entityTextPtr + enc->minBytesPerChar,
4420 next - enc->minBytesPerChar);
4421 if (!name) {
4422 result = XML_ERROR_NO_MEMORY;
4423 goto endEntityValue;
4424 }
4425 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4426 poolDiscard(&tempPool);
4427 if (!entity) {
4428 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4429 /* cannot report skipped entity here - see comments on
4430 skippedEntityHandler
4431 if (skippedEntityHandler)
4432 skippedEntityHandler(handlerArg, name, 0);
4433 */
4434 dtd->keepProcessing = dtd->standalone;
4435 goto endEntityValue;
4436 }
4437 if (entity->open) {
4438 if (enc == encoding)
4439 eventPtr = entityTextPtr;
4440 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4441 goto endEntityValue;
4442 }
4443 if (entity->systemId) {
4444 if (externalEntityRefHandler) {
4445 dtd->paramEntityRead = XML_FALSE;
4446 entity->open = XML_TRUE;
4447 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4448 0,
4449 entity->base,
4450 entity->systemId,
4451 entity->publicId)) {
4452 entity->open = XML_FALSE;
4453 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4454 goto endEntityValue;
4455 }
4456 entity->open = XML_FALSE;
4457 if (!dtd->paramEntityRead)
4458 dtd->keepProcessing = dtd->standalone;
4459 }
4460 else
4461 dtd->keepProcessing = dtd->standalone;
4462 }
4463 else {
4464 entity->open = XML_TRUE;
4465 result = storeEntityValue(parser,
4466 internalEncoding,
4467 (char *)entity->textPtr,
4468 (char *)(entity->textPtr
4469 + entity->textLen));
4470 entity->open = XML_FALSE;
4471 if (result)
4472 goto endEntityValue;
4473 }
4474 break;
4475 }
4476#endif /* XML_DTD */
4477 /* in the internal subset, PE references are not legal
4478 within markup declarations, e.g entity values in this case */
4479 eventPtr = entityTextPtr;
4480 result = XML_ERROR_PARAM_ENTITY_REF;
4481 goto endEntityValue;
4482 case XML_TOK_NONE:
4483 result = XML_ERROR_NONE;
4484 goto endEntityValue;
4485 case XML_TOK_ENTITY_REF:
4486 case XML_TOK_DATA_CHARS:
4487 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4488 result = XML_ERROR_NO_MEMORY;
4489 goto endEntityValue;
4490 }
4491 break;
4492 case XML_TOK_TRAILING_CR:
4493 next = entityTextPtr + enc->minBytesPerChar;
4494 /* fall through */
4495 case XML_TOK_DATA_NEWLINE:
4496 if (pool->end == pool->ptr && !poolGrow(pool)) {
4497 result = XML_ERROR_NO_MEMORY;
4498 goto endEntityValue;
4499 }
4500 *(pool->ptr)++ = 0xA;
4501 break;
4502 case XML_TOK_CHAR_REF:
4503 {
4504 XML_Char buf[XML_ENCODE_MAX];
4505 int i;
4506 int n = XmlCharRefNumber(enc, entityTextPtr);
4507 if (n < 0) {
4508 if (enc == encoding)
4509 eventPtr = entityTextPtr;
4510 result = XML_ERROR_BAD_CHAR_REF;
4511 goto endEntityValue;
4512 }
4513 n = XmlEncode(n, (ICHAR *)buf);
4514 if (!n) {
4515 if (enc == encoding)
4516 eventPtr = entityTextPtr;
4517 result = XML_ERROR_BAD_CHAR_REF;
4518 goto endEntityValue;
4519 }
4520 for (i = 0; i < n; i++) {
4521 if (pool->end == pool->ptr && !poolGrow(pool)) {
4522 result = XML_ERROR_NO_MEMORY;
4523 goto endEntityValue;
4524 }
4525 *(pool->ptr)++ = buf[i];
4526 }
4527 }
4528 break;
4529 case XML_TOK_PARTIAL:
4530 if (enc == encoding)
4531 eventPtr = entityTextPtr;
4532 result = XML_ERROR_INVALID_TOKEN;
4533 goto endEntityValue;
4534 case XML_TOK_INVALID:
4535 if (enc == encoding)
4536 eventPtr = next;
4537 result = XML_ERROR_INVALID_TOKEN;
4538 goto endEntityValue;
4539 default:
4540 if (enc == encoding)
4541 eventPtr = entityTextPtr;
4542 result = XML_ERROR_UNEXPECTED_STATE;
4543 goto endEntityValue;
4544 }
4545 entityTextPtr = next;
4546 }
4547endEntityValue:
4548#ifdef XML_DTD
4549 prologState.inEntityValue = oldInEntityValue;
4550#endif /* XML_DTD */
4551 return result;
4552}
4553
4554static void FASTCALL
4555normalizeLines(XML_Char *s)
4556{
4557 XML_Char *p;
4558 for (;; s++) {
4559 if (*s == XML_T('\0'))
4560 return;
4561 if (*s == 0xD)
4562 break;
4563 }
4564 p = s;
4565 do {
4566 if (*s == 0xD) {
4567 *p++ = 0xA;
4568 if (*++s == 0xA)
4569 s++;
4570 }
4571 else
4572 *p++ = *s++;
4573 } while (*s);
4574 *p = XML_T('\0');
4575}
4576
4577static int
4578reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4579 const char *start, const char *end)
4580{
4581 const XML_Char *target;
4582 XML_Char *data;
4583 const char *tem;
4584 if (!processingInstructionHandler) {
4585 if (defaultHandler)
4586 reportDefault(parser, enc, start, end);
4587 return 1;
4588 }
4589 start += enc->minBytesPerChar * 2;
4590 tem = start + XmlNameLength(enc, start);
4591 target = poolStoreString(&tempPool, enc, start, tem);
4592 if (!target)
4593 return 0;
4594 poolFinish(&tempPool);
4595 data = poolStoreString(&tempPool, enc,
4596 XmlSkipS(enc, tem),
4597 end - enc->minBytesPerChar*2);
4598 if (!data)
4599 return 0;
4600 normalizeLines(data);
4601 processingInstructionHandler(handlerArg, target, data);
4602 poolClear(&tempPool);
4603 return 1;
4604}
4605
4606static int
4607reportComment(XML_Parser parser, const ENCODING *enc,
4608 const char *start, const char *end)
4609{
4610 XML_Char *data;
4611 if (!commentHandler) {
4612 if (defaultHandler)
4613 reportDefault(parser, enc, start, end);
4614 return 1;
4615 }
4616 data = poolStoreString(&tempPool,
4617 enc,
4618 start + enc->minBytesPerChar * 4,
4619 end - enc->minBytesPerChar * 3);
4620 if (!data)
4621 return 0;
4622 normalizeLines(data);
4623 commentHandler(handlerArg, data);
4624 poolClear(&tempPool);
4625 return 1;
4626}
4627
4628static void
4629reportDefault(XML_Parser parser, const ENCODING *enc,
4630 const char *s, const char *end)
4631{
4632 if (MUST_CONVERT(enc, s)) {
4633 const char **eventPP;
4634 const char **eventEndPP;
4635 if (enc == encoding) {
4636 eventPP = &eventPtr;
4637 eventEndPP = &eventEndPtr;
4638 }
4639 else {
4640 eventPP = &(openInternalEntities->internalEventPtr);
4641 eventEndPP = &(openInternalEntities->internalEventEndPtr);
4642 }
4643 do {
4644 ICHAR *dataPtr = (ICHAR *)dataBuf;
4645 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4646 *eventEndPP = s;
4647 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4648 *eventPP = s;
4649 } while (s != end);
4650 }
4651 else
4652 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4653}
4654
4655
4656static int
4657defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4658 XML_Bool isId, const XML_Char *value, XML_Parser parser)
4659{
4660 DEFAULT_ATTRIBUTE *att;
4661 if (value || isId) {
4662 /* The handling of default attributes gets messed up if we have
4663 a default which duplicates a non-default. */
4664 int i;
4665 for (i = 0; i < type->nDefaultAtts; i++)
4666 if (attId == type->defaultAtts[i].id)
4667 return 1;
4668 if (isId && !type->idAtt && !attId->xmlns)
4669 type->idAtt = attId;
4670 }
4671 if (type->nDefaultAtts == type->allocDefaultAtts) {
4672 if (type->allocDefaultAtts == 0) {
4673 type->allocDefaultAtts = 8;
4674 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
4675 * sizeof(DEFAULT_ATTRIBUTE));
4676 if (!type->defaultAtts)
4677 return 0;
4678 }
4679 else {
4680 DEFAULT_ATTRIBUTE *temp;
4681 int count = type->allocDefaultAtts * 2;
4682 temp = (DEFAULT_ATTRIBUTE *)
4683 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4684 if (temp == NULL)
4685 return 0;
4686 type->allocDefaultAtts = count;
4687 type->defaultAtts = temp;
4688 }
4689 }
4690 att = type->defaultAtts + type->nDefaultAtts;
4691 att->id = attId;
4692 att->value = value;
4693 att->isCdata = isCdata;
4694 if (!isCdata)
4695 attId->maybeTokenized = XML_TRUE;
4696 type->nDefaultAtts += 1;
4697 return 1;
4698}
4699
4700static int
4701setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
4702{
4703 DTD * const dtd = _dtd; /* save one level of indirection */
4704 const XML_Char *name;
4705 for (name = elementType->name; *name; name++) {
4706 if (*name == XML_T(':')) {
4707 PREFIX *prefix;
4708 const XML_Char *s;
4709 for (s = elementType->name; s != name; s++) {
4710 if (!poolAppendChar(&dtd->pool, *s))
4711 return 0;
4712 }
4713 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4714 return 0;
4715 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4716 sizeof(PREFIX));
4717 if (!prefix)
4718 return 0;
4719 if (prefix->name == poolStart(&dtd->pool))
4720 poolFinish(&dtd->pool);
4721 else
4722 poolDiscard(&dtd->pool);
4723 elementType->prefix = prefix;
4724
4725 }
4726 }
4727 return 1;
4728}
4729
4730static ATTRIBUTE_ID *
4731getAttributeId(XML_Parser parser, const ENCODING *enc,
4732 const char *start, const char *end)
4733{
4734 DTD * const dtd = _dtd; /* save one level of indirection */
4735 ATTRIBUTE_ID *id;
4736 const XML_Char *name;
4737 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4738 return NULL;
4739 name = poolStoreString(&dtd->pool, enc, start, end);
4740 if (!name)
4741 return NULL;
4742 ++name;
4743 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
4744 if (!id)
4745 return NULL;
4746 if (id->name != name)
4747 poolDiscard(&dtd->pool);
4748 else {
4749 poolFinish(&dtd->pool);
4750 if (!ns)
4751 ;
4752 else if (name[0] == XML_T('x')
4753 && name[1] == XML_T('m')
4754 && name[2] == XML_T('l')
4755 && name[3] == XML_T('n')
4756 && name[4] == XML_T('s')
4757 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4758 if (name[5] == XML_T('\0'))
4759 id->prefix = &dtd->defaultPrefix;
4760 else
4761 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
4762 id->xmlns = XML_TRUE;
4763 }
4764 else {
4765 int i;
4766 for (i = 0; name[i]; i++) {
4767 if (name[i] == XML_T(':')) {
4768 int j;
4769 for (j = 0; j < i; j++) {
4770 if (!poolAppendChar(&dtd->pool, name[j]))
4771 return NULL;
4772 }
4773 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4774 return NULL;
4775 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4776 sizeof(PREFIX));
4777 if (id->prefix->name == poolStart(&dtd->pool))
4778 poolFinish(&dtd->pool);
4779 else
4780 poolDiscard(&dtd->pool);
4781 break;
4782 }
4783 }
4784 }
4785 }
4786 return id;
4787}
4788
4789#define CONTEXT_SEP XML_T('\f')
4790
4791static const XML_Char *
4792getContext(XML_Parser parser)
4793{
4794 DTD * const dtd = _dtd; /* save one level of indirection */
4795 HASH_TABLE_ITER iter;
4796 XML_Bool needSep = XML_FALSE;
4797
4798 if (dtd->defaultPrefix.binding) {
4799 int i;
4800 int len;
4801 if (!poolAppendChar(&tempPool, XML_T('=')))
4802 return NULL;
4803 len = dtd->defaultPrefix.binding->uriLen;
4804 if (namespaceSeparator != XML_T('\0'))
4805 len--;
4806 for (i = 0; i < len; i++)
4807 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
4808 return NULL;
4809 needSep = XML_TRUE;
4810 }
4811
4812 hashTableIterInit(&iter, &(dtd->prefixes));
4813 for (;;) {
4814 int i;
4815 int len;
4816 const XML_Char *s;
4817 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4818 if (!prefix)
4819 break;
4820 if (!prefix->binding)
4821 continue;
4822 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4823 return NULL;
4824 for (s = prefix->name; *s; s++)
4825 if (!poolAppendChar(&tempPool, *s))
4826 return NULL;
4827 if (!poolAppendChar(&tempPool, XML_T('=')))
4828 return NULL;
4829 len = prefix->binding->uriLen;
4830 if (namespaceSeparator != XML_T('\0'))
4831 len--;
4832 for (i = 0; i < len; i++)
4833 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
4834 return NULL;
4835 needSep = XML_TRUE;
4836 }
4837
4838
4839 hashTableIterInit(&iter, &(dtd->generalEntities));
4840 for (;;) {
4841 const XML_Char *s;
4842 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4843 if (!e)
4844 break;
4845 if (!e->open)
4846 continue;
4847 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4848 return NULL;
4849 for (s = e->name; *s; s++)
4850 if (!poolAppendChar(&tempPool, *s))
4851 return 0;
4852 needSep = XML_TRUE;
4853 }
4854
4855 if (!poolAppendChar(&tempPool, XML_T('\0')))
4856 return NULL;
4857 return tempPool.start;
4858}
4859
4860static XML_Bool
4861setContext(XML_Parser parser, const XML_Char *context)
4862{
4863 DTD * const dtd = _dtd; /* save one level of indirection */
4864 const XML_Char *s = context;
4865
4866 while (*context != XML_T('\0')) {
4867 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4868 ENTITY *e;
4869 if (!poolAppendChar(&tempPool, XML_T('\0')))
4870 return XML_FALSE;
4871 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
4872 if (e)
4873 e->open = XML_TRUE;
4874 if (*s != XML_T('\0'))
4875 s++;
4876 context = s;
4877 poolDiscard(&tempPool);
4878 }
4879 else if (*s == XML_T('=')) {
4880 PREFIX *prefix;
4881 if (poolLength(&tempPool) == 0)
4882 prefix = &dtd->defaultPrefix;
4883 else {
4884 if (!poolAppendChar(&tempPool, XML_T('\0')))
4885 return XML_FALSE;
4886 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
4887 sizeof(PREFIX));
4888 if (!prefix)
4889 return XML_FALSE;
4890 if (prefix->name == poolStart(&tempPool)) {
4891 prefix->name = poolCopyString(&dtd->pool, prefix->name);
4892 if (!prefix->name)
4893 return XML_FALSE;
4894 }
4895 poolDiscard(&tempPool);
4896 }
4897 for (context = s + 1;
4898 *context != CONTEXT_SEP && *context != XML_T('\0');
4899 context++)
4900 if (!poolAppendChar(&tempPool, *context))
4901 return XML_FALSE;
4902 if (!poolAppendChar(&tempPool, XML_T('\0')))
4903 return XML_FALSE;
4904 if (addBinding(parser, prefix, 0, poolStart(&tempPool),
4905 &inheritedBindings) != XML_ERROR_NONE)
4906 return XML_FALSE;
4907 poolDiscard(&tempPool);
4908 if (*context != XML_T('\0'))
4909 ++context;
4910 s = context;
4911 }
4912 else {
4913 if (!poolAppendChar(&tempPool, *s))
4914 return XML_FALSE;
4915 s++;
4916 }
4917 }
4918 return XML_TRUE;
4919}
4920
4921static void FASTCALL
4922normalizePublicId(XML_Char *publicId)
4923{
4924 XML_Char *p = publicId;
4925 XML_Char *s;
4926 for (s = publicId; *s; s++) {
4927 switch (*s) {
4928 case 0x20:
4929 case 0xD:
4930 case 0xA:
4931 if (p != publicId && p[-1] != 0x20)
4932 *p++ = 0x20;
4933 break;
4934 default:
4935 *p++ = *s;
4936 }
4937 }
4938 if (p != publicId && p[-1] == 0x20)
4939 --p;
4940 *p = XML_T('\0');
4941}
4942
4943static DTD *
4944dtdCreate(const XML_Memory_Handling_Suite *ms)
4945{
4946 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
4947 if (p == NULL)
4948 return p;
4949 poolInit(&(p->pool), ms);
4950#ifdef XML_DTD
4951 poolInit(&(p->entityValuePool), ms);
4952#endif /* XML_DTD */
4953 hashTableInit(&(p->generalEntities), ms);
4954 hashTableInit(&(p->elementTypes), ms);
4955 hashTableInit(&(p->attributeIds), ms);
4956 hashTableInit(&(p->prefixes), ms);
4957#ifdef XML_DTD
4958 p->paramEntityRead = XML_FALSE;
4959 hashTableInit(&(p->paramEntities), ms);
4960#endif /* XML_DTD */
4961 p->defaultPrefix.name = NULL;
4962 p->defaultPrefix.binding = NULL;
4963
4964 p->in_eldecl = XML_FALSE;
4965 p->scaffIndex = NULL;
4966 p->scaffold = NULL;
4967 p->scaffLevel = 0;
4968 p->scaffSize = 0;
4969 p->scaffCount = 0;
4970 p->contentStringLen = 0;
4971
4972 p->keepProcessing = XML_TRUE;
4973 p->hasParamEntityRefs = XML_FALSE;
4974 p->standalone = XML_FALSE;
4975 return p;
4976}
4977
4978static void
4979dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
4980{
4981 HASH_TABLE_ITER iter;
4982 hashTableIterInit(&iter, &(p->elementTypes));
4983 for (;;) {
4984 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4985 if (!e)
4986 break;
4987 if (e->allocDefaultAtts != 0)
4988 ms->free_fcn(e->defaultAtts);
4989 }
4990 hashTableClear(&(p->generalEntities));
4991#ifdef XML_DTD
4992 p->paramEntityRead = XML_FALSE;
4993 hashTableClear(&(p->paramEntities));
4994#endif /* XML_DTD */
4995 hashTableClear(&(p->elementTypes));
4996 hashTableClear(&(p->attributeIds));
4997 hashTableClear(&(p->prefixes));
4998 poolClear(&(p->pool));
4999#ifdef XML_DTD
5000 poolClear(&(p->entityValuePool));
5001#endif /* XML_DTD */
5002 p->defaultPrefix.name = NULL;
5003 p->defaultPrefix.binding = NULL;
5004
5005 p->in_eldecl = XML_FALSE;
5006 if (p->scaffIndex) {
5007 ms->free_fcn(p->scaffIndex);
5008 p->scaffIndex = NULL;
5009 }
5010 if (p->scaffold) {
5011 ms->free_fcn(p->scaffold);
5012 p->scaffold = NULL;
5013 }
5014 p->scaffLevel = 0;
5015 p->scaffSize = 0;
5016 p->scaffCount = 0;
5017 p->contentStringLen = 0;
5018
5019 p->keepProcessing = XML_TRUE;
5020 p->hasParamEntityRefs = XML_FALSE;
5021 p->standalone = XML_FALSE;
5022}
5023
5024static void
5025dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5026{
5027 HASH_TABLE_ITER iter;
5028 hashTableIterInit(&iter, &(p->elementTypes));
5029 for (;;) {
5030 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5031 if (!e)
5032 break;
5033 if (e->allocDefaultAtts != 0)
5034 ms->free_fcn(e->defaultAtts);
5035 }
5036 hashTableDestroy(&(p->generalEntities));
5037#ifdef XML_DTD
5038 hashTableDestroy(&(p->paramEntities));
5039#endif /* XML_DTD */
5040 hashTableDestroy(&(p->elementTypes));
5041 hashTableDestroy(&(p->attributeIds));
5042 hashTableDestroy(&(p->prefixes));
5043 poolDestroy(&(p->pool));
5044#ifdef XML_DTD
5045 poolDestroy(&(p->entityValuePool));
5046#endif /* XML_DTD */
5047 if (isDocEntity) {
5048 if (p->scaffIndex)
5049 ms->free_fcn(p->scaffIndex);
5050 if (p->scaffold)
5051 ms->free_fcn(p->scaffold);
5052 }
5053 ms->free_fcn(p);
5054}
5055
5056/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5057 The new DTD has already been initialized.
5058*/
5059static int
5060dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5061{
5062 HASH_TABLE_ITER iter;
5063
5064 /* Copy the prefix table. */
5065
5066 hashTableIterInit(&iter, &(oldDtd->prefixes));
5067 for (;;) {
5068 const XML_Char *name;
5069 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5070 if (!oldP)
5071 break;
5072 name = poolCopyString(&(newDtd->pool), oldP->name);
5073 if (!name)
5074 return 0;
5075 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5076 return 0;
5077 }
5078
5079 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5080
5081 /* Copy the attribute id table. */
5082
5083 for (;;) {
5084 ATTRIBUTE_ID *newA;
5085 const XML_Char *name;
5086 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5087
5088 if (!oldA)
5089 break;
5090 /* Remember to allocate the scratch byte before the name. */
5091 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5092 return 0;
5093 name = poolCopyString(&(newDtd->pool), oldA->name);
5094 if (!name)
5095 return 0;
5096 ++name;
5097 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5098 sizeof(ATTRIBUTE_ID));
5099 if (!newA)
5100 return 0;
5101 newA->maybeTokenized = oldA->maybeTokenized;
5102 if (oldA->prefix) {
5103 newA->xmlns = oldA->xmlns;
5104 if (oldA->prefix == &oldDtd->defaultPrefix)
5105 newA->prefix = &newDtd->defaultPrefix;
5106 else
5107 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5108 oldA->prefix->name, 0);
5109 }
5110 }
5111
5112 /* Copy the element type table. */
5113
5114 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5115
5116 for (;;) {
5117 int i;
5118 ELEMENT_TYPE *newE;
5119 const XML_Char *name;
5120 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5121 if (!oldE)
5122 break;
5123 name = poolCopyString(&(newDtd->pool), oldE->name);
5124 if (!name)
5125 return 0;
5126 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5127 sizeof(ELEMENT_TYPE));
5128 if (!newE)
5129 return 0;
5130 if (oldE->nDefaultAtts) {
5131 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5132 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5133 if (!newE->defaultAtts) {
5134 ms->free_fcn(newE);
5135 return 0;
5136 }
5137 }
5138 if (oldE->idAtt)
5139 newE->idAtt = (ATTRIBUTE_ID *)
5140 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5141 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5142 if (oldE->prefix)
5143 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5144 oldE->prefix->name, 0);
5145 for (i = 0; i < newE->nDefaultAtts; i++) {
5146 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5147 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5148 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5149 if (oldE->defaultAtts[i].value) {
5150 newE->defaultAtts[i].value
5151 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5152 if (!newE->defaultAtts[i].value)
5153 return 0;
5154 }
5155 else
5156 newE->defaultAtts[i].value = NULL;
5157 }
5158 }
5159
5160 /* Copy the entity tables. */
5161 if (!copyEntityTable(&(newDtd->generalEntities),
5162 &(newDtd->pool),
5163 &(oldDtd->generalEntities)))
5164 return 0;
5165
5166#ifdef XML_DTD
5167 if (!copyEntityTable(&(newDtd->paramEntities),
5168 &(newDtd->pool),
5169 &(oldDtd->paramEntities)))
5170 return 0;
5171 newDtd->paramEntityRead = oldDtd->paramEntityRead;
5172#endif /* XML_DTD */
5173
5174 newDtd->keepProcessing = oldDtd->keepProcessing;
5175 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5176 newDtd->standalone = oldDtd->standalone;
5177
5178 /* Don't want deep copying for scaffolding */
5179 newDtd->in_eldecl = oldDtd->in_eldecl;
5180 newDtd->scaffold = oldDtd->scaffold;
5181 newDtd->contentStringLen = oldDtd->contentStringLen;
5182 newDtd->scaffSize = oldDtd->scaffSize;
5183 newDtd->scaffLevel = oldDtd->scaffLevel;
5184 newDtd->scaffIndex = oldDtd->scaffIndex;
5185
5186 return 1;
5187} /* End dtdCopy */
5188
5189static int
5190copyEntityTable(HASH_TABLE *newTable,
5191 STRING_POOL *newPool,
5192 const HASH_TABLE *oldTable)
5193{
5194 HASH_TABLE_ITER iter;
5195 const XML_Char *cachedOldBase = NULL;
5196 const XML_Char *cachedNewBase = NULL;
5197
5198 hashTableIterInit(&iter, oldTable);
5199
5200 for (;;) {
5201 ENTITY *newE;
5202 const XML_Char *name;
5203 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5204 if (!oldE)
5205 break;
5206 name = poolCopyString(newPool, oldE->name);
5207 if (!name)
5208 return 0;
5209 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5210 if (!newE)
5211 return 0;
5212 if (oldE->systemId) {
5213 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5214 if (!tem)
5215 return 0;
5216 newE->systemId = tem;
5217 if (oldE->base) {
5218 if (oldE->base == cachedOldBase)
5219 newE->base = cachedNewBase;
5220 else {
5221 cachedOldBase = oldE->base;
5222 tem = poolCopyString(newPool, cachedOldBase);
5223 if (!tem)
5224 return 0;
5225 cachedNewBase = newE->base = tem;
5226 }
5227 }
5228 if (oldE->publicId) {
5229 tem = poolCopyString(newPool, oldE->publicId);
5230 if (!tem)
5231 return 0;
5232 newE->publicId = tem;
5233 }
5234 }
5235 else {
5236 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5237 oldE->textLen);
5238 if (!tem)
5239 return 0;
5240 newE->textPtr = tem;
5241 newE->textLen = oldE->textLen;
5242 }
5243 if (oldE->notation) {
5244 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5245 if (!tem)
5246 return 0;
5247 newE->notation = tem;
5248 }
5249 newE->is_param = oldE->is_param;
5250 newE->is_internal = oldE->is_internal;
5251 }
5252 return 1;
5253}
5254
5255#define INIT_SIZE 64
5256
5257static int FASTCALL
5258keyeq(KEY s1, KEY s2)
5259{
5260 for (; *s1 == *s2; s1++, s2++)
5261 if (*s1 == 0)
5262 return 1;
5263 return 0;
5264}
5265
5266static unsigned long FASTCALL
5267hash(KEY s)
5268{
5269 unsigned long h = 0;
5270 while (*s)
5271 h = (h << 5) + h + (unsigned char)*s++;
5272 return h;
5273}
5274
5275static NAMED *
5276lookup(HASH_TABLE *table, KEY name, size_t createSize)
5277{
5278 size_t i;
5279 if (table->size == 0) {
5280 size_t tsize;
5281
5282 if (!createSize)
5283 return NULL;
5284 tsize = INIT_SIZE * sizeof(NAMED *);
5285 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
5286 if (!table->v)
5287 return NULL;
5288 memset(table->v, 0, tsize);
5289 table->size = INIT_SIZE;
5290 table->usedLim = INIT_SIZE / 2;
5291 i = hash(name) & (table->size - 1);
5292 }
5293 else {
5294 unsigned long h = hash(name);
5295 for (i = h & (table->size - 1);
5296 table->v[i];
5297 i == 0 ? i = table->size - 1 : --i) {
5298 if (keyeq(name, table->v[i]->name))
5299 return table->v[i];
5300 }
5301 if (!createSize)
5302 return NULL;
5303 if (table->used == table->usedLim) {
5304 /* check for overflow */
5305 size_t newSize = table->size * 2;
5306 size_t tsize = newSize * sizeof(NAMED *);
5307 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
5308 if (!newV)
5309 return NULL;
5310 memset(newV, 0, tsize);
5311 for (i = 0; i < table->size; i++)
5312 if (table->v[i]) {
5313 size_t j;
5314 for (j = hash(table->v[i]->name) & (newSize - 1);
5315 newV[j];
5316 j == 0 ? j = newSize - 1 : --j)
5317 ;
5318 newV[j] = table->v[i];
5319 }
5320 table->mem->free_fcn(table->v);
5321 table->v = newV;
5322 table->size = newSize;
5323 table->usedLim = newSize/2;
5324 for (i = h & (table->size - 1);
5325 table->v[i];
5326 i == 0 ? i = table->size - 1 : --i)
5327 ;
5328 }
5329 }
5330 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
5331 if (!table->v[i])
5332 return NULL;
5333 memset(table->v[i], 0, createSize);
5334 table->v[i]->name = name;
5335 (table->used)++;
5336 return table->v[i];
5337}
5338
5339static void FASTCALL
5340hashTableClear(HASH_TABLE *table)
5341{
5342 size_t i;
5343 for (i = 0; i < table->size; i++) {
5344 NAMED *p = table->v[i];
5345 if (p) {
5346 table->mem->free_fcn(p);
5347 table->v[i] = NULL;
5348 }
5349 }
5350 table->usedLim = table->size / 2;
5351 table->used = 0;
5352}
5353
5354static void FASTCALL
5355hashTableDestroy(HASH_TABLE *table)
5356{
5357 size_t i;
5358 for (i = 0; i < table->size; i++) {
5359 NAMED *p = table->v[i];
5360 if (p)
5361 table->mem->free_fcn(p);
5362 }
5363 if (table->v)
5364 table->mem->free_fcn(table->v);
5365}
5366
5367static void FASTCALL
5368hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
5369{
5370 p->size = 0;
5371 p->usedLim = 0;
5372 p->used = 0;
5373 p->v = NULL;
5374 p->mem = ms;
5375}
5376
5377static void FASTCALL
5378hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
5379{
5380 iter->p = table->v;
5381 iter->end = iter->p + table->size;
5382}
5383
5384static NAMED * FASTCALL
5385hashTableIterNext(HASH_TABLE_ITER *iter)
5386{
5387 while (iter->p != iter->end) {
5388 NAMED *tem = *(iter->p)++;
5389 if (tem)
5390 return tem;
5391 }
5392 return NULL;
5393}
5394
5395static void FASTCALL
5396poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
5397{
5398 pool->blocks = NULL;
5399 pool->freeBlocks = NULL;
5400 pool->start = NULL;
5401 pool->ptr = NULL;
5402 pool->end = NULL;
5403 pool->mem = ms;
5404}
5405
5406static void FASTCALL
5407poolClear(STRING_POOL *pool)
5408{
5409 if (!pool->freeBlocks)
5410 pool->freeBlocks = pool->blocks;
5411 else {
5412 BLOCK *p = pool->blocks;
5413 while (p) {
5414 BLOCK *tem = p->next;
5415 p->next = pool->freeBlocks;
5416 pool->freeBlocks = p;
5417 p = tem;
5418 }
5419 }
5420 pool->blocks = NULL;
5421 pool->start = NULL;
5422 pool->ptr = NULL;
5423 pool->end = NULL;
5424}
5425
5426static void FASTCALL
5427poolDestroy(STRING_POOL *pool)
5428{
5429 BLOCK *p = pool->blocks;
5430 while (p) {
5431 BLOCK *tem = p->next;
5432 pool->mem->free_fcn(p);
5433 p = tem;
5434 }
5435 p = pool->freeBlocks;
5436 while (p) {
5437 BLOCK *tem = p->next;
5438 pool->mem->free_fcn(p);
5439 p = tem;
5440 }
5441}
5442
5443static XML_Char *
5444poolAppend(STRING_POOL *pool, const ENCODING *enc,
5445 const char *ptr, const char *end)
5446{
5447 if (!pool->ptr && !poolGrow(pool))
5448 return NULL;
5449 for (;;) {
5450 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5451 if (ptr == end)
5452 break;
5453 if (!poolGrow(pool))
5454 return NULL;
5455 }
5456 return pool->start;
5457}
5458
5459static const XML_Char * FASTCALL
5460poolCopyString(STRING_POOL *pool, const XML_Char *s)
5461{
5462 do {
5463 if (!poolAppendChar(pool, *s))
5464 return NULL;
5465 } while (*s++);
5466 s = pool->start;
5467 poolFinish(pool);
5468 return s;
5469}
5470
5471static const XML_Char *
5472poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
5473{
5474 if (!pool->ptr && !poolGrow(pool))
5475 return NULL;
5476 for (; n > 0; --n, s++) {
5477 if (!poolAppendChar(pool, *s))
5478 return NULL;
5479 }
5480 s = pool->start;
5481 poolFinish(pool);
5482 return s;
5483}
5484
5485static const XML_Char * FASTCALL
5486poolAppendString(STRING_POOL *pool, const XML_Char *s)
5487{
5488 while (*s) {
5489 if (!poolAppendChar(pool, *s))
5490 return NULL;
5491 s++;
5492 }
5493 return pool->start;
5494}
5495
5496static XML_Char *
5497poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5498 const char *ptr, const char *end)
5499{
5500 if (!poolAppend(pool, enc, ptr, end))
5501 return NULL;
5502 if (pool->ptr == pool->end && !poolGrow(pool))
5503 return NULL;
5504 *(pool->ptr)++ = 0;
5505 return pool->start;
5506}
5507
5508static XML_Bool FASTCALL
5509poolGrow(STRING_POOL *pool)
5510{
5511 if (pool->freeBlocks) {
5512 if (pool->start == 0) {
5513 pool->blocks = pool->freeBlocks;
5514 pool->freeBlocks = pool->freeBlocks->next;
5515 pool->blocks->next = NULL;
5516 pool->start = pool->blocks->s;
5517 pool->end = pool->start + pool->blocks->size;
5518 pool->ptr = pool->start;
5519 return XML_TRUE;
5520 }
5521 if (pool->end - pool->start < pool->freeBlocks->size) {
5522 BLOCK *tem = pool->freeBlocks->next;
5523 pool->freeBlocks->next = pool->blocks;
5524 pool->blocks = pool->freeBlocks;
5525 pool->freeBlocks = tem;
5526 memcpy(pool->blocks->s, pool->start,
5527 (pool->end - pool->start) * sizeof(XML_Char));
5528 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5529 pool->start = pool->blocks->s;
5530 pool->end = pool->start + pool->blocks->size;
5531 return XML_TRUE;
5532 }
5533 }
5534 if (pool->blocks && pool->start == pool->blocks->s) {
5535 int blockSize = (pool->end - pool->start)*2;
5536 pool->blocks = (BLOCK *)
5537 pool->mem->realloc_fcn(pool->blocks,
5538 (offsetof(BLOCK, s)
5539 + blockSize * sizeof(XML_Char)));
5540 if (pool->blocks == NULL)
5541 return XML_FALSE;
5542 pool->blocks->size = blockSize;
5543 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5544 pool->start = pool->blocks->s;
5545 pool->end = pool->start + blockSize;
5546 }
5547 else {
5548 BLOCK *tem;
5549 int blockSize = pool->end - pool->start;
5550 if (blockSize < INIT_BLOCK_SIZE)
5551 blockSize = INIT_BLOCK_SIZE;
5552 else
5553 blockSize *= 2;
5554 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
5555 + blockSize * sizeof(XML_Char));
5556 if (!tem)
5557 return XML_FALSE;
5558 tem->size = blockSize;
5559 tem->next = pool->blocks;
5560 pool->blocks = tem;
5561 if (pool->ptr != pool->start)
5562 memcpy(tem->s, pool->start,
5563 (pool->ptr - pool->start) * sizeof(XML_Char));
5564 pool->ptr = tem->s + (pool->ptr - pool->start);
5565 pool->start = tem->s;
5566 pool->end = tem->s + blockSize;
5567 }
5568 return XML_TRUE;
5569}
5570
5571static int FASTCALL
5572nextScaffoldPart(XML_Parser parser)
5573{
5574 DTD * const dtd = _dtd; /* save one level of indirection */
5575 CONTENT_SCAFFOLD * me;
5576 int next;
5577
5578 if (!dtd->scaffIndex) {
5579 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
5580 if (!dtd->scaffIndex)
5581 return -1;
5582 dtd->scaffIndex[0] = 0;
5583 }
5584
5585 if (dtd->scaffCount >= dtd->scaffSize) {
5586 CONTENT_SCAFFOLD *temp;
5587 if (dtd->scaffold) {
5588 temp = (CONTENT_SCAFFOLD *)
5589 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5590 if (temp == NULL)
5591 return -1;
5592 dtd->scaffSize *= 2;
5593 }
5594 else {
5595 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
5596 * sizeof(CONTENT_SCAFFOLD));
5597 if (temp == NULL)
5598 return -1;
5599 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
5600 }
5601 dtd->scaffold = temp;
5602 }
5603 next = dtd->scaffCount++;
5604 me = &dtd->scaffold[next];
5605 if (dtd->scaffLevel) {
5606 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
5607 if (parent->lastchild) {
5608 dtd->scaffold[parent->lastchild].nextsib = next;
5609 }
5610 if (!parent->childcnt)
5611 parent->firstchild = next;
5612 parent->lastchild = next;
5613 parent->childcnt++;
5614 }
5615 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5616 return next;
5617}
5618
5619static void
5620build_node(XML_Parser parser,
5621 int src_node,
5622 XML_Content *dest,
5623 XML_Content **contpos,
5624 XML_Char **strpos)
5625{
5626 DTD * const dtd = _dtd; /* save one level of indirection */
5627 dest->type = dtd->scaffold[src_node].type;
5628 dest->quant = dtd->scaffold[src_node].quant;
5629 if (dest->type == XML_CTYPE_NAME) {
5630 const XML_Char *src;
5631 dest->name = *strpos;
5632 src = dtd->scaffold[src_node].name;
5633 for (;;) {
5634 *(*strpos)++ = *src;
5635 if (!*src)
5636 break;
5637 src++;
5638 }
5639 dest->numchildren = 0;
5640 dest->children = NULL;
5641 }
5642 else {
5643 unsigned int i;
5644 int cn;
5645 dest->numchildren = dtd->scaffold[src_node].childcnt;
5646 dest->children = *contpos;
5647 *contpos += dest->numchildren;
5648 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
5649 i < dest->numchildren;
5650 i++, cn = dtd->scaffold[cn].nextsib) {
5651 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5652 }
5653 dest->name = NULL;
5654 }
5655}
5656
5657static XML_Content *
5658build_model (XML_Parser parser)
5659{
5660 DTD * const dtd = _dtd; /* save one level of indirection */
5661 XML_Content *ret;
5662 XML_Content *cpos;
5663 XML_Char * str;
5664 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
5665 + (dtd->contentStringLen * sizeof(XML_Char)));
5666
5667 ret = (XML_Content *)MALLOC(allocsize);
5668 if (!ret)
5669 return NULL;
5670
5671 str = (XML_Char *) (&ret[dtd->scaffCount]);
5672 cpos = &ret[1];
5673
5674 build_node(parser, 0, ret, &cpos, &str);
5675 return ret;
5676}
5677
5678static ELEMENT_TYPE *
5679getElementType(XML_Parser parser,
5680 const ENCODING *enc,
5681 const char *ptr,
5682 const char *end)
5683{
5684 DTD * const dtd = _dtd; /* save one level of indirection */
5685 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
5686 ELEMENT_TYPE *ret;
5687
5688 if (!name)
5689 return NULL;
5690 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5691 if (!ret)
5692 return NULL;
5693 if (ret->name != name)
5694 poolDiscard(&dtd->pool);
5695 else {
5696 poolFinish(&dtd->pool);
5697 if (!setElementTypePrefix(parser, ret))
5698 return NULL;
5699 }
5700 return ret;
5701}