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