]> git.saurik.com Git - wxWidgets.git/blame - src/expat/lib/xmlparse.c
Add wxActivateEvent::GetActivationReason().
[wxWidgets.git] / src / expat / lib / xmlparse.c
CommitLineData
5e9f2524
VS
1/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
3*/
4
5#include <stddef.h>
6#include <string.h> /* memset(), memcpy() */
11a3e7b6
VZ
7#include <assert.h>
8#include <limits.h> /* UINT_MAX */
9#include <time.h> /* time() */
5e9f2524 10
11a3e7b6 11#define XML_BUILDING_EXPAT 1
5e9f2524 12
11a3e7b6 13#ifdef COMPILED_FROM_DSP
5e9f2524 14#include "winconfig.h"
8ce8835c
WS
15#elif defined(OS2_32)
16
17#include "os2config.h"
18#include "expat.h"
19
b8af111f
WS
20#elif defined(__MSDOS__)
21
22#include "dosconfig.h"
23#include "expat.h"
24
5e9f2524 25#elif defined(MACOS_CLASSIC)
5e9f2524 26#include "macconfig.h"
11a3e7b6
VZ
27#elif defined(__amigaos__)
28#include "amigaconfig.h"
29#elif defined(__WATCOMC__)
30#include "watcomconfig.h"
31#elif defined(HAVE_EXPAT_CONFIG_H)
b5172775 32#include "expat_config.h"
11a3e7b6 33#endif /* ndef COMPILED_FROM_DSP */
5e9f2524 34
11a3e7b6 35#include "ascii.h"
5e9f2524
VS
36#include "expat.h"
37
5e9f2524
VS
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
11a3e7b6
VZ
44/* Using pointer subtraction to convert to integer type. */
45#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
5e9f2524
VS
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;
11a3e7b6 109 unsigned char power;
5e9f2524
VS
110 size_t size;
111 size_t used;
5e9f2524
VS
112 const XML_Memory_Handling_Suite *mem;
113} HASH_TABLE;
114
11a3e7b6
VZ
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
5e9f2524
VS
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
11a3e7b6 148#define INIT_ATTS_VERSION 0xFFFFFFFF
5e9f2524
VS
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;
11a3e7b6
VZ
204 int textLen; /* length in XML_Chars */
205 int processed; /* # of processed bytes - when suspended */
5e9f2524
VS
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
11a3e7b6
VZ
257typedef struct {
258 unsigned long version;
259 unsigned long hash;
260 const XML_Char *uriName;
261} NS_ATT;
262
5e9f2524
VS
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;
11a3e7b6
VZ
306 int startTagLevel;
307 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
5e9f2524
VS
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;
11a3e7b6 332static Processor internalEntityProcessor;
5e9f2524
VS
333
334static enum XML_Error
335handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
336static enum XML_Error
337processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
11a3e7b6 338 const char *s, const char *next);
5e9f2524
VS
339static enum XML_Error
340initializeEncoding(XML_Parser parser);
341static enum XML_Error
342doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
11a3e7b6
VZ
343 const char *end, int tok, const char *next, const char **nextPtr,
344 XML_Bool haveMore);
5e9f2524 345static enum XML_Error
11a3e7b6
VZ
346processInternalEntity(XML_Parser parser, ENTITY *entity,
347 XML_Bool betweenDecl);
5e9f2524
VS
348static enum XML_Error
349doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
11a3e7b6
VZ
350 const char *start, const char *end, const char **endPtr,
351 XML_Bool haveMore);
5e9f2524
VS
352static enum XML_Error
353doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
11a3e7b6 354 const char *end, const char **nextPtr, XML_Bool haveMore);
5e9f2524
VS
355#ifdef XML_DTD
356static enum XML_Error
357doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
11a3e7b6 358 const char *end, const char **nextPtr, XML_Bool haveMore);
5e9f2524
VS
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
11a3e7b6
VZ
368defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
369 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
5e9f2524
VS
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
11a3e7b6
VZ
406dtdCopy(XML_Parser oldParser,
407 DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
5e9f2524 408static int
11a3e7b6
VZ
409copyEntityTable(XML_Parser oldParser,
410 HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
5e9f2524 411static NAMED *
11a3e7b6 412lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
5e9f2524
VS
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
11a3e7b6
VZ
445static unsigned long generate_hash_secret_salt(void);
446static XML_Bool startParsing(XML_Parser parser);
447
5e9f2524
VS
448static XML_Parser
449parserCreate(const XML_Char *encodingName,
450 const XML_Memory_Handling_Suite *memsuite,
451 const XML_Char *nameSep,
452 DTD *dtd);
11a3e7b6 453
5e9f2524
VS
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;
11a3e7b6 482 XML_Index m_parseEndByteIndex;
5e9f2524
VS
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;
11a3e7b6 518 void (XMLCALL *m_unknownEncodingRelease)(void *);
5e9f2524
VS
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;
11a3e7b6 526 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
5e9f2524
VS
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;
11a3e7b6
VZ
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
5e9f2524
VS
556 POSITION m_position;
557 STRING_POOL m_tempPool;
558 STRING_POOL m_temp2Pool;
559 char *m_groupConnector;
11a3e7b6 560 unsigned int m_groupSize;
5e9f2524
VS
561 XML_Char m_namespaceSeparator;
562 XML_Parser m_parentParser;
11a3e7b6 563 XML_ParsingStatus m_parsingStatus;
5e9f2524
VS
564#ifdef XML_DTD
565 XML_Bool m_isParamEntity;
566 XML_Bool m_useForeignDTD;
567 enum XML_ParamEntityParsing m_paramEntityParsing;
568#endif
11a3e7b6 569 unsigned long m_hash_secret_salt;
5e9f2524
VS
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)
11a3e7b6 628#define freeInternalEntities (parser->m_freeInternalEntities)
5e9f2524
VS
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)
11a3e7b6
VZ
661#define nsAtts (parser->m_nsAtts)
662#define nsAttsVersion (parser->m_nsAttsVersion)
663#define nsAttsPower (parser->m_nsAttsPower)
664#define attInfo (parser->m_attInfo)
5e9f2524
VS
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)
11a3e7b6
VZ
671#define ps_parsing (parser->m_parsingStatus.parsing)
672#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
5e9f2524
VS
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 */
11a3e7b6 678#define hash_secret_salt (parser->m_hash_secret_salt)
5e9f2524 679
11a3e7b6 680XML_Parser XMLCALL
5e9f2524
VS
681XML_ParserCreate(const XML_Char *encodingName)
682{
683 return XML_ParserCreate_MM(encodingName, NULL, NULL);
684}
685
11a3e7b6 686XML_Parser XMLCALL
5e9f2524
VS
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[] = {
11a3e7b6
VZ
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'
5e9f2524
VS
701};
702
11a3e7b6
VZ
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
5e9f2524
VS
727XML_ParserCreate_MM(const XML_Char *encodingName,
728 const XML_Memory_Handling_Suite *memsuite,
729 const XML_Char *nameSep)
730{
11a3e7b6 731 return parserCreate(encodingName, memsuite, nameSep, NULL);
5e9f2524
VS
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 }
11a3e7b6
VZ
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
5e9f2524
VS
784 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
785 if (dataBuf == NULL) {
786 FREE(atts);
11a3e7b6
VZ
787#ifdef XML_ATTR_INFO
788 FREE(attInfo);
789#endif
5e9f2524
VS
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);
11a3e7b6
VZ
802#ifdef XML_ATTR_INFO
803 FREE(attInfo);
804#endif
5e9f2524
VS
805 FREE(parser);
806 return NULL;
807 }
808 }
809
810 freeBindingList = NULL;
811 freeTagList = NULL;
11a3e7b6 812 freeInternalEntities = NULL;
5e9f2524
VS
813
814 groupSize = 0;
815 groupConnector = NULL;
816
817 unknownEncodingHandler = NULL;
818 unknownEncodingHandlerData = NULL;
819
11a3e7b6 820 namespaceSeparator = ASCII_EXCL;
5e9f2524
VS
821 ns = XML_FALSE;
822 ns_triplets = XML_FALSE;
823
11a3e7b6
VZ
824 nsAtts = NULL;
825 nsAttsVersion = 0;
826 nsAttsPower = 0;
827
5e9f2524
VS
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;
11a3e7b6 903 openInternalEntities = NULL;
5e9f2524
VS
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;
11a3e7b6 913 ps_parsing = XML_INITIALIZED;
5e9f2524
VS
914#ifdef XML_DTD
915 isParamEntity = XML_FALSE;
916 useForeignDTD = XML_FALSE;
917 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
918#endif
11a3e7b6 919 hash_secret_salt = 0;
5e9f2524
VS
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
11a3e7b6 934XML_Bool XMLCALL
5e9f2524
VS
935XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
936{
937 TAG *tStk;
11a3e7b6 938 OPEN_INTERNAL_ENTITY *openEntityList;
5e9f2524
VS
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 }
11a3e7b6
VZ
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 }
5e9f2524 959 moveToFreeBindingList(parser, inheritedBindings);
11a3e7b6 960 FREE(unknownEncodingMem);
5e9f2524
VS
961 if (unknownEncodingRelease)
962 unknownEncodingRelease(unknownEncodingData);
963 poolClear(&tempPool);
964 poolClear(&temp2Pool);
965 parserInit(parser, encodingName);
966 dtdReset(_dtd, &parser->m_mem);
11a3e7b6 967 return XML_TRUE;
5e9f2524
VS
968}
969
11a3e7b6 970enum XML_Status XMLCALL
5e9f2524
VS
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 */
11a3e7b6 977 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
5e9f2524
VS
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
11a3e7b6 989XML_Parser XMLCALL
5e9f2524
VS
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;
11a3e7b6
VZ
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;
5e9f2524
VS
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;
11a3e7b6 1095 hash_secret_salt = oldhash_secret_salt;
5e9f2524
VS
1096 parentParser = oldParser;
1097#ifdef XML_DTD
1098 paramEntityParsing = oldParamEntityParsing;
1099 prologState.inEntityValue = oldInEntityValue;
1100 if (context) {
1101#endif /* XML_DTD */
11a3e7b6 1102 if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
5e9f2524
VS
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
11a3e7b6 1139void XMLCALL
5e9f2524
VS
1140XML_ParserFree(XML_Parser parser)
1141{
11a3e7b6
VZ
1142 TAG *tagList;
1143 OPEN_INTERNAL_ENTITY *entityList;
1144 if (parser == NULL)
1145 return;
1146 /* free tagStack and freeTagList */
1147 tagList = tagStack;
5e9f2524
VS
1148 for (;;) {
1149 TAG *p;
11a3e7b6 1150 if (tagList == NULL) {
5e9f2524
VS
1151 if (freeTagList == NULL)
1152 break;
11a3e7b6 1153 tagList = freeTagList;
5e9f2524
VS
1154 freeTagList = NULL;
1155 }
11a3e7b6
VZ
1156 p = tagList;
1157 tagList = tagList->parent;
5e9f2524
VS
1158 FREE(p->buf);
1159 destroyBindings(p->bindings, parser);
1160 FREE(p);
1161 }
11a3e7b6
VZ
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
5e9f2524
VS
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);
11a3e7b6
VZ
1191#ifdef XML_ATTR_INFO
1192 FREE((void *)attInfo);
1193#endif
1194 FREE(groupConnector);
1195 FREE(buffer);
5e9f2524 1196 FREE(dataBuf);
11a3e7b6
VZ
1197 FREE(nsAtts);
1198 FREE(unknownEncodingMem);
5e9f2524
VS
1199 if (unknownEncodingRelease)
1200 unknownEncodingRelease(unknownEncodingData);
1201 FREE(parser);
1202}
1203
11a3e7b6 1204void XMLCALL
5e9f2524
VS
1205XML_UseParserAsHandlerArg(XML_Parser parser)
1206{
1207 handlerArg = parser;
1208}
1209
11a3e7b6 1210enum XML_Error XMLCALL
5e9f2524
VS
1211XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1212{
1213#ifdef XML_DTD
1214 /* block after XML_Parse()/XML_ParseBuffer() has been called */
11a3e7b6 1215 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
5e9f2524
VS
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
11a3e7b6 1224void XMLCALL
5e9f2524
VS
1225XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1226{
1227 /* block after XML_Parse()/XML_ParseBuffer() has been called */
11a3e7b6 1228 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
5e9f2524
VS
1229 return;
1230 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1231}
1232
11a3e7b6 1233void XMLCALL
5e9f2524
VS
1234XML_SetUserData(XML_Parser parser, void *p)
1235{
1236 if (handlerArg == userData)
1237 handlerArg = userData = p;
1238 else
1239 userData = p;
1240}
1241
11a3e7b6 1242enum XML_Status XMLCALL
5e9f2524
VS
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
11a3e7b6 1256const XML_Char * XMLCALL
5e9f2524
VS
1257XML_GetBase(XML_Parser parser)
1258{
1259 return curBase;
1260}
1261
11a3e7b6 1262int XMLCALL
5e9f2524
VS
1263XML_GetSpecifiedAttributeCount(XML_Parser parser)
1264{
1265 return nSpecifiedAtts;
1266}
1267
11a3e7b6 1268int XMLCALL
5e9f2524
VS
1269XML_GetIdAttributeIndex(XML_Parser parser)
1270{
1271 return idAttIndex;
1272}
1273
11a3e7b6
VZ
1274#ifdef XML_ATTR_INFO
1275const XML_AttrInfo * XMLCALL
1276XML_GetAttributeInfo(XML_Parser parser)
1277{
1278 return attInfo;
1279}
1280#endif
1281
1282void XMLCALL
5e9f2524
VS
1283XML_SetElementHandler(XML_Parser parser,
1284 XML_StartElementHandler start,
1285 XML_EndElementHandler end)
1286{
1287 startElementHandler = start;
1288 endElementHandler = end;
1289}
1290
11a3e7b6 1291void XMLCALL
5e9f2524
VS
1292XML_SetStartElementHandler(XML_Parser parser,
1293 XML_StartElementHandler start) {
1294 startElementHandler = start;
1295}
1296
11a3e7b6 1297void XMLCALL
5e9f2524
VS
1298XML_SetEndElementHandler(XML_Parser parser,
1299 XML_EndElementHandler end) {
1300 endElementHandler = end;
1301}
1302
11a3e7b6 1303void XMLCALL
5e9f2524
VS
1304XML_SetCharacterDataHandler(XML_Parser parser,
1305 XML_CharacterDataHandler handler)
1306{
1307 characterDataHandler = handler;
1308}
1309
11a3e7b6 1310void XMLCALL
5e9f2524
VS
1311XML_SetProcessingInstructionHandler(XML_Parser parser,
1312 XML_ProcessingInstructionHandler handler)
1313{
1314 processingInstructionHandler = handler;
1315}
1316
11a3e7b6 1317void XMLCALL
5e9f2524
VS
1318XML_SetCommentHandler(XML_Parser parser,
1319 XML_CommentHandler handler)
1320{
1321 commentHandler = handler;
1322}
1323
11a3e7b6 1324void XMLCALL
5e9f2524
VS
1325XML_SetCdataSectionHandler(XML_Parser parser,
1326 XML_StartCdataSectionHandler start,
1327 XML_EndCdataSectionHandler end)
1328{
1329 startCdataSectionHandler = start;
1330 endCdataSectionHandler = end;
1331}
1332
11a3e7b6 1333void XMLCALL
5e9f2524
VS
1334XML_SetStartCdataSectionHandler(XML_Parser parser,
1335 XML_StartCdataSectionHandler start) {
1336 startCdataSectionHandler = start;
1337}
1338
11a3e7b6 1339void XMLCALL
5e9f2524
VS
1340XML_SetEndCdataSectionHandler(XML_Parser parser,
1341 XML_EndCdataSectionHandler end) {
1342 endCdataSectionHandler = end;
1343}
1344
11a3e7b6 1345void XMLCALL
5e9f2524
VS
1346XML_SetDefaultHandler(XML_Parser parser,
1347 XML_DefaultHandler handler)
1348{
1349 defaultHandler = handler;
1350 defaultExpandInternalEntities = XML_FALSE;
1351}
1352
11a3e7b6 1353void XMLCALL
5e9f2524
VS
1354XML_SetDefaultHandlerExpand(XML_Parser parser,
1355 XML_DefaultHandler handler)
1356{
1357 defaultHandler = handler;
1358 defaultExpandInternalEntities = XML_TRUE;
1359}
1360
11a3e7b6 1361void XMLCALL
5e9f2524
VS
1362XML_SetDoctypeDeclHandler(XML_Parser parser,
1363 XML_StartDoctypeDeclHandler start,
1364 XML_EndDoctypeDeclHandler end)
1365{
1366 startDoctypeDeclHandler = start;
1367 endDoctypeDeclHandler = end;
1368}
1369
11a3e7b6 1370void XMLCALL
5e9f2524
VS
1371XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1372 XML_StartDoctypeDeclHandler start) {
1373 startDoctypeDeclHandler = start;
1374}
1375
11a3e7b6 1376void XMLCALL
5e9f2524
VS
1377XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1378 XML_EndDoctypeDeclHandler end) {
1379 endDoctypeDeclHandler = end;
1380}
1381
11a3e7b6 1382void XMLCALL
5e9f2524
VS
1383XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1384 XML_UnparsedEntityDeclHandler handler)
1385{
1386 unparsedEntityDeclHandler = handler;
1387}
1388
11a3e7b6 1389void XMLCALL
5e9f2524
VS
1390XML_SetNotationDeclHandler(XML_Parser parser,
1391 XML_NotationDeclHandler handler)
1392{
1393 notationDeclHandler = handler;
1394}
1395
11a3e7b6 1396void XMLCALL
5e9f2524
VS
1397XML_SetNamespaceDeclHandler(XML_Parser parser,
1398 XML_StartNamespaceDeclHandler start,
1399 XML_EndNamespaceDeclHandler end)
1400{
1401 startNamespaceDeclHandler = start;
1402 endNamespaceDeclHandler = end;
1403}
1404
11a3e7b6 1405void XMLCALL
5e9f2524
VS
1406XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1407 XML_StartNamespaceDeclHandler start) {
1408 startNamespaceDeclHandler = start;
1409}
1410
11a3e7b6 1411void XMLCALL
5e9f2524
VS
1412XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1413 XML_EndNamespaceDeclHandler end) {
1414 endNamespaceDeclHandler = end;
1415}
1416
11a3e7b6 1417void XMLCALL
5e9f2524
VS
1418XML_SetNotStandaloneHandler(XML_Parser parser,
1419 XML_NotStandaloneHandler handler)
1420{
1421 notStandaloneHandler = handler;
1422}
1423
11a3e7b6 1424void XMLCALL
5e9f2524
VS
1425XML_SetExternalEntityRefHandler(XML_Parser parser,
1426 XML_ExternalEntityRefHandler handler)
1427{
1428 externalEntityRefHandler = handler;
1429}
1430
11a3e7b6 1431void XMLCALL
5e9f2524
VS
1432XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1433{
1434 if (arg)
1435 externalEntityRefHandlerArg = (XML_Parser)arg;
1436 else
1437 externalEntityRefHandlerArg = parser;
1438}
1439
11a3e7b6 1440void XMLCALL
5e9f2524
VS
1441XML_SetSkippedEntityHandler(XML_Parser parser,
1442 XML_SkippedEntityHandler handler)
1443{
1444 skippedEntityHandler = handler;
1445}
1446
11a3e7b6 1447void XMLCALL
5e9f2524
VS
1448XML_SetUnknownEncodingHandler(XML_Parser parser,
1449 XML_UnknownEncodingHandler handler,
1450 void *data)
1451{
1452 unknownEncodingHandler = handler;
1453 unknownEncodingHandlerData = data;
1454}
1455
11a3e7b6 1456void XMLCALL
5e9f2524
VS
1457XML_SetElementDeclHandler(XML_Parser parser,
1458 XML_ElementDeclHandler eldecl)
1459{
1460 elementDeclHandler = eldecl;
1461}
1462
11a3e7b6 1463void XMLCALL
5e9f2524
VS
1464XML_SetAttlistDeclHandler(XML_Parser parser,
1465 XML_AttlistDeclHandler attdecl)
1466{
1467 attlistDeclHandler = attdecl;
1468}
1469
11a3e7b6 1470void XMLCALL
5e9f2524
VS
1471XML_SetEntityDeclHandler(XML_Parser parser,
1472 XML_EntityDeclHandler handler)
1473{
1474 entityDeclHandler = handler;
1475}
1476
11a3e7b6 1477void XMLCALL
5e9f2524
VS
1478XML_SetXmlDeclHandler(XML_Parser parser,
1479 XML_XmlDeclHandler handler) {
1480 xmlDeclHandler = handler;
1481}
1482
11a3e7b6 1483int XMLCALL
5e9f2524
VS
1484XML_SetParamEntityParsing(XML_Parser parser,
1485 enum XML_ParamEntityParsing peParsing)
1486{
1487 /* block after XML_Parse()/XML_ParseBuffer() has been called */
11a3e7b6 1488 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
5e9f2524
VS
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
11a3e7b6
VZ
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
5e9f2524
VS
1510XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1511{
11a3e7b6
VZ
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
5e9f2524 1528 if (len == 0) {
11a3e7b6 1529 ps_finalBuffer = (XML_Bool)isFinal;
5e9f2524
VS
1530 if (!isFinal)
1531 return XML_STATUS_OK;
1532 positionPtr = bufferPtr;
11a3e7b6
VZ
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 }
5e9f2524
VS
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;
11a3e7b6 1563 enum XML_Error result;
5e9f2524
VS
1564 parseEndByteIndex += len;
1565 positionPtr = s;
11a3e7b6
VZ
1566 ps_finalBuffer = (XML_Bool)isFinal;
1567
5e9f2524 1568 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
11a3e7b6 1569
5e9f2524
VS
1570 if (errorCode != XML_ERROR_NONE) {
1571 eventEndPtr = eventPtr;
1572 processor = errorProcessor;
1573 return XML_STATUS_ERROR;
1574 }
11a3e7b6
VZ
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
5e9f2524 1592 XmlUpdatePosition(encoding, positionPtr, end, &position);
5e9f2524
VS
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) {
5e9f2524
VS
1602 errorCode = XML_ERROR_NO_MEMORY;
1603 eventPtr = eventEndPtr = NULL;
1604 processor = errorProcessor;
1605 return XML_STATUS_ERROR;
1606 }
11a3e7b6 1607 buffer = temp;
5e9f2524
VS
1608 bufferLim = buffer + len * 2;
1609 }
1610 memcpy(buffer, end, nLeftOver);
5e9f2524 1611 }
11a3e7b6
VZ
1612 bufferPtr = buffer;
1613 bufferEnd = buffer + nLeftOver;
1614 positionPtr = bufferPtr;
1615 parseEndPtr = bufferEnd;
1616 eventPtr = bufferPtr;
1617 eventEndPtr = bufferPtr;
1618 return result;
5e9f2524
VS
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
11a3e7b6 1632enum XML_Status XMLCALL
5e9f2524
VS
1633XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1634{
11a3e7b6
VZ
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;
5e9f2524
VS
1655 positionPtr = start;
1656 bufferEnd += len;
11a3e7b6 1657 parseEndPtr = bufferEnd;
5e9f2524 1658 parseEndByteIndex += len;
11a3e7b6
VZ
1659 ps_finalBuffer = (XML_Bool)isFinal;
1660
1661 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1662
1663 if (errorCode != XML_ERROR_NONE) {
5e9f2524
VS
1664 eventEndPtr = eventPtr;
1665 processor = errorProcessor;
1666 return XML_STATUS_ERROR;
1667 }
11a3e7b6
VZ
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;
5e9f2524
VS
1686}
1687
11a3e7b6 1688void * XMLCALL
5e9f2524
VS
1689XML_GetBuffer(XML_Parser parser, int len)
1690{
11a3e7b6
VZ
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
5e9f2524
VS
1701 if (len > bufferLim - bufferEnd) {
1702 /* FIXME avoid integer overflow */
11a3e7b6 1703 int neededSize = len + (int)(bufferEnd - bufferPtr);
5e9f2524 1704#ifdef XML_CONTEXT_BYTES
11a3e7b6 1705 int keep = (int)(bufferPtr - buffer);
5e9f2524
VS
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) {
11a3e7b6 1714 int offset = (int)(bufferPtr - buffer) - keep;
5e9f2524
VS
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;
11a3e7b6 1727 int bufferSize = (int)(bufferLim - bufferPtr);
5e9f2524
VS
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) {
11a3e7b6 1741 int keep = (int)(bufferPtr - buffer);
5e9f2524
VS
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 }
11a3e7b6
VZ
1763 eventPtr = eventEndPtr = NULL;
1764 positionPtr = NULL;
5e9f2524
VS
1765 }
1766 return bufferEnd;
1767}
1768
11a3e7b6
VZ
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
5e9f2524
VS
1845XML_GetErrorCode(XML_Parser parser)
1846{
1847 return errorCode;
1848}
1849
11a3e7b6 1850XML_Index XMLCALL
5e9f2524
VS
1851XML_GetCurrentByteIndex(XML_Parser parser)
1852{
1853 if (eventPtr)
1854 return parseEndByteIndex - (parseEndPtr - eventPtr);
1855 return -1;
1856}
1857
11a3e7b6 1858int XMLCALL
5e9f2524
VS
1859XML_GetCurrentByteCount(XML_Parser parser)
1860{
1861 if (eventEndPtr && eventPtr)
11a3e7b6 1862 return (int)(eventEndPtr - eventPtr);
5e9f2524
VS
1863 return 0;
1864}
1865
11a3e7b6 1866const char * XMLCALL
5e9f2524
VS
1867XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1868{
1869#ifdef XML_CONTEXT_BYTES
1870 if (eventPtr && buffer) {
11a3e7b6
VZ
1871 *offset = (int)(eventPtr - buffer);
1872 *size = (int)(bufferEnd - buffer);
5e9f2524
VS
1873 return buffer;
1874 }
1875#endif /* defined XML_CONTEXT_BYTES */
1876 return (char *) 0;
1877}
1878
11a3e7b6 1879XML_Size XMLCALL
5e9f2524
VS
1880XML_GetCurrentLineNumber(XML_Parser parser)
1881{
11a3e7b6 1882 if (eventPtr && eventPtr >= positionPtr) {
5e9f2524
VS
1883 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1884 positionPtr = eventPtr;
1885 }
1886 return position.lineNumber + 1;
1887}
1888
11a3e7b6 1889XML_Size XMLCALL
5e9f2524
VS
1890XML_GetCurrentColumnNumber(XML_Parser parser)
1891{
11a3e7b6 1892 if (eventPtr && eventPtr >= positionPtr) {
5e9f2524
VS
1893 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1894 positionPtr = eventPtr;
1895 }
1896 return position.columnNumber;
1897}
1898
11a3e7b6 1899void XMLCALL
5e9f2524
VS
1900XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1901{
1902 FREE(model);
1903}
1904
11a3e7b6 1905void * XMLCALL
5e9f2524
VS
1906XML_MemMalloc(XML_Parser parser, size_t size)
1907{
1908 return MALLOC(size);
1909}
1910
11a3e7b6 1911void * XMLCALL
5e9f2524
VS
1912XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1913{
1914 return REALLOC(ptr, size);
1915}
1916
11a3e7b6 1917void XMLCALL
5e9f2524
VS
1918XML_MemFree(XML_Parser parser, void *ptr)
1919{
1920 FREE(ptr);
1921}
1922
11a3e7b6 1923void XMLCALL
5e9f2524
VS
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
11a3e7b6 1937const XML_LChar * XMLCALL
5e9f2524
VS
1938XML_ErrorString(enum XML_Error code)
1939{
11a3e7b6 1940 static const XML_LChar* const message[] = {
5e9f2524
VS
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"),
11a3e7b6 1958 XML_L("XML or text declaration not at start of entity"),
5e9f2524
VS
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"),
11a3e7b6
VZ
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")
5e9f2524
VS
1982 };
1983 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1984 return message[code];
1985 return NULL;
1986}
1987
11a3e7b6 1988const XML_LChar * XMLCALL
5e9f2524
VS
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
11a3e7b6 2008XML_Expat_Version XMLCALL
5e9f2524
VS
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
11a3e7b6 2020const XML_Feature * XMLCALL
5e9f2524
VS
2021XML_GetFeatureList(void)
2022{
11a3e7b6
VZ
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)},
5e9f2524 2028#ifdef XML_UNICODE
11a3e7b6 2029 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
5e9f2524
VS
2030#endif
2031#ifdef XML_UNICODE_WCHAR_T
11a3e7b6 2032 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
5e9f2524
VS
2033#endif
2034#ifdef XML_DTD
11a3e7b6 2035 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
5e9f2524
VS
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
11a3e7b6
VZ
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},
5e9f2524 2046#endif
11a3e7b6
VZ
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}
5e9f2524
VS
2054 };
2055
5e9f2524
VS
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{
11a3e7b6
VZ
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 }
5e9f2524
VS
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 */
11a3e7b6 2152 if (next == end && !ps_finalBuffer) {
5e9f2524
VS
2153 *endPtr = next;
2154 return XML_ERROR_NONE;
2155 }
2156 start = next;
2157 break;
2158 case XML_TOK_PARTIAL:
11a3e7b6 2159 if (!ps_finalBuffer) {
5e9f2524
VS
2160 *endPtr = start;
2161 return XML_ERROR_NONE;
2162 }
2163 eventPtr = start;
2164 return XML_ERROR_UNCLOSED_TOKEN;
2165 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 2166 if (!ps_finalBuffer) {
5e9f2524
VS
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{
11a3e7b6 2183 int tok;
5e9f2524 2184 const char *next = start; /* XmlContentTok doesn't always set the last arg */
11a3e7b6
VZ
2185 eventPtr = start;
2186 tok = XmlContentTok(encoding, start, end, &next);
2187 eventEndPtr = next;
2188
5e9f2524
VS
2189 switch (tok) {
2190 case XML_TOK_XML_DECL:
2191 {
11a3e7b6
VZ
2192 enum XML_Error result;
2193 result = processXmlDecl(parser, 1, start, next);
5e9f2524
VS
2194 if (result != XML_ERROR_NONE)
2195 return result;
11a3e7b6
VZ
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 }
5e9f2524
VS
2205 }
2206 break;
2207 case XML_TOK_PARTIAL:
11a3e7b6 2208 if (!ps_finalBuffer) {
5e9f2524
VS
2209 *endPtr = start;
2210 return XML_ERROR_NONE;
2211 }
5e9f2524
VS
2212 return XML_ERROR_UNCLOSED_TOKEN;
2213 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 2214 if (!ps_finalBuffer) {
5e9f2524
VS
2215 *endPtr = start;
2216 return XML_ERROR_NONE;
2217 }
5e9f2524
VS
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{
11a3e7b6
VZ
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 }
5e9f2524
VS
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,
11a3e7b6
VZ
2246 const char **nextPtr,
2247 XML_Bool haveMore)
5e9f2524 2248{
11a3e7b6
VZ
2249 /* save one level of indirection */
2250 DTD * const dtd = _dtd;
2251
5e9f2524
VS
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;
11a3e7b6 2263
5e9f2524
VS
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:
11a3e7b6 2270 if (haveMore) {
5e9f2524
VS
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);
11a3e7b6
VZ
2281 /* We are at the end of the final buffer, should we check for
2282 XML_SUSPENDED, XML_FINISHED?
2283 */
5e9f2524
VS
2284 if (startTagLevel == 0)
2285 return XML_ERROR_NO_ELEMENTS;
2286 if (tagLevel != startTagLevel)
2287 return XML_ERROR_ASYNC_ENTITY;
11a3e7b6 2288 *nextPtr = end;
5e9f2524
VS
2289 return XML_ERROR_NONE;
2290 case XML_TOK_NONE:
11a3e7b6 2291 if (haveMore) {
5e9f2524
VS
2292 *nextPtr = s;
2293 return XML_ERROR_NONE;
2294 }
2295 if (startTagLevel > 0) {
2296 if (tagLevel != startTagLevel)
2297 return XML_ERROR_ASYNC_ENTITY;
11a3e7b6 2298 *nextPtr = s;
5e9f2524
VS
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:
11a3e7b6 2306 if (haveMore) {
5e9f2524
VS
2307 *nextPtr = s;
2308 return XML_ERROR_NONE;
2309 }
2310 return XML_ERROR_UNCLOSED_TOKEN;
2311 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 2312 if (haveMore) {
5e9f2524
VS
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;
11a3e7b6 2336 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5e9f2524
VS
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;
5e9f2524
VS
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 }
11a3e7b6
VZ
2368 result = processInternalEntity(parser, entity, XML_FALSE);
2369 if (result != XML_ERROR_NONE)
5e9f2524
VS
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;
11a3e7b6 2379 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5e9f2524
VS
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);
11a3e7b6 2431 convLen = (int)(toPtr - (XML_Char *)tag->buf);
5e9f2524
VS
2432 if (fromPtr == rawNameEnd) {
2433 tag->name.strLen = convLen;
2434 break;
2435 }
11a3e7b6 2436 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
5e9f2524
VS
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);
11a3e7b6
VZ
2605 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2606 if (result != XML_ERROR_NONE)
2607 return result;
2608 else if (!next) {
5e9f2524
VS
2609 processor = cdataSectionProcessor;
2610 return result;
2611 }
2612 }
2613 break;
2614 case XML_TOK_TRAILING_RSQB:
11a3e7b6 2615 if (haveMore) {
5e9f2524
VS
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,
11a3e7b6 2624 (int)(dataPtr - (ICHAR *)dataBuf));
5e9f2524
VS
2625 }
2626 else
2627 characterDataHandler(handlerArg,
2628 (XML_Char *)s,
11a3e7b6 2629 (int)((XML_Char *)end - (XML_Char *)s));
5e9f2524
VS
2630 }
2631 else if (defaultHandler)
2632 reportDefault(parser, enc, s, end);
11a3e7b6
VZ
2633 /* We are at the end of the final buffer, should we check for
2634 XML_SUSPENDED, XML_FINISHED?
2635 */
5e9f2524
VS
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 }
11a3e7b6 2644 *nextPtr = end;
5e9f2524
VS
2645 return XML_ERROR_NONE;
2646 case XML_TOK_DATA_CHARS:
11a3e7b6
VZ
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 }
5e9f2524 2661 }
11a3e7b6
VZ
2662 else
2663 charDataHandler(handlerArg,
2664 (XML_Char *)s,
2665 (int)((XML_Char *)next - (XML_Char *)s));
5e9f2524 2666 }
11a3e7b6
VZ
2667 else if (defaultHandler)
2668 reportDefault(parser, enc, s, next);
5e9f2524 2669 }
5e9f2524
VS
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;
11a3e7b6
VZ
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 }
5e9f2524
VS
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 */
11a3e7b6
VZ
2713 ELEMENT_TYPE *elementType;
2714 int nDefaultAtts;
5e9f2524
VS
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 */
11a3e7b6 2726 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
5e9f2524
VS
2727 if (!elementType) {
2728 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2729 if (!name)
2730 return XML_ERROR_NO_MEMORY;
11a3e7b6 2731 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
5e9f2524
VS
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;
11a3e7b6
VZ
2745#ifdef XML_ATTR_INFO
2746 XML_AttrInfo *temp2;
2747#endif
5e9f2524
VS
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;
11a3e7b6
VZ
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
5e9f2524
VS
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++) {
11a3e7b6
VZ
2765 ATTRIBUTE *currAtt = &atts[i];
2766#ifdef XML_ATTR_INFO
2767 XML_AttrInfo *currAttInfo = &attInfo[i];
2768#endif
5e9f2524 2769 /* add the name and value to the attribute list */
11a3e7b6
VZ
2770 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2771 currAtt->name
2772 + XmlNameLength(enc, currAtt->name));
5e9f2524
VS
2773 if (!attId)
2774 return XML_ERROR_NO_MEMORY;
11a3e7b6
VZ
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 */
5e9f2524
VS
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
11a3e7b6
VZ
2886 /* expand prefixed attribute names, check for duplicates,
2887 and clear flags that say whether attributes were specified */
5e9f2524
VS
2888 i = 0;
2889 if (nPrefixes) {
11a3e7b6
VZ
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 */
5e9f2524 2916 for (; i < attIndex; i += 2) {
11a3e7b6
VZ
2917 const XML_Char *s = appAtts[i];
2918 if (s[-1] == 2) { /* prefixed */
5e9f2524 2919 ATTRIBUTE_ID *id;
11a3e7b6
VZ
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);
5e9f2524 2963 }
11a3e7b6
VZ
2964 }
2965
2966 if (ns_triplets) { /* append namespace separator and prefix */
2967 tempPool.ptr[-1] = namespaceSeparator;
2968 s = b->prefix->name;
5e9f2524
VS
2969 do {
2970 if (!poolAppendChar(&tempPool, *s))
2971 return XML_ERROR_NO_MEMORY;
2972 } while (*s++);
5e9f2524 2973 }
11a3e7b6
VZ
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;
5e9f2524 2987 break;
11a3e7b6 2988 }
5e9f2524 2989 }
11a3e7b6
VZ
2990 else /* not prefixed */
2991 ((XML_Char *)s)[-1] = 0; /* clear flag */
5e9f2524
VS
2992 }
2993 }
11a3e7b6 2994 /* clear flags for the remaining attributes */
5e9f2524
VS
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
11a3e7b6
VZ
3000 if (!ns)
3001 return XML_ERROR_NONE;
3002
5e9f2524
VS
3003 /* expand the element type name */
3004 if (elementType->prefix) {
3005 binding = elementType->prefix->binding;
3006 if (!binding)
11a3e7b6 3007 return XML_ERROR_UNBOUND_PREFIX;
5e9f2524 3008 localPart = tagNamePtr->str;
11a3e7b6 3009 while (*localPart++ != XML_T(ASCII_COLON))
5e9f2524
VS
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;
11a3e7b6 3019 if (ns_triplets && binding->prefix->name) {
5e9f2524 3020 for (; binding->prefix->name[prefixLen++];)
11a3e7b6 3021 ; /* prefixLen includes null terminator */
5e9f2524
VS
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++];)
11a3e7b6 3028 ; /* i includes null terminator */
5e9f2524
VS
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 }
11a3e7b6 3043 /* if namespaceSeparator != '\0' then uri includes it already */
5e9f2524
VS
3044 uri = binding->uri + binding->uriLen;
3045 memcpy(uri, localPart, i * sizeof(XML_Char));
11a3e7b6 3046 /* we always have a namespace separator between localPart and prefix */
5e9f2524 3047 if (prefixLen) {
11a3e7b6
VZ
3048 uri += i - 1;
3049 *uri = namespaceSeparator; /* replace null terminator */
5e9f2524
VS
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{
11a3e7b6
VZ
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
5e9f2524
VS
3087 BINDING *b;
3088 int len;
3089
11a3e7b6 3090 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
5e9f2524 3091 if (*uri == XML_T('\0') && prefix->name)
11a3e7b6
VZ
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;
5e9f2524 3126
5e9f2524
VS
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;
11a3e7b6 3159 /* NULL binding when default namespace undeclared */
5e9f2524
VS
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;
11a3e7b6
VZ
3166 /* if attId == NULL then we are not starting a namespace scope */
3167 if (attId && startNamespaceDeclHandler)
5e9f2524
VS
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{
11a3e7b6
VZ
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;
5e9f2524
VS
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
11a3e7b6 3199/* startPtr gets set to non-null if the section is closed, and to null if
5e9f2524
VS
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,
11a3e7b6
VZ
3207 const char **nextPtr,
3208 XML_Bool haveMore)
5e9f2524
VS
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;
11a3e7b6 3224
5e9f2524
VS
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;
11a3e7b6
VZ
3241 *nextPtr = next;
3242 if (ps_parsing == XML_FINISHED)
3243 return XML_ERROR_ABORTED;
3244 else
3245 return XML_ERROR_NONE;
5e9f2524
VS
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:
11a3e7b6
VZ
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 }
5e9f2524 3269 }
11a3e7b6
VZ
3270 else
3271 charDataHandler(handlerArg,
3272 (XML_Char *)s,
3273 (int)((XML_Char *)next - (XML_Char *)s));
5e9f2524 3274 }
11a3e7b6
VZ
3275 else if (defaultHandler)
3276 reportDefault(parser, enc, s, next);
5e9f2524 3277 }
5e9f2524
VS
3278 break;
3279 case XML_TOK_INVALID:
3280 *eventPP = next;
3281 return XML_ERROR_INVALID_TOKEN;
3282 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 3283 if (haveMore) {
5e9f2524
VS
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:
11a3e7b6 3290 if (haveMore) {
5e9f2524
VS
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 }
11a3e7b6 3299
5e9f2524 3300 *eventPP = s = next;
11a3e7b6
VZ
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 }
5e9f2524
VS
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{
11a3e7b6
VZ
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;
5e9f2524
VS
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,
11a3e7b6
VZ
3343 const char **nextPtr,
3344 XML_Bool haveMore)
5e9f2524
VS
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;
11a3e7b6
VZ
3369 *nextPtr = next;
3370 if (ps_parsing == XML_FINISHED)
3371 return XML_ERROR_ABORTED;
3372 else
3373 return XML_ERROR_NONE;
5e9f2524
VS
3374 case XML_TOK_INVALID:
3375 *eventPP = next;
3376 return XML_ERROR_INVALID_TOKEN;
3377 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 3378 if (haveMore) {
5e9f2524
VS
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:
11a3e7b6 3385 if (haveMore) {
5e9f2524
VS
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,
11a3e7b6
VZ
3450 &standalone)) {
3451 if (isGeneralTextEntity)
3452 return XML_ERROR_TEXT_DECL;
3453 else
3454 return XML_ERROR_XML_DECL;
3455 }
5e9f2524
VS
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{
5e9f2524 3601 int tok;
11a3e7b6
VZ
3602 const char *start = s;
3603 const char *next = start;
3604 eventPtr = start;
5e9f2524
VS
3605
3606 for (;;) {
3607 tok = XmlPrologTok(encoding, start, end, &next);
11a3e7b6 3608 eventEndPtr = next;
5e9f2524 3609 if (tok <= 0) {
11a3e7b6
VZ
3610 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3611 *nextPtr = s;
3612 return XML_ERROR_NONE;
5e9f2524
VS
3613 }
3614 switch (tok) {
3615 case XML_TOK_INVALID:
11a3e7b6 3616 return XML_ERROR_INVALID_TOKEN;
5e9f2524 3617 case XML_TOK_PARTIAL:
11a3e7b6 3618 return XML_ERROR_UNCLOSED_TOKEN;
5e9f2524 3619 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 3620 return XML_ERROR_PARTIAL_CHAR;
5e9f2524
VS
3621 case XML_TOK_NONE: /* start == end */
3622 default:
3623 break;
3624 }
11a3e7b6 3625 /* found end of entity value - can store it now */
5e9f2524
VS
3626 return storeEntityValue(parser, encoding, s, end);
3627 }
3628 else if (tok == XML_TOK_XML_DECL) {
11a3e7b6
VZ
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 }
5e9f2524
VS
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 */
11a3e7b6 3653 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
5e9f2524
VS
3654 *nextPtr = next;
3655 return XML_ERROR_NONE;
3656 }
3657 start = next;
11a3e7b6 3658 eventPtr = start;
5e9f2524
VS
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{
5e9f2524
VS
3668 const char *next = s;
3669 int tok;
3670
11a3e7b6 3671 tok = XmlPrologTok(encoding, s, end, &next);
5e9f2524 3672 if (tok <= 0) {
11a3e7b6 3673 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
5e9f2524
VS
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;
11a3e7b6
VZ
3699 return doProlog(parser, encoding, s, end, tok, next,
3700 nextPtr, (XML_Bool)!ps_finalBuffer);
5e9f2524
VS
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) {
11a3e7b6 3717 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
5e9f2524
VS
3718 *nextPtr = s;
3719 return XML_ERROR_NONE;
3720 }
3721 switch (tok) {
3722 case XML_TOK_INVALID:
11a3e7b6 3723 return XML_ERROR_INVALID_TOKEN;
5e9f2524 3724 case XML_TOK_PARTIAL:
11a3e7b6 3725 return XML_ERROR_UNCLOSED_TOKEN;
5e9f2524 3726 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 3727 return XML_ERROR_PARTIAL_CHAR;
5e9f2524
VS
3728 case XML_TOK_NONE: /* start == end */
3729 default:
3730 break;
3731 }
11a3e7b6 3732 /* found end of entity value - can store it now */
5e9f2524
VS
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);
11a3e7b6
VZ
3749 return doProlog(parser, encoding, s, end, tok, next,
3750 nextPtr, (XML_Bool)!ps_finalBuffer);
5e9f2524
VS
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,
11a3e7b6
VZ
3760 const char **nextPtr,
3761 XML_Bool haveMore)
5e9f2524
VS
3762{
3763#ifdef XML_DTD
11a3e7b6 3764 static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
5e9f2524 3765#endif /* XML_DTD */
11a3e7b6
VZ
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' };
5e9f2524 3777 static const XML_Char atypeNMTOKEN[] = {
11a3e7b6
VZ
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' };
5e9f2524 3785
11a3e7b6
VZ
3786 /* save one level of indirection */
3787 DTD * const dtd = _dtd;
5e9f2524
VS
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 }
11a3e7b6 3801
5e9f2524
VS
3802 for (;;) {
3803 int role;
3804 XML_Bool handleDefault = XML_TRUE;
3805 *eventPP = s;
3806 *eventEndPP = next;
3807 if (tok <= 0) {
11a3e7b6 3808 if (haveMore && tok != XML_TOK_INVALID) {
5e9f2524
VS
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;
11a3e7b6
VZ
3820 case -XML_TOK_PROLOG_S:
3821 tok = -tok;
3822 break;
5e9f2524
VS
3823 case XML_TOK_NONE:
3824#ifdef XML_DTD
11a3e7b6
VZ
3825 /* for internal PE NOT referenced between declarations */
3826 if (enc != encoding && !openInternalEntities->betweenDecl) {
3827 *nextPtr = s;
5e9f2524 3828 return XML_ERROR_NONE;
11a3e7b6
VZ
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) {
5e9f2524
VS
3835 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3836 == XML_ROLE_ERROR)
11a3e7b6
VZ
3837 return XML_ERROR_INCOMPLETE_PE;
3838 *nextPtr = s;
5e9f2524
VS
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;
11a3e7b6
VZ
3894 declEntity = (ENTITY *)lookup(parser,
3895 &dtd->paramEntities,
3896 externalSubsetName,
3897 sizeof(ENTITY));
3898 if (!declEntity)
3899 return XML_ERROR_NO_MEMORY;
5e9f2524
VS
3900#endif /* XML_DTD */
3901 dtd->hasParamEntityRefs = XML_TRUE;
3902 if (startDoctypeDeclHandler) {
11a3e7b6
VZ
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)
5e9f2524 3910 return XML_ERROR_NO_MEMORY;
11a3e7b6 3911 normalizePublicId(pubId);
5e9f2524 3912 poolFinish(&tempPool);
11a3e7b6 3913 doctypePubid = pubId;
5e9f2524 3914 handleDefault = XML_FALSE;
11a3e7b6 3915 goto alreadyChecked;
5e9f2524 3916 }
5e9f2524
VS
3917 /* fall through */
3918 case XML_ROLE_ENTITY_PUBLIC_ID:
3919 if (!XmlIsPublicId(enc, s, next, eventPP))
11a3e7b6
VZ
3920 return XML_ERROR_PUBLICID;
3921 alreadyChecked:
5e9f2524
VS
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) {
11a3e7b6
VZ
3949 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3950 dtd->hasParamEntityRefs = XML_TRUE;
5e9f2524 3951 if (paramEntityParsing && externalEntityRefHandler) {
11a3e7b6
VZ
3952 ENTITY *entity = (ENTITY *)lookup(parser,
3953 &dtd->paramEntities,
5e9f2524
VS
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;
11a3e7b6
VZ
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;
5e9f2524
VS
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) {
11a3e7b6 3994 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
5e9f2524
VS
3995 dtd->hasParamEntityRefs = XML_TRUE;
3996 if (paramEntityParsing && externalEntityRefHandler) {
11a3e7b6 3997 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
5e9f2524
VS
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;
11a3e7b6
VZ
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;
5e9f2524
VS
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,
11a3e7b6
VZ
4093 declAttributeIsCdata, declAttributeIsId,
4094 0, parser))
5e9f2524
VS
4095 return XML_ERROR_NO_MEMORY;
4096 if (attlistDeclHandler && declAttributeType) {
11a3e7b6
VZ
4097 if (*declAttributeType == XML_T(ASCII_LPAREN)
4098 || (*declAttributeType == XML_T(ASCII_N)
4099 && declAttributeType[1] == XML_T(ASCII_O))) {
5e9f2524 4100 /* Enumerated or Notation type */
11a3e7b6 4101 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
5e9f2524
VS
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;
11a3e7b6
VZ
4120 enum XML_Error result =
4121 storeAttributeValue(parser, enc, declAttributeIsCdata,
4122 s + enc->minBytesPerChar,
4123 next - enc->minBytesPerChar,
4124 &dtd->pool);
5e9f2524
VS
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) {
11a3e7b6
VZ
4134 if (*declAttributeType == XML_T(ASCII_LPAREN)
4135 || (*declAttributeType == XML_T(ASCII_N)
4136 && declAttributeType[1] == XML_T(ASCII_O))) {
5e9f2524 4137 /* Enumerated or Notation type */
11a3e7b6 4138 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
5e9f2524
VS
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);
11a3e7b6 4161 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
5e9f2524
VS
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) {
11a3e7b6
VZ
4211 declEntity = (ENTITY *)lookup(parser,
4212 &dtd->paramEntities,
5e9f2524
VS
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;
11a3e7b6 4287 declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
5e9f2524
VS
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;
11a3e7b6 4319 declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
5e9f2524
VS
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))
11a3e7b6 4360 return XML_ERROR_PUBLICID;
5e9f2524
VS
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:
11a3e7b6
VZ
4407 /* PE references in internal subset are
4408 not allowed within declarations. */
5e9f2524
VS
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;
11a3e7b6
VZ
4422 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4423 if (result != XML_ERROR_NONE)
4424 return result;
4425 else if (!next) {
5e9f2524
VS
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:
11a3e7b6 4466 if (groupConnector[prologState.level] == ASCII_PIPE)
5e9f2524 4467 return XML_ERROR_SYNTAX;
11a3e7b6 4468 groupConnector[prologState.level] = ASCII_COMMA;
5e9f2524
VS
4469 if (dtd->in_eldecl && elementDeclHandler)
4470 handleDefault = XML_FALSE;
4471 break;
4472 case XML_ROLE_GROUP_CHOICE:
11a3e7b6 4473 if (groupConnector[prologState.level] == ASCII_COMMA)
5e9f2524
VS
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 }
11a3e7b6 4485 groupConnector[prologState.level] = ASCII_PIPE;
5e9f2524
VS
4486 break;
4487 case XML_ROLE_PARAM_ENTITY_REF:
4488#ifdef XML_DTD
4489 case XML_ROLE_INNER_PARAM_ENTITY_REF:
5e9f2524
VS
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;
11a3e7b6 4501 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5e9f2524
VS
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;
11a3e7b6
VZ
4529 XML_Bool betweenDecl =
4530 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4531 result = processInternalEntity(parser, entity, betweenDecl);
5e9f2524
VS
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;
b2247ee9
CE
4642 for (; name[nameLen++]; )
4643 ;
5e9f2524
VS
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
11a3e7b6
VZ
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 }
5e9f2524
VS
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) {
5e9f2524 4754 reportDefault(parser, encoding, s, next);
11a3e7b6
VZ
4755 if (ps_parsing == XML_FINISHED)
4756 return XML_ERROR_ABORTED;
5e9f2524 4757 }
11a3e7b6 4758 *nextPtr = next;
5e9f2524
VS
4759 return XML_ERROR_NONE;
4760 case XML_TOK_NONE:
11a3e7b6 4761 *nextPtr = s;
5e9f2524
VS
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:
11a3e7b6 4779 if (!ps_finalBuffer) {
5e9f2524
VS
4780 *nextPtr = s;
4781 return XML_ERROR_NONE;
4782 }
4783 return XML_ERROR_UNCLOSED_TOKEN;
4784 case XML_TOK_PARTIAL_CHAR:
11a3e7b6 4785 if (!ps_finalBuffer) {
5e9f2524
VS
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;
11a3e7b6
VZ
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 }
5e9f2524
VS
4802 }
4803}
4804
5e9f2524 4805static enum XML_Error
11a3e7b6
VZ
4806processInternalEntity(XML_Parser parser, ENTITY *entity,
4807 XML_Bool betweenDecl)
5e9f2524 4808{
11a3e7b6
VZ
4809 const char *textStart, *textEnd;
4810 const char *next;
5e9f2524 4811 enum XML_Error result;
11a3e7b6
VZ
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 }
5e9f2524 4823 entity->open = XML_TRUE;
11a3e7b6
VZ
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 }
5e9f2524
VS
4859 return result;
4860}
4861
11a3e7b6
VZ
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
5e9f2524 4887#endif /* XML_DTD */
11a3e7b6
VZ
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}
5e9f2524
VS
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;
11a3e7b6 5026 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5e9f2524 5027 poolDiscard(&temp2Pool);
11a3e7b6
VZ
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.
5e9f2524
VS
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) {
11a3e7b6
VZ
5048 /* Cannot report skipped entity here - see comments on
5049 skippedEntityHandler.
5e9f2524
VS
5050 if (skippedEntityHandler)
5051 skippedEntityHandler(handlerArg, name, 0);
5052 */
11a3e7b6
VZ
5053 /* Cannot call the default handler because this would be
5054 out of sync with the call to the startElementHandler.
5e9f2524
VS
5055 if ((pool == &tempPool) && defaultHandler)
5056 reportDefault(parser, enc, ptr, next);
11a3e7b6 5057 */
5e9f2524
VS
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;
11a3e7b6 5073 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5e9f2524
VS
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 }
11a3e7b6 5135 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5e9f2524
VS
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 */
11a3e7b6
VZ
5187 /* In the internal subset, PE references are not legal
5188 within markup declarations, e.g entity values in this case. */
5e9f2524
VS
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;
11a3e7b6 5357 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5e9f2524
VS
5358 *eventPP = s;
5359 } while (s != end);
5360 }
5361 else
11a3e7b6 5362 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5e9f2524
VS
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;
8ce8835c 5384 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5e9f2524
VS
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++) {
11a3e7b6 5416 if (*name == XML_T(ASCII_COLON)) {
5e9f2524
VS
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;
11a3e7b6 5425 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5e9f2524
VS
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;
11a3e7b6 5452 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5e9f2524 5453 ++name;
11a3e7b6 5454 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5e9f2524
VS
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 ;
11a3e7b6
VZ
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))) {
5e9f2524
VS
5469 if (name[5] == XML_T('\0'))
5470 id->prefix = &dtd->defaultPrefix;
5471 else
11a3e7b6 5472 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
5e9f2524
VS
5473 id->xmlns = XML_TRUE;
5474 }
5475 else {
5476 int i;
5477 for (i = 0; name[i]; i++) {
11a3e7b6
VZ
5478 /* attributes without prefix are *not* in the default namespace */
5479 if (name[i] == XML_T(ASCII_COLON)) {
5e9f2524
VS
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;
11a3e7b6 5487 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5e9f2524
VS
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
11a3e7b6 5501#define CONTEXT_SEP XML_T(ASCII_FF)
5e9f2524
VS
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;
11a3e7b6 5513 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5e9f2524
VS
5514 return NULL;
5515 len = dtd->defaultPrefix.binding->uriLen;
11a3e7b6 5516 if (namespaceSeparator)
5e9f2524
VS
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;
11a3e7b6 5539 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5e9f2524
VS
5540 return NULL;
5541 len = prefix->binding->uriLen;
11a3e7b6 5542 if (namespaceSeparator)
5e9f2524
VS
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;
11a3e7b6 5583 e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
5e9f2524
VS
5584 if (e)
5585 e->open = XML_TRUE;
5586 if (*s != XML_T('\0'))
5587 s++;
5588 context = s;
5589 poolDiscard(&tempPool);
5590 }
11a3e7b6 5591 else if (*s == XML_T(ASCII_EQUALS)) {
5e9f2524
VS
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;
11a3e7b6 5598 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
5e9f2524
VS
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;
11a3e7b6 5616 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5e9f2524
VS
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);
5e9f2524 5662 poolInit(&(p->entityValuePool), ms);
5e9f2524
VS
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));
5e9f2524 5709 poolClear(&(p->entityValuePool));
5e9f2524
VS
5710 p->defaultPrefix.name = NULL;
5711 p->defaultPrefix.binding = NULL;
5712
5713 p->in_eldecl = XML_FALSE;
11a3e7b6
VZ
5714
5715 ms->free_fcn(p->scaffIndex);
5716 p->scaffIndex = NULL;
5717 ms->free_fcn(p->scaffold);
5718 p->scaffold = NULL;
5719
5e9f2524
VS
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));
5e9f2524 5750 poolDestroy(&(p->entityValuePool));
5e9f2524 5751 if (isDocEntity) {
11a3e7b6
VZ
5752 ms->free_fcn(p->scaffIndex);
5753 ms->free_fcn(p->scaffold);
5e9f2524
VS
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
11a3e7b6 5762dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5e9f2524
VS
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;
11a3e7b6 5777 if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
5e9f2524
VS
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;
11a3e7b6 5799 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
5e9f2524
VS
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
11a3e7b6 5809 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5e9f2524
VS
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;
11a3e7b6 5828 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
5e9f2524
VS
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 *)
11a3e7b6 5842 lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
5e9f2524
VS
5843 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5844 if (oldE->prefix)
11a3e7b6 5845 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5e9f2524
VS
5846 oldE->prefix->name, 0);
5847 for (i = 0; i < newE->nDefaultAtts; i++) {
5848 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
11a3e7b6 5849 lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5e9f2524
VS
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. */
11a3e7b6
VZ
5863 if (!copyEntityTable(oldParser,
5864 &(newDtd->generalEntities),
5e9f2524
VS
5865 &(newDtd->pool),
5866 &(oldDtd->generalEntities)))
5867 return 0;
5868
5869#ifdef XML_DTD
11a3e7b6
VZ
5870 if (!copyEntityTable(oldParser,
5871 &(newDtd->paramEntities),
5e9f2524
VS
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
11a3e7b6
VZ
5894copyEntityTable(XML_Parser oldParser,
5895 HASH_TABLE *newTable,
5e9f2524
VS
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;
11a3e7b6 5914 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
5e9f2524
VS
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
11a3e7b6 5960#define INIT_POWER 6
5e9f2524 5961
11a3e7b6 5962static XML_Bool FASTCALL
5e9f2524
VS
5963keyeq(KEY s1, KEY s2)
5964{
5965 for (; *s1 == *s2; s1++, s2++)
5966 if (*s1 == 0)
11a3e7b6
VZ
5967 return XML_TRUE;
5968 return XML_FALSE;
5e9f2524
VS
5969}
5970
5971static unsigned long FASTCALL
11a3e7b6 5972hash(XML_Parser parser, KEY s)
5e9f2524 5973{
11a3e7b6 5974 unsigned long h = hash_secret_salt;
5e9f2524 5975 while (*s)
11a3e7b6 5976 h = CHAR_HASH(h, *s++);
5e9f2524
VS
5977 return h;
5978}
5979
5980static NAMED *
11a3e7b6 5981lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
5e9f2524
VS
5982{
5983 size_t i;
5984 if (table->size == 0) {
5985 size_t tsize;
5e9f2524
VS
5986 if (!createSize)
5987 return NULL;
11a3e7b6
VZ
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 *);
5e9f2524 5992 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
11a3e7b6
VZ
5993 if (!table->v) {
5994 table->size = 0;
5e9f2524 5995 return NULL;
11a3e7b6 5996 }
5e9f2524 5997 memset(table->v, 0, tsize);
11a3e7b6 5998 i = hash(parser, name) & ((unsigned long)table->size - 1);
5e9f2524
VS
5999 }
6000 else {
11a3e7b6
VZ
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]) {
5e9f2524
VS
6006 if (keyeq(name, table->v[i]->name))
6007 return table->v[i];
11a3e7b6
VZ
6008 if (!step)
6009 step = PROBE_STEP(h, mask, table->power);
6010 i < step ? (i += table->size - step) : (i -= step);
5e9f2524
VS
6011 }
6012 if (!createSize)
6013 return NULL;
11a3e7b6
VZ
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;
5e9f2524
VS
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]) {
11a3e7b6
VZ
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 }
5e9f2524
VS
6035 newV[j] = table->v[i];
6036 }
6037 table->mem->free_fcn(table->v);
6038 table->v = newV;
11a3e7b6 6039 table->power = newPower;
5e9f2524 6040 table->size = newSize;
11a3e7b6
VZ
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 }
5e9f2524
VS
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++) {
11a3e7b6
VZ
6064 table->mem->free_fcn(table->v[i]);
6065 table->v[i] = NULL;
5e9f2524 6066 }
5e9f2524
VS
6067 table->used = 0;
6068}
6069
6070static void FASTCALL
6071hashTableDestroy(HASH_TABLE *table)
6072{
6073 size_t i;
11a3e7b6
VZ
6074 for (i = 0; i < table->size; i++)
6075 table->mem->free_fcn(table->v[i]);
6076 table->mem->free_fcn(table->v);
5e9f2524
VS
6077}
6078
6079static void FASTCALL
6080hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6081{
11a3e7b6 6082 p->power = 0;
5e9f2524 6083 p->size = 0;
5e9f2524
VS
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) {
11a3e7b6
VZ
6247 int blockSize = (int)(pool->end - pool->start)*2;
6248 BLOCK *temp = (BLOCK *)
5e9f2524 6249 pool->mem->realloc_fcn(pool->blocks,
8ce8835c 6250 (offsetof(BLOCK, s)
11a3e7b6
VZ
6251 + blockSize * sizeof(XML_Char)));
6252 if (temp == NULL)
5e9f2524 6253 return XML_FALSE;
11a3e7b6 6254 pool->blocks = temp;
5e9f2524
VS
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;
11a3e7b6 6262 int blockSize = (int)(pool->end - pool->start);
5e9f2524
VS
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)
11a3e7b6 6268 + blockSize * sizeof(XML_Char));
5e9f2524
VS
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;
11a3e7b6 6403 ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5e9f2524
VS
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}