blob: 882470dee3caca59339387e08e92fe4e38df9024 [file] [log] [blame]
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003*/
4
Fred Drake08317ae2003-10-21 15:38:55 +00005#define XML_BUILDING_EXPAT 1
6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00007#ifdef COMPILED_FROM_DSP
Martin v. Löwisfc03a942003-01-25 22:41:29 +00008#include "winconfig.h"
Martin v. Löwisfc03a942003-01-25 22:41:29 +00009#elif defined(MACOS_CLASSIC)
Martin v. Löwisfc03a942003-01-25 22:41:29 +000010#include "macconfig.h"
Thomas Wouters0e3f5912006-08-11 14:57:12 +000011#elif defined(__amigaos4__)
12#include "amigaconfig.h"
Fred Drake31d485c2004-08-03 07:06:22 +000013#elif defined(HAVE_EXPAT_CONFIG_H)
Martin v. Löwisfc03a942003-01-25 22:41:29 +000014#include <expat_config.h>
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000015#endif /* ndef COMPILED_FROM_DSP */
16
Thomas Wouters477c8d52006-05-27 19:21:47 +000017#include <stddef.h>
18#include <string.h> /* memset(), memcpy() */
19#include <assert.h>
20
Fred Drake08317ae2003-10-21 15:38:55 +000021#include "expat.h"
22
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000023#ifdef XML_UNICODE
24#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
25#define XmlConvert XmlUtf16Convert
26#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
27#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
28#define XmlEncode XmlUtf16Encode
29#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
30typedef unsigned short ICHAR;
31#else
32#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
33#define XmlConvert XmlUtf8Convert
34#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
35#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
36#define XmlEncode XmlUtf8Encode
37#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
38typedef char ICHAR;
39#endif
40
41
42#ifndef XML_NS
43
44#define XmlInitEncodingNS XmlInitEncoding
45#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
46#undef XmlGetInternalEncodingNS
47#define XmlGetInternalEncodingNS XmlGetInternalEncoding
48#define XmlParseXmlDeclNS XmlParseXmlDecl
49
50#endif
51
Martin v. Löwisfc03a942003-01-25 22:41:29 +000052#ifdef XML_UNICODE
53
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000054#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000055#define XML_T(x) (const wchar_t)x
56#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000057#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000058#define XML_T(x) (const unsigned short)x
59#define XML_L(x) x
60#endif
61
62#else
63
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000064#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000065#define XML_L(x) x
66
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000067#endif
68
69/* Round up n to be a multiple of sz, where sz is a power of 2. */
70#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
71
Fred Drake08317ae2003-10-21 15:38:55 +000072/* Handle the case where memmove() doesn't exist. */
73#ifndef HAVE_MEMMOVE
74#ifdef HAVE_BCOPY
75#define memmove(d,s,l) bcopy((s),(d),(l))
76#else
77#error memmove does not exist on this platform, nor is a substitute available
78#endif /* HAVE_BCOPY */
79#endif /* HAVE_MEMMOVE */
80
Martin v. Löwisfc03a942003-01-25 22:41:29 +000081#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000082#include "xmltok.h"
83#include "xmlrole.h"
84
85typedef const XML_Char *KEY;
86
87typedef struct {
88 KEY name;
89} NAMED;
90
91typedef struct {
92 NAMED **v;
Fred Drake08317ae2003-10-21 15:38:55 +000093 unsigned char power;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000094 size_t size;
95 size_t used;
Martin v. Löwisfc03a942003-01-25 22:41:29 +000096 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000097} HASH_TABLE;
98
Fred Drake08317ae2003-10-21 15:38:55 +000099/* Basic character hash algorithm, taken from Python's string hash:
100 h = h * 1000003 ^ character, the constant being a prime number.
101
102*/
103#ifdef XML_UNICODE
104#define CHAR_HASH(h, c) \
105 (((h) * 0xF4243) ^ (unsigned short)(c))
106#else
107#define CHAR_HASH(h, c) \
108 (((h) * 0xF4243) ^ (unsigned char)(c))
109#endif
110
111/* For probing (after a collision) we need a step size relative prime
112 to the hash table size, which is a power of 2. We use double-hashing,
113 since we can calculate a second hash value cheaply by taking those bits
114 of the first hash value that were discarded (masked out) when the table
115 index was calculated: index = hash & mask, where mask = table->size - 1.
116 We limit the maximum step size to table->size / 4 (mask >> 2) and make
117 it odd, since odd numbers are always relative prime to a power of 2.
118*/
119#define SECOND_HASH(hash, mask, power) \
120 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
121#define PROBE_STEP(hash, mask, power) \
122 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
123
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000124typedef struct {
125 NAMED **p;
126 NAMED **end;
127} HASH_TABLE_ITER;
128
129#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
130#define INIT_DATA_BUF_SIZE 1024
131#define INIT_ATTS_SIZE 16
Fred Drake08317ae2003-10-21 15:38:55 +0000132#define INIT_ATTS_VERSION 0xFFFFFFFF
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000133#define INIT_BLOCK_SIZE 1024
134#define INIT_BUFFER_SIZE 1024
135
136#define EXPAND_SPARE 24
137
138typedef struct binding {
139 struct prefix *prefix;
140 struct binding *nextTagBinding;
141 struct binding *prevPrefixBinding;
142 const struct attribute_id *attId;
143 XML_Char *uri;
144 int uriLen;
145 int uriAlloc;
146} BINDING;
147
148typedef struct prefix {
149 const XML_Char *name;
150 BINDING *binding;
151} PREFIX;
152
153typedef struct {
154 const XML_Char *str;
155 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000156 const XML_Char *prefix;
157 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000158 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000159 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000160} TAG_NAME;
161
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000162/* TAG represents an open element.
163 The name of the element is stored in both the document and API
164 encodings. The memory buffer 'buf' is a separately-allocated
165 memory area which stores the name. During the XML_Parse()/
166 XMLParseBuffer() when the element is open, the memory for the 'raw'
167 version of the name (in the document encoding) is shared with the
168 document buffer. If the element is open across calls to
169 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
170 contain the 'raw' name as well.
171
172 A parser re-uses these structures, maintaining a list of allocated
173 TAG objects in a free list.
174*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000175typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000176 struct tag *parent; /* parent of this element */
177 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000178 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000179 TAG_NAME name; /* tagName in the API encoding */
180 char *buf; /* buffer for name components */
181 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000182 BINDING *bindings;
183} TAG;
184
185typedef struct {
186 const XML_Char *name;
187 const XML_Char *textPtr;
Fred Drake31d485c2004-08-03 07:06:22 +0000188 int textLen; /* length in XML_Chars */
189 int processed; /* # of processed bytes - when suspended */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000190 const XML_Char *systemId;
191 const XML_Char *base;
192 const XML_Char *publicId;
193 const XML_Char *notation;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000194 XML_Bool open;
195 XML_Bool is_param;
196 XML_Bool is_internal; /* true if declared in internal subset outside PE */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000197} ENTITY;
198
199typedef struct {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000200 enum XML_Content_Type type;
201 enum XML_Content_Quant quant;
202 const XML_Char * name;
203 int firstchild;
204 int lastchild;
205 int childcnt;
206 int nextsib;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000207} CONTENT_SCAFFOLD;
208
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000209#define INIT_SCAFFOLD_ELEMENTS 32
210
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000211typedef struct block {
212 struct block *next;
213 int size;
214 XML_Char s[1];
215} BLOCK;
216
217typedef struct {
218 BLOCK *blocks;
219 BLOCK *freeBlocks;
220 const XML_Char *end;
221 XML_Char *ptr;
222 XML_Char *start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000223 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000224} STRING_POOL;
225
226/* The XML_Char before the name is used to determine whether
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000227 an attribute has been specified. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000228typedef struct attribute_id {
229 XML_Char *name;
230 PREFIX *prefix;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000231 XML_Bool maybeTokenized;
232 XML_Bool xmlns;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000233} ATTRIBUTE_ID;
234
235typedef struct {
236 const ATTRIBUTE_ID *id;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000237 XML_Bool isCdata;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000238 const XML_Char *value;
239} DEFAULT_ATTRIBUTE;
240
241typedef struct {
Fred Drake08317ae2003-10-21 15:38:55 +0000242 unsigned long version;
243 unsigned long hash;
244 const XML_Char *uriName;
245} NS_ATT;
246
247typedef struct {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000248 const XML_Char *name;
249 PREFIX *prefix;
250 const ATTRIBUTE_ID *idAtt;
251 int nDefaultAtts;
252 int allocDefaultAtts;
253 DEFAULT_ATTRIBUTE *defaultAtts;
254} ELEMENT_TYPE;
255
256typedef struct {
257 HASH_TABLE generalEntities;
258 HASH_TABLE elementTypes;
259 HASH_TABLE attributeIds;
260 HASH_TABLE prefixes;
261 STRING_POOL pool;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000262 STRING_POOL entityValuePool;
263 /* false once a parameter entity reference has been skipped */
264 XML_Bool keepProcessing;
265 /* true once an internal or external PE reference has been encountered;
266 this includes the reference to an external subset */
267 XML_Bool hasParamEntityRefs;
268 XML_Bool standalone;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000269#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000270 /* indicates if external PE has been read */
271 XML_Bool paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000272 HASH_TABLE paramEntities;
273#endif /* XML_DTD */
274 PREFIX defaultPrefix;
275 /* === scaffolding for building content model === */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000276 XML_Bool in_eldecl;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000277 CONTENT_SCAFFOLD *scaffold;
278 unsigned contentStringLen;
279 unsigned scaffSize;
280 unsigned scaffCount;
281 int scaffLevel;
282 int *scaffIndex;
283} DTD;
284
285typedef struct open_internal_entity {
286 const char *internalEventPtr;
287 const char *internalEventEndPtr;
288 struct open_internal_entity *next;
289 ENTITY *entity;
Fred Drake31d485c2004-08-03 07:06:22 +0000290 int startTagLevel;
291 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000292} OPEN_INTERNAL_ENTITY;
293
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000294typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
295 const char *start,
296 const char *end,
297 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000298
299static Processor prologProcessor;
300static Processor prologInitProcessor;
301static Processor contentProcessor;
302static Processor cdataSectionProcessor;
303#ifdef XML_DTD
304static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000305static Processor externalParEntProcessor;
306static Processor externalParEntInitProcessor;
307static Processor entityValueProcessor;
308static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000309#endif /* XML_DTD */
310static Processor epilogProcessor;
311static Processor errorProcessor;
312static Processor externalEntityInitProcessor;
313static Processor externalEntityInitProcessor2;
314static Processor externalEntityInitProcessor3;
315static Processor externalEntityContentProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +0000316static Processor internalEntityProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000317
318static enum XML_Error
319handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
320static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000321processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Fred Drake31d485c2004-08-03 07:06:22 +0000322 const char *s, const char *next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000323static enum XML_Error
324initializeEncoding(XML_Parser parser);
325static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000326doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
327 const char *end, int tok, const char *next, const char **nextPtr,
328 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000329static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000330processInternalEntity(XML_Parser parser, ENTITY *entity,
331 XML_Bool betweenDecl);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000332static enum XML_Error
333doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Fred Drake31d485c2004-08-03 07:06:22 +0000334 const char *start, const char *end, const char **endPtr,
335 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000336static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000337doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000338 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000339#ifdef XML_DTD
340static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000341doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000342 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000343#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000344
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000345static enum XML_Error
Fred Drake4faea012003-01-28 06:42:40 +0000346storeAtts(XML_Parser parser, const ENCODING *, const char *s,
347 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000348static enum XML_Error
349addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
350 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000351static int
Fred Drake31d485c2004-08-03 07:06:22 +0000352defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
353 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000354static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000355storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
356 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000357static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000358appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
359 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000360static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000361getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
362 const char *end);
363static int
364setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000365static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000366storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
367 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000368static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000369reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
370 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000371static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000372reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
373 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000374static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000375reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
376 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000377
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000378static const XML_Char * getContext(XML_Parser parser);
379static XML_Bool
380setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000381
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000382static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000383
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000384static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
385/* do not call if parentParser != NULL */
386static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
387static void
388dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
389static int
390dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
391static int
392copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000393
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000394static NAMED *
395lookup(HASH_TABLE *table, KEY name, size_t createSize);
396static void FASTCALL
397hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
398static void FASTCALL hashTableClear(HASH_TABLE *);
399static void FASTCALL hashTableDestroy(HASH_TABLE *);
400static void FASTCALL
401hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
402static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000403
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000404static void FASTCALL
405poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
406static void FASTCALL poolClear(STRING_POOL *);
407static void FASTCALL poolDestroy(STRING_POOL *);
408static XML_Char *
409poolAppend(STRING_POOL *pool, const ENCODING *enc,
410 const char *ptr, const char *end);
411static XML_Char *
412poolStoreString(STRING_POOL *pool, const ENCODING *enc,
413 const char *ptr, const char *end);
414static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
415static const XML_Char * FASTCALL
416poolCopyString(STRING_POOL *pool, const XML_Char *s);
417static const XML_Char *
418poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
419static const XML_Char * FASTCALL
420poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000421
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000422static int FASTCALL nextScaffoldPart(XML_Parser parser);
423static XML_Content * build_model(XML_Parser parser);
424static ELEMENT_TYPE *
425getElementType(XML_Parser parser, const ENCODING *enc,
426 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000427
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000428static XML_Parser
429parserCreate(const XML_Char *encodingName,
430 const XML_Memory_Handling_Suite *memsuite,
431 const XML_Char *nameSep,
432 DTD *dtd);
433static void
434parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000435
436#define poolStart(pool) ((pool)->start)
437#define poolEnd(pool) ((pool)->ptr)
438#define poolLength(pool) ((pool)->ptr - (pool)->start)
439#define poolChop(pool) ((void)--(pool->ptr))
440#define poolLastChar(pool) (((pool)->ptr)[-1])
441#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
442#define poolFinish(pool) ((pool)->start = (pool)->ptr)
443#define poolAppendChar(pool, c) \
444 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
445 ? 0 \
446 : ((*((pool)->ptr)++ = c), 1))
447
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000448struct XML_ParserStruct {
449 /* The first member must be userData so that the XML_GetUserData
450 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000451 void *m_userData;
452 void *m_handlerArg;
453 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000454 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000455 /* first character to be parsed */
456 const char *m_bufferPtr;
457 /* past last character to be parsed */
458 char *m_bufferEnd;
459 /* allocated end of buffer */
460 const char *m_bufferLim;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000461 XML_Index m_parseEndByteIndex;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000462 const char *m_parseEndPtr;
463 XML_Char *m_dataBuf;
464 XML_Char *m_dataBufEnd;
465 XML_StartElementHandler m_startElementHandler;
466 XML_EndElementHandler m_endElementHandler;
467 XML_CharacterDataHandler m_characterDataHandler;
468 XML_ProcessingInstructionHandler m_processingInstructionHandler;
469 XML_CommentHandler m_commentHandler;
470 XML_StartCdataSectionHandler m_startCdataSectionHandler;
471 XML_EndCdataSectionHandler m_endCdataSectionHandler;
472 XML_DefaultHandler m_defaultHandler;
473 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
474 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
475 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
476 XML_NotationDeclHandler m_notationDeclHandler;
477 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
478 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
479 XML_NotStandaloneHandler m_notStandaloneHandler;
480 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000481 XML_Parser m_externalEntityRefHandlerArg;
482 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000483 XML_UnknownEncodingHandler m_unknownEncodingHandler;
484 XML_ElementDeclHandler m_elementDeclHandler;
485 XML_AttlistDeclHandler m_attlistDeclHandler;
486 XML_EntityDeclHandler m_entityDeclHandler;
487 XML_XmlDeclHandler m_xmlDeclHandler;
488 const ENCODING *m_encoding;
489 INIT_ENCODING m_initEncoding;
490 const ENCODING *m_internalEncoding;
491 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000492 XML_Bool m_ns;
493 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000494 void *m_unknownEncodingMem;
495 void *m_unknownEncodingData;
496 void *m_unknownEncodingHandlerData;
Fred Drake31d485c2004-08-03 07:06:22 +0000497 void (XMLCALL *m_unknownEncodingRelease)(void *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000498 PROLOG_STATE m_prologState;
499 Processor *m_processor;
500 enum XML_Error m_errorCode;
501 const char *m_eventPtr;
502 const char *m_eventEndPtr;
503 const char *m_positionPtr;
504 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Fred Drake31d485c2004-08-03 07:06:22 +0000505 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000506 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000507 int m_tagLevel;
508 ENTITY *m_declEntity;
509 const XML_Char *m_doctypeName;
510 const XML_Char *m_doctypeSysid;
511 const XML_Char *m_doctypePubid;
512 const XML_Char *m_declAttributeType;
513 const XML_Char *m_declNotationName;
514 const XML_Char *m_declNotationPublicId;
515 ELEMENT_TYPE *m_declElementType;
516 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000517 XML_Bool m_declAttributeIsCdata;
518 XML_Bool m_declAttributeIsId;
519 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000520 const XML_Char *m_curBase;
521 TAG *m_tagStack;
522 TAG *m_freeTagList;
523 BINDING *m_inheritedBindings;
524 BINDING *m_freeBindingList;
525 int m_attsSize;
526 int m_nSpecifiedAtts;
527 int m_idAttIndex;
528 ATTRIBUTE *m_atts;
Fred Drake08317ae2003-10-21 15:38:55 +0000529 NS_ATT *m_nsAtts;
530 unsigned long m_nsAttsVersion;
531 unsigned char m_nsAttsPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000532 POSITION m_position;
533 STRING_POOL m_tempPool;
534 STRING_POOL m_temp2Pool;
535 char *m_groupConnector;
Fred Drake08317ae2003-10-21 15:38:55 +0000536 unsigned int m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000537 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000538 XML_Parser m_parentParser;
Fred Drake31d485c2004-08-03 07:06:22 +0000539 XML_ParsingStatus m_parsingStatus;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000540#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000541 XML_Bool m_isParamEntity;
542 XML_Bool m_useForeignDTD;
543 enum XML_ParamEntityParsing m_paramEntityParsing;
544#endif
545};
546
547#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
548#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
549#define FREE(p) (parser->m_mem.free_fcn((p)))
550
551#define userData (parser->m_userData)
552#define handlerArg (parser->m_handlerArg)
553#define startElementHandler (parser->m_startElementHandler)
554#define endElementHandler (parser->m_endElementHandler)
555#define characterDataHandler (parser->m_characterDataHandler)
556#define processingInstructionHandler \
557 (parser->m_processingInstructionHandler)
558#define commentHandler (parser->m_commentHandler)
559#define startCdataSectionHandler \
560 (parser->m_startCdataSectionHandler)
561#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
562#define defaultHandler (parser->m_defaultHandler)
563#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
564#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
565#define unparsedEntityDeclHandler \
566 (parser->m_unparsedEntityDeclHandler)
567#define notationDeclHandler (parser->m_notationDeclHandler)
568#define startNamespaceDeclHandler \
569 (parser->m_startNamespaceDeclHandler)
570#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
571#define notStandaloneHandler (parser->m_notStandaloneHandler)
572#define externalEntityRefHandler \
573 (parser->m_externalEntityRefHandler)
574#define externalEntityRefHandlerArg \
575 (parser->m_externalEntityRefHandlerArg)
576#define internalEntityRefHandler \
577 (parser->m_internalEntityRefHandler)
578#define skippedEntityHandler (parser->m_skippedEntityHandler)
579#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
580#define elementDeclHandler (parser->m_elementDeclHandler)
581#define attlistDeclHandler (parser->m_attlistDeclHandler)
582#define entityDeclHandler (parser->m_entityDeclHandler)
583#define xmlDeclHandler (parser->m_xmlDeclHandler)
584#define encoding (parser->m_encoding)
585#define initEncoding (parser->m_initEncoding)
586#define internalEncoding (parser->m_internalEncoding)
587#define unknownEncodingMem (parser->m_unknownEncodingMem)
588#define unknownEncodingData (parser->m_unknownEncodingData)
589#define unknownEncodingHandlerData \
590 (parser->m_unknownEncodingHandlerData)
591#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
592#define protocolEncodingName (parser->m_protocolEncodingName)
593#define ns (parser->m_ns)
594#define ns_triplets (parser->m_ns_triplets)
595#define prologState (parser->m_prologState)
596#define processor (parser->m_processor)
597#define errorCode (parser->m_errorCode)
598#define eventPtr (parser->m_eventPtr)
599#define eventEndPtr (parser->m_eventEndPtr)
600#define positionPtr (parser->m_positionPtr)
601#define position (parser->m_position)
602#define openInternalEntities (parser->m_openInternalEntities)
Fred Drake31d485c2004-08-03 07:06:22 +0000603#define freeInternalEntities (parser->m_freeInternalEntities)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000604#define defaultExpandInternalEntities \
605 (parser->m_defaultExpandInternalEntities)
606#define tagLevel (parser->m_tagLevel)
607#define buffer (parser->m_buffer)
608#define bufferPtr (parser->m_bufferPtr)
609#define bufferEnd (parser->m_bufferEnd)
610#define parseEndByteIndex (parser->m_parseEndByteIndex)
611#define parseEndPtr (parser->m_parseEndPtr)
612#define bufferLim (parser->m_bufferLim)
613#define dataBuf (parser->m_dataBuf)
614#define dataBufEnd (parser->m_dataBufEnd)
615#define _dtd (parser->m_dtd)
616#define curBase (parser->m_curBase)
617#define declEntity (parser->m_declEntity)
618#define doctypeName (parser->m_doctypeName)
619#define doctypeSysid (parser->m_doctypeSysid)
620#define doctypePubid (parser->m_doctypePubid)
621#define declAttributeType (parser->m_declAttributeType)
622#define declNotationName (parser->m_declNotationName)
623#define declNotationPublicId (parser->m_declNotationPublicId)
624#define declElementType (parser->m_declElementType)
625#define declAttributeId (parser->m_declAttributeId)
626#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
627#define declAttributeIsId (parser->m_declAttributeIsId)
628#define freeTagList (parser->m_freeTagList)
629#define freeBindingList (parser->m_freeBindingList)
630#define inheritedBindings (parser->m_inheritedBindings)
631#define tagStack (parser->m_tagStack)
632#define atts (parser->m_atts)
633#define attsSize (parser->m_attsSize)
634#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
635#define idAttIndex (parser->m_idAttIndex)
Fred Drake08317ae2003-10-21 15:38:55 +0000636#define nsAtts (parser->m_nsAtts)
637#define nsAttsVersion (parser->m_nsAttsVersion)
638#define nsAttsPower (parser->m_nsAttsPower)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000639#define tempPool (parser->m_tempPool)
640#define temp2Pool (parser->m_temp2Pool)
641#define groupConnector (parser->m_groupConnector)
642#define groupSize (parser->m_groupSize)
643#define namespaceSeparator (parser->m_namespaceSeparator)
644#define parentParser (parser->m_parentParser)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000645#define ps_parsing (parser->m_parsingStatus.parsing)
646#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000647#ifdef XML_DTD
648#define isParamEntity (parser->m_isParamEntity)
649#define useForeignDTD (parser->m_useForeignDTD)
650#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000651#endif /* XML_DTD */
652
Fred Drake08317ae2003-10-21 15:38:55 +0000653XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000654XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000655{
656 return XML_ParserCreate_MM(encodingName, NULL, NULL);
657}
658
Fred Drake08317ae2003-10-21 15:38:55 +0000659XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000660XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000661{
662 XML_Char tmp[2];
663 *tmp = nsSep;
664 return XML_ParserCreate_MM(encodingName, NULL, tmp);
665}
666
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000667static const XML_Char implicitContext[] = {
668 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
669 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
670 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
671 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
672};
673
Fred Drake08317ae2003-10-21 15:38:55 +0000674XML_Parser XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000675XML_ParserCreate_MM(const XML_Char *encodingName,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000676 const XML_Memory_Handling_Suite *memsuite,
677 const XML_Char *nameSep)
678{
679 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
680 if (parser != NULL && ns) {
681 /* implicit context only set for root parser, since child
682 parsers (i.e. external entity parsers) will inherit it
683 */
684 if (!setContext(parser, implicitContext)) {
685 XML_ParserFree(parser);
686 return NULL;
687 }
688 }
689 return parser;
690}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000691
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000692static XML_Parser
693parserCreate(const XML_Char *encodingName,
694 const XML_Memory_Handling_Suite *memsuite,
695 const XML_Char *nameSep,
696 DTD *dtd)
697{
698 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000699
700 if (memsuite) {
701 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000702 parser = (XML_Parser)
703 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
704 if (parser != NULL) {
705 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
706 mtemp->malloc_fcn = memsuite->malloc_fcn;
707 mtemp->realloc_fcn = memsuite->realloc_fcn;
708 mtemp->free_fcn = memsuite->free_fcn;
709 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000710 }
711 else {
712 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000713 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
714 if (parser != NULL) {
715 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
716 mtemp->malloc_fcn = malloc;
717 mtemp->realloc_fcn = realloc;
718 mtemp->free_fcn = free;
719 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000720 }
721
722 if (!parser)
723 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000724
725 buffer = NULL;
726 bufferLim = NULL;
727
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000728 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000729 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
730 if (atts == NULL) {
731 FREE(parser);
732 return NULL;
733 }
734 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
735 if (dataBuf == NULL) {
736 FREE(atts);
737 FREE(parser);
738 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000739 }
740 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
741
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000742 if (dtd)
743 _dtd = dtd;
744 else {
745 _dtd = dtdCreate(&parser->m_mem);
746 if (_dtd == NULL) {
747 FREE(dataBuf);
748 FREE(atts);
749 FREE(parser);
750 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000751 }
752 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000753
754 freeBindingList = NULL;
755 freeTagList = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000756 freeInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000757
758 groupSize = 0;
759 groupConnector = NULL;
760
761 unknownEncodingHandler = NULL;
762 unknownEncodingHandlerData = NULL;
763
764 namespaceSeparator = '!';
765 ns = XML_FALSE;
766 ns_triplets = XML_FALSE;
767
Fred Drake08317ae2003-10-21 15:38:55 +0000768 nsAtts = NULL;
769 nsAttsVersion = 0;
770 nsAttsPower = 0;
771
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000772 poolInit(&tempPool, &(parser->m_mem));
773 poolInit(&temp2Pool, &(parser->m_mem));
774 parserInit(parser, encodingName);
775
776 if (encodingName && !protocolEncodingName) {
777 XML_ParserFree(parser);
778 return NULL;
779 }
780
781 if (nameSep) {
782 ns = XML_TRUE;
783 internalEncoding = XmlGetInternalEncodingNS();
784 namespaceSeparator = *nameSep;
785 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000786 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000787 internalEncoding = XmlGetInternalEncoding();
788 }
789
790 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000791}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000792
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000793static void
794parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000795{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000796 processor = prologInitProcessor;
797 XmlPrologStateInit(&prologState);
798 protocolEncodingName = (encodingName != NULL
799 ? poolCopyString(&tempPool, encodingName)
800 : NULL);
801 curBase = NULL;
802 XmlInitEncoding(&initEncoding, &encoding, 0);
803 userData = NULL;
804 handlerArg = NULL;
805 startElementHandler = NULL;
806 endElementHandler = NULL;
807 characterDataHandler = NULL;
808 processingInstructionHandler = NULL;
809 commentHandler = NULL;
810 startCdataSectionHandler = NULL;
811 endCdataSectionHandler = NULL;
812 defaultHandler = NULL;
813 startDoctypeDeclHandler = NULL;
814 endDoctypeDeclHandler = NULL;
815 unparsedEntityDeclHandler = NULL;
816 notationDeclHandler = NULL;
817 startNamespaceDeclHandler = NULL;
818 endNamespaceDeclHandler = NULL;
819 notStandaloneHandler = NULL;
820 externalEntityRefHandler = NULL;
821 externalEntityRefHandlerArg = parser;
822 skippedEntityHandler = NULL;
823 elementDeclHandler = NULL;
824 attlistDeclHandler = NULL;
825 entityDeclHandler = NULL;
826 xmlDeclHandler = NULL;
827 bufferPtr = buffer;
828 bufferEnd = buffer;
829 parseEndByteIndex = 0;
830 parseEndPtr = NULL;
831 declElementType = NULL;
832 declAttributeId = NULL;
833 declEntity = NULL;
834 doctypeName = NULL;
835 doctypeSysid = NULL;
836 doctypePubid = NULL;
837 declAttributeType = NULL;
838 declNotationName = NULL;
839 declNotationPublicId = NULL;
840 declAttributeIsCdata = XML_FALSE;
841 declAttributeIsId = XML_FALSE;
842 memset(&position, 0, sizeof(POSITION));
843 errorCode = XML_ERROR_NONE;
844 eventPtr = NULL;
845 eventEndPtr = NULL;
846 positionPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000847 openInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000848 defaultExpandInternalEntities = XML_TRUE;
849 tagLevel = 0;
850 tagStack = NULL;
851 inheritedBindings = NULL;
852 nSpecifiedAtts = 0;
853 unknownEncodingMem = NULL;
854 unknownEncodingRelease = NULL;
855 unknownEncodingData = NULL;
856 parentParser = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000857 ps_parsing = XML_INITIALIZED;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000858#ifdef XML_DTD
859 isParamEntity = XML_FALSE;
860 useForeignDTD = XML_FALSE;
861 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
862#endif
863}
864
865/* moves list of bindings to freeBindingList */
866static void FASTCALL
867moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
868{
869 while (bindings) {
870 BINDING *b = bindings;
871 bindings = bindings->nextTagBinding;
872 b->nextTagBinding = freeBindingList;
873 freeBindingList = b;
874 }
875}
876
Fred Drake08317ae2003-10-21 15:38:55 +0000877XML_Bool XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000878XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
879{
880 TAG *tStk;
Fred Drake31d485c2004-08-03 07:06:22 +0000881 OPEN_INTERNAL_ENTITY *openEntityList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000882 if (parentParser)
883 return XML_FALSE;
884 /* move tagStack to freeTagList */
885 tStk = tagStack;
886 while (tStk) {
887 TAG *tag = tStk;
888 tStk = tStk->parent;
889 tag->parent = freeTagList;
890 moveToFreeBindingList(parser, tag->bindings);
891 tag->bindings = NULL;
892 freeTagList = tag;
893 }
Fred Drake31d485c2004-08-03 07:06:22 +0000894 /* move openInternalEntities to freeInternalEntities */
895 openEntityList = openInternalEntities;
896 while (openEntityList) {
897 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
898 openEntityList = openEntity->next;
899 openEntity->next = freeInternalEntities;
900 freeInternalEntities = openEntity;
901 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000902 moveToFreeBindingList(parser, inheritedBindings);
Fred Drake08317ae2003-10-21 15:38:55 +0000903 FREE(unknownEncodingMem);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000904 if (unknownEncodingRelease)
905 unknownEncodingRelease(unknownEncodingData);
906 poolClear(&tempPool);
907 poolClear(&temp2Pool);
908 parserInit(parser, encodingName);
909 dtdReset(_dtd, &parser->m_mem);
910 return setContext(parser, implicitContext);
911}
912
Fred Drake08317ae2003-10-21 15:38:55 +0000913enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000914XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
915{
916 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
917 XXX There's no way for the caller to determine which of the
918 XXX possible error cases caused the XML_STATUS_ERROR return.
919 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000920 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000921 return XML_STATUS_ERROR;
922 if (encodingName == NULL)
923 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000924 else {
925 protocolEncodingName = poolCopyString(&tempPool, encodingName);
926 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000927 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000928 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000929 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000930}
931
Fred Drake08317ae2003-10-21 15:38:55 +0000932XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000933XML_ExternalEntityParserCreate(XML_Parser oldParser,
934 const XML_Char *context,
935 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000936{
937 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000938 DTD *newDtd = NULL;
939 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000940 XML_StartElementHandler oldStartElementHandler = startElementHandler;
941 XML_EndElementHandler oldEndElementHandler = endElementHandler;
942 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000943 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
944 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000945 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000946 XML_StartCdataSectionHandler oldStartCdataSectionHandler
947 = startCdataSectionHandler;
948 XML_EndCdataSectionHandler oldEndCdataSectionHandler
949 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000950 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000951 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
952 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000953 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000954 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
955 = startNamespaceDeclHandler;
956 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
957 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000958 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000959 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
960 = externalEntityRefHandler;
961 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
962 XML_UnknownEncodingHandler oldUnknownEncodingHandler
963 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000964 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
965 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
966 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
967 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
968 ELEMENT_TYPE * oldDeclElementType = declElementType;
969
970 void *oldUserData = userData;
971 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000972 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
973 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000974#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000975 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
976 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000977#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000978 XML_Bool oldns_triplets = ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000979
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000980#ifdef XML_DTD
981 if (!context)
982 newDtd = oldDtd;
983#endif /* XML_DTD */
984
985 /* Note that the magical uses of the pre-processor to make field
986 access look more like C++ require that `parser' be overwritten
987 here. This makes this function more painful to follow than it
988 would be otherwise.
989 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000990 if (ns) {
991 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000992 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000993 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000994 }
995 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000996 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000997 }
998
999 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001000 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001001
1002 startElementHandler = oldStartElementHandler;
1003 endElementHandler = oldEndElementHandler;
1004 characterDataHandler = oldCharacterDataHandler;
1005 processingInstructionHandler = oldProcessingInstructionHandler;
1006 commentHandler = oldCommentHandler;
1007 startCdataSectionHandler = oldStartCdataSectionHandler;
1008 endCdataSectionHandler = oldEndCdataSectionHandler;
1009 defaultHandler = oldDefaultHandler;
1010 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1011 notationDeclHandler = oldNotationDeclHandler;
1012 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1013 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1014 notStandaloneHandler = oldNotStandaloneHandler;
1015 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001016 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001017 unknownEncodingHandler = oldUnknownEncodingHandler;
1018 elementDeclHandler = oldElementDeclHandler;
1019 attlistDeclHandler = oldAttlistDeclHandler;
1020 entityDeclHandler = oldEntityDeclHandler;
1021 xmlDeclHandler = oldXmlDeclHandler;
1022 declElementType = oldDeclElementType;
1023 userData = oldUserData;
1024 if (oldUserData == oldHandlerArg)
1025 handlerArg = userData;
1026 else
1027 handlerArg = parser;
1028 if (oldExternalEntityRefHandlerArg != oldParser)
1029 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1030 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1031 ns_triplets = oldns_triplets;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001032 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001033#ifdef XML_DTD
1034 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001035 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001036 if (context) {
1037#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001038 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1039 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001040 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001041 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001042 }
1043 processor = externalEntityInitProcessor;
1044#ifdef XML_DTD
1045 }
1046 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001047 /* The DTD instance referenced by _dtd is shared between the document's
1048 root parser and external PE parsers, therefore one does not need to
1049 call setContext. In addition, one also *must* not call setContext,
1050 because this would overwrite existing prefix->binding pointers in
1051 _dtd with ones that get destroyed with the external PE parser.
1052 This would leave those prefixes with dangling pointers.
1053 */
1054 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001055 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001056 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001057 }
1058#endif /* XML_DTD */
1059 return parser;
1060}
1061
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001062static void FASTCALL
1063destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001064{
1065 for (;;) {
1066 BINDING *b = bindings;
1067 if (!b)
1068 break;
1069 bindings = b->nextTagBinding;
1070 FREE(b->uri);
1071 FREE(b);
1072 }
1073}
1074
Fred Drake08317ae2003-10-21 15:38:55 +00001075void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001076XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001077{
Fred Drake31d485c2004-08-03 07:06:22 +00001078 TAG *tagList;
1079 OPEN_INTERNAL_ENTITY *entityList;
1080 if (parser == NULL)
1081 return;
1082 /* free tagStack and freeTagList */
1083 tagList = tagStack;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001084 for (;;) {
1085 TAG *p;
Fred Drake31d485c2004-08-03 07:06:22 +00001086 if (tagList == NULL) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001087 if (freeTagList == NULL)
1088 break;
Fred Drake31d485c2004-08-03 07:06:22 +00001089 tagList = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001090 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001091 }
Fred Drake31d485c2004-08-03 07:06:22 +00001092 p = tagList;
1093 tagList = tagList->parent;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001094 FREE(p->buf);
1095 destroyBindings(p->bindings, parser);
1096 FREE(p);
1097 }
Fred Drake31d485c2004-08-03 07:06:22 +00001098 /* free openInternalEntities and freeInternalEntities */
1099 entityList = openInternalEntities;
1100 for (;;) {
1101 OPEN_INTERNAL_ENTITY *openEntity;
1102 if (entityList == NULL) {
1103 if (freeInternalEntities == NULL)
1104 break;
1105 entityList = freeInternalEntities;
1106 freeInternalEntities = NULL;
1107 }
1108 openEntity = entityList;
1109 entityList = entityList->next;
1110 FREE(openEntity);
1111 }
1112
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001113 destroyBindings(freeBindingList, parser);
1114 destroyBindings(inheritedBindings, parser);
1115 poolDestroy(&tempPool);
1116 poolDestroy(&temp2Pool);
1117#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001118 /* external parameter entity parsers share the DTD structure
1119 parser->m_dtd with the root parser, so we must not destroy it
1120 */
1121 if (!isParamEntity && _dtd)
1122#else
1123 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001124#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001125 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001126 FREE((void *)atts);
Fred Drake08317ae2003-10-21 15:38:55 +00001127 FREE(groupConnector);
1128 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001129 FREE(dataBuf);
Fred Drake08317ae2003-10-21 15:38:55 +00001130 FREE(nsAtts);
1131 FREE(unknownEncodingMem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001132 if (unknownEncodingRelease)
1133 unknownEncodingRelease(unknownEncodingData);
1134 FREE(parser);
1135}
1136
Fred Drake08317ae2003-10-21 15:38:55 +00001137void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001138XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001139{
1140 handlerArg = parser;
1141}
1142
Fred Drake08317ae2003-10-21 15:38:55 +00001143enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001144XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1145{
1146#ifdef XML_DTD
1147 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001148 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001149 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1150 useForeignDTD = useDTD;
1151 return XML_ERROR_NONE;
1152#else
1153 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1154#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001155}
1156
Fred Drake08317ae2003-10-21 15:38:55 +00001157void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001158XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1159{
1160 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001161 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001162 return;
1163 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1164}
1165
Fred Drake08317ae2003-10-21 15:38:55 +00001166void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001167XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001168{
1169 if (handlerArg == userData)
1170 handlerArg = userData = p;
1171 else
1172 userData = p;
1173}
1174
Fred Drake08317ae2003-10-21 15:38:55 +00001175enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001176XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001177{
1178 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001179 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001180 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001181 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001182 curBase = p;
1183 }
1184 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001185 curBase = NULL;
1186 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001187}
1188
Fred Drake08317ae2003-10-21 15:38:55 +00001189const XML_Char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001190XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001191{
1192 return curBase;
1193}
1194
Fred Drake08317ae2003-10-21 15:38:55 +00001195int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001196XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001197{
1198 return nSpecifiedAtts;
1199}
1200
Fred Drake08317ae2003-10-21 15:38:55 +00001201int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001202XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001203{
1204 return idAttIndex;
1205}
1206
Fred Drake08317ae2003-10-21 15:38:55 +00001207void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001208XML_SetElementHandler(XML_Parser parser,
1209 XML_StartElementHandler start,
1210 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001211{
1212 startElementHandler = start;
1213 endElementHandler = end;
1214}
1215
Fred Drake08317ae2003-10-21 15:38:55 +00001216void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001217XML_SetStartElementHandler(XML_Parser parser,
1218 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001219 startElementHandler = start;
1220}
1221
Fred Drake08317ae2003-10-21 15:38:55 +00001222void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001223XML_SetEndElementHandler(XML_Parser parser,
1224 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001225 endElementHandler = end;
1226}
1227
Fred Drake08317ae2003-10-21 15:38:55 +00001228void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001229XML_SetCharacterDataHandler(XML_Parser parser,
1230 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001231{
1232 characterDataHandler = handler;
1233}
1234
Fred Drake08317ae2003-10-21 15:38:55 +00001235void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001236XML_SetProcessingInstructionHandler(XML_Parser parser,
1237 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001238{
1239 processingInstructionHandler = handler;
1240}
1241
Fred Drake08317ae2003-10-21 15:38:55 +00001242void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001243XML_SetCommentHandler(XML_Parser parser,
1244 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001245{
1246 commentHandler = handler;
1247}
1248
Fred Drake08317ae2003-10-21 15:38:55 +00001249void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001250XML_SetCdataSectionHandler(XML_Parser parser,
1251 XML_StartCdataSectionHandler start,
1252 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001253{
1254 startCdataSectionHandler = start;
1255 endCdataSectionHandler = end;
1256}
1257
Fred Drake08317ae2003-10-21 15:38:55 +00001258void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001259XML_SetStartCdataSectionHandler(XML_Parser parser,
1260 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001261 startCdataSectionHandler = start;
1262}
1263
Fred Drake08317ae2003-10-21 15:38:55 +00001264void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001265XML_SetEndCdataSectionHandler(XML_Parser parser,
1266 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001267 endCdataSectionHandler = end;
1268}
1269
Fred Drake08317ae2003-10-21 15:38:55 +00001270void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001271XML_SetDefaultHandler(XML_Parser parser,
1272 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001273{
1274 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001275 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001276}
1277
Fred Drake08317ae2003-10-21 15:38:55 +00001278void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001279XML_SetDefaultHandlerExpand(XML_Parser parser,
1280 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001281{
1282 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001283 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001284}
1285
Fred Drake08317ae2003-10-21 15:38:55 +00001286void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001287XML_SetDoctypeDeclHandler(XML_Parser parser,
1288 XML_StartDoctypeDeclHandler start,
1289 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001290{
1291 startDoctypeDeclHandler = start;
1292 endDoctypeDeclHandler = end;
1293}
1294
Fred Drake08317ae2003-10-21 15:38:55 +00001295void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001296XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1297 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001298 startDoctypeDeclHandler = start;
1299}
1300
Fred Drake08317ae2003-10-21 15:38:55 +00001301void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001302XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1303 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001304 endDoctypeDeclHandler = end;
1305}
1306
Fred Drake08317ae2003-10-21 15:38:55 +00001307void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001308XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1309 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001310{
1311 unparsedEntityDeclHandler = handler;
1312}
1313
Fred Drake08317ae2003-10-21 15:38:55 +00001314void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001315XML_SetNotationDeclHandler(XML_Parser parser,
1316 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001317{
1318 notationDeclHandler = handler;
1319}
1320
Fred Drake08317ae2003-10-21 15:38:55 +00001321void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001322XML_SetNamespaceDeclHandler(XML_Parser parser,
1323 XML_StartNamespaceDeclHandler start,
1324 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001325{
1326 startNamespaceDeclHandler = start;
1327 endNamespaceDeclHandler = end;
1328}
1329
Fred Drake08317ae2003-10-21 15:38:55 +00001330void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001331XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1332 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001333 startNamespaceDeclHandler = start;
1334}
1335
Fred Drake08317ae2003-10-21 15:38:55 +00001336void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001337XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1338 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001339 endNamespaceDeclHandler = end;
1340}
1341
Fred Drake08317ae2003-10-21 15:38:55 +00001342void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001343XML_SetNotStandaloneHandler(XML_Parser parser,
1344 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001345{
1346 notStandaloneHandler = handler;
1347}
1348
Fred Drake08317ae2003-10-21 15:38:55 +00001349void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001350XML_SetExternalEntityRefHandler(XML_Parser parser,
1351 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001352{
1353 externalEntityRefHandler = handler;
1354}
1355
Fred Drake08317ae2003-10-21 15:38:55 +00001356void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001357XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001358{
1359 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001360 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001361 else
1362 externalEntityRefHandlerArg = parser;
1363}
1364
Fred Drake08317ae2003-10-21 15:38:55 +00001365void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001366XML_SetSkippedEntityHandler(XML_Parser parser,
1367 XML_SkippedEntityHandler handler)
1368{
1369 skippedEntityHandler = handler;
1370}
1371
Fred Drake08317ae2003-10-21 15:38:55 +00001372void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001373XML_SetUnknownEncodingHandler(XML_Parser parser,
1374 XML_UnknownEncodingHandler handler,
1375 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001376{
1377 unknownEncodingHandler = handler;
1378 unknownEncodingHandlerData = data;
1379}
1380
Fred Drake08317ae2003-10-21 15:38:55 +00001381void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001382XML_SetElementDeclHandler(XML_Parser parser,
1383 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001384{
1385 elementDeclHandler = eldecl;
1386}
1387
Fred Drake08317ae2003-10-21 15:38:55 +00001388void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001389XML_SetAttlistDeclHandler(XML_Parser parser,
1390 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001391{
1392 attlistDeclHandler = attdecl;
1393}
1394
Fred Drake08317ae2003-10-21 15:38:55 +00001395void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001396XML_SetEntityDeclHandler(XML_Parser parser,
1397 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001398{
1399 entityDeclHandler = handler;
1400}
1401
Fred Drake08317ae2003-10-21 15:38:55 +00001402void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001403XML_SetXmlDeclHandler(XML_Parser parser,
1404 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001405 xmlDeclHandler = handler;
1406}
1407
Fred Drake08317ae2003-10-21 15:38:55 +00001408int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001409XML_SetParamEntityParsing(XML_Parser parser,
1410 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001411{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001412 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001413 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001414 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001415#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001416 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001417 return 1;
1418#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001419 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001420#endif
1421}
1422
Fred Drake08317ae2003-10-21 15:38:55 +00001423enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001424XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001425{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001426 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001427 case XML_SUSPENDED:
1428 errorCode = XML_ERROR_SUSPENDED;
1429 return XML_STATUS_ERROR;
1430 case XML_FINISHED:
1431 errorCode = XML_ERROR_FINISHED;
1432 return XML_STATUS_ERROR;
1433 default:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001434 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001435 }
1436
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001437 if (len == 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001438 ps_finalBuffer = (XML_Bool)isFinal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001439 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001440 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001441 positionPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001442 parseEndPtr = bufferEnd;
1443
1444 /* If data are left over from last buffer, and we now know that these
1445 data are the final chunk of input, then we have to check them again
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001446 to detect errors based on that fact.
Fred Drake31d485c2004-08-03 07:06:22 +00001447 */
1448 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1449
1450 if (errorCode == XML_ERROR_NONE) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001451 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001452 case XML_SUSPENDED:
1453 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1454 positionPtr = bufferPtr;
1455 return XML_STATUS_SUSPENDED;
1456 case XML_INITIALIZED:
1457 case XML_PARSING:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001458 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001459 /* fall through */
1460 default:
1461 return XML_STATUS_OK;
1462 }
1463 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001464 eventEndPtr = eventPtr;
1465 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001466 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001467 }
1468#ifndef XML_CONTEXT_BYTES
1469 else if (bufferPtr == bufferEnd) {
1470 const char *end;
1471 int nLeftOver;
Fred Drake31d485c2004-08-03 07:06:22 +00001472 enum XML_Error result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001473 parseEndByteIndex += len;
1474 positionPtr = s;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001475 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001476
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001477 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
Fred Drake31d485c2004-08-03 07:06:22 +00001478
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001479 if (errorCode != XML_ERROR_NONE) {
1480 eventEndPtr = eventPtr;
1481 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001482 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001483 }
Fred Drake31d485c2004-08-03 07:06:22 +00001484 else {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001485 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001486 case XML_SUSPENDED:
1487 result = XML_STATUS_SUSPENDED;
1488 break;
1489 case XML_INITIALIZED:
1490 case XML_PARSING:
1491 result = XML_STATUS_OK;
1492 if (isFinal) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001493 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001494 return result;
1495 }
1496 }
1497 }
1498
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001499 XmlUpdatePosition(encoding, positionPtr, end, &position);
1500 nLeftOver = s + len - end;
1501 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001502 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1503 /* FIXME avoid integer overflow */
1504 char *temp;
1505 temp = (buffer == NULL
1506 ? (char *)MALLOC(len * 2)
1507 : (char *)REALLOC(buffer, len * 2));
1508 if (temp == NULL) {
1509 errorCode = XML_ERROR_NO_MEMORY;
1510 return XML_STATUS_ERROR;
1511 }
1512 buffer = temp;
1513 if (!buffer) {
1514 errorCode = XML_ERROR_NO_MEMORY;
1515 eventPtr = eventEndPtr = NULL;
1516 processor = errorProcessor;
1517 return XML_STATUS_ERROR;
1518 }
1519 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001520 }
1521 memcpy(buffer, end, nLeftOver);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001522 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001523 bufferPtr = buffer;
1524 bufferEnd = buffer + nLeftOver;
1525 positionPtr = bufferPtr;
1526 parseEndPtr = bufferEnd;
1527 eventPtr = bufferPtr;
1528 eventEndPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001529 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001530 }
1531#endif /* not defined XML_CONTEXT_BYTES */
1532 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001533 void *buff = XML_GetBuffer(parser, len);
1534 if (buff == NULL)
1535 return XML_STATUS_ERROR;
1536 else {
1537 memcpy(buff, s, len);
1538 return XML_ParseBuffer(parser, len, isFinal);
1539 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001540 }
1541}
1542
Fred Drake08317ae2003-10-21 15:38:55 +00001543enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001544XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001545{
Fred Drake31d485c2004-08-03 07:06:22 +00001546 const char *start;
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001547 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001548
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001549 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001550 case XML_SUSPENDED:
1551 errorCode = XML_ERROR_SUSPENDED;
1552 return XML_STATUS_ERROR;
1553 case XML_FINISHED:
1554 errorCode = XML_ERROR_FINISHED;
1555 return XML_STATUS_ERROR;
1556 default:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001557 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001558 }
1559
1560 start = bufferPtr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001561 positionPtr = start;
1562 bufferEnd += len;
Fred Drake31d485c2004-08-03 07:06:22 +00001563 parseEndPtr = bufferEnd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001564 parseEndByteIndex += len;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001565 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001566
1567 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1568
1569 if (errorCode != XML_ERROR_NONE) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001570 eventEndPtr = eventPtr;
1571 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001572 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001573 }
Fred Drake31d485c2004-08-03 07:06:22 +00001574 else {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001575 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001576 case XML_SUSPENDED:
1577 result = XML_STATUS_SUSPENDED;
1578 break;
1579 case XML_INITIALIZED:
1580 case XML_PARSING:
1581 if (isFinal) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001582 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001583 return result;
1584 }
1585 default: ; /* should not happen */
1586 }
1587 }
1588
1589 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1590 positionPtr = bufferPtr;
1591 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001592}
1593
Fred Drake08317ae2003-10-21 15:38:55 +00001594void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001595XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001596{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001597 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001598 case XML_SUSPENDED:
1599 errorCode = XML_ERROR_SUSPENDED;
1600 return NULL;
1601 case XML_FINISHED:
1602 errorCode = XML_ERROR_FINISHED;
1603 return NULL;
1604 default: ;
1605 }
1606
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001607 if (len > bufferLim - bufferEnd) {
1608 /* FIXME avoid integer overflow */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001609 int neededSize = len + (int)(bufferEnd - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001610#ifdef XML_CONTEXT_BYTES
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001611 int keep = (int)(bufferPtr - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001612
1613 if (keep > XML_CONTEXT_BYTES)
1614 keep = XML_CONTEXT_BYTES;
1615 neededSize += keep;
1616#endif /* defined XML_CONTEXT_BYTES */
1617 if (neededSize <= bufferLim - buffer) {
1618#ifdef XML_CONTEXT_BYTES
1619 if (keep < bufferPtr - buffer) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001620 int offset = (int)(bufferPtr - buffer) - keep;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001621 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1622 bufferEnd -= offset;
1623 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001624 }
1625#else
1626 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1627 bufferEnd = buffer + (bufferEnd - bufferPtr);
1628 bufferPtr = buffer;
1629#endif /* not defined XML_CONTEXT_BYTES */
1630 }
1631 else {
1632 char *newBuf;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001633 int bufferSize = (int)(bufferLim - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001634 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001635 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001636 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001637 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001638 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001639 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001640 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001641 errorCode = XML_ERROR_NO_MEMORY;
1642 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001643 }
1644 bufferLim = newBuf + bufferSize;
1645#ifdef XML_CONTEXT_BYTES
1646 if (bufferPtr) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001647 int keep = (int)(bufferPtr - buffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001648 if (keep > XML_CONTEXT_BYTES)
1649 keep = XML_CONTEXT_BYTES;
1650 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1651 FREE(buffer);
1652 buffer = newBuf;
1653 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1654 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001655 }
1656 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001657 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1658 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001659 }
1660#else
1661 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001662 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1663 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001664 }
1665 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1666 bufferPtr = buffer = newBuf;
1667#endif /* not defined XML_CONTEXT_BYTES */
1668 }
1669 }
1670 return bufferEnd;
1671}
1672
Fred Drake31d485c2004-08-03 07:06:22 +00001673enum XML_Status XMLCALL
1674XML_StopParser(XML_Parser parser, XML_Bool resumable)
1675{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001676 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001677 case XML_SUSPENDED:
1678 if (resumable) {
1679 errorCode = XML_ERROR_SUSPENDED;
1680 return XML_STATUS_ERROR;
1681 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001682 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001683 break;
1684 case XML_FINISHED:
1685 errorCode = XML_ERROR_FINISHED;
1686 return XML_STATUS_ERROR;
1687 default:
1688 if (resumable) {
1689#ifdef XML_DTD
1690 if (isParamEntity) {
1691 errorCode = XML_ERROR_SUSPEND_PE;
1692 return XML_STATUS_ERROR;
1693 }
1694#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001695 ps_parsing = XML_SUSPENDED;
Fred Drake31d485c2004-08-03 07:06:22 +00001696 }
1697 else
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001698 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001699 }
1700 return XML_STATUS_OK;
1701}
1702
1703enum XML_Status XMLCALL
1704XML_ResumeParser(XML_Parser parser)
1705{
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001706 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001707
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001708 if (ps_parsing != XML_SUSPENDED) {
Fred Drake31d485c2004-08-03 07:06:22 +00001709 errorCode = XML_ERROR_NOT_SUSPENDED;
1710 return XML_STATUS_ERROR;
1711 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001712 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001713
1714 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1715
1716 if (errorCode != XML_ERROR_NONE) {
1717 eventEndPtr = eventPtr;
1718 processor = errorProcessor;
1719 return XML_STATUS_ERROR;
1720 }
1721 else {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001722 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001723 case XML_SUSPENDED:
1724 result = XML_STATUS_SUSPENDED;
1725 break;
1726 case XML_INITIALIZED:
1727 case XML_PARSING:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001728 if (ps_finalBuffer) {
1729 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001730 return result;
1731 }
1732 default: ;
1733 }
1734 }
1735
1736 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1737 positionPtr = bufferPtr;
1738 return result;
1739}
1740
1741void XMLCALL
1742XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1743{
1744 assert(status != NULL);
1745 *status = parser->m_parsingStatus;
1746}
1747
Fred Drake08317ae2003-10-21 15:38:55 +00001748enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001749XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001750{
1751 return errorCode;
1752}
1753
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001754XML_Index XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001755XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001756{
1757 if (eventPtr)
1758 return parseEndByteIndex - (parseEndPtr - eventPtr);
1759 return -1;
1760}
1761
Fred Drake08317ae2003-10-21 15:38:55 +00001762int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001763XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001764{
1765 if (eventEndPtr && eventPtr)
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001766 return (int)(eventEndPtr - eventPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001767 return 0;
1768}
1769
Fred Drake08317ae2003-10-21 15:38:55 +00001770const char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001771XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001772{
1773#ifdef XML_CONTEXT_BYTES
1774 if (eventPtr && buffer) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001775 *offset = (int)(eventPtr - buffer);
1776 *size = (int)(bufferEnd - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001777 return buffer;
1778 }
1779#endif /* defined XML_CONTEXT_BYTES */
1780 return (char *) 0;
1781}
1782
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001783XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001784XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001785{
Fred Drake31d485c2004-08-03 07:06:22 +00001786 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001787 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1788 positionPtr = eventPtr;
1789 }
1790 return position.lineNumber + 1;
1791}
1792
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001793XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001794XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001795{
Fred Drake31d485c2004-08-03 07:06:22 +00001796 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001797 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1798 positionPtr = eventPtr;
1799 }
1800 return position.columnNumber;
1801}
1802
Fred Drake08317ae2003-10-21 15:38:55 +00001803void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001804XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1805{
1806 FREE(model);
1807}
1808
Fred Drake08317ae2003-10-21 15:38:55 +00001809void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001810XML_MemMalloc(XML_Parser parser, size_t size)
1811{
1812 return MALLOC(size);
1813}
1814
Fred Drake08317ae2003-10-21 15:38:55 +00001815void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001816XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1817{
1818 return REALLOC(ptr, size);
1819}
1820
Fred Drake08317ae2003-10-21 15:38:55 +00001821void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001822XML_MemFree(XML_Parser parser, void *ptr)
1823{
1824 FREE(ptr);
1825}
1826
Fred Drake08317ae2003-10-21 15:38:55 +00001827void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001828XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001829{
1830 if (defaultHandler) {
1831 if (openInternalEntities)
1832 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001833 internalEncoding,
1834 openInternalEntities->internalEventPtr,
1835 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001836 else
1837 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1838 }
1839}
1840
Fred Drake08317ae2003-10-21 15:38:55 +00001841const XML_LChar * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001842XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001843{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001844 static const XML_LChar* const message[] = {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001845 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001846 XML_L("out of memory"),
1847 XML_L("syntax error"),
1848 XML_L("no element found"),
1849 XML_L("not well-formed (invalid token)"),
1850 XML_L("unclosed token"),
1851 XML_L("partial character"),
1852 XML_L("mismatched tag"),
1853 XML_L("duplicate attribute"),
1854 XML_L("junk after document element"),
1855 XML_L("illegal parameter entity reference"),
1856 XML_L("undefined entity"),
1857 XML_L("recursive entity reference"),
1858 XML_L("asynchronous entity"),
1859 XML_L("reference to invalid character number"),
1860 XML_L("reference to binary entity"),
1861 XML_L("reference to external entity in attribute"),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001862 XML_L("XML or text declaration not at start of entity"),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001863 XML_L("unknown encoding"),
1864 XML_L("encoding specified in XML declaration is incorrect"),
1865 XML_L("unclosed CDATA section"),
1866 XML_L("error in processing external entity reference"),
1867 XML_L("document is not standalone"),
1868 XML_L("unexpected parser state - please send a bug report"),
1869 XML_L("entity declared in parameter entity"),
1870 XML_L("requested feature requires XML_DTD support in Expat"),
Fred Drake08317ae2003-10-21 15:38:55 +00001871 XML_L("cannot change setting once parsing has begun"),
Fred Drake31d485c2004-08-03 07:06:22 +00001872 XML_L("unbound prefix"),
1873 XML_L("must not undeclare prefix"),
1874 XML_L("incomplete markup in parameter entity"),
1875 XML_L("XML declaration not well-formed"),
1876 XML_L("text declaration not well-formed"),
1877 XML_L("illegal character(s) in public id"),
1878 XML_L("parser suspended"),
1879 XML_L("parser not suspended"),
1880 XML_L("parsing aborted"),
1881 XML_L("parsing finished"),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001882 XML_L("cannot suspend in external parameter entity"),
1883 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1884 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1885 XML_L("prefix must not be bound to one of the reserved namespace names")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001886 };
1887 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1888 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001889 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001890}
1891
Fred Drake08317ae2003-10-21 15:38:55 +00001892const XML_LChar * XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001893XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001894
1895 /* V1 is used to string-ize the version number. However, it would
1896 string-ize the actual version macro *names* unless we get them
1897 substituted before being passed to V1. CPP is defined to expand
1898 a macro, then rescan for more expansions. Thus, we use V2 to expand
1899 the version macros, then CPP will expand the resulting V1() macro
1900 with the correct numerals. */
1901 /* ### I'm assuming cpp is portable in this respect... */
1902
1903#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1904#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1905
1906 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1907
1908#undef V1
1909#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001910}
1911
Fred Drake08317ae2003-10-21 15:38:55 +00001912XML_Expat_Version XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001913XML_ExpatVersionInfo(void)
1914{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001915 XML_Expat_Version version;
1916
1917 version.major = XML_MAJOR_VERSION;
1918 version.minor = XML_MINOR_VERSION;
1919 version.micro = XML_MICRO_VERSION;
1920
1921 return version;
1922}
1923
Fred Drake08317ae2003-10-21 15:38:55 +00001924const XML_Feature * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001925XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001926{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001927 static const XML_Feature features[] = {
1928 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
1929 sizeof(XML_Char)},
1930 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
1931 sizeof(XML_LChar)},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001932#ifdef XML_UNICODE
Fred Drake08317ae2003-10-21 15:38:55 +00001933 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001934#endif
1935#ifdef XML_UNICODE_WCHAR_T
Fred Drake08317ae2003-10-21 15:38:55 +00001936 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001937#endif
1938#ifdef XML_DTD
Fred Drake08317ae2003-10-21 15:38:55 +00001939 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001940#endif
1941#ifdef XML_CONTEXT_BYTES
1942 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1943 XML_CONTEXT_BYTES},
1944#endif
1945#ifdef XML_MIN_SIZE
Fred Drake08317ae2003-10-21 15:38:55 +00001946 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001947#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001948#ifdef XML_NS
1949 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
1950#endif
Fred Drake08317ae2003-10-21 15:38:55 +00001951 {XML_FEATURE_END, NULL, 0}
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001952 };
1953
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001954 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001955}
1956
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001957/* Initially tag->rawName always points into the parse buffer;
1958 for those TAG instances opened while the current parse buffer was
1959 processed, and not yet closed, we need to store tag->rawName in a more
1960 permanent location, since the parse buffer is about to be discarded.
1961*/
1962static XML_Bool
1963storeRawNames(XML_Parser parser)
1964{
1965 TAG *tag = tagStack;
1966 while (tag) {
1967 int bufSize;
1968 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1969 char *rawNameBuf = tag->buf + nameLen;
1970 /* Stop if already stored. Since tagStack is a stack, we can stop
1971 at the first entry that has already been copied; everything
1972 below it in the stack is already been accounted for in a
1973 previous call to this function.
1974 */
1975 if (tag->rawName == rawNameBuf)
1976 break;
1977 /* For re-use purposes we need to ensure that the
1978 size of tag->buf is a multiple of sizeof(XML_Char).
1979 */
1980 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1981 if (bufSize > tag->bufEnd - tag->buf) {
1982 char *temp = (char *)REALLOC(tag->buf, bufSize);
1983 if (temp == NULL)
1984 return XML_FALSE;
1985 /* if tag->name.str points to tag->buf (only when namespace
1986 processing is off) then we have to update it
1987 */
1988 if (tag->name.str == (XML_Char *)tag->buf)
1989 tag->name.str = (XML_Char *)temp;
1990 /* if tag->name.localPart is set (when namespace processing is on)
1991 then update it as well, since it will always point into tag->buf
1992 */
1993 if (tag->name.localPart)
1994 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1995 (XML_Char *)tag->buf);
1996 tag->buf = temp;
1997 tag->bufEnd = temp + bufSize;
1998 rawNameBuf = temp + nameLen;
1999 }
2000 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2001 tag->rawName = rawNameBuf;
2002 tag = tag->parent;
2003 }
2004 return XML_TRUE;
2005}
2006
2007static enum XML_Error PTRCALL
2008contentProcessor(XML_Parser parser,
2009 const char *start,
2010 const char *end,
2011 const char **endPtr)
2012{
Fred Drake31d485c2004-08-03 07:06:22 +00002013 enum XML_Error result = doContent(parser, 0, encoding, start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002014 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002015 if (result == XML_ERROR_NONE) {
2016 if (!storeRawNames(parser))
2017 return XML_ERROR_NO_MEMORY;
2018 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002019 return result;
2020}
2021
2022static enum XML_Error PTRCALL
2023externalEntityInitProcessor(XML_Parser parser,
2024 const char *start,
2025 const char *end,
2026 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002027{
2028 enum XML_Error result = initializeEncoding(parser);
2029 if (result != XML_ERROR_NONE)
2030 return result;
2031 processor = externalEntityInitProcessor2;
2032 return externalEntityInitProcessor2(parser, start, end, endPtr);
2033}
2034
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002035static enum XML_Error PTRCALL
2036externalEntityInitProcessor2(XML_Parser parser,
2037 const char *start,
2038 const char *end,
2039 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002040{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002041 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002042 int tok = XmlContentTok(encoding, start, end, &next);
2043 switch (tok) {
2044 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002045 /* If we are at the end of the buffer, this would cause the next stage,
2046 i.e. externalEntityInitProcessor3, to pass control directly to
2047 doContent (by detecting XML_TOK_NONE) without processing any xml text
2048 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2049 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002050 if (next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002051 *endPtr = next;
2052 return XML_ERROR_NONE;
2053 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002054 start = next;
2055 break;
2056 case XML_TOK_PARTIAL:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002057 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002058 *endPtr = start;
2059 return XML_ERROR_NONE;
2060 }
2061 eventPtr = start;
2062 return XML_ERROR_UNCLOSED_TOKEN;
2063 case XML_TOK_PARTIAL_CHAR:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002064 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002065 *endPtr = start;
2066 return XML_ERROR_NONE;
2067 }
2068 eventPtr = start;
2069 return XML_ERROR_PARTIAL_CHAR;
2070 }
2071 processor = externalEntityInitProcessor3;
2072 return externalEntityInitProcessor3(parser, start, end, endPtr);
2073}
2074
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002075static enum XML_Error PTRCALL
2076externalEntityInitProcessor3(XML_Parser parser,
2077 const char *start,
2078 const char *end,
2079 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002080{
Fred Drake31d485c2004-08-03 07:06:22 +00002081 int tok;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002082 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Fred Drake31d485c2004-08-03 07:06:22 +00002083 eventPtr = start;
2084 tok = XmlContentTok(encoding, start, end, &next);
2085 eventEndPtr = next;
2086
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002087 switch (tok) {
2088 case XML_TOK_XML_DECL:
2089 {
Fred Drake31d485c2004-08-03 07:06:22 +00002090 enum XML_Error result;
2091 result = processXmlDecl(parser, 1, start, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002092 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002093 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002094 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00002095 case XML_SUSPENDED:
2096 *endPtr = next;
2097 return XML_ERROR_NONE;
2098 case XML_FINISHED:
2099 return XML_ERROR_ABORTED;
2100 default:
2101 start = next;
2102 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002103 }
2104 break;
2105 case XML_TOK_PARTIAL:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002106 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002107 *endPtr = start;
2108 return XML_ERROR_NONE;
2109 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002110 return XML_ERROR_UNCLOSED_TOKEN;
2111 case XML_TOK_PARTIAL_CHAR:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002112 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002113 *endPtr = start;
2114 return XML_ERROR_NONE;
2115 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002116 return XML_ERROR_PARTIAL_CHAR;
2117 }
2118 processor = externalEntityContentProcessor;
2119 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002120 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002121}
2122
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002123static enum XML_Error PTRCALL
2124externalEntityContentProcessor(XML_Parser parser,
2125 const char *start,
2126 const char *end,
2127 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002128{
Fred Drake31d485c2004-08-03 07:06:22 +00002129 enum XML_Error result = doContent(parser, 1, encoding, start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002130 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002131 if (result == XML_ERROR_NONE) {
2132 if (!storeRawNames(parser))
2133 return XML_ERROR_NO_MEMORY;
2134 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002135 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002136}
2137
2138static enum XML_Error
2139doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002140 int startTagLevel,
2141 const ENCODING *enc,
2142 const char *s,
2143 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00002144 const char **nextPtr,
2145 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002146{
Fred Drake31d485c2004-08-03 07:06:22 +00002147 /* save one level of indirection */
2148 DTD * const dtd = _dtd;
2149
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002150 const char **eventPP;
2151 const char **eventEndPP;
2152 if (enc == encoding) {
2153 eventPP = &eventPtr;
2154 eventEndPP = &eventEndPtr;
2155 }
2156 else {
2157 eventPP = &(openInternalEntities->internalEventPtr);
2158 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2159 }
2160 *eventPP = s;
Fred Drake31d485c2004-08-03 07:06:22 +00002161
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002162 for (;;) {
2163 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2164 int tok = XmlContentTok(enc, s, end, &next);
2165 *eventEndPP = next;
2166 switch (tok) {
2167 case XML_TOK_TRAILING_CR:
Fred Drake31d485c2004-08-03 07:06:22 +00002168 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002169 *nextPtr = s;
2170 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002171 }
2172 *eventEndPP = end;
2173 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002174 XML_Char c = 0xA;
2175 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002176 }
2177 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002178 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002179 /* We are at the end of the final buffer, should we check for
2180 XML_SUSPENDED, XML_FINISHED?
2181 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002182 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002183 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002184 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002185 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002186 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002187 return XML_ERROR_NONE;
2188 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00002189 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002190 *nextPtr = s;
2191 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002192 }
2193 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002194 if (tagLevel != startTagLevel)
2195 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002196 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002197 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002198 }
2199 return XML_ERROR_NO_ELEMENTS;
2200 case XML_TOK_INVALID:
2201 *eventPP = next;
2202 return XML_ERROR_INVALID_TOKEN;
2203 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002204 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002205 *nextPtr = s;
2206 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002207 }
2208 return XML_ERROR_UNCLOSED_TOKEN;
2209 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002210 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002211 *nextPtr = s;
2212 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002213 }
2214 return XML_ERROR_PARTIAL_CHAR;
2215 case XML_TOK_ENTITY_REF:
2216 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002217 const XML_Char *name;
2218 ENTITY *entity;
2219 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2220 s + enc->minBytesPerChar,
2221 next - enc->minBytesPerChar);
2222 if (ch) {
2223 if (characterDataHandler)
2224 characterDataHandler(handlerArg, &ch, 1);
2225 else if (defaultHandler)
2226 reportDefault(parser, enc, s, next);
2227 break;
2228 }
2229 name = poolStoreString(&dtd->pool, enc,
2230 s + enc->minBytesPerChar,
2231 next - enc->minBytesPerChar);
2232 if (!name)
2233 return XML_ERROR_NO_MEMORY;
2234 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2235 poolDiscard(&dtd->pool);
2236 /* First, determine if a check for an existing declaration is needed;
2237 if yes, check that the entity exists, and that it is internal,
2238 otherwise call the skipped entity or default handler.
2239 */
2240 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2241 if (!entity)
2242 return XML_ERROR_UNDEFINED_ENTITY;
2243 else if (!entity->is_internal)
2244 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2245 }
2246 else if (!entity) {
2247 if (skippedEntityHandler)
2248 skippedEntityHandler(handlerArg, name, 0);
2249 else if (defaultHandler)
2250 reportDefault(parser, enc, s, next);
2251 break;
2252 }
2253 if (entity->open)
2254 return XML_ERROR_RECURSIVE_ENTITY_REF;
2255 if (entity->notation)
2256 return XML_ERROR_BINARY_ENTITY_REF;
2257 if (entity->textPtr) {
2258 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002259 if (!defaultExpandInternalEntities) {
2260 if (skippedEntityHandler)
2261 skippedEntityHandler(handlerArg, entity->name, 0);
2262 else if (defaultHandler)
2263 reportDefault(parser, enc, s, next);
2264 break;
2265 }
Fred Drake31d485c2004-08-03 07:06:22 +00002266 result = processInternalEntity(parser, entity, XML_FALSE);
2267 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002268 return result;
2269 }
2270 else if (externalEntityRefHandler) {
2271 const XML_Char *context;
2272 entity->open = XML_TRUE;
2273 context = getContext(parser);
2274 entity->open = XML_FALSE;
2275 if (!context)
2276 return XML_ERROR_NO_MEMORY;
Fred Drake31d485c2004-08-03 07:06:22 +00002277 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002278 context,
2279 entity->base,
2280 entity->systemId,
2281 entity->publicId))
2282 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2283 poolDiscard(&tempPool);
2284 }
2285 else if (defaultHandler)
2286 reportDefault(parser, enc, s, next);
2287 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002288 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002289 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002290 /* fall through */
2291 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002292 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002293 TAG *tag;
2294 enum XML_Error result;
2295 XML_Char *toPtr;
2296 if (freeTagList) {
2297 tag = freeTagList;
2298 freeTagList = freeTagList->parent;
2299 }
2300 else {
2301 tag = (TAG *)MALLOC(sizeof(TAG));
2302 if (!tag)
2303 return XML_ERROR_NO_MEMORY;
2304 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2305 if (!tag->buf) {
2306 FREE(tag);
2307 return XML_ERROR_NO_MEMORY;
2308 }
2309 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2310 }
2311 tag->bindings = NULL;
2312 tag->parent = tagStack;
2313 tagStack = tag;
2314 tag->name.localPart = NULL;
2315 tag->name.prefix = NULL;
2316 tag->rawName = s + enc->minBytesPerChar;
2317 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2318 ++tagLevel;
2319 {
2320 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2321 const char *fromPtr = tag->rawName;
2322 toPtr = (XML_Char *)tag->buf;
2323 for (;;) {
2324 int bufSize;
2325 int convLen;
2326 XmlConvert(enc,
2327 &fromPtr, rawNameEnd,
2328 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002329 convLen = (int)(toPtr - (XML_Char *)tag->buf);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002330 if (fromPtr == rawNameEnd) {
2331 tag->name.strLen = convLen;
2332 break;
2333 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002334 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002335 {
2336 char *temp = (char *)REALLOC(tag->buf, bufSize);
2337 if (temp == NULL)
2338 return XML_ERROR_NO_MEMORY;
2339 tag->buf = temp;
2340 tag->bufEnd = temp + bufSize;
2341 toPtr = (XML_Char *)temp + convLen;
2342 }
2343 }
2344 }
2345 tag->name.str = (XML_Char *)tag->buf;
2346 *toPtr = XML_T('\0');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002347 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2348 if (result)
2349 return result;
2350 if (startElementHandler)
2351 startElementHandler(handlerArg, tag->name.str,
2352 (const XML_Char **)atts);
2353 else if (defaultHandler)
2354 reportDefault(parser, enc, s, next);
2355 poolClear(&tempPool);
2356 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002357 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002358 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002359 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002360 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2361 {
2362 const char *rawName = s + enc->minBytesPerChar;
2363 enum XML_Error result;
2364 BINDING *bindings = NULL;
2365 XML_Bool noElmHandlers = XML_TRUE;
2366 TAG_NAME name;
2367 name.str = poolStoreString(&tempPool, enc, rawName,
2368 rawName + XmlNameLength(enc, rawName));
2369 if (!name.str)
2370 return XML_ERROR_NO_MEMORY;
2371 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002372 result = storeAtts(parser, enc, s, &name, &bindings);
2373 if (result)
2374 return result;
2375 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002376 if (startElementHandler) {
2377 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2378 noElmHandlers = XML_FALSE;
2379 }
2380 if (endElementHandler) {
2381 if (startElementHandler)
2382 *eventPP = *eventEndPP;
2383 endElementHandler(handlerArg, name.str);
2384 noElmHandlers = XML_FALSE;
2385 }
2386 if (noElmHandlers && defaultHandler)
2387 reportDefault(parser, enc, s, next);
2388 poolClear(&tempPool);
2389 while (bindings) {
2390 BINDING *b = bindings;
2391 if (endNamespaceDeclHandler)
2392 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2393 bindings = bindings->nextTagBinding;
2394 b->nextTagBinding = freeBindingList;
2395 freeBindingList = b;
2396 b->prefix->binding = b->prevPrefixBinding;
2397 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002398 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002399 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002400 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002401 break;
2402 case XML_TOK_END_TAG:
2403 if (tagLevel == startTagLevel)
2404 return XML_ERROR_ASYNC_ENTITY;
2405 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002406 int len;
2407 const char *rawName;
2408 TAG *tag = tagStack;
2409 tagStack = tag->parent;
2410 tag->parent = freeTagList;
2411 freeTagList = tag;
2412 rawName = s + enc->minBytesPerChar*2;
2413 len = XmlNameLength(enc, rawName);
2414 if (len != tag->rawNameLength
2415 || memcmp(tag->rawName, rawName, len) != 0) {
2416 *eventPP = rawName;
2417 return XML_ERROR_TAG_MISMATCH;
2418 }
2419 --tagLevel;
2420 if (endElementHandler) {
2421 const XML_Char *localPart;
2422 const XML_Char *prefix;
2423 XML_Char *uri;
2424 localPart = tag->name.localPart;
2425 if (ns && localPart) {
2426 /* localPart and prefix may have been overwritten in
2427 tag->name.str, since this points to the binding->uri
2428 buffer which gets re-used; so we have to add them again
2429 */
2430 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2431 /* don't need to check for space - already done in storeAtts() */
2432 while (*localPart) *uri++ = *localPart++;
2433 prefix = (XML_Char *)tag->name.prefix;
2434 if (ns_triplets && prefix) {
2435 *uri++ = namespaceSeparator;
2436 while (*prefix) *uri++ = *prefix++;
2437 }
2438 *uri = XML_T('\0');
2439 }
2440 endElementHandler(handlerArg, tag->name.str);
2441 }
2442 else if (defaultHandler)
2443 reportDefault(parser, enc, s, next);
2444 while (tag->bindings) {
2445 BINDING *b = tag->bindings;
2446 if (endNamespaceDeclHandler)
2447 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2448 tag->bindings = tag->bindings->nextTagBinding;
2449 b->nextTagBinding = freeBindingList;
2450 freeBindingList = b;
2451 b->prefix->binding = b->prevPrefixBinding;
2452 }
2453 if (tagLevel == 0)
2454 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002455 }
2456 break;
2457 case XML_TOK_CHAR_REF:
2458 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002459 int n = XmlCharRefNumber(enc, s);
2460 if (n < 0)
2461 return XML_ERROR_BAD_CHAR_REF;
2462 if (characterDataHandler) {
2463 XML_Char buf[XML_ENCODE_MAX];
2464 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2465 }
2466 else if (defaultHandler)
2467 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002468 }
2469 break;
2470 case XML_TOK_XML_DECL:
2471 return XML_ERROR_MISPLACED_XML_PI;
2472 case XML_TOK_DATA_NEWLINE:
2473 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002474 XML_Char c = 0xA;
2475 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002476 }
2477 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002478 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002479 break;
2480 case XML_TOK_CDATA_SECT_OPEN:
2481 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002482 enum XML_Error result;
2483 if (startCdataSectionHandler)
2484 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002485#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002486 /* Suppose you doing a transformation on a document that involves
2487 changing only the character data. You set up a defaultHandler
2488 and a characterDataHandler. The defaultHandler simply copies
2489 characters through. The characterDataHandler does the
2490 transformation and writes the characters out escaping them as
2491 necessary. This case will fail to work if we leave out the
2492 following two lines (because & and < inside CDATA sections will
2493 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002494
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002495 However, now we have a start/endCdataSectionHandler, so it seems
2496 easier to let the user deal with this.
2497 */
2498 else if (characterDataHandler)
2499 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002500#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002501 else if (defaultHandler)
2502 reportDefault(parser, enc, s, next);
Fred Drake31d485c2004-08-03 07:06:22 +00002503 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2504 if (result != XML_ERROR_NONE)
2505 return result;
2506 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002507 processor = cdataSectionProcessor;
2508 return result;
2509 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002510 }
2511 break;
2512 case XML_TOK_TRAILING_RSQB:
Fred Drake31d485c2004-08-03 07:06:22 +00002513 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002514 *nextPtr = s;
2515 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002516 }
2517 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002518 if (MUST_CONVERT(enc, s)) {
2519 ICHAR *dataPtr = (ICHAR *)dataBuf;
2520 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2521 characterDataHandler(handlerArg, dataBuf,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002522 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002523 }
2524 else
2525 characterDataHandler(handlerArg,
2526 (XML_Char *)s,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002527 (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002528 }
2529 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002530 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002531 /* We are at the end of the final buffer, should we check for
2532 XML_SUSPENDED, XML_FINISHED?
2533 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002534 if (startTagLevel == 0) {
2535 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002536 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002537 }
2538 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002539 *eventPP = end;
2540 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002541 }
Fred Drake31d485c2004-08-03 07:06:22 +00002542 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002543 return XML_ERROR_NONE;
2544 case XML_TOK_DATA_CHARS:
2545 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002546 if (MUST_CONVERT(enc, s)) {
2547 for (;;) {
2548 ICHAR *dataPtr = (ICHAR *)dataBuf;
2549 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2550 *eventEndPP = s;
2551 characterDataHandler(handlerArg, dataBuf,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002552 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002553 if (s == next)
2554 break;
2555 *eventPP = s;
2556 }
2557 }
2558 else
2559 characterDataHandler(handlerArg,
2560 (XML_Char *)s,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002561 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002562 }
2563 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002564 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002565 break;
2566 case XML_TOK_PI:
2567 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002568 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002569 break;
2570 case XML_TOK_COMMENT:
2571 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002572 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002573 break;
2574 default:
2575 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002576 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002577 break;
2578 }
2579 *eventPP = s = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002580 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00002581 case XML_SUSPENDED:
2582 *nextPtr = next;
2583 return XML_ERROR_NONE;
2584 case XML_FINISHED:
2585 return XML_ERROR_ABORTED;
2586 default: ;
2587 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002588 }
2589 /* not reached */
2590}
2591
Fred Drake4faea012003-01-28 06:42:40 +00002592/* Precondition: all arguments must be non-NULL;
2593 Purpose:
2594 - normalize attributes
2595 - check attributes for well-formedness
2596 - generate namespace aware attribute names (URI, prefix)
2597 - build list of attributes for startElementHandler
2598 - default attributes
2599 - process namespace declarations (check and report them)
2600 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002601*/
2602static enum XML_Error
2603storeAtts(XML_Parser parser, const ENCODING *enc,
2604 const char *attStr, TAG_NAME *tagNamePtr,
2605 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002606{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002607 DTD * const dtd = _dtd; /* save one level of indirection */
Fred Drake08317ae2003-10-21 15:38:55 +00002608 ELEMENT_TYPE *elementType;
2609 int nDefaultAtts;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002610 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002611 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002612 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002613 int i;
2614 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002615 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002616 int nPrefixes = 0;
2617 BINDING *binding;
2618 const XML_Char *localPart;
2619
2620 /* lookup the element type name */
Fred Drake4faea012003-01-28 06:42:40 +00002621 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2622 if (!elementType) {
2623 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2624 if (!name)
2625 return XML_ERROR_NO_MEMORY;
2626 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2627 sizeof(ELEMENT_TYPE));
2628 if (!elementType)
2629 return XML_ERROR_NO_MEMORY;
2630 if (ns && !setElementTypePrefix(parser, elementType))
2631 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002632 }
Fred Drake4faea012003-01-28 06:42:40 +00002633 nDefaultAtts = elementType->nDefaultAtts;
2634
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002635 /* get the attributes from the tokenizer */
2636 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2637 if (n + nDefaultAtts > attsSize) {
2638 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002639 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002640 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002641 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2642 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002643 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002644 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002645 if (n > oldAttsSize)
2646 XmlGetAttributes(enc, attStr, n, atts);
2647 }
Fred Drake4faea012003-01-28 06:42:40 +00002648
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002649 appAtts = (const XML_Char **)atts;
2650 for (i = 0; i < n; i++) {
2651 /* add the name and value to the attribute list */
2652 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002653 atts[i].name
2654 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002655 if (!attId)
2656 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002657 /* Detect duplicate attributes by their QNames. This does not work when
2658 namespace processing is turned on and different prefixes for the same
2659 namespace are used. For this case we have a check further down.
2660 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002661 if ((attId->name)[-1]) {
2662 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002663 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002664 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2665 }
2666 (attId->name)[-1] = 1;
2667 appAtts[attIndex++] = attId->name;
2668 if (!atts[i].normalized) {
2669 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002670 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002671
2672 /* figure out whether declared as other than CDATA */
2673 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002674 int j;
2675 for (j = 0; j < nDefaultAtts; j++) {
2676 if (attId == elementType->defaultAtts[j].id) {
2677 isCdata = elementType->defaultAtts[j].isCdata;
2678 break;
2679 }
2680 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002681 }
2682
2683 /* normalize the attribute value */
2684 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002685 atts[i].valuePtr, atts[i].valueEnd,
2686 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002687 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002688 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002689 appAtts[attIndex] = poolStart(&tempPool);
2690 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002691 }
Fred Drake4faea012003-01-28 06:42:40 +00002692 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002693 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002694 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2695 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002696 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002697 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002698 poolFinish(&tempPool);
2699 }
2700 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002701 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002702 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002703 /* deal with namespace declarations here */
2704 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2705 appAtts[attIndex], bindingsPtr);
2706 if (result)
2707 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002708 --attIndex;
2709 }
2710 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002711 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002712 attIndex++;
2713 nPrefixes++;
2714 (attId->name)[-1] = 2;
2715 }
2716 }
2717 else
2718 attIndex++;
2719 }
Fred Drake4faea012003-01-28 06:42:40 +00002720
2721 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2722 nSpecifiedAtts = attIndex;
2723 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2724 for (i = 0; i < attIndex; i += 2)
2725 if (appAtts[i] == elementType->idAtt->name) {
2726 idAttIndex = i;
2727 break;
2728 }
2729 }
2730 else
2731 idAttIndex = -1;
2732
2733 /* do attribute defaulting */
2734 for (i = 0; i < nDefaultAtts; i++) {
2735 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2736 if (!(da->id->name)[-1] && da->value) {
2737 if (da->id->prefix) {
2738 if (da->id->xmlns) {
2739 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2740 da->value, bindingsPtr);
2741 if (result)
2742 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002743 }
2744 else {
Fred Drake4faea012003-01-28 06:42:40 +00002745 (da->id->name)[-1] = 2;
2746 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002747 appAtts[attIndex++] = da->id->name;
2748 appAtts[attIndex++] = da->value;
2749 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002750 }
Fred Drake4faea012003-01-28 06:42:40 +00002751 else {
2752 (da->id->name)[-1] = 1;
2753 appAtts[attIndex++] = da->id->name;
2754 appAtts[attIndex++] = da->value;
2755 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002756 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002757 }
Fred Drake4faea012003-01-28 06:42:40 +00002758 appAtts[attIndex] = 0;
2759
Fred Drake08317ae2003-10-21 15:38:55 +00002760 /* expand prefixed attribute names, check for duplicates,
2761 and clear flags that say whether attributes were specified */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002762 i = 0;
2763 if (nPrefixes) {
Fred Drake08317ae2003-10-21 15:38:55 +00002764 int j; /* hash table index */
2765 unsigned long version = nsAttsVersion;
2766 int nsAttsSize = (int)1 << nsAttsPower;
2767 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2768 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2769 NS_ATT *temp;
2770 /* hash table size must also be a power of 2 and >= 8 */
2771 while (nPrefixes >> nsAttsPower++);
2772 if (nsAttsPower < 3)
2773 nsAttsPower = 3;
2774 nsAttsSize = (int)1 << nsAttsPower;
2775 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2776 if (!temp)
2777 return XML_ERROR_NO_MEMORY;
2778 nsAtts = temp;
2779 version = 0; /* force re-initialization of nsAtts hash table */
2780 }
2781 /* using a version flag saves us from initializing nsAtts every time */
2782 if (!version) { /* initialize version flags when version wraps around */
2783 version = INIT_ATTS_VERSION;
2784 for (j = nsAttsSize; j != 0; )
2785 nsAtts[--j].version = version;
2786 }
2787 nsAttsVersion = --version;
2788
2789 /* expand prefixed names and check for duplicates */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002790 for (; i < attIndex; i += 2) {
Fred Drake08317ae2003-10-21 15:38:55 +00002791 const XML_Char *s = appAtts[i];
2792 if (s[-1] == 2) { /* prefixed */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002793 ATTRIBUTE_ID *id;
Fred Drake08317ae2003-10-21 15:38:55 +00002794 const BINDING *b;
2795 unsigned long uriHash = 0;
2796 ((XML_Char *)s)[-1] = 0; /* clear flag */
2797 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2798 b = id->prefix->binding;
2799 if (!b)
2800 return XML_ERROR_UNBOUND_PREFIX;
2801
2802 /* as we expand the name we also calculate its hash value */
2803 for (j = 0; j < b->uriLen; j++) {
2804 const XML_Char c = b->uri[j];
2805 if (!poolAppendChar(&tempPool, c))
2806 return XML_ERROR_NO_MEMORY;
2807 uriHash = CHAR_HASH(uriHash, c);
2808 }
2809 while (*s++ != XML_T(':'))
2810 ;
2811 do { /* copies null terminator */
2812 const XML_Char c = *s;
2813 if (!poolAppendChar(&tempPool, *s))
2814 return XML_ERROR_NO_MEMORY;
2815 uriHash = CHAR_HASH(uriHash, c);
2816 } while (*s++);
2817
2818 { /* Check hash table for duplicate of expanded name (uriName).
2819 Derived from code in lookup(HASH_TABLE *table, ...).
2820 */
2821 unsigned char step = 0;
2822 unsigned long mask = nsAttsSize - 1;
2823 j = uriHash & mask; /* index into hash table */
2824 while (nsAtts[j].version == version) {
2825 /* for speed we compare stored hash values first */
2826 if (uriHash == nsAtts[j].hash) {
2827 const XML_Char *s1 = poolStart(&tempPool);
2828 const XML_Char *s2 = nsAtts[j].uriName;
2829 /* s1 is null terminated, but not s2 */
2830 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2831 if (*s1 == 0)
2832 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2833 }
2834 if (!step)
2835 step = PROBE_STEP(uriHash, mask, nsAttsPower);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002836 j < step ? (j += nsAttsSize - step) : (j -= step);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002837 }
Fred Drake08317ae2003-10-21 15:38:55 +00002838 }
2839
2840 if (ns_triplets) { /* append namespace separator and prefix */
2841 tempPool.ptr[-1] = namespaceSeparator;
2842 s = b->prefix->name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002843 do {
2844 if (!poolAppendChar(&tempPool, *s))
2845 return XML_ERROR_NO_MEMORY;
2846 } while (*s++);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002847 }
Fred Drake08317ae2003-10-21 15:38:55 +00002848
2849 /* store expanded name in attribute list */
2850 s = poolStart(&tempPool);
2851 poolFinish(&tempPool);
2852 appAtts[i] = s;
2853
2854 /* fill empty slot with new version, uriName and hash value */
2855 nsAtts[j].version = version;
2856 nsAtts[j].hash = uriHash;
2857 nsAtts[j].uriName = s;
2858
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002859 if (!--nPrefixes) {
2860 i += 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002861 break;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002862 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002863 }
Fred Drake08317ae2003-10-21 15:38:55 +00002864 else /* not prefixed */
2865 ((XML_Char *)s)[-1] = 0; /* clear flag */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002866 }
2867 }
Fred Drake08317ae2003-10-21 15:38:55 +00002868 /* clear flags for the remaining attributes */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002869 for (; i < attIndex; i += 2)
2870 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002871 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2872 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002873
Fred Drake08317ae2003-10-21 15:38:55 +00002874 if (!ns)
2875 return XML_ERROR_NONE;
2876
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002877 /* expand the element type name */
2878 if (elementType->prefix) {
2879 binding = elementType->prefix->binding;
2880 if (!binding)
Fred Drake08317ae2003-10-21 15:38:55 +00002881 return XML_ERROR_UNBOUND_PREFIX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002882 localPart = tagNamePtr->str;
2883 while (*localPart++ != XML_T(':'))
2884 ;
2885 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002886 else if (dtd->defaultPrefix.binding) {
2887 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002888 localPart = tagNamePtr->str;
2889 }
2890 else
2891 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002892 prefixLen = 0;
Fred Drake08317ae2003-10-21 15:38:55 +00002893 if (ns_triplets && binding->prefix->name) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002894 for (; binding->prefix->name[prefixLen++];)
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002895 ; /* prefixLen includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002896 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002897 tagNamePtr->localPart = localPart;
2898 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002899 tagNamePtr->prefix = binding->prefix->name;
2900 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002901 for (i = 0; localPart[i++];)
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002902 ; /* i includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002903 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002904 if (n > binding->uriAlloc) {
2905 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002906 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002907 if (!uri)
2908 return XML_ERROR_NO_MEMORY;
2909 binding->uriAlloc = n + EXPAND_SPARE;
2910 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2911 for (p = tagStack; p; p = p->parent)
2912 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002913 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002914 FREE(binding->uri);
2915 binding->uri = uri;
2916 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002917 /* if namespaceSeparator != '\0' then uri includes it already */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002918 uri = binding->uri + binding->uriLen;
2919 memcpy(uri, localPart, i * sizeof(XML_Char));
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002920 /* we always have a namespace separator between localPart and prefix */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002921 if (prefixLen) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002922 uri += i - 1;
2923 *uri = namespaceSeparator; /* replace null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002924 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2925 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002926 tagNamePtr->str = binding->uri;
2927 return XML_ERROR_NONE;
2928}
2929
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002930/* addBinding() overwrites the value of prefix->binding without checking.
2931 Therefore one must keep track of the old value outside of addBinding().
2932*/
2933static enum XML_Error
2934addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2935 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002936{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002937 static const XML_Char xmlNamespace[] = {
2938 'h', 't', 't', 'p', ':', '/', '/',
2939 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2940 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
2941 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
2942 };
2943 static const int xmlLen =
2944 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
2945 static const XML_Char xmlnsNamespace[] = {
2946 'h', 't', 't', 'p', ':', '/', '/',
2947 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2948 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
2949 };
2950 static const int xmlnsLen =
2951 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
2952
2953 XML_Bool mustBeXML = XML_FALSE;
2954 XML_Bool isXML = XML_TRUE;
2955 XML_Bool isXMLNS = XML_TRUE;
2956
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002957 BINDING *b;
2958 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002959
Fred Drake31d485c2004-08-03 07:06:22 +00002960 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002961 if (*uri == XML_T('\0') && prefix->name)
Fred Drake31d485c2004-08-03 07:06:22 +00002962 return XML_ERROR_UNDECLARING_PREFIX;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002963
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002964 if (prefix->name
2965 && prefix->name[0] == XML_T('x')
2966 && prefix->name[1] == XML_T('m')
2967 && prefix->name[2] == XML_T('l')) {
2968
2969 /* Not allowed to bind xmlns */
2970 if (prefix->name[3] == XML_T('n')
2971 && prefix->name[4] == XML_T('s')
2972 && prefix->name[5] == XML_T('\0'))
2973 return XML_ERROR_RESERVED_PREFIX_XMLNS;
2974
2975 if (prefix->name[3] == XML_T('\0'))
2976 mustBeXML = XML_TRUE;
2977 }
2978
2979 for (len = 0; uri[len]; len++) {
2980 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
2981 isXML = XML_FALSE;
2982
2983 if (!mustBeXML && isXMLNS
2984 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
2985 isXMLNS = XML_FALSE;
2986 }
2987 isXML = isXML && len == xmlLen;
2988 isXMLNS = isXMLNS && len == xmlnsLen;
2989
2990 if (mustBeXML != isXML)
2991 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
2992 : XML_ERROR_RESERVED_NAMESPACE_URI;
2993
2994 if (isXMLNS)
2995 return XML_ERROR_RESERVED_NAMESPACE_URI;
2996
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002997 if (namespaceSeparator)
2998 len++;
2999 if (freeBindingList) {
3000 b = freeBindingList;
3001 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003002 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3003 sizeof(XML_Char) * (len + EXPAND_SPARE));
3004 if (temp == NULL)
3005 return XML_ERROR_NO_MEMORY;
3006 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003007 b->uriAlloc = len + EXPAND_SPARE;
3008 }
3009 freeBindingList = b->nextTagBinding;
3010 }
3011 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003012 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003013 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003014 return XML_ERROR_NO_MEMORY;
3015 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003016 if (!b->uri) {
3017 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003018 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003019 }
3020 b->uriAlloc = len + EXPAND_SPARE;
3021 }
3022 b->uriLen = len;
3023 memcpy(b->uri, uri, len * sizeof(XML_Char));
3024 if (namespaceSeparator)
3025 b->uri[len - 1] = namespaceSeparator;
3026 b->prefix = prefix;
3027 b->attId = attId;
3028 b->prevPrefixBinding = prefix->binding;
Fred Drake08317ae2003-10-21 15:38:55 +00003029 /* NULL binding when default namespace undeclared */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003030 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3031 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003032 else
3033 prefix->binding = b;
3034 b->nextTagBinding = *bindingsPtr;
3035 *bindingsPtr = b;
Fred Drake31d485c2004-08-03 07:06:22 +00003036 /* if attId == NULL then we are not starting a namespace scope */
3037 if (attId && startNamespaceDeclHandler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003038 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003039 prefix->binding ? uri : 0);
3040 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003041}
3042
3043/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003044 the whole file is parsed with one call.
3045*/
3046static enum XML_Error PTRCALL
3047cdataSectionProcessor(XML_Parser parser,
3048 const char *start,
3049 const char *end,
3050 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003051{
Fred Drake31d485c2004-08-03 07:06:22 +00003052 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003053 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003054 if (result != XML_ERROR_NONE)
3055 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003056 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003057 if (parentParser) { /* we are parsing an external entity */
3058 processor = externalEntityContentProcessor;
3059 return externalEntityContentProcessor(parser, start, end, endPtr);
3060 }
3061 else {
3062 processor = contentProcessor;
3063 return contentProcessor(parser, start, end, endPtr);
3064 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003065 }
3066 return result;
3067}
3068
Fred Drake31d485c2004-08-03 07:06:22 +00003069/* startPtr gets set to non-null if the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003070 the section is not yet closed.
3071*/
3072static enum XML_Error
3073doCdataSection(XML_Parser parser,
3074 const ENCODING *enc,
3075 const char **startPtr,
3076 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003077 const char **nextPtr,
3078 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003079{
3080 const char *s = *startPtr;
3081 const char **eventPP;
3082 const char **eventEndPP;
3083 if (enc == encoding) {
3084 eventPP = &eventPtr;
3085 *eventPP = s;
3086 eventEndPP = &eventEndPtr;
3087 }
3088 else {
3089 eventPP = &(openInternalEntities->internalEventPtr);
3090 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3091 }
3092 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003093 *startPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00003094
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003095 for (;;) {
3096 const char *next;
3097 int tok = XmlCdataSectionTok(enc, s, end, &next);
3098 *eventEndPP = next;
3099 switch (tok) {
3100 case XML_TOK_CDATA_SECT_CLOSE:
3101 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003102 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003103#if 0
3104 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3105 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003106 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003107#endif
3108 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003109 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003110 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003111 *nextPtr = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003112 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003113 return XML_ERROR_ABORTED;
3114 else
3115 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003116 case XML_TOK_DATA_NEWLINE:
3117 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003118 XML_Char c = 0xA;
3119 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003120 }
3121 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003122 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003123 break;
3124 case XML_TOK_DATA_CHARS:
3125 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003126 if (MUST_CONVERT(enc, s)) {
3127 for (;;) {
3128 ICHAR *dataPtr = (ICHAR *)dataBuf;
3129 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3130 *eventEndPP = next;
3131 characterDataHandler(handlerArg, dataBuf,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003132 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003133 if (s == next)
3134 break;
3135 *eventPP = s;
3136 }
3137 }
3138 else
3139 characterDataHandler(handlerArg,
3140 (XML_Char *)s,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003141 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003142 }
3143 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003144 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003145 break;
3146 case XML_TOK_INVALID:
3147 *eventPP = next;
3148 return XML_ERROR_INVALID_TOKEN;
3149 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003150 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003151 *nextPtr = s;
3152 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003153 }
3154 return XML_ERROR_PARTIAL_CHAR;
3155 case XML_TOK_PARTIAL:
3156 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003157 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003158 *nextPtr = s;
3159 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003160 }
3161 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3162 default:
3163 *eventPP = next;
3164 return XML_ERROR_UNEXPECTED_STATE;
3165 }
Fred Drake31d485c2004-08-03 07:06:22 +00003166
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003167 *eventPP = s = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003168 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003169 case XML_SUSPENDED:
3170 *nextPtr = next;
3171 return XML_ERROR_NONE;
3172 case XML_FINISHED:
3173 return XML_ERROR_ABORTED;
3174 default: ;
3175 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003176 }
3177 /* not reached */
3178}
3179
3180#ifdef XML_DTD
3181
3182/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003183 the whole file is parsed with one call.
3184*/
3185static enum XML_Error PTRCALL
3186ignoreSectionProcessor(XML_Parser parser,
3187 const char *start,
3188 const char *end,
3189 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003190{
Fred Drake31d485c2004-08-03 07:06:22 +00003191 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003192 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003193 if (result != XML_ERROR_NONE)
3194 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003195 if (start) {
3196 processor = prologProcessor;
3197 return prologProcessor(parser, start, end, endPtr);
3198 }
3199 return result;
3200}
3201
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003202/* startPtr gets set to non-null is the section is closed, and to null
3203 if the section is not yet closed.
3204*/
3205static enum XML_Error
3206doIgnoreSection(XML_Parser parser,
3207 const ENCODING *enc,
3208 const char **startPtr,
3209 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003210 const char **nextPtr,
3211 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003212{
3213 const char *next;
3214 int tok;
3215 const char *s = *startPtr;
3216 const char **eventPP;
3217 const char **eventEndPP;
3218 if (enc == encoding) {
3219 eventPP = &eventPtr;
3220 *eventPP = s;
3221 eventEndPP = &eventEndPtr;
3222 }
3223 else {
3224 eventPP = &(openInternalEntities->internalEventPtr);
3225 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3226 }
3227 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003228 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003229 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3230 *eventEndPP = next;
3231 switch (tok) {
3232 case XML_TOK_IGNORE_SECT:
3233 if (defaultHandler)
3234 reportDefault(parser, enc, s, next);
3235 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003236 *nextPtr = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003237 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003238 return XML_ERROR_ABORTED;
3239 else
3240 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003241 case XML_TOK_INVALID:
3242 *eventPP = next;
3243 return XML_ERROR_INVALID_TOKEN;
3244 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003245 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003246 *nextPtr = s;
3247 return XML_ERROR_NONE;
3248 }
3249 return XML_ERROR_PARTIAL_CHAR;
3250 case XML_TOK_PARTIAL:
3251 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003252 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003253 *nextPtr = s;
3254 return XML_ERROR_NONE;
3255 }
3256 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3257 default:
3258 *eventPP = next;
3259 return XML_ERROR_UNEXPECTED_STATE;
3260 }
3261 /* not reached */
3262}
3263
3264#endif /* XML_DTD */
3265
3266static enum XML_Error
3267initializeEncoding(XML_Parser parser)
3268{
3269 const char *s;
3270#ifdef XML_UNICODE
3271 char encodingBuf[128];
3272 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003273 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003274 else {
3275 int i;
3276 for (i = 0; protocolEncodingName[i]; i++) {
3277 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003278 || (protocolEncodingName[i] & ~0x7f) != 0) {
3279 encodingBuf[0] = '\0';
3280 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003281 }
3282 encodingBuf[i] = (char)protocolEncodingName[i];
3283 }
3284 encodingBuf[i] = '\0';
3285 s = encodingBuf;
3286 }
3287#else
3288 s = protocolEncodingName;
3289#endif
3290 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3291 return XML_ERROR_NONE;
3292 return handleUnknownEncoding(parser, protocolEncodingName);
3293}
3294
3295static enum XML_Error
3296processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003297 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003298{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003299 const char *encodingName = NULL;
3300 const XML_Char *storedEncName = NULL;
3301 const ENCODING *newEncoding = NULL;
3302 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003303 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003304 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003305 int standalone = -1;
3306 if (!(ns
3307 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003308 : XmlParseXmlDecl)(isGeneralTextEntity,
3309 encoding,
3310 s,
3311 next,
3312 &eventPtr,
3313 &version,
3314 &versionend,
3315 &encodingName,
3316 &newEncoding,
Fred Drake31d485c2004-08-03 07:06:22 +00003317 &standalone)) {
3318 if (isGeneralTextEntity)
3319 return XML_ERROR_TEXT_DECL;
3320 else
3321 return XML_ERROR_XML_DECL;
3322 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003323 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003324 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003325#ifdef XML_DTD
3326 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3327 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3328#endif /* XML_DTD */
3329 }
3330 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003331 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003332 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003333 encoding,
3334 encodingName,
3335 encodingName
3336 + XmlNameLength(encoding, encodingName));
3337 if (!storedEncName)
3338 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003339 poolFinish(&temp2Pool);
3340 }
3341 if (version) {
3342 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003343 encoding,
3344 version,
3345 versionend - encoding->minBytesPerChar);
3346 if (!storedversion)
3347 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003348 }
3349 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3350 }
3351 else if (defaultHandler)
3352 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003353 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003354 if (newEncoding) {
3355 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003356 eventPtr = encodingName;
3357 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003358 }
3359 encoding = newEncoding;
3360 }
3361 else if (encodingName) {
3362 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003363 if (!storedEncName) {
3364 storedEncName = poolStoreString(
3365 &temp2Pool, encoding, encodingName,
3366 encodingName + XmlNameLength(encoding, encodingName));
3367 if (!storedEncName)
3368 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003369 }
3370 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003371 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003372 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003373 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003374 return result;
3375 }
3376 }
3377
3378 if (storedEncName || storedversion)
3379 poolClear(&temp2Pool);
3380
3381 return XML_ERROR_NONE;
3382}
3383
3384static enum XML_Error
3385handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3386{
3387 if (unknownEncodingHandler) {
3388 XML_Encoding info;
3389 int i;
3390 for (i = 0; i < 256; i++)
3391 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003392 info.convert = NULL;
3393 info.data = NULL;
3394 info.release = NULL;
3395 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3396 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003397 ENCODING *enc;
3398 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3399 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003400 if (info.release)
3401 info.release(info.data);
3402 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003403 }
3404 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003405 ? XmlInitUnknownEncodingNS
3406 : XmlInitUnknownEncoding)(unknownEncodingMem,
3407 info.map,
3408 info.convert,
3409 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003410 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003411 unknownEncodingData = info.data;
3412 unknownEncodingRelease = info.release;
3413 encoding = enc;
3414 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003415 }
3416 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003417 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003418 info.release(info.data);
3419 }
3420 return XML_ERROR_UNKNOWN_ENCODING;
3421}
3422
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003423static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003424prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003425 const char *s,
3426 const char *end,
3427 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003428{
3429 enum XML_Error result = initializeEncoding(parser);
3430 if (result != XML_ERROR_NONE)
3431 return result;
3432 processor = prologProcessor;
3433 return prologProcessor(parser, s, end, nextPtr);
3434}
3435
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003436#ifdef XML_DTD
3437
3438static enum XML_Error PTRCALL
3439externalParEntInitProcessor(XML_Parser parser,
3440 const char *s,
3441 const char *end,
3442 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003443{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003444 enum XML_Error result = initializeEncoding(parser);
3445 if (result != XML_ERROR_NONE)
3446 return result;
3447
3448 /* we know now that XML_Parse(Buffer) has been called,
3449 so we consider the external parameter entity read */
3450 _dtd->paramEntityRead = XML_TRUE;
3451
3452 if (prologState.inEntityValue) {
3453 processor = entityValueInitProcessor;
3454 return entityValueInitProcessor(parser, s, end, nextPtr);
3455 }
3456 else {
3457 processor = externalParEntProcessor;
3458 return externalParEntProcessor(parser, s, end, nextPtr);
3459 }
3460}
3461
3462static enum XML_Error PTRCALL
3463entityValueInitProcessor(XML_Parser parser,
3464 const char *s,
3465 const char *end,
3466 const char **nextPtr)
3467{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003468 int tok;
Fred Drake31d485c2004-08-03 07:06:22 +00003469 const char *start = s;
3470 const char *next = start;
3471 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003472
Fred Drake31d485c2004-08-03 07:06:22 +00003473 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003474 tok = XmlPrologTok(encoding, start, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003475 eventEndPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003476 if (tok <= 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003477 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Fred Drake31d485c2004-08-03 07:06:22 +00003478 *nextPtr = s;
3479 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003480 }
3481 switch (tok) {
3482 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003483 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003484 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003485 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003486 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003487 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003488 case XML_TOK_NONE: /* start == end */
3489 default:
3490 break;
3491 }
Fred Drake31d485c2004-08-03 07:06:22 +00003492 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003493 return storeEntityValue(parser, encoding, s, end);
3494 }
3495 else if (tok == XML_TOK_XML_DECL) {
Fred Drake31d485c2004-08-03 07:06:22 +00003496 enum XML_Error result;
3497 result = processXmlDecl(parser, 0, start, next);
3498 if (result != XML_ERROR_NONE)
3499 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003500 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003501 case XML_SUSPENDED:
3502 *nextPtr = next;
3503 return XML_ERROR_NONE;
3504 case XML_FINISHED:
3505 return XML_ERROR_ABORTED;
3506 default:
3507 *nextPtr = next;
3508 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003509 /* stop scanning for text declaration - we found one */
3510 processor = entityValueProcessor;
3511 return entityValueProcessor(parser, next, end, nextPtr);
3512 }
3513 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3514 return XML_TOK_NONE on the next call, which would then cause the
3515 function to exit with *nextPtr set to s - that is what we want for other
3516 tokens, but not for the BOM - we would rather like to skip it;
3517 then, when this routine is entered the next time, XmlPrologTok will
3518 return XML_TOK_INVALID, since the BOM is still in the buffer
3519 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003520 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003521 *nextPtr = next;
3522 return XML_ERROR_NONE;
3523 }
3524 start = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003525 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003526 }
3527}
3528
3529static enum XML_Error PTRCALL
3530externalParEntProcessor(XML_Parser parser,
3531 const char *s,
3532 const char *end,
3533 const char **nextPtr)
3534{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003535 const char *next = s;
3536 int tok;
3537
Fred Drake31d485c2004-08-03 07:06:22 +00003538 tok = XmlPrologTok(encoding, s, end, &next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003539 if (tok <= 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003540 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003541 *nextPtr = s;
3542 return XML_ERROR_NONE;
3543 }
3544 switch (tok) {
3545 case XML_TOK_INVALID:
3546 return XML_ERROR_INVALID_TOKEN;
3547 case XML_TOK_PARTIAL:
3548 return XML_ERROR_UNCLOSED_TOKEN;
3549 case XML_TOK_PARTIAL_CHAR:
3550 return XML_ERROR_PARTIAL_CHAR;
3551 case XML_TOK_NONE: /* start == end */
3552 default:
3553 break;
3554 }
3555 }
3556 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3557 However, when parsing an external subset, doProlog will not accept a BOM
3558 as valid, and report a syntax error, so we have to skip the BOM
3559 */
3560 else if (tok == XML_TOK_BOM) {
3561 s = next;
3562 tok = XmlPrologTok(encoding, s, end, &next);
3563 }
3564
3565 processor = prologProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +00003566 return doProlog(parser, encoding, s, end, tok, next,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003567 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003568}
3569
3570static enum XML_Error PTRCALL
3571entityValueProcessor(XML_Parser parser,
3572 const char *s,
3573 const char *end,
3574 const char **nextPtr)
3575{
3576 const char *start = s;
3577 const char *next = s;
3578 const ENCODING *enc = encoding;
3579 int tok;
3580
3581 for (;;) {
3582 tok = XmlPrologTok(enc, start, end, &next);
3583 if (tok <= 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003584 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003585 *nextPtr = s;
3586 return XML_ERROR_NONE;
3587 }
3588 switch (tok) {
3589 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003590 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003591 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003592 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003593 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003594 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003595 case XML_TOK_NONE: /* start == end */
3596 default:
3597 break;
3598 }
Fred Drake31d485c2004-08-03 07:06:22 +00003599 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003600 return storeEntityValue(parser, enc, s, end);
3601 }
3602 start = next;
3603 }
3604}
3605
3606#endif /* XML_DTD */
3607
3608static enum XML_Error PTRCALL
3609prologProcessor(XML_Parser parser,
3610 const char *s,
3611 const char *end,
3612 const char **nextPtr)
3613{
3614 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003615 int tok = XmlPrologTok(encoding, s, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003616 return doProlog(parser, encoding, s, end, tok, next,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003617 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003618}
3619
3620static enum XML_Error
3621doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003622 const ENCODING *enc,
3623 const char *s,
3624 const char *end,
3625 int tok,
3626 const char *next,
Fred Drake31d485c2004-08-03 07:06:22 +00003627 const char **nextPtr,
3628 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003629{
3630#ifdef XML_DTD
3631 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3632#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003633 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3634 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3635 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3636 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3637 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3638 static const XML_Char atypeENTITIES[] =
3639 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3640 static const XML_Char atypeNMTOKEN[] = {
3641 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3642 static const XML_Char atypeNMTOKENS[] = {
3643 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3644 static const XML_Char notationPrefix[] = {
3645 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3646 static const XML_Char enumValueSep[] = { '|', '\0' };
3647 static const XML_Char enumValueStart[] = { '(', '\0' };
3648
Fred Drake31d485c2004-08-03 07:06:22 +00003649 /* save one level of indirection */
3650 DTD * const dtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003651
3652 const char **eventPP;
3653 const char **eventEndPP;
3654 enum XML_Content_Quant quant;
3655
3656 if (enc == encoding) {
3657 eventPP = &eventPtr;
3658 eventEndPP = &eventEndPtr;
3659 }
3660 else {
3661 eventPP = &(openInternalEntities->internalEventPtr);
3662 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3663 }
Fred Drake31d485c2004-08-03 07:06:22 +00003664
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003665 for (;;) {
3666 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003667 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003668 *eventPP = s;
3669 *eventEndPP = next;
3670 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003671 if (haveMore && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003672 *nextPtr = s;
3673 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003674 }
3675 switch (tok) {
3676 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003677 *eventPP = next;
3678 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003679 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003680 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003681 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003682 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003683 case XML_TOK_NONE:
3684#ifdef XML_DTD
Fred Drake31d485c2004-08-03 07:06:22 +00003685 /* for internal PE NOT referenced between declarations */
3686 if (enc != encoding && !openInternalEntities->betweenDecl) {
3687 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003688 return XML_ERROR_NONE;
Fred Drake31d485c2004-08-03 07:06:22 +00003689 }
3690 /* WFC: PE Between Declarations - must check that PE contains
3691 complete markup, not only for external PEs, but also for
3692 internal PEs if the reference occurs between declarations.
3693 */
3694 if (isParamEntity || enc != encoding) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003695 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3696 == XML_ROLE_ERROR)
Fred Drake31d485c2004-08-03 07:06:22 +00003697 return XML_ERROR_INCOMPLETE_PE;
3698 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003699 return XML_ERROR_NONE;
3700 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003701#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003702 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003703 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003704 tok = -tok;
3705 next = end;
3706 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003707 }
3708 }
3709 role = XmlTokenRole(&prologState, tok, s, next, enc);
3710 switch (role) {
3711 case XML_ROLE_XML_DECL:
3712 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003713 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3714 if (result != XML_ERROR_NONE)
3715 return result;
3716 enc = encoding;
3717 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003718 }
3719 break;
3720 case XML_ROLE_DOCTYPE_NAME:
3721 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003722 doctypeName = poolStoreString(&tempPool, enc, s, next);
3723 if (!doctypeName)
3724 return XML_ERROR_NO_MEMORY;
3725 poolFinish(&tempPool);
3726 doctypePubid = NULL;
3727 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003728 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003729 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003730 break;
3731 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3732 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003733 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3734 doctypePubid, 1);
3735 doctypeName = NULL;
3736 poolClear(&tempPool);
3737 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003738 }
3739 break;
3740#ifdef XML_DTD
3741 case XML_ROLE_TEXT_DECL:
3742 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003743 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3744 if (result != XML_ERROR_NONE)
3745 return result;
3746 enc = encoding;
3747 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003748 }
3749 break;
3750#endif /* XML_DTD */
3751 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003752#ifdef XML_DTD
3753 useForeignDTD = XML_FALSE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003754 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3755 externalSubsetName,
3756 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003757 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003758 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003759#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00003760 dtd->hasParamEntityRefs = XML_TRUE;
3761 if (startDoctypeDeclHandler) {
3762 if (!XmlIsPublicId(enc, s, next, eventPP))
3763 return XML_ERROR_PUBLICID;
3764 doctypePubid = poolStoreString(&tempPool, enc,
3765 s + enc->minBytesPerChar,
3766 next - enc->minBytesPerChar);
3767 if (!doctypePubid)
3768 return XML_ERROR_NO_MEMORY;
3769 normalizePublicId((XML_Char *)doctypePubid);
3770 poolFinish(&tempPool);
3771 handleDefault = XML_FALSE;
3772 goto alreadyChecked;
3773 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003774 /* fall through */
3775 case XML_ROLE_ENTITY_PUBLIC_ID:
3776 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00003777 return XML_ERROR_PUBLICID;
3778 alreadyChecked:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003779 if (dtd->keepProcessing && declEntity) {
3780 XML_Char *tem = poolStoreString(&dtd->pool,
3781 enc,
3782 s + enc->minBytesPerChar,
3783 next - enc->minBytesPerChar);
3784 if (!tem)
3785 return XML_ERROR_NO_MEMORY;
3786 normalizePublicId(tem);
3787 declEntity->publicId = tem;
3788 poolFinish(&dtd->pool);
3789 if (entityDeclHandler)
3790 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003791 }
3792 break;
3793 case XML_ROLE_DOCTYPE_CLOSE:
3794 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003795 startDoctypeDeclHandler(handlerArg, doctypeName,
3796 doctypeSysid, doctypePubid, 0);
3797 poolClear(&tempPool);
3798 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003799 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003800 /* doctypeSysid will be non-NULL in the case of a previous
3801 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3802 was not set, indicating an external subset
3803 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003804#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003805 if (doctypeSysid || useForeignDTD) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003806 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3807 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003808 if (paramEntityParsing && externalEntityRefHandler) {
3809 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3810 externalSubsetName,
3811 sizeof(ENTITY));
3812 if (!entity)
3813 return XML_ERROR_NO_MEMORY;
3814 if (useForeignDTD)
3815 entity->base = curBase;
3816 dtd->paramEntityRead = XML_FALSE;
3817 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3818 0,
3819 entity->base,
3820 entity->systemId,
3821 entity->publicId))
3822 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003823 if (dtd->paramEntityRead) {
3824 if (!dtd->standalone &&
3825 notStandaloneHandler &&
3826 !notStandaloneHandler(handlerArg))
3827 return XML_ERROR_NOT_STANDALONE;
3828 }
3829 /* if we didn't read the foreign DTD then this means that there
3830 is no external subset and we must reset dtd->hasParamEntityRefs
3831 */
3832 else if (!doctypeSysid)
3833 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003834 /* end of DTD - no need to update dtd->keepProcessing */
3835 }
3836 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003837 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003838#endif /* XML_DTD */
3839 if (endDoctypeDeclHandler) {
3840 endDoctypeDeclHandler(handlerArg);
3841 handleDefault = XML_FALSE;
3842 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003843 break;
3844 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003845#ifdef XML_DTD
3846 /* if there is no DOCTYPE declaration then now is the
3847 last chance to read the foreign DTD
3848 */
3849 if (useForeignDTD) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003850 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003851 dtd->hasParamEntityRefs = XML_TRUE;
3852 if (paramEntityParsing && externalEntityRefHandler) {
3853 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3854 externalSubsetName,
3855 sizeof(ENTITY));
3856 if (!entity)
3857 return XML_ERROR_NO_MEMORY;
3858 entity->base = curBase;
3859 dtd->paramEntityRead = XML_FALSE;
3860 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3861 0,
3862 entity->base,
3863 entity->systemId,
3864 entity->publicId))
3865 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003866 if (dtd->paramEntityRead) {
3867 if (!dtd->standalone &&
3868 notStandaloneHandler &&
3869 !notStandaloneHandler(handlerArg))
3870 return XML_ERROR_NOT_STANDALONE;
3871 }
3872 /* if we didn't read the foreign DTD then this means that there
3873 is no external subset and we must reset dtd->hasParamEntityRefs
3874 */
3875 else
3876 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003877 /* end of DTD - no need to update dtd->keepProcessing */
3878 }
3879 }
3880#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003881 processor = contentProcessor;
3882 return contentProcessor(parser, s, end, nextPtr);
3883 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3884 declElementType = getElementType(parser, enc, s, next);
3885 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003886 return XML_ERROR_NO_MEMORY;
3887 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003888 case XML_ROLE_ATTRIBUTE_NAME:
3889 declAttributeId = getAttributeId(parser, enc, s, next);
3890 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003891 return XML_ERROR_NO_MEMORY;
3892 declAttributeIsCdata = XML_FALSE;
3893 declAttributeType = NULL;
3894 declAttributeIsId = XML_FALSE;
3895 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003896 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003897 declAttributeIsCdata = XML_TRUE;
3898 declAttributeType = atypeCDATA;
3899 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003900 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003901 declAttributeIsId = XML_TRUE;
3902 declAttributeType = atypeID;
3903 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003904 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003905 declAttributeType = atypeIDREF;
3906 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003907 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003908 declAttributeType = atypeIDREFS;
3909 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003910 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003911 declAttributeType = atypeENTITY;
3912 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003913 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003914 declAttributeType = atypeENTITIES;
3915 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003916 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003917 declAttributeType = atypeNMTOKEN;
3918 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003919 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003920 declAttributeType = atypeNMTOKENS;
3921 checkAttListDeclHandler:
3922 if (dtd->keepProcessing && attlistDeclHandler)
3923 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003924 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003925 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3926 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003927 if (dtd->keepProcessing && attlistDeclHandler) {
3928 const XML_Char *prefix;
3929 if (declAttributeType) {
3930 prefix = enumValueSep;
3931 }
3932 else {
3933 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3934 ? notationPrefix
3935 : enumValueStart);
3936 }
3937 if (!poolAppendString(&tempPool, prefix))
3938 return XML_ERROR_NO_MEMORY;
3939 if (!poolAppend(&tempPool, enc, s, next))
3940 return XML_ERROR_NO_MEMORY;
3941 declAttributeType = tempPool.start;
3942 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003943 }
3944 break;
3945 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3946 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003947 if (dtd->keepProcessing) {
3948 if (!defineAttribute(declElementType, declAttributeId,
Fred Drake08317ae2003-10-21 15:38:55 +00003949 declAttributeIsCdata, declAttributeIsId,
3950 0, parser))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003951 return XML_ERROR_NO_MEMORY;
3952 if (attlistDeclHandler && declAttributeType) {
3953 if (*declAttributeType == XML_T('(')
3954 || (*declAttributeType == XML_T('N')
3955 && declAttributeType[1] == XML_T('O'))) {
3956 /* Enumerated or Notation type */
3957 if (!poolAppendChar(&tempPool, XML_T(')'))
3958 || !poolAppendChar(&tempPool, XML_T('\0')))
3959 return XML_ERROR_NO_MEMORY;
3960 declAttributeType = tempPool.start;
3961 poolFinish(&tempPool);
3962 }
3963 *eventEndPP = s;
3964 attlistDeclHandler(handlerArg, declElementType->name,
3965 declAttributeId->name, declAttributeType,
3966 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3967 poolClear(&tempPool);
3968 handleDefault = XML_FALSE;
3969 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003970 }
3971 break;
3972 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3973 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003974 if (dtd->keepProcessing) {
3975 const XML_Char *attVal;
Fred Drake08317ae2003-10-21 15:38:55 +00003976 enum XML_Error result =
3977 storeAttributeValue(parser, enc, declAttributeIsCdata,
3978 s + enc->minBytesPerChar,
3979 next - enc->minBytesPerChar,
3980 &dtd->pool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003981 if (result)
3982 return result;
3983 attVal = poolStart(&dtd->pool);
3984 poolFinish(&dtd->pool);
3985 /* ID attributes aren't allowed to have a default */
3986 if (!defineAttribute(declElementType, declAttributeId,
3987 declAttributeIsCdata, XML_FALSE, attVal, parser))
3988 return XML_ERROR_NO_MEMORY;
3989 if (attlistDeclHandler && declAttributeType) {
3990 if (*declAttributeType == XML_T('(')
3991 || (*declAttributeType == XML_T('N')
3992 && declAttributeType[1] == XML_T('O'))) {
3993 /* Enumerated or Notation type */
3994 if (!poolAppendChar(&tempPool, XML_T(')'))
3995 || !poolAppendChar(&tempPool, XML_T('\0')))
3996 return XML_ERROR_NO_MEMORY;
3997 declAttributeType = tempPool.start;
3998 poolFinish(&tempPool);
3999 }
4000 *eventEndPP = s;
4001 attlistDeclHandler(handlerArg, declElementType->name,
4002 declAttributeId->name, declAttributeType,
4003 attVal,
4004 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4005 poolClear(&tempPool);
4006 handleDefault = XML_FALSE;
4007 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004008 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004009 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004010 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004011 if (dtd->keepProcessing) {
4012 enum XML_Error result = storeEntityValue(parser, enc,
4013 s + enc->minBytesPerChar,
4014 next - enc->minBytesPerChar);
4015 if (declEntity) {
4016 declEntity->textPtr = poolStart(&dtd->entityValuePool);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004017 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004018 poolFinish(&dtd->entityValuePool);
4019 if (entityDeclHandler) {
4020 *eventEndPP = s;
4021 entityDeclHandler(handlerArg,
4022 declEntity->name,
4023 declEntity->is_param,
4024 declEntity->textPtr,
4025 declEntity->textLen,
4026 curBase, 0, 0, 0);
4027 handleDefault = XML_FALSE;
4028 }
4029 }
4030 else
4031 poolDiscard(&dtd->entityValuePool);
4032 if (result != XML_ERROR_NONE)
4033 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004034 }
4035 break;
4036 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004037#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004038 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004039#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004040 dtd->hasParamEntityRefs = XML_TRUE;
4041 if (startDoctypeDeclHandler) {
4042 doctypeSysid = poolStoreString(&tempPool, enc,
4043 s + enc->minBytesPerChar,
4044 next - enc->minBytesPerChar);
4045 if (doctypeSysid == NULL)
4046 return XML_ERROR_NO_MEMORY;
4047 poolFinish(&tempPool);
4048 handleDefault = XML_FALSE;
4049 }
4050#ifdef XML_DTD
4051 else
4052 /* use externalSubsetName to make doctypeSysid non-NULL
4053 for the case where no startDoctypeDeclHandler is set */
4054 doctypeSysid = externalSubsetName;
4055#endif /* XML_DTD */
4056 if (!dtd->standalone
4057#ifdef XML_DTD
4058 && !paramEntityParsing
4059#endif /* XML_DTD */
4060 && notStandaloneHandler
4061 && !notStandaloneHandler(handlerArg))
4062 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004063#ifndef XML_DTD
4064 break;
4065#else /* XML_DTD */
4066 if (!declEntity) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004067 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4068 externalSubsetName,
4069 sizeof(ENTITY));
4070 if (!declEntity)
4071 return XML_ERROR_NO_MEMORY;
4072 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004073 }
4074 /* fall through */
4075#endif /* XML_DTD */
4076 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004077 if (dtd->keepProcessing && declEntity) {
4078 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4079 s + enc->minBytesPerChar,
4080 next - enc->minBytesPerChar);
4081 if (!declEntity->systemId)
4082 return XML_ERROR_NO_MEMORY;
4083 declEntity->base = curBase;
4084 poolFinish(&dtd->pool);
4085 if (entityDeclHandler)
4086 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004087 }
4088 break;
4089 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004090 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4091 *eventEndPP = s;
4092 entityDeclHandler(handlerArg,
4093 declEntity->name,
4094 declEntity->is_param,
4095 0,0,
4096 declEntity->base,
4097 declEntity->systemId,
4098 declEntity->publicId,
4099 0);
4100 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004101 }
4102 break;
4103 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004104 if (dtd->keepProcessing && declEntity) {
4105 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4106 if (!declEntity->notation)
4107 return XML_ERROR_NO_MEMORY;
4108 poolFinish(&dtd->pool);
4109 if (unparsedEntityDeclHandler) {
4110 *eventEndPP = s;
4111 unparsedEntityDeclHandler(handlerArg,
4112 declEntity->name,
4113 declEntity->base,
4114 declEntity->systemId,
4115 declEntity->publicId,
4116 declEntity->notation);
4117 handleDefault = XML_FALSE;
4118 }
4119 else if (entityDeclHandler) {
4120 *eventEndPP = s;
4121 entityDeclHandler(handlerArg,
4122 declEntity->name,
4123 0,0,0,
4124 declEntity->base,
4125 declEntity->systemId,
4126 declEntity->publicId,
4127 declEntity->notation);
4128 handleDefault = XML_FALSE;
4129 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004130 }
4131 break;
4132 case XML_ROLE_GENERAL_ENTITY_NAME:
4133 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004134 if (XmlPredefinedEntityName(enc, s, next)) {
4135 declEntity = NULL;
4136 break;
4137 }
4138 if (dtd->keepProcessing) {
4139 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4140 if (!name)
4141 return XML_ERROR_NO_MEMORY;
4142 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
4143 sizeof(ENTITY));
4144 if (!declEntity)
4145 return XML_ERROR_NO_MEMORY;
4146 if (declEntity->name != name) {
4147 poolDiscard(&dtd->pool);
4148 declEntity = NULL;
4149 }
4150 else {
4151 poolFinish(&dtd->pool);
4152 declEntity->publicId = NULL;
4153 declEntity->is_param = XML_FALSE;
4154 /* if we have a parent parser or are reading an internal parameter
4155 entity, then the entity declaration is not considered "internal"
4156 */
4157 declEntity->is_internal = !(parentParser || openInternalEntities);
4158 if (entityDeclHandler)
4159 handleDefault = XML_FALSE;
4160 }
4161 }
4162 else {
4163 poolDiscard(&dtd->pool);
4164 declEntity = NULL;
4165 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004166 }
4167 break;
4168 case XML_ROLE_PARAM_ENTITY_NAME:
4169#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004170 if (dtd->keepProcessing) {
4171 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4172 if (!name)
4173 return XML_ERROR_NO_MEMORY;
4174 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4175 name, sizeof(ENTITY));
4176 if (!declEntity)
4177 return XML_ERROR_NO_MEMORY;
4178 if (declEntity->name != name) {
4179 poolDiscard(&dtd->pool);
4180 declEntity = NULL;
4181 }
4182 else {
4183 poolFinish(&dtd->pool);
4184 declEntity->publicId = NULL;
4185 declEntity->is_param = XML_TRUE;
4186 /* if we have a parent parser or are reading an internal parameter
4187 entity, then the entity declaration is not considered "internal"
4188 */
4189 declEntity->is_internal = !(parentParser || openInternalEntities);
4190 if (entityDeclHandler)
4191 handleDefault = XML_FALSE;
4192 }
4193 }
4194 else {
4195 poolDiscard(&dtd->pool);
4196 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004197 }
4198#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004199 declEntity = NULL;
4200#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004201 break;
4202 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004203 declNotationPublicId = NULL;
4204 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004205 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004206 declNotationName = poolStoreString(&tempPool, enc, s, next);
4207 if (!declNotationName)
4208 return XML_ERROR_NO_MEMORY;
4209 poolFinish(&tempPool);
4210 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004211 }
4212 break;
4213 case XML_ROLE_NOTATION_PUBLIC_ID:
4214 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00004215 return XML_ERROR_PUBLICID;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004216 if (declNotationName) { /* means notationDeclHandler != NULL */
4217 XML_Char *tem = poolStoreString(&tempPool,
4218 enc,
4219 s + enc->minBytesPerChar,
4220 next - enc->minBytesPerChar);
4221 if (!tem)
4222 return XML_ERROR_NO_MEMORY;
4223 normalizePublicId(tem);
4224 declNotationPublicId = tem;
4225 poolFinish(&tempPool);
4226 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004227 }
4228 break;
4229 case XML_ROLE_NOTATION_SYSTEM_ID:
4230 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004231 const XML_Char *systemId
4232 = poolStoreString(&tempPool, enc,
4233 s + enc->minBytesPerChar,
4234 next - enc->minBytesPerChar);
4235 if (!systemId)
4236 return XML_ERROR_NO_MEMORY;
4237 *eventEndPP = s;
4238 notationDeclHandler(handlerArg,
4239 declNotationName,
4240 curBase,
4241 systemId,
4242 declNotationPublicId);
4243 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004244 }
4245 poolClear(&tempPool);
4246 break;
4247 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4248 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004249 *eventEndPP = s;
4250 notationDeclHandler(handlerArg,
4251 declNotationName,
4252 curBase,
4253 0,
4254 declNotationPublicId);
4255 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004256 }
4257 poolClear(&tempPool);
4258 break;
4259 case XML_ROLE_ERROR:
4260 switch (tok) {
4261 case XML_TOK_PARAM_ENTITY_REF:
Fred Drake31d485c2004-08-03 07:06:22 +00004262 /* PE references in internal subset are
4263 not allowed within declarations. */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004264 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004265 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004266 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004267 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004268 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004269 }
4270#ifdef XML_DTD
4271 case XML_ROLE_IGNORE_SECT:
4272 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004273 enum XML_Error result;
4274 if (defaultHandler)
4275 reportDefault(parser, enc, s, next);
4276 handleDefault = XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00004277 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4278 if (result != XML_ERROR_NONE)
4279 return result;
4280 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004281 processor = ignoreSectionProcessor;
4282 return result;
4283 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004284 }
4285 break;
4286#endif /* XML_DTD */
4287 case XML_ROLE_GROUP_OPEN:
4288 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004289 if (groupSize) {
4290 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4291 if (temp == NULL)
4292 return XML_ERROR_NO_MEMORY;
4293 groupConnector = temp;
4294 if (dtd->scaffIndex) {
4295 int *temp = (int *)REALLOC(dtd->scaffIndex,
4296 groupSize * sizeof(int));
4297 if (temp == NULL)
4298 return XML_ERROR_NO_MEMORY;
4299 dtd->scaffIndex = temp;
4300 }
4301 }
4302 else {
4303 groupConnector = (char *)MALLOC(groupSize = 32);
4304 if (!groupConnector)
4305 return XML_ERROR_NO_MEMORY;
4306 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004307 }
4308 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004309 if (dtd->in_eldecl) {
4310 int myindex = nextScaffoldPart(parser);
4311 if (myindex < 0)
4312 return XML_ERROR_NO_MEMORY;
4313 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4314 dtd->scaffLevel++;
4315 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4316 if (elementDeclHandler)
4317 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004318 }
4319 break;
4320 case XML_ROLE_GROUP_SEQUENCE:
4321 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004322 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004323 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004324 if (dtd->in_eldecl && elementDeclHandler)
4325 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004326 break;
4327 case XML_ROLE_GROUP_CHOICE:
4328 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004329 return XML_ERROR_SYNTAX;
4330 if (dtd->in_eldecl
4331 && !groupConnector[prologState.level]
4332 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4333 != XML_CTYPE_MIXED)
4334 ) {
4335 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4336 = XML_CTYPE_CHOICE;
4337 if (elementDeclHandler)
4338 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004339 }
4340 groupConnector[prologState.level] = '|';
4341 break;
4342 case XML_ROLE_PARAM_ENTITY_REF:
4343#ifdef XML_DTD
4344 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004345 dtd->hasParamEntityRefs = XML_TRUE;
4346 if (!paramEntityParsing)
4347 dtd->keepProcessing = dtd->standalone;
4348 else {
4349 const XML_Char *name;
4350 ENTITY *entity;
4351 name = poolStoreString(&dtd->pool, enc,
4352 s + enc->minBytesPerChar,
4353 next - enc->minBytesPerChar);
4354 if (!name)
4355 return XML_ERROR_NO_MEMORY;
4356 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4357 poolDiscard(&dtd->pool);
4358 /* first, determine if a check for an existing declaration is needed;
4359 if yes, check that the entity exists, and that it is internal,
4360 otherwise call the skipped entity handler
4361 */
4362 if (prologState.documentEntity &&
4363 (dtd->standalone
4364 ? !openInternalEntities
4365 : !dtd->hasParamEntityRefs)) {
4366 if (!entity)
4367 return XML_ERROR_UNDEFINED_ENTITY;
4368 else if (!entity->is_internal)
4369 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4370 }
4371 else if (!entity) {
4372 dtd->keepProcessing = dtd->standalone;
4373 /* cannot report skipped entities in declarations */
4374 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4375 skippedEntityHandler(handlerArg, name, 1);
4376 handleDefault = XML_FALSE;
4377 }
4378 break;
4379 }
4380 if (entity->open)
4381 return XML_ERROR_RECURSIVE_ENTITY_REF;
4382 if (entity->textPtr) {
4383 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004384 XML_Bool betweenDecl =
4385 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4386 result = processInternalEntity(parser, entity, betweenDecl);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004387 if (result != XML_ERROR_NONE)
4388 return result;
4389 handleDefault = XML_FALSE;
4390 break;
4391 }
4392 if (externalEntityRefHandler) {
4393 dtd->paramEntityRead = XML_FALSE;
4394 entity->open = XML_TRUE;
4395 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4396 0,
4397 entity->base,
4398 entity->systemId,
4399 entity->publicId)) {
4400 entity->open = XML_FALSE;
4401 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4402 }
4403 entity->open = XML_FALSE;
4404 handleDefault = XML_FALSE;
4405 if (!dtd->paramEntityRead) {
4406 dtd->keepProcessing = dtd->standalone;
4407 break;
4408 }
4409 }
4410 else {
4411 dtd->keepProcessing = dtd->standalone;
4412 break;
4413 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004414 }
4415#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004416 if (!dtd->standalone &&
4417 notStandaloneHandler &&
4418 !notStandaloneHandler(handlerArg))
4419 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004420 break;
4421
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004422 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004423
4424 case XML_ROLE_ELEMENT_NAME:
4425 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004426 declElementType = getElementType(parser, enc, s, next);
4427 if (!declElementType)
4428 return XML_ERROR_NO_MEMORY;
4429 dtd->scaffLevel = 0;
4430 dtd->scaffCount = 0;
4431 dtd->in_eldecl = XML_TRUE;
4432 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004433 }
4434 break;
4435
4436 case XML_ROLE_CONTENT_ANY:
4437 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004438 if (dtd->in_eldecl) {
4439 if (elementDeclHandler) {
4440 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4441 if (!content)
4442 return XML_ERROR_NO_MEMORY;
4443 content->quant = XML_CQUANT_NONE;
4444 content->name = NULL;
4445 content->numchildren = 0;
4446 content->children = NULL;
4447 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4448 XML_CTYPE_ANY :
4449 XML_CTYPE_EMPTY);
4450 *eventEndPP = s;
4451 elementDeclHandler(handlerArg, declElementType->name, content);
4452 handleDefault = XML_FALSE;
4453 }
4454 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004455 }
4456 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004457
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004458 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004459 if (dtd->in_eldecl) {
4460 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4461 = XML_CTYPE_MIXED;
4462 if (elementDeclHandler)
4463 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004464 }
4465 break;
4466
4467 case XML_ROLE_CONTENT_ELEMENT:
4468 quant = XML_CQUANT_NONE;
4469 goto elementContent;
4470 case XML_ROLE_CONTENT_ELEMENT_OPT:
4471 quant = XML_CQUANT_OPT;
4472 goto elementContent;
4473 case XML_ROLE_CONTENT_ELEMENT_REP:
4474 quant = XML_CQUANT_REP;
4475 goto elementContent;
4476 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4477 quant = XML_CQUANT_PLUS;
4478 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004479 if (dtd->in_eldecl) {
4480 ELEMENT_TYPE *el;
4481 const XML_Char *name;
4482 int nameLen;
4483 const char *nxt = (quant == XML_CQUANT_NONE
4484 ? next
4485 : next - enc->minBytesPerChar);
4486 int myindex = nextScaffoldPart(parser);
4487 if (myindex < 0)
4488 return XML_ERROR_NO_MEMORY;
4489 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4490 dtd->scaffold[myindex].quant = quant;
4491 el = getElementType(parser, enc, s, nxt);
4492 if (!el)
4493 return XML_ERROR_NO_MEMORY;
4494 name = el->name;
4495 dtd->scaffold[myindex].name = name;
4496 nameLen = 0;
4497 for (; name[nameLen++]; );
4498 dtd->contentStringLen += nameLen;
4499 if (elementDeclHandler)
4500 handleDefault = XML_FALSE;
4501 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004502 break;
4503
4504 case XML_ROLE_GROUP_CLOSE:
4505 quant = XML_CQUANT_NONE;
4506 goto closeGroup;
4507 case XML_ROLE_GROUP_CLOSE_OPT:
4508 quant = XML_CQUANT_OPT;
4509 goto closeGroup;
4510 case XML_ROLE_GROUP_CLOSE_REP:
4511 quant = XML_CQUANT_REP;
4512 goto closeGroup;
4513 case XML_ROLE_GROUP_CLOSE_PLUS:
4514 quant = XML_CQUANT_PLUS;
4515 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004516 if (dtd->in_eldecl) {
4517 if (elementDeclHandler)
4518 handleDefault = XML_FALSE;
4519 dtd->scaffLevel--;
4520 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4521 if (dtd->scaffLevel == 0) {
4522 if (!handleDefault) {
4523 XML_Content *model = build_model(parser);
4524 if (!model)
4525 return XML_ERROR_NO_MEMORY;
4526 *eventEndPP = s;
4527 elementDeclHandler(handlerArg, declElementType->name, model);
4528 }
4529 dtd->in_eldecl = XML_FALSE;
4530 dtd->contentStringLen = 0;
4531 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004532 }
4533 break;
4534 /* End element declaration stuff */
4535
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004536 case XML_ROLE_PI:
4537 if (!reportProcessingInstruction(parser, enc, s, next))
4538 return XML_ERROR_NO_MEMORY;
4539 handleDefault = XML_FALSE;
4540 break;
4541 case XML_ROLE_COMMENT:
4542 if (!reportComment(parser, enc, s, next))
4543 return XML_ERROR_NO_MEMORY;
4544 handleDefault = XML_FALSE;
4545 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004546 case XML_ROLE_NONE:
4547 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004548 case XML_TOK_BOM:
4549 handleDefault = XML_FALSE;
4550 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004551 }
4552 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004553 case XML_ROLE_DOCTYPE_NONE:
4554 if (startDoctypeDeclHandler)
4555 handleDefault = XML_FALSE;
4556 break;
4557 case XML_ROLE_ENTITY_NONE:
4558 if (dtd->keepProcessing && entityDeclHandler)
4559 handleDefault = XML_FALSE;
4560 break;
4561 case XML_ROLE_NOTATION_NONE:
4562 if (notationDeclHandler)
4563 handleDefault = XML_FALSE;
4564 break;
4565 case XML_ROLE_ATTLIST_NONE:
4566 if (dtd->keepProcessing && attlistDeclHandler)
4567 handleDefault = XML_FALSE;
4568 break;
4569 case XML_ROLE_ELEMENT_NONE:
4570 if (elementDeclHandler)
4571 handleDefault = XML_FALSE;
4572 break;
4573 } /* end of big switch */
4574
4575 if (handleDefault && defaultHandler)
4576 reportDefault(parser, enc, s, next);
4577
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004578 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00004579 case XML_SUSPENDED:
4580 *nextPtr = next;
4581 return XML_ERROR_NONE;
4582 case XML_FINISHED:
4583 return XML_ERROR_ABORTED;
4584 default:
4585 s = next;
4586 tok = XmlPrologTok(enc, s, end, &next);
4587 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004588 }
4589 /* not reached */
4590}
4591
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004592static enum XML_Error PTRCALL
4593epilogProcessor(XML_Parser parser,
4594 const char *s,
4595 const char *end,
4596 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004597{
4598 processor = epilogProcessor;
4599 eventPtr = s;
4600 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004601 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004602 int tok = XmlPrologTok(encoding, s, end, &next);
4603 eventEndPtr = next;
4604 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004605 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004606 case -XML_TOK_PROLOG_S:
4607 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004608 reportDefault(parser, encoding, s, next);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004609 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00004610 return XML_ERROR_ABORTED;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004611 }
Fred Drake31d485c2004-08-03 07:06:22 +00004612 *nextPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004613 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004614 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00004615 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004616 return XML_ERROR_NONE;
4617 case XML_TOK_PROLOG_S:
4618 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004619 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004620 break;
4621 case XML_TOK_PI:
4622 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004623 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004624 break;
4625 case XML_TOK_COMMENT:
4626 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004627 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004628 break;
4629 case XML_TOK_INVALID:
4630 eventPtr = next;
4631 return XML_ERROR_INVALID_TOKEN;
4632 case XML_TOK_PARTIAL:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004633 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004634 *nextPtr = s;
4635 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004636 }
4637 return XML_ERROR_UNCLOSED_TOKEN;
4638 case XML_TOK_PARTIAL_CHAR:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004639 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004640 *nextPtr = s;
4641 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004642 }
4643 return XML_ERROR_PARTIAL_CHAR;
4644 default:
4645 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4646 }
4647 eventPtr = s = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004648 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00004649 case XML_SUSPENDED:
4650 *nextPtr = next;
4651 return XML_ERROR_NONE;
4652 case XML_FINISHED:
4653 return XML_ERROR_ABORTED;
4654 default: ;
4655 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004656 }
4657}
4658
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004659static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +00004660processInternalEntity(XML_Parser parser, ENTITY *entity,
4661 XML_Bool betweenDecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004662{
Fred Drake31d485c2004-08-03 07:06:22 +00004663 const char *textStart, *textEnd;
4664 const char *next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004665 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004666 OPEN_INTERNAL_ENTITY *openEntity;
4667
4668 if (freeInternalEntities) {
4669 openEntity = freeInternalEntities;
4670 freeInternalEntities = openEntity->next;
4671 }
4672 else {
4673 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4674 if (!openEntity)
4675 return XML_ERROR_NO_MEMORY;
4676 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004677 entity->open = XML_TRUE;
Fred Drake31d485c2004-08-03 07:06:22 +00004678 entity->processed = 0;
4679 openEntity->next = openInternalEntities;
4680 openInternalEntities = openEntity;
4681 openEntity->entity = entity;
4682 openEntity->startTagLevel = tagLevel;
4683 openEntity->betweenDecl = betweenDecl;
4684 openEntity->internalEventPtr = NULL;
4685 openEntity->internalEventEndPtr = NULL;
4686 textStart = (char *)entity->textPtr;
4687 textEnd = (char *)(entity->textPtr + entity->textLen);
4688
4689#ifdef XML_DTD
4690 if (entity->is_param) {
4691 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4692 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4693 next, &next, XML_FALSE);
4694 }
4695 else
4696#endif /* XML_DTD */
4697 result = doContent(parser, tagLevel, internalEncoding, textStart,
4698 textEnd, &next, XML_FALSE);
4699
4700 if (result == XML_ERROR_NONE) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004701 if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4702 entity->processed = (int)(next - textStart);
Fred Drake31d485c2004-08-03 07:06:22 +00004703 processor = internalEntityProcessor;
4704 }
4705 else {
4706 entity->open = XML_FALSE;
4707 openInternalEntities = openEntity->next;
4708 /* put openEntity back in list of free instances */
4709 openEntity->next = freeInternalEntities;
4710 freeInternalEntities = openEntity;
4711 }
4712 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004713 return result;
4714}
4715
Fred Drake31d485c2004-08-03 07:06:22 +00004716static enum XML_Error PTRCALL
4717internalEntityProcessor(XML_Parser parser,
4718 const char *s,
4719 const char *end,
4720 const char **nextPtr)
4721{
4722 ENTITY *entity;
4723 const char *textStart, *textEnd;
4724 const char *next;
4725 enum XML_Error result;
4726 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4727 if (!openEntity)
4728 return XML_ERROR_UNEXPECTED_STATE;
4729
4730 entity = openEntity->entity;
4731 textStart = ((char *)entity->textPtr) + entity->processed;
4732 textEnd = (char *)(entity->textPtr + entity->textLen);
4733
4734#ifdef XML_DTD
4735 if (entity->is_param) {
4736 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4737 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4738 next, &next, XML_FALSE);
4739 }
4740 else
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004741#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00004742 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4743 textStart, textEnd, &next, XML_FALSE);
4744
4745 if (result != XML_ERROR_NONE)
4746 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004747 else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4748 entity->processed = (int)(next - (char *)entity->textPtr);
Fred Drake31d485c2004-08-03 07:06:22 +00004749 return result;
4750 }
4751 else {
4752 entity->open = XML_FALSE;
4753 openInternalEntities = openEntity->next;
4754 /* put openEntity back in list of free instances */
4755 openEntity->next = freeInternalEntities;
4756 freeInternalEntities = openEntity;
4757 }
4758
4759#ifdef XML_DTD
4760 if (entity->is_param) {
4761 int tok;
4762 processor = prologProcessor;
4763 tok = XmlPrologTok(encoding, s, end, &next);
4764 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004765 (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004766 }
4767 else
4768#endif /* XML_DTD */
4769 {
4770 processor = contentProcessor;
4771 /* see externalEntityContentProcessor vs contentProcessor */
4772 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004773 nextPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004774 }
4775}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004776
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004777static enum XML_Error PTRCALL
4778errorProcessor(XML_Parser parser,
4779 const char *s,
4780 const char *end,
4781 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004782{
4783 return errorCode;
4784}
4785
4786static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004787storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4788 const char *ptr, const char *end,
4789 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004790{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004791 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4792 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004793 if (result)
4794 return result;
4795 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4796 poolChop(pool);
4797 if (!poolAppendChar(pool, XML_T('\0')))
4798 return XML_ERROR_NO_MEMORY;
4799 return XML_ERROR_NONE;
4800}
4801
4802static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004803appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4804 const char *ptr, const char *end,
4805 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004806{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004807 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004808 for (;;) {
4809 const char *next;
4810 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4811 switch (tok) {
4812 case XML_TOK_NONE:
4813 return XML_ERROR_NONE;
4814 case XML_TOK_INVALID:
4815 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004816 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004817 return XML_ERROR_INVALID_TOKEN;
4818 case XML_TOK_PARTIAL:
4819 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004820 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004821 return XML_ERROR_INVALID_TOKEN;
4822 case XML_TOK_CHAR_REF:
4823 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004824 XML_Char buf[XML_ENCODE_MAX];
4825 int i;
4826 int n = XmlCharRefNumber(enc, ptr);
4827 if (n < 0) {
4828 if (enc == encoding)
4829 eventPtr = ptr;
4830 return XML_ERROR_BAD_CHAR_REF;
4831 }
4832 if (!isCdata
4833 && n == 0x20 /* space */
4834 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4835 break;
4836 n = XmlEncode(n, (ICHAR *)buf);
4837 if (!n) {
4838 if (enc == encoding)
4839 eventPtr = ptr;
4840 return XML_ERROR_BAD_CHAR_REF;
4841 }
4842 for (i = 0; i < n; i++) {
4843 if (!poolAppendChar(pool, buf[i]))
4844 return XML_ERROR_NO_MEMORY;
4845 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004846 }
4847 break;
4848 case XML_TOK_DATA_CHARS:
4849 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004850 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004851 break;
4852 case XML_TOK_TRAILING_CR:
4853 next = ptr + enc->minBytesPerChar;
4854 /* fall through */
4855 case XML_TOK_ATTRIBUTE_VALUE_S:
4856 case XML_TOK_DATA_NEWLINE:
4857 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004858 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004859 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004860 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004861 break;
4862 case XML_TOK_ENTITY_REF:
4863 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004864 const XML_Char *name;
4865 ENTITY *entity;
4866 char checkEntityDecl;
4867 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4868 ptr + enc->minBytesPerChar,
4869 next - enc->minBytesPerChar);
4870 if (ch) {
4871 if (!poolAppendChar(pool, ch))
4872 return XML_ERROR_NO_MEMORY;
4873 break;
4874 }
4875 name = poolStoreString(&temp2Pool, enc,
4876 ptr + enc->minBytesPerChar,
4877 next - enc->minBytesPerChar);
4878 if (!name)
4879 return XML_ERROR_NO_MEMORY;
4880 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4881 poolDiscard(&temp2Pool);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004882 /* First, determine if a check for an existing declaration is needed;
4883 if yes, check that the entity exists, and that it is internal.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004884 */
4885 if (pool == &dtd->pool) /* are we called from prolog? */
4886 checkEntityDecl =
4887#ifdef XML_DTD
4888 prologState.documentEntity &&
4889#endif /* XML_DTD */
4890 (dtd->standalone
4891 ? !openInternalEntities
4892 : !dtd->hasParamEntityRefs);
4893 else /* if (pool == &tempPool): we are called from content */
4894 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4895 if (checkEntityDecl) {
4896 if (!entity)
4897 return XML_ERROR_UNDEFINED_ENTITY;
4898 else if (!entity->is_internal)
4899 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4900 }
4901 else if (!entity) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004902 /* Cannot report skipped entity here - see comments on
4903 skippedEntityHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004904 if (skippedEntityHandler)
4905 skippedEntityHandler(handlerArg, name, 0);
4906 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004907 /* Cannot call the default handler because this would be
4908 out of sync with the call to the startElementHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004909 if ((pool == &tempPool) && defaultHandler)
4910 reportDefault(parser, enc, ptr, next);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004911 */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004912 break;
4913 }
4914 if (entity->open) {
4915 if (enc == encoding)
4916 eventPtr = ptr;
4917 return XML_ERROR_RECURSIVE_ENTITY_REF;
4918 }
4919 if (entity->notation) {
4920 if (enc == encoding)
4921 eventPtr = ptr;
4922 return XML_ERROR_BINARY_ENTITY_REF;
4923 }
4924 if (!entity->textPtr) {
4925 if (enc == encoding)
4926 eventPtr = ptr;
4927 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4928 }
4929 else {
4930 enum XML_Error result;
4931 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4932 entity->open = XML_TRUE;
4933 result = appendAttributeValue(parser, internalEncoding, isCdata,
4934 (char *)entity->textPtr,
4935 (char *)textEnd, pool);
4936 entity->open = XML_FALSE;
4937 if (result)
4938 return result;
4939 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004940 }
4941 break;
4942 default:
4943 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004944 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004945 return XML_ERROR_UNEXPECTED_STATE;
4946 }
4947 ptr = next;
4948 }
4949 /* not reached */
4950}
4951
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004952static enum XML_Error
4953storeEntityValue(XML_Parser parser,
4954 const ENCODING *enc,
4955 const char *entityTextPtr,
4956 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004957{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004958 DTD * const dtd = _dtd; /* save one level of indirection */
4959 STRING_POOL *pool = &(dtd->entityValuePool);
4960 enum XML_Error result = XML_ERROR_NONE;
4961#ifdef XML_DTD
4962 int oldInEntityValue = prologState.inEntityValue;
4963 prologState.inEntityValue = 1;
4964#endif /* XML_DTD */
4965 /* never return Null for the value argument in EntityDeclHandler,
4966 since this would indicate an external entity; therefore we
4967 have to make sure that entityValuePool.start is not null */
4968 if (!pool->blocks) {
4969 if (!poolGrow(pool))
4970 return XML_ERROR_NO_MEMORY;
4971 }
4972
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004973 for (;;) {
4974 const char *next;
4975 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4976 switch (tok) {
4977 case XML_TOK_PARAM_ENTITY_REF:
4978#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004979 if (isParamEntity || enc != encoding) {
4980 const XML_Char *name;
4981 ENTITY *entity;
4982 name = poolStoreString(&tempPool, enc,
4983 entityTextPtr + enc->minBytesPerChar,
4984 next - enc->minBytesPerChar);
4985 if (!name) {
4986 result = XML_ERROR_NO_MEMORY;
4987 goto endEntityValue;
4988 }
4989 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4990 poolDiscard(&tempPool);
4991 if (!entity) {
4992 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4993 /* cannot report skipped entity here - see comments on
4994 skippedEntityHandler
4995 if (skippedEntityHandler)
4996 skippedEntityHandler(handlerArg, name, 0);
4997 */
4998 dtd->keepProcessing = dtd->standalone;
4999 goto endEntityValue;
5000 }
5001 if (entity->open) {
5002 if (enc == encoding)
5003 eventPtr = entityTextPtr;
5004 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5005 goto endEntityValue;
5006 }
5007 if (entity->systemId) {
5008 if (externalEntityRefHandler) {
5009 dtd->paramEntityRead = XML_FALSE;
5010 entity->open = XML_TRUE;
5011 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5012 0,
5013 entity->base,
5014 entity->systemId,
5015 entity->publicId)) {
5016 entity->open = XML_FALSE;
5017 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5018 goto endEntityValue;
5019 }
5020 entity->open = XML_FALSE;
5021 if (!dtd->paramEntityRead)
5022 dtd->keepProcessing = dtd->standalone;
5023 }
5024 else
5025 dtd->keepProcessing = dtd->standalone;
5026 }
5027 else {
5028 entity->open = XML_TRUE;
5029 result = storeEntityValue(parser,
5030 internalEncoding,
5031 (char *)entity->textPtr,
5032 (char *)(entity->textPtr
5033 + entity->textLen));
5034 entity->open = XML_FALSE;
5035 if (result)
5036 goto endEntityValue;
5037 }
5038 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005039 }
5040#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00005041 /* In the internal subset, PE references are not legal
5042 within markup declarations, e.g entity values in this case. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005043 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005044 result = XML_ERROR_PARAM_ENTITY_REF;
5045 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005046 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005047 result = XML_ERROR_NONE;
5048 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005049 case XML_TOK_ENTITY_REF:
5050 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005051 if (!poolAppend(pool, enc, entityTextPtr, next)) {
5052 result = XML_ERROR_NO_MEMORY;
5053 goto endEntityValue;
5054 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005055 break;
5056 case XML_TOK_TRAILING_CR:
5057 next = entityTextPtr + enc->minBytesPerChar;
5058 /* fall through */
5059 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005060 if (pool->end == pool->ptr && !poolGrow(pool)) {
5061 result = XML_ERROR_NO_MEMORY;
5062 goto endEntityValue;
5063 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005064 *(pool->ptr)++ = 0xA;
5065 break;
5066 case XML_TOK_CHAR_REF:
5067 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005068 XML_Char buf[XML_ENCODE_MAX];
5069 int i;
5070 int n = XmlCharRefNumber(enc, entityTextPtr);
5071 if (n < 0) {
5072 if (enc == encoding)
5073 eventPtr = entityTextPtr;
5074 result = XML_ERROR_BAD_CHAR_REF;
5075 goto endEntityValue;
5076 }
5077 n = XmlEncode(n, (ICHAR *)buf);
5078 if (!n) {
5079 if (enc == encoding)
5080 eventPtr = entityTextPtr;
5081 result = XML_ERROR_BAD_CHAR_REF;
5082 goto endEntityValue;
5083 }
5084 for (i = 0; i < n; i++) {
5085 if (pool->end == pool->ptr && !poolGrow(pool)) {
5086 result = XML_ERROR_NO_MEMORY;
5087 goto endEntityValue;
5088 }
5089 *(pool->ptr)++ = buf[i];
5090 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005091 }
5092 break;
5093 case XML_TOK_PARTIAL:
5094 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005095 eventPtr = entityTextPtr;
5096 result = XML_ERROR_INVALID_TOKEN;
5097 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005098 case XML_TOK_INVALID:
5099 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005100 eventPtr = next;
5101 result = XML_ERROR_INVALID_TOKEN;
5102 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005103 default:
5104 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005105 eventPtr = entityTextPtr;
5106 result = XML_ERROR_UNEXPECTED_STATE;
5107 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005108 }
5109 entityTextPtr = next;
5110 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005111endEntityValue:
5112#ifdef XML_DTD
5113 prologState.inEntityValue = oldInEntityValue;
5114#endif /* XML_DTD */
5115 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005116}
5117
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005118static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005119normalizeLines(XML_Char *s)
5120{
5121 XML_Char *p;
5122 for (;; s++) {
5123 if (*s == XML_T('\0'))
5124 return;
5125 if (*s == 0xD)
5126 break;
5127 }
5128 p = s;
5129 do {
5130 if (*s == 0xD) {
5131 *p++ = 0xA;
5132 if (*++s == 0xA)
5133 s++;
5134 }
5135 else
5136 *p++ = *s++;
5137 } while (*s);
5138 *p = XML_T('\0');
5139}
5140
5141static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005142reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5143 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005144{
5145 const XML_Char *target;
5146 XML_Char *data;
5147 const char *tem;
5148 if (!processingInstructionHandler) {
5149 if (defaultHandler)
5150 reportDefault(parser, enc, start, end);
5151 return 1;
5152 }
5153 start += enc->minBytesPerChar * 2;
5154 tem = start + XmlNameLength(enc, start);
5155 target = poolStoreString(&tempPool, enc, start, tem);
5156 if (!target)
5157 return 0;
5158 poolFinish(&tempPool);
5159 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005160 XmlSkipS(enc, tem),
5161 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005162 if (!data)
5163 return 0;
5164 normalizeLines(data);
5165 processingInstructionHandler(handlerArg, target, data);
5166 poolClear(&tempPool);
5167 return 1;
5168}
5169
5170static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005171reportComment(XML_Parser parser, const ENCODING *enc,
5172 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005173{
5174 XML_Char *data;
5175 if (!commentHandler) {
5176 if (defaultHandler)
5177 reportDefault(parser, enc, start, end);
5178 return 1;
5179 }
5180 data = poolStoreString(&tempPool,
5181 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005182 start + enc->minBytesPerChar * 4,
5183 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005184 if (!data)
5185 return 0;
5186 normalizeLines(data);
5187 commentHandler(handlerArg, data);
5188 poolClear(&tempPool);
5189 return 1;
5190}
5191
5192static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005193reportDefault(XML_Parser parser, const ENCODING *enc,
5194 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005195{
5196 if (MUST_CONVERT(enc, s)) {
5197 const char **eventPP;
5198 const char **eventEndPP;
5199 if (enc == encoding) {
5200 eventPP = &eventPtr;
5201 eventEndPP = &eventEndPtr;
5202 }
5203 else {
5204 eventPP = &(openInternalEntities->internalEventPtr);
5205 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5206 }
5207 do {
5208 ICHAR *dataPtr = (ICHAR *)dataBuf;
5209 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5210 *eventEndPP = s;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005211 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005212 *eventPP = s;
5213 } while (s != end);
5214 }
5215 else
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005216 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005217}
5218
5219
5220static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005221defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5222 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005223{
5224 DEFAULT_ATTRIBUTE *att;
5225 if (value || isId) {
5226 /* The handling of default attributes gets messed up if we have
5227 a default which duplicates a non-default. */
5228 int i;
5229 for (i = 0; i < type->nDefaultAtts; i++)
5230 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005231 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005232 if (isId && !type->idAtt && !attId->xmlns)
5233 type->idAtt = attId;
5234 }
5235 if (type->nDefaultAtts == type->allocDefaultAtts) {
5236 if (type->allocDefaultAtts == 0) {
5237 type->allocDefaultAtts = 8;
Fred Drake08317ae2003-10-21 15:38:55 +00005238 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005239 * sizeof(DEFAULT_ATTRIBUTE));
5240 if (!type->defaultAtts)
5241 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005242 }
5243 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005244 DEFAULT_ATTRIBUTE *temp;
5245 int count = type->allocDefaultAtts * 2;
5246 temp = (DEFAULT_ATTRIBUTE *)
5247 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5248 if (temp == NULL)
5249 return 0;
5250 type->allocDefaultAtts = count;
5251 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005252 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005253 }
5254 att = type->defaultAtts + type->nDefaultAtts;
5255 att->id = attId;
5256 att->value = value;
5257 att->isCdata = isCdata;
5258 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005259 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005260 type->nDefaultAtts += 1;
5261 return 1;
5262}
5263
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005264static int
5265setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005266{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005267 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005268 const XML_Char *name;
5269 for (name = elementType->name; *name; name++) {
5270 if (*name == XML_T(':')) {
5271 PREFIX *prefix;
5272 const XML_Char *s;
5273 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005274 if (!poolAppendChar(&dtd->pool, *s))
5275 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005276 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005277 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5278 return 0;
5279 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5280 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005281 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005282 return 0;
5283 if (prefix->name == poolStart(&dtd->pool))
5284 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005285 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005286 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005287 elementType->prefix = prefix;
5288
5289 }
5290 }
5291 return 1;
5292}
5293
5294static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005295getAttributeId(XML_Parser parser, const ENCODING *enc,
5296 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005297{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005298 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005299 ATTRIBUTE_ID *id;
5300 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005301 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5302 return NULL;
5303 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005304 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005305 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005306 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005307 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005308 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005309 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005310 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005311 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005312 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005313 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005314 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005315 if (!ns)
5316 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005317 else if (name[0] == XML_T('x')
5318 && name[1] == XML_T('m')
5319 && name[2] == XML_T('l')
5320 && name[3] == XML_T('n')
5321 && name[4] == XML_T('s')
5322 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
5323 if (name[5] == XML_T('\0'))
5324 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005325 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005326 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
5327 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005328 }
5329 else {
5330 int i;
5331 for (i = 0; name[i]; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005332 /* attributes without prefix are *not* in the default namespace */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005333 if (name[i] == XML_T(':')) {
5334 int j;
5335 for (j = 0; j < i; j++) {
5336 if (!poolAppendChar(&dtd->pool, name[j]))
5337 return NULL;
5338 }
5339 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5340 return NULL;
5341 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5342 sizeof(PREFIX));
5343 if (id->prefix->name == poolStart(&dtd->pool))
5344 poolFinish(&dtd->pool);
5345 else
5346 poolDiscard(&dtd->pool);
5347 break;
5348 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005349 }
5350 }
5351 }
5352 return id;
5353}
5354
5355#define CONTEXT_SEP XML_T('\f')
5356
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005357static const XML_Char *
5358getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005359{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005360 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005361 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005362 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005363
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005364 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005365 int i;
5366 int len;
5367 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005368 return NULL;
5369 len = dtd->defaultPrefix.binding->uriLen;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005370 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005371 len--;
5372 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005373 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5374 return NULL;
5375 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005376 }
5377
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005378 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005379 for (;;) {
5380 int i;
5381 int len;
5382 const XML_Char *s;
5383 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5384 if (!prefix)
5385 break;
5386 if (!prefix->binding)
5387 continue;
5388 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005389 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005390 for (s = prefix->name; *s; s++)
5391 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005392 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005393 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005394 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005395 len = prefix->binding->uriLen;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005396 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005397 len--;
5398 for (i = 0; i < len; i++)
5399 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005400 return NULL;
5401 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005402 }
5403
5404
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005405 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005406 for (;;) {
5407 const XML_Char *s;
5408 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5409 if (!e)
5410 break;
5411 if (!e->open)
5412 continue;
5413 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005414 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005415 for (s = e->name; *s; s++)
5416 if (!poolAppendChar(&tempPool, *s))
5417 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005418 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005419 }
5420
5421 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005422 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005423 return tempPool.start;
5424}
5425
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005426static XML_Bool
5427setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005428{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005429 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005430 const XML_Char *s = context;
5431
5432 while (*context != XML_T('\0')) {
5433 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5434 ENTITY *e;
5435 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005436 return XML_FALSE;
5437 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005438 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005439 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005440 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005441 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005442 context = s;
5443 poolDiscard(&tempPool);
5444 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005445 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005446 PREFIX *prefix;
5447 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005448 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005449 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005450 if (!poolAppendChar(&tempPool, XML_T('\0')))
5451 return XML_FALSE;
5452 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
5453 sizeof(PREFIX));
5454 if (!prefix)
5455 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005456 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005457 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5458 if (!prefix->name)
5459 return XML_FALSE;
5460 }
5461 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005462 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005463 for (context = s + 1;
5464 *context != CONTEXT_SEP && *context != XML_T('\0');
5465 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005466 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005467 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005468 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005469 return XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00005470 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005471 &inheritedBindings) != XML_ERROR_NONE)
5472 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005473 poolDiscard(&tempPool);
5474 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005475 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005476 s = context;
5477 }
5478 else {
5479 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005480 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005481 s++;
5482 }
5483 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005484 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005485}
5486
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005487static void FASTCALL
5488normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005489{
5490 XML_Char *p = publicId;
5491 XML_Char *s;
5492 for (s = publicId; *s; s++) {
5493 switch (*s) {
5494 case 0x20:
5495 case 0xD:
5496 case 0xA:
5497 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005498 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005499 break;
5500 default:
5501 *p++ = *s;
5502 }
5503 }
5504 if (p != publicId && p[-1] == 0x20)
5505 --p;
5506 *p = XML_T('\0');
5507}
5508
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005509static DTD *
5510dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005511{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005512 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5513 if (p == NULL)
5514 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005515 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005516 poolInit(&(p->entityValuePool), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005517 hashTableInit(&(p->generalEntities), ms);
5518 hashTableInit(&(p->elementTypes), ms);
5519 hashTableInit(&(p->attributeIds), ms);
5520 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005521#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005522 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005523 hashTableInit(&(p->paramEntities), ms);
5524#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005525 p->defaultPrefix.name = NULL;
5526 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005527
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005528 p->in_eldecl = XML_FALSE;
5529 p->scaffIndex = NULL;
5530 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005531 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005532 p->scaffSize = 0;
5533 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005534 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005535
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005536 p->keepProcessing = XML_TRUE;
5537 p->hasParamEntityRefs = XML_FALSE;
5538 p->standalone = XML_FALSE;
5539 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005540}
5541
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005542static void
5543dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005544{
5545 HASH_TABLE_ITER iter;
5546 hashTableIterInit(&iter, &(p->elementTypes));
5547 for (;;) {
5548 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5549 if (!e)
5550 break;
5551 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005552 ms->free_fcn(e->defaultAtts);
5553 }
5554 hashTableClear(&(p->generalEntities));
5555#ifdef XML_DTD
5556 p->paramEntityRead = XML_FALSE;
5557 hashTableClear(&(p->paramEntities));
5558#endif /* XML_DTD */
5559 hashTableClear(&(p->elementTypes));
5560 hashTableClear(&(p->attributeIds));
5561 hashTableClear(&(p->prefixes));
5562 poolClear(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005563 poolClear(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005564 p->defaultPrefix.name = NULL;
5565 p->defaultPrefix.binding = NULL;
5566
5567 p->in_eldecl = XML_FALSE;
Fred Drake08317ae2003-10-21 15:38:55 +00005568
5569 ms->free_fcn(p->scaffIndex);
5570 p->scaffIndex = NULL;
5571 ms->free_fcn(p->scaffold);
5572 p->scaffold = NULL;
5573
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005574 p->scaffLevel = 0;
5575 p->scaffSize = 0;
5576 p->scaffCount = 0;
5577 p->contentStringLen = 0;
5578
5579 p->keepProcessing = XML_TRUE;
5580 p->hasParamEntityRefs = XML_FALSE;
5581 p->standalone = XML_FALSE;
5582}
5583
5584static void
5585dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5586{
5587 HASH_TABLE_ITER iter;
5588 hashTableIterInit(&iter, &(p->elementTypes));
5589 for (;;) {
5590 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5591 if (!e)
5592 break;
5593 if (e->allocDefaultAtts != 0)
5594 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005595 }
5596 hashTableDestroy(&(p->generalEntities));
5597#ifdef XML_DTD
5598 hashTableDestroy(&(p->paramEntities));
5599#endif /* XML_DTD */
5600 hashTableDestroy(&(p->elementTypes));
5601 hashTableDestroy(&(p->attributeIds));
5602 hashTableDestroy(&(p->prefixes));
5603 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005604 poolDestroy(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005605 if (isDocEntity) {
Fred Drake08317ae2003-10-21 15:38:55 +00005606 ms->free_fcn(p->scaffIndex);
5607 ms->free_fcn(p->scaffold);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005608 }
5609 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005610}
5611
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005612/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5613 The new DTD has already been initialized.
5614*/
5615static int
5616dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005617{
5618 HASH_TABLE_ITER iter;
5619
5620 /* Copy the prefix table. */
5621
5622 hashTableIterInit(&iter, &(oldDtd->prefixes));
5623 for (;;) {
5624 const XML_Char *name;
5625 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5626 if (!oldP)
5627 break;
5628 name = poolCopyString(&(newDtd->pool), oldP->name);
5629 if (!name)
5630 return 0;
5631 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5632 return 0;
5633 }
5634
5635 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5636
5637 /* Copy the attribute id table. */
5638
5639 for (;;) {
5640 ATTRIBUTE_ID *newA;
5641 const XML_Char *name;
5642 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5643
5644 if (!oldA)
5645 break;
5646 /* Remember to allocate the scratch byte before the name. */
5647 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5648 return 0;
5649 name = poolCopyString(&(newDtd->pool), oldA->name);
5650 if (!name)
5651 return 0;
5652 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005653 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5654 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005655 if (!newA)
5656 return 0;
5657 newA->maybeTokenized = oldA->maybeTokenized;
5658 if (oldA->prefix) {
5659 newA->xmlns = oldA->xmlns;
5660 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005661 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005662 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005663 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5664 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005665 }
5666 }
5667
5668 /* Copy the element type table. */
5669
5670 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5671
5672 for (;;) {
5673 int i;
5674 ELEMENT_TYPE *newE;
5675 const XML_Char *name;
5676 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5677 if (!oldE)
5678 break;
5679 name = poolCopyString(&(newDtd->pool), oldE->name);
5680 if (!name)
5681 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005682 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5683 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005684 if (!newE)
5685 return 0;
5686 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005687 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5688 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5689 if (!newE->defaultAtts) {
5690 ms->free_fcn(newE);
5691 return 0;
5692 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005693 }
5694 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005695 newE->idAtt = (ATTRIBUTE_ID *)
5696 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005697 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5698 if (oldE->prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005699 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5700 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005701 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005702 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5703 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005704 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5705 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005706 newE->defaultAtts[i].value
5707 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5708 if (!newE->defaultAtts[i].value)
5709 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005710 }
5711 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005712 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005713 }
5714 }
5715
5716 /* Copy the entity tables. */
5717 if (!copyEntityTable(&(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005718 &(newDtd->pool),
5719 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005720 return 0;
5721
5722#ifdef XML_DTD
5723 if (!copyEntityTable(&(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005724 &(newDtd->pool),
5725 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005726 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005727 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005728#endif /* XML_DTD */
5729
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005730 newDtd->keepProcessing = oldDtd->keepProcessing;
5731 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005732 newDtd->standalone = oldDtd->standalone;
5733
5734 /* Don't want deep copying for scaffolding */
5735 newDtd->in_eldecl = oldDtd->in_eldecl;
5736 newDtd->scaffold = oldDtd->scaffold;
5737 newDtd->contentStringLen = oldDtd->contentStringLen;
5738 newDtd->scaffSize = oldDtd->scaffSize;
5739 newDtd->scaffLevel = oldDtd->scaffLevel;
5740 newDtd->scaffIndex = oldDtd->scaffIndex;
5741
5742 return 1;
5743} /* End dtdCopy */
5744
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005745static int
5746copyEntityTable(HASH_TABLE *newTable,
5747 STRING_POOL *newPool,
5748 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005749{
5750 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005751 const XML_Char *cachedOldBase = NULL;
5752 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005753
5754 hashTableIterInit(&iter, oldTable);
5755
5756 for (;;) {
5757 ENTITY *newE;
5758 const XML_Char *name;
5759 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5760 if (!oldE)
5761 break;
5762 name = poolCopyString(newPool, oldE->name);
5763 if (!name)
5764 return 0;
5765 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5766 if (!newE)
5767 return 0;
5768 if (oldE->systemId) {
5769 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5770 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005771 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005772 newE->systemId = tem;
5773 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005774 if (oldE->base == cachedOldBase)
5775 newE->base = cachedNewBase;
5776 else {
5777 cachedOldBase = oldE->base;
5778 tem = poolCopyString(newPool, cachedOldBase);
5779 if (!tem)
5780 return 0;
5781 cachedNewBase = newE->base = tem;
5782 }
5783 }
5784 if (oldE->publicId) {
5785 tem = poolCopyString(newPool, oldE->publicId);
5786 if (!tem)
5787 return 0;
5788 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005789 }
5790 }
5791 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005792 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5793 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005794 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005795 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005796 newE->textPtr = tem;
5797 newE->textLen = oldE->textLen;
5798 }
5799 if (oldE->notation) {
5800 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5801 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005802 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005803 newE->notation = tem;
5804 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005805 newE->is_param = oldE->is_param;
5806 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005807 }
5808 return 1;
5809}
5810
Fred Drake08317ae2003-10-21 15:38:55 +00005811#define INIT_POWER 6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005812
Fred Drake08317ae2003-10-21 15:38:55 +00005813static XML_Bool FASTCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005814keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005815{
5816 for (; *s1 == *s2; s1++, s2++)
5817 if (*s1 == 0)
Fred Drake08317ae2003-10-21 15:38:55 +00005818 return XML_TRUE;
5819 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005820}
5821
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005822static unsigned long FASTCALL
5823hash(KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005824{
5825 unsigned long h = 0;
5826 while (*s)
Fred Drake08317ae2003-10-21 15:38:55 +00005827 h = CHAR_HASH(h, *s++);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005828 return h;
5829}
5830
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005831static NAMED *
5832lookup(HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005833{
5834 size_t i;
5835 if (table->size == 0) {
5836 size_t tsize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005837 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005838 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005839 table->power = INIT_POWER;
5840 /* table->size is a power of 2 */
5841 table->size = (size_t)1 << INIT_POWER;
5842 tsize = table->size * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005843 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Fred Drake31d485c2004-08-03 07:06:22 +00005844 if (!table->v) {
5845 table->size = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005846 return NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00005847 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005848 memset(table->v, 0, tsize);
Fred Drake08317ae2003-10-21 15:38:55 +00005849 i = hash(name) & ((unsigned long)table->size - 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005850 }
5851 else {
5852 unsigned long h = hash(name);
Fred Drake08317ae2003-10-21 15:38:55 +00005853 unsigned long mask = (unsigned long)table->size - 1;
5854 unsigned char step = 0;
5855 i = h & mask;
5856 while (table->v[i]) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005857 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005858 return table->v[i];
Fred Drake08317ae2003-10-21 15:38:55 +00005859 if (!step)
5860 step = PROBE_STEP(h, mask, table->power);
5861 i < step ? (i += table->size - step) : (i -= step);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005862 }
5863 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005864 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005865
5866 /* check for overflow (table is half full) */
5867 if (table->used >> (table->power - 1)) {
5868 unsigned char newPower = table->power + 1;
5869 size_t newSize = (size_t)1 << newPower;
5870 unsigned long newMask = (unsigned long)newSize - 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005871 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005872 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005873 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005874 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005875 memset(newV, 0, tsize);
5876 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005877 if (table->v[i]) {
Fred Drake08317ae2003-10-21 15:38:55 +00005878 unsigned long newHash = hash(table->v[i]->name);
5879 size_t j = newHash & newMask;
5880 step = 0;
5881 while (newV[j]) {
5882 if (!step)
5883 step = PROBE_STEP(newHash, newMask, newPower);
5884 j < step ? (j += newSize - step) : (j -= step);
5885 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005886 newV[j] = table->v[i];
5887 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005888 table->mem->free_fcn(table->v);
5889 table->v = newV;
Fred Drake08317ae2003-10-21 15:38:55 +00005890 table->power = newPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005891 table->size = newSize;
Fred Drake08317ae2003-10-21 15:38:55 +00005892 i = h & newMask;
5893 step = 0;
5894 while (table->v[i]) {
5895 if (!step)
5896 step = PROBE_STEP(h, newMask, newPower);
5897 i < step ? (i += newSize - step) : (i -= step);
5898 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005899 }
5900 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005901 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005902 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005903 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005904 memset(table->v[i], 0, createSize);
5905 table->v[i]->name = name;
5906 (table->used)++;
5907 return table->v[i];
5908}
5909
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005910static void FASTCALL
5911hashTableClear(HASH_TABLE *table)
5912{
5913 size_t i;
5914 for (i = 0; i < table->size; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005915 table->mem->free_fcn(table->v[i]);
5916 table->v[i] = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005917 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005918 table->used = 0;
5919}
5920
5921static void FASTCALL
5922hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005923{
5924 size_t i;
Fred Drake08317ae2003-10-21 15:38:55 +00005925 for (i = 0; i < table->size; i++)
5926 table->mem->free_fcn(table->v[i]);
5927 table->mem->free_fcn(table->v);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005928}
5929
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005930static void FASTCALL
5931hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005932{
Fred Drake08317ae2003-10-21 15:38:55 +00005933 p->power = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005934 p->size = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005935 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005936 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005937 p->mem = ms;
5938}
5939
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005940static void FASTCALL
5941hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005942{
5943 iter->p = table->v;
5944 iter->end = iter->p + table->size;
5945}
5946
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005947static NAMED * FASTCALL
5948hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005949{
5950 while (iter->p != iter->end) {
5951 NAMED *tem = *(iter->p)++;
5952 if (tem)
5953 return tem;
5954 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005955 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005956}
5957
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005958static void FASTCALL
5959poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005960{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005961 pool->blocks = NULL;
5962 pool->freeBlocks = NULL;
5963 pool->start = NULL;
5964 pool->ptr = NULL;
5965 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005966 pool->mem = ms;
5967}
5968
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005969static void FASTCALL
5970poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005971{
5972 if (!pool->freeBlocks)
5973 pool->freeBlocks = pool->blocks;
5974 else {
5975 BLOCK *p = pool->blocks;
5976 while (p) {
5977 BLOCK *tem = p->next;
5978 p->next = pool->freeBlocks;
5979 pool->freeBlocks = p;
5980 p = tem;
5981 }
5982 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005983 pool->blocks = NULL;
5984 pool->start = NULL;
5985 pool->ptr = NULL;
5986 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005987}
5988
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005989static void FASTCALL
5990poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005991{
5992 BLOCK *p = pool->blocks;
5993 while (p) {
5994 BLOCK *tem = p->next;
5995 pool->mem->free_fcn(p);
5996 p = tem;
5997 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005998 p = pool->freeBlocks;
5999 while (p) {
6000 BLOCK *tem = p->next;
6001 pool->mem->free_fcn(p);
6002 p = tem;
6003 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006004}
6005
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006006static XML_Char *
6007poolAppend(STRING_POOL *pool, const ENCODING *enc,
6008 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006009{
6010 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006011 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006012 for (;;) {
6013 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6014 if (ptr == end)
6015 break;
6016 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006017 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006018 }
6019 return pool->start;
6020}
6021
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006022static const XML_Char * FASTCALL
6023poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006024{
6025 do {
6026 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006027 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006028 } while (*s++);
6029 s = pool->start;
6030 poolFinish(pool);
6031 return s;
6032}
6033
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006034static const XML_Char *
6035poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006036{
6037 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006038 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006039 for (; n > 0; --n, s++) {
6040 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006041 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006042 }
6043 s = pool->start;
6044 poolFinish(pool);
6045 return s;
6046}
6047
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006048static const XML_Char * FASTCALL
6049poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006050{
6051 while (*s) {
6052 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006053 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006054 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006055 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006056 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006057}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006058
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006059static XML_Char *
6060poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6061 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006062{
6063 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006064 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006065 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006066 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006067 *(pool->ptr)++ = 0;
6068 return pool->start;
6069}
6070
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006071static XML_Bool FASTCALL
6072poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006073{
6074 if (pool->freeBlocks) {
6075 if (pool->start == 0) {
6076 pool->blocks = pool->freeBlocks;
6077 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006078 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006079 pool->start = pool->blocks->s;
6080 pool->end = pool->start + pool->blocks->size;
6081 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006082 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006083 }
6084 if (pool->end - pool->start < pool->freeBlocks->size) {
6085 BLOCK *tem = pool->freeBlocks->next;
6086 pool->freeBlocks->next = pool->blocks;
6087 pool->blocks = pool->freeBlocks;
6088 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006089 memcpy(pool->blocks->s, pool->start,
6090 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006091 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6092 pool->start = pool->blocks->s;
6093 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006094 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006095 }
6096 }
6097 if (pool->blocks && pool->start == pool->blocks->s) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006098 int blockSize = (int)(pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006099 pool->blocks = (BLOCK *)
6100 pool->mem->realloc_fcn(pool->blocks,
Fred Drake08317ae2003-10-21 15:38:55 +00006101 (offsetof(BLOCK, s)
6102 + blockSize * sizeof(XML_Char)));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006103 if (pool->blocks == NULL)
6104 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006105 pool->blocks->size = blockSize;
6106 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6107 pool->start = pool->blocks->s;
6108 pool->end = pool->start + blockSize;
6109 }
6110 else {
6111 BLOCK *tem;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006112 int blockSize = (int)(pool->end - pool->start);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006113 if (blockSize < INIT_BLOCK_SIZE)
6114 blockSize = INIT_BLOCK_SIZE;
6115 else
6116 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006117 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
Fred Drake08317ae2003-10-21 15:38:55 +00006118 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006119 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006120 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006121 tem->size = blockSize;
6122 tem->next = pool->blocks;
6123 pool->blocks = tem;
6124 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006125 memcpy(tem->s, pool->start,
6126 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006127 pool->ptr = tem->s + (pool->ptr - pool->start);
6128 pool->start = tem->s;
6129 pool->end = tem->s + blockSize;
6130 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006131 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006132}
6133
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006134static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006135nextScaffoldPart(XML_Parser parser)
6136{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006137 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006138 CONTENT_SCAFFOLD * me;
6139 int next;
6140
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006141 if (!dtd->scaffIndex) {
6142 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6143 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006144 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006145 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006146 }
6147
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006148 if (dtd->scaffCount >= dtd->scaffSize) {
6149 CONTENT_SCAFFOLD *temp;
6150 if (dtd->scaffold) {
6151 temp = (CONTENT_SCAFFOLD *)
6152 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6153 if (temp == NULL)
6154 return -1;
6155 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006156 }
6157 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006158 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6159 * sizeof(CONTENT_SCAFFOLD));
6160 if (temp == NULL)
6161 return -1;
6162 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006163 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006164 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006165 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006166 next = dtd->scaffCount++;
6167 me = &dtd->scaffold[next];
6168 if (dtd->scaffLevel) {
6169 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006170 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006171 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006172 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006173 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006174 parent->firstchild = next;
6175 parent->lastchild = next;
6176 parent->childcnt++;
6177 }
6178 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6179 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006180}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006181
6182static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006183build_node(XML_Parser parser,
6184 int src_node,
6185 XML_Content *dest,
6186 XML_Content **contpos,
6187 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006188{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006189 DTD * const dtd = _dtd; /* save one level of indirection */
6190 dest->type = dtd->scaffold[src_node].type;
6191 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006192 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006193 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006194 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006195 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006196 for (;;) {
6197 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006198 if (!*src)
6199 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006200 src++;
6201 }
6202 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006203 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006204 }
6205 else {
6206 unsigned int i;
6207 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006208 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006209 dest->children = *contpos;
6210 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006211 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6212 i < dest->numchildren;
6213 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006214 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6215 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006216 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006217 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006218}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006219
6220static XML_Content *
6221build_model (XML_Parser parser)
6222{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006223 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006224 XML_Content *ret;
6225 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006226 XML_Char * str;
6227 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6228 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006229
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006230 ret = (XML_Content *)MALLOC(allocsize);
6231 if (!ret)
6232 return NULL;
6233
6234 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006235 cpos = &ret[1];
6236
6237 build_node(parser, 0, ret, &cpos, &str);
6238 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006239}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006240
6241static ELEMENT_TYPE *
6242getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006243 const ENCODING *enc,
6244 const char *ptr,
6245 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006246{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006247 DTD * const dtd = _dtd; /* save one level of indirection */
6248 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006249 ELEMENT_TYPE *ret;
6250
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006251 if (!name)
6252 return NULL;
6253 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6254 if (!ret)
6255 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006256 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006257 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006258 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006259 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006260 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006261 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006262 }
6263 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006264}